# Romanian power grid (Transelectrica SEN) > Romania's electricity grid in real time, as published by Transelectrica, the transmission system operator. The SEN feed gives a snapshot roughly every ten seconds: national consumption and production, the eight generation sources, the eighteen interconnection points with Bulgaria, Serbia, Hungary, Moldova and Ukraine, and the 15-minute averages the feed publishes alongside. The source keeps no history — there is only "now" — so this dataset is the history. Beside it sit two series from Transelectrica's prosumers application: installed prosumer capacity by county and month, and hourly production forecasts per county published one and two days ahead. - Dataset id: `transelectrica-sen` - Update cadence: hourly - Upstream source: https://www.transelectrica.ro/widget/web/tel/sen-harta - Tags: energy, electricity, grid, romania, transelectrica, renewables, prosumers, time-series - Current version: ingest `01M54P1P6KG1XYB7D0NBYB8HGM`, snapshot 2026-10-17, generated 2026-10-17T10:21:17.573Z ## Licence and attribution - Licence: Transelectrica public operational data (no explicit re-use licence) (`LicenseRef-Transelectrica-Public-Data`) - Licence text: https://www.transelectrica.ro/ - Required attribution: Transelectrica - Notes: Transelectrica publishes this operational data openly on its public website and its public prosumers application, with no authentication and no stated restriction on access. It states NO re-use licence of any kind: there is no licence page, no terms-of-use page and no open-data statement on the site. The only relevant notice is a bare "Copyright © Transelectrica 2013 - 2026" in the page footer; the GDPR and cookie policies concern personal data and say nothing about this data, and the prosumers application carries an accuracy and liability disclaimer only. So the position is: publicly published operational data, no re-use licence stated by the publisher, only a bare copyright notice. This dataset is a derived work — the numeric measurements, restructured, documented and re-typed, with no page, image or other creative material copied — and it is republished with attribution to Transelectrica. Anyone redistributing it commercially, or relying on it where the terms matter, should seek permission from Transelectrica first. It is also an operational feed, not a settlement record: values are instantaneous readings and forecasts, they are not reconciled afterwards, and they must not be used where money or safety depends on the number. Reproduce the attribution line verbatim anywhere you republish this data. ## Manifest - Start here for how this directory works: https://data.bunnytech.app/llms.txt - This dataset: https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/manifest.json - All datasets: https://data-directory.fsn1.your-objectstorage.com/public/index.json - Human page: https://data.bunnytech.app/datasets/transelectrica-sen The manifest is the contract: file URLs, row counts, column types, min/max statistics and example queries all live there. Re-read it to discover a new version. ## Fastest path — Parquet exports Immutable, physically sorted snapshot exports. No catalog fetch, best row-group pruning, safe to cache forever. Register one view per table: ```sql INSTALL httpfs; LOAD httpfs; CREATE OR REPLACE VIEW sen_readings AS SELECT * FROM read_parquet('https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_readings.parquet'); CREATE OR REPLACE VIEW sen_generation AS SELECT * FROM read_parquet('https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_generation.parquet'); CREATE OR REPLACE VIEW sen_interconnection_flows AS SELECT * FROM read_parquet('https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_interconnection_flows.parquet'); CREATE OR REPLACE VIEW sen_feed_keys AS SELECT * FROM read_parquet('https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_feed_keys.parquet'); CREATE OR REPLACE VIEW prosumer_installed_capacity AS SELECT * FROM read_parquet('https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/prosumer_installed_capacity.parquet'); CREATE OR REPLACE VIEW prosumer_forecast_hourly AS SELECT * FROM read_parquet('https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/prosumer_forecast_hourly.parquet'); ``` Example queries: -- Production mix over the last week: The long table is the one to group by. The time filter comes first because reading_time is the leading sort column. ```sql ATTACH IF NOT EXISTS 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/catalog.ducklake' AS "datadirectory" (READ_ONLY); SELECT date_trunc('hour', reading_time) AS hour, source_code, avg(power_mw) AS avg_mw FROM datadirectory.transelectrica_sen.sen_generation WHERE reading_time >= now() - INTERVAL 7 DAY GROUP BY 1, 2 ORDER BY 1 DESC, 3 DESC ``` -- Net cross-border exchange by country: Positive is an import into Romania. The eighteen points sum to SOLD in sen_readings. ```sql ATTACH IF NOT EXISTS 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/catalog.ducklake' AS "datadirectory" (READ_ONLY); SELECT country, avg(flow_mw) AS avg_mw FROM datadirectory.transelectrica_sen.sen_interconnection_flows WHERE reading_time >= now() - INTERVAL 1 DAY AND country IS NOT NULL GROUP BY 1 ORDER BY 2 DESC ``` ## Live lake — DuckLake catalog with time travel Attach the published catalog read-only over plain https. This works in native DuckDB AND in duckdb-wasm in the browser — the reader catalog resolves its data files through public https URLs, so no credentials and no backend are involved. ```sql INSTALL ducklake; LOAD ducklake; ATTACH 'ducklake:https://data-directory.fsn1.your-objectstorage.com/catalog/transelectrica-sen/catalog.ducklake' AS transelectrica_sen (READ_ONLY); SELECT * FROM transelectrica_sen.main.sen_readings LIMIT 5; USE transelectrica_sen; ``` - Latest catalog: https://data-directory.fsn1.your-objectstorage.com/catalog/transelectrica-sen/catalog.ducklake - This exact version: https://data-directory.fsn1.your-objectstorage.com/catalog/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/catalog.ducklake (sha256 2a6e6bd5981a9d430e23f34991cc3ba5e28e64f671d9ffacf4181ffe1bf58123) - Written by DuckDB v1.5.5 - Time travel: this ingest is snapshot 30 — e.g. `SELECT * FROM transelectrica_sen.sen_readings AT (VERSION => 30)` ## Wholesale — S3 access For bulk downloads, read the bucket prefix directly over S3 with httpfs: ```sql INSTALL httpfs; LOAD httpfs; CREATE SECRET hetzner ( TYPE s3, ENDPOINT 'fsn1.your-objectstorage.com', URL_STYLE 'path', KEY_ID '', SECRET '' ); SELECT * FROM read_parquet('s3://data-directory/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/**/*.parquet'); ``` ## Schema ### sen_readings One row per snapshot of Transelectrica's live SEN feed, wide: every documented quantity the feed publishes as its own column, plus the six it publishes without documenting. Border-crossing flows are NOT here — they have eighteen columns of their own shape and are published long-form in sen_interconnection_flows. The feed refreshes roughly every ten seconds and carries no history, so this table is the history: it is only as complete as the ingest schedule that filled it. Empty is missing, never zero, and negative values are real. - 22 rows · 9.1 KB · write mode `append` - Physically sorted by: `reading_time` - Primary key: `reading_time` - Files: 1 - https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_readings.parquet (22 rows) Columns: - `reading_time` TIMESTAMP NOT NULL — The instant the feed itself stamped on this snapshot, in UTC. The source writes it as "yy/M/d HH:mm:ss" in Romanian civil time (Europe/Bucharest, EET/EEST) with a two-digit year and an unpadded month and day; it is parsed and converted here so the column is a single, sortable, zone-free UTC scale. This is the identity of the row. (range: "2026-09-03 06:02:42" … "2026-10-17 10:19:32") (~22 distinct) - `ingested_at` TIMESTAMPTZ NOT NULL — When this connector read the feed (UTC). Compare it with reading_time to see how stale the snapshot was when it was captured; a gap of more than a minute or two means the feed, not the ingest, was behind. - `carb_mw` DOUBLE [MW] — CARB gives the instantaneous power, in MW, generated from coal in Romania's National Power System, one of the eight sources that sum to total production (PROD). - `gaze_mw` DOUBLE [MW] — GAZE gives the instantaneous power, in MW, generated from hydrocarbons (natural gas) in Romania's National Power System, one of the eight sources that sum to total production (PROD). - `ape_mw` DOUBLE [MW] — APE gives the total instantaneous hydro power, in MW, generated in Romania's National Power System, computed as the sum of the CHEA and CHEF components and itself folded into total production (PROD). - `nucl_mw` DOUBLE [MW] — NUCL gives the instantaneous power, in MW, generated at the nuclear power plant in Romania's National Power System, one of the eight sources that sum to total production (PROD). - `eolian_mw` DOUBLE [MW] — EOLIAN gives the instantaneous power, in MW, generated from wind in Romania's National Power System, one of the eight sources that sum to total production (PROD). - `foto_mw` DOUBLE [MW] — FOTO gives the instantaneous power, in MW, generated from photovoltaic panels in Romania's National Power System, which can read slightly negative overnight due to the installations' own consumption, and is one of the eight sources that sum to total production (PROD). - `bmasa_mw` DOUBLE [MW] — BMASA gives the instantaneous power, in MW, generated from biomass in Romania's National Power System, one of the eight sources that sum to total production (PROD). - `ispoz_mw` DOUBLE [MW] — ISPOZ gives the instantaneous power, in MW, generated from pumped-storage hydro plants in Romania's National Power System, one of the eight sources that sum to total production (PROD). - `cons_mw` DOUBLE [MW] — CONS gives the total instantaneous consumption, in MW, of Romania's National Power System. - `prod_mw` DOUBLE [MW] — PROD gives the total instantaneous production, in MW, of the National Power System, computed as the sum of the eight sources CARB, GAZE, APE, NUCL, EOLIAN, FOTO, BMASA and ISPOZ. - `sold_mw` DOUBLE [MW] — SOLD gives the instantaneous cross-border exchange balance, in MW, computed as CONS minus PROD and equal to the sum of the 18 real cross-border interconnection points, where a positive value means Romania is a net importer and a negative value means it is a net exporter. - `chea_mw` DOUBLE [MW] — CHEA gives the instantaneous power, in MW, of one of the two components the source splits total hydro production into (APE = CHEA + CHEF); the source does not document which plant or group of hydro plants this code covers, so nothing further is assumed. - `chef_mw` DOUBLE [MW] — CHEF gives the instantaneous power, in MW, of the other component the source splits total hydro production into (APE = CHEA + CHEF); the source does not document which plants this code covers, and it is NOT a cross-border interconnection point, contrary to some unofficial listings. - `mint_mw` DOUBLE [MW] — MINT gives the instantaneous power, in MW, measured at the Mintia point, a domestic location within Romania's National Power System (not a cross-border interconnection point, contrary to some unofficial listings), with no further detail documented by the source about the exact meaning of the value. - `paro_mw` DOUBLE [MW] — PARO gives the instantaneous power, in MW, measured at the Paroșeni point, a domestic location within Romania's National Power System (not a cross-border interconnection point, contrary to some unofficial listings), with no further detail documented by the source about the exact meaning of the value. - `ias2_mw` DOUBLE [MW] — IAS2 gives the instantaneous power, in MW, measured at the Iași 2 point, a domestic location within Romania's National Power System (not a cross-border interconnection point, contrary to some unofficial listings), with no further detail documented by the source about the exact meaning of the value. - `cons15_mw` DOUBLE [MW] — CONS15 is the 15-minute rolling average, in MW, of total consumption CONS of the National Power System. - `carb15_mw` DOUBLE [MW] — CARB15 is the 15-minute rolling average, in MW, of the coal-fired generation CARB. - `gaze15_mw` DOUBLE [MW] — GAZE15 is the 15-minute rolling average, in MW, of the hydrocarbon (natural gas) generation GAZE. - `nucl15_mw` DOUBLE [MW] — NUCL15 is the 15-minute rolling average, in MW, of the nuclear generation NUCL. - `eolian15_mw` DOUBLE [MW] — EOLIAN15 is the 15-minute rolling average, in MW, of the wind generation EOLIAN. - `foto15_mw` DOUBLE [MW] — FOTO15 is the 15-minute rolling average, in MW, of the photovoltaic generation FOTO. - `bmasa15_mw` DOUBLE [MW] — BMASA15 is the 15-minute rolling average, in MW, of the biomass generation BMASA. - `chea15_mw` DOUBLE [MW] — CHEA15 is the 15-minute rolling average, in MW, of the CHEA hydro component, one of the two components of total hydro production APE not documented in further detail by the source. - `chef15_mw` DOUBLE [MW] — CHEF15 is the 15-minute rolling average, in MW, of the CHEF hydro component, the other undocumented component of total hydro production APE, and NOT a cross-border interconnection point. - `kozl115_mw` DOUBLE [MW] — KOZL115 is the 15-minute rolling average, in MW, of the KOZL1 power flow on the Kozlodui 1 interconnection line with Bulgaria. - `kozl215_mw` DOUBLE [MW] — KOZL215 is the 15-minute rolling average, in MW, of the KOZL2 power flow on the Kozlodui 2 interconnection line with Bulgaria. - `varn15_mw` DOUBLE [MW] — VARN15 is the 15-minute rolling average, in MW, of the VARN power flow on the Varna interconnection line with Bulgaria. - `dobr15_mw` DOUBLE [MW] — DOBR15 is the 15-minute rolling average, in MW, of the DOBR power flow on the Dobrogea interconnection line with Bulgaria. - `djer15_mw` DOUBLE [MW] — DJER15 is the 15-minute rolling average, in MW, of the DJER power flow on the Djerdap interconnection line with Serbia. - `pancevo2115_mw` DOUBLE [MW] — PANCEVO2115 is the 15-minute rolling average, in MW, of the PANCEVO21 power flow on the Pancevo 2.1 interconnection line with Serbia. - `pancevo2215_mw` DOUBLE [MW] — PANCEVO2215 is the 15-minute rolling average, in MW, of the PANCEVO22 power flow on the Pancevo 2.2 interconnection line with Serbia. - `beke115_mw` DOUBLE [MW] — BEKE115 is the 15-minute rolling average, in MW, of the BEKE1 power flow on the Bekescsaba interconnection line with Hungary. - `sand15_mw` DOUBLE [MW] — SAND15 is the 15-minute rolling average, in MW, of the SAND power flow on the Sandorfalva interconnection line with Hungary. - `muka15_mw` DOUBLE [MW] — MUKA15 is the 15-minute rolling average, in MW, of the MUKA power flow on the Mukacevo interconnection line with Ukraine. - `paro15_mw` DOUBLE [MW] — PARO15 is the 15-minute rolling average, in MW, of the PARO value measured at the domestic Paroșeni point, which is not a cross-border interconnection point. - `ias215_mw` DOUBLE [MW] — IAS215 is the 15-minute rolling average, in MW, of the IAS2 value measured at the domestic Iași 2 point, which is not a cross-border interconnection point. - `mint15_mw` DOUBLE [MW] — MINT15 is the 15-minute rolling average, in MW, of the MINT value measured at the domestic Mintia point, which is not a cross-border interconnection point. - `prog_raw` DOUBLE — PROG is published by the feed with no documentation of its meaning, the observed value being an empty string (""), and this catalogue does not guess what it represents. - `is_raw` DOUBLE — IS is published by the feed with no documentation of its meaning, the observed value in the reference snapshot being 108, and this catalogue does not guess what it represents. - `prot1tms_raw` DOUBLE — Prot1TMS is published by the feed with no documentation of its meaning, the observed value being an empty string (""), and this catalogue does not guess what it represents. - `plan_raw` DOUBLE — PLAN is published by the feed with no documentation of its meaning, the observed value in the reference snapshot being 1228, and this catalogue does not guess what it represents. - `s110_raw` DOUBLE — S110 is published by the feed with no documentation of its meaning, the observed value in the reference snapshot being -3, and this catalogue does not guess what it represents. - `cons2_raw` DOUBLE — CONS2 is published by the feed with no documentation of its meaning, the observed value in the reference snapshot being 6374, close to but different from total consumption CONS, and this catalogue does not guess what it represents. ### sen_generation The same snapshots as sen_readings, reshaped: one row per generation source per snapshot, eight rows each. This is the table to group by — "share of production by source", "how much of the year did coal run" — where the wide table would need eight named columns in a CASE. The eight sources are exactly the ones that sum to total production (PROD): coal, gas, hydro, nuclear, wind, solar, biomass and pumped storage. source_code joins to sen_feed_keys.key for the label and the full definition in either language. - 176 rows · 1.6 KB · write mode `append` - Physically sorted by: `reading_time`, `source_code` - Primary key: `reading_time`, `source_code` - Files: 1 - https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_generation.parquet (176 rows) Columns: - `reading_time` TIMESTAMP NOT NULL — The instant the feed stamped on this snapshot, in UTC. Identical to sen_readings.reading_time — join on it to put a source next to total consumption. (range: "2026-09-03 06:02:42" … "2026-10-17 10:19:32") (~22 distinct) - `source_code` VARCHAR NOT NULL — The feed's own code for the generation source: CARB (coal), GAZE (natural gas), APE (hydro, itself CHEA + CHEF), NUCL (nuclear), EOLIAN (wind), FOTO (solar), BMASA (biomass), ISPOZ (pumped storage). Join it to sen_feed_keys.key. (range: "APE" … "NUCL") (~9 distinct) - `power_mw` DOUBLE [MW] — Instantaneous power from this source at reading_time. NULL when the feed sent an empty value — that is missing, not zero. Slightly negative values are real: solar (FOTO) draws a little power at night for its own auxiliaries, and pumped storage (ISPOZ) is negative while it is pumping. - `avg15_mw` DOUBLE [MW] — The 15-minute average the feed publishes alongside this source, from the matching 15 key. NULL where the feed has no such key at all: APE is an arithmetic sum of its two hydro components (whose own 15-minute averages ARE published, as chea15_mw and chef15_mw in sen_readings) and pumped storage ISPOZ has none. Also NULL when the key exists but the value was empty. ### sen_interconnection_flows The eighteen cross-border measuring points, one row each per snapshot. Sign convention: POSITIVE is an import into Romania, negative is an export. The eighteen values sum to SOLD, the national exchange balance in sen_readings — that identity is the feed's own arithmetic and holds within a megawatt or two of rounding. country and point_name are carried on the row so a cross-border question never needs a join; point_code joins to sen_feed_keys.key for the full definition. - 396 rows · 3 KB · write mode `append` - Physically sorted by: `reading_time`, `point_code` - Primary key: `reading_time`, `point_code` - Files: 1 - https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_interconnection_flows.parquet (396 rows) Columns: - `reading_time` TIMESTAMP NOT NULL — The instant the feed stamped on this snapshot, in UTC. Identical to sen_readings.reading_time. (range: "2026-09-03 06:02:42" … "2026-10-17 10:19:32") (~22 distinct) - `point_code` VARCHAR NOT NULL — The feed's own code for the interconnection point, e.g. KOZL1, BEKE1, VULC. Join it to sen_feed_keys.key. (range: "BEKE1" … "VULC") (~18 distinct) - `country` VARCHAR — The system on the other side of this point: Bulgaria, Serbia, Hungary, Moldova or Ukraine. Denormalised from the key catalogue so a per-country total is a GROUP BY and not a join. - `point_name` VARCHAR — The substation or line the point is named after, e.g. Kozlodui 1, Bekescsaba, Vulcănești. - `flow_mw` DOUBLE [MW] — Instantaneous power crossing this point at reading_time. POSITIVE means power flowing INTO Romania (import); negative means an export. NULL when the feed sent an empty value — missing, not a zero flow, which is a different and common state on a point that is simply idle. - `avg15_mw` DOUBLE [MW] — The 15-minute average the feed publishes for this point, from the matching 15 key, on the same sign convention. NULL where the feed publishes no such key — it does so for nine of the eighteen points, including every Moldovan point — and NULL when the key exists but the value was empty. ### sen_feed_keys The complete catalogue of the 63 keys the SEN feed publishes: what each one is, in Romanian and in English, and which of this dataset's tables carries it. Reference data — it is rewritten whole on every run and has no history. Read it first: without it the feed is 63 opaque abbreviations, and with it every column and every code in the other three SEN tables explains itself. Six keys are catalogued as kind = 'unknown': the publisher documents no meaning for them, so this catalogue states that fact instead of guessing. - 63 rows · 9.3 KB · write mode `replace` - Physically sorted by: `kind`, `key` - Primary key: `key` - Text search columns: `key` - Files: 1 - https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/sen_feed_keys.parquet (63 rows) Columns: - `key` VARCHAR NOT NULL — The key exactly as the feed writes it, e.g. CARB, KOZL115, row1_HARTASEN_DATA. Case and spelling are the source's own, underscore and all. This is the primary key. (range: "APE" … "row1_HARTASEN_DATA") (~75 distinct) - `kind` VARCHAR NOT NULL — What the key is: 'source' (one of the eight that sum to production), 'total' (a national aggregate: CONS, PROD, SOLD), 'border_flow' (one of the eighteen interconnection points), 'domestic_flow' (an internal measuring point), 'avg15' (the fifteen-minute average of another key), or 'unknown' (published with no documented meaning). (range: "avg15" … "unknown") - `base_key` VARCHAR NOT NULL — For an avg15 key, the key it averages — CARB15 has base_key CARB. For every other kind it is the key itself, so grouping by base_key pairs an instantaneous value with its fifteen-minute average without any string surgery. - `unit` VARCHAR — The unit of the value, 'MW' for every documented key. NULL for the timestamp key and for the six undocumented ones, whose unit is genuinely not known. - `country` VARCHAR — For a border_flow key, the system on the other side: Bulgaria, Serbia, Hungary, Moldova or Ukraine. NULL for every other kind. - `point_name` VARCHAR — For a border_flow or domestic_flow key, the substation, line or plant it measures. NULL for aggregates and averages. - `label_ro` VARCHAR NOT NULL — A short Romanian label for the key, fit for a chart legend. - `label_en` VARCHAR NOT NULL — A short English label for the key, fit for a chart legend. - `description_ro` TEXT NOT NULL — What the key means, in Romanian, in full. - `description_en` TEXT NOT NULL — What the key means, in English, in full. - `reading_column` VARCHAR — The column of sen_readings that carries this key — the lowercased key plus _mw where the unit is known and _raw where it is not. NULL for the eighteen border_flow keys, which are published as rows of sen_interconnection_flows instead of columns, and for the timestamp key, which becomes reading_time. ### prosumer_installed_capacity Installed prosumer generating capacity connected to the grid, by month and by county, from Transelectrica's prosumers application. A prosumer is a consumer who also generates — in Romania overwhelmingly a rooftop solar installation — and this is the series that shows that build-out: roughly 1.5 GW nationally in March 2024 against roughly 4 GW two years later. Coverage starts 2024-03. The source file is cumulative, so every run restates the whole history and a revised month is corrected rather than duplicated. county_code RO is the national total, not a county: exclude it or you will double every sum. - 1,290 rows · 3.7 KB · write mode `snapshot_history` - Physically sorted by: `month`, `county_code` - Primary key: `month`, `county_code` - Files: 1 - https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/prosumer_installed_capacity.parquet (1,290 rows) Columns: - `month` DATE NOT NULL — The month the capacity was measured, as the first day of that month (UTC). The source reports monthly and gives no finer date. (range: "2024-03-01" … "2026-08-01") (~30 distinct) - `county_code` VARCHAR NOT NULL — ISO 3166-2:RO county code without the RO- prefix — TM, CJ, IS … — plus B for the municipality of Bucharest. The synthetic code RO is the NATIONAL total across the whole National Power System and is a separate row: filter it out before summing counties. (range: "AB" … "VS") (~48 distinct) - `county_name` VARCHAR NOT NULL — The official Romanian name of the county, with diacritics (Timiș, Bistrița-Năsăud, București). Proper nouns, so they are not translated; România is the name carried on the national RO row. - `capacity_mw` DOUBLE [MW] — Installed prosumer capacity connected in this county at the end of this month. NULL when the source left the value empty for that month. ### prosumer_forecast_hourly Hourly forecasts of prosumer production, by county, published by Transelectrica in two vintages: d1 the day before, d2 two days before. One row per forecast date, vintage, hour and county — 1,032 rows per day per vintage. Both vintages are kept because comparing them is the point: the same day forecast twice shows how the forecast moved as the weather firmed up. d1 coverage starts 2024-07-12 and d2 starts 2024-08. county_code RO is the national total, not a county. - 1.7M rows · 763 KB · write mode `snapshot_history` - Physically sorted by: `forecast_date`, `vintage`, `hour`, `county_code` - Primary key: `forecast_date`, `vintage`, `hour`, `county_code` - Files: 1 - https://data-directory.fsn1.your-objectstorage.com/public/transelectrica-sen/v/01M54P1P6KG1XYB7D0NBYB8HGM/prosumer_forecast_hourly.parquet (1.7M rows) Columns: - `forecast_date` DATE NOT NULL — The day being forecast (UTC calendar date). (range: "2024-07-12" … "2026-10-19") (~897 distinct) - `vintage` VARCHAR NOT NULL — Which horizon this forecast was published at: 'd1' the day before the forecast date, 'd2' two days before. A d1 forecast is later and normally better; a d2 forecast for the same date is what it looked like a day earlier. (range: "d1" … "d2") (~2 distinct) - `hour` INTEGER NOT NULL [hour of day] — Hour of the day, 1 to 24, exactly as the source labels its own hour axis — hour 1 is the first hour of the day, hour 24 the last. The source publishes 24 values on every day, including the 23- and 25-hour days when Romanian clocks change, so on those two days a year the hour numbers do not line up with civil time. (range: 1 … 24) (~24 distinct) - `county_code` VARCHAR NOT NULL — ISO 3166-2:RO county code without the RO- prefix, plus B for the municipality of Bucharest. The synthetic code RO is the NATIONAL total and is a separate row: filter it out before summing counties. (range: "AB" … "VS") (~48 distinct) - `county_name` VARCHAR NOT NULL — The official Romanian name of the county, with diacritics. România on the national RO row. - `power_mw` DOUBLE [MW] — Forecast prosumer production in this county in this hour. Zero overnight is a real forecast of zero and not a missing value; NULL means the source published nothing for that cell. - `published_at` VARCHAR — The clock time the source stamps on the file, as "HH:MM" — the time of day the forecast was published. It is stored as text on purpose: the source gives a time with NO date and no timezone, and turning it into a timestamp would mean inventing both. NULL when the file carried no stamp. ## Performance notes - There are no indexes in a lakehouse. The physical sort order plus Parquet row-group min/max statistics ARE the index. Predicates on the leading sort columns prune whole row groups; everything else is a full column scan. - `sen_readings` prunes on `reading_time`. - `sen_generation` prunes on `reading_time` → `source_code`. - `sen_interconnection_flows` prunes on `reading_time` → `point_code`. - `sen_feed_keys` prunes on `kind` → `key`. - `prosumer_installed_capacity` prunes on `month` → `county_code`. - `prosumer_forecast_hourly` prunes on `forecast_date` → `vintage` → `hour` → `county_code`. - `ILIKE '%needle%'` cannot prune: it decompresses that whole column. Prefer prefix predicates on the lowercased search companion columns where they exist. - Every file URL under `/v//` is immutable. Cache it as aggressively as you like. - Files are never rewritten in place — a new ingest writes a new version path. Re-read the manifest to pick up updates rather than polling the file URLs. - Pull only the columns you need. Parquet is columnar and the reader range-GETs what it reads. ## Do not - Do not scrape https://data.bunnytech.app HTML. Every number on those pages comes from the manifest above. - Do not hit the upstream source (https://www.transelectrica.ro/widget/web/tel/sen-harta) in bulk. This mirror exists so you do not have to. - Do not read DuckLake internal data files with a plain Parquet reader. They come with positional delete files, and ignoring those silently returns deleted rows. Use the ducklake extension, or use the published exports above. - Do not republish without the attribution line, and do not imply endorsement.