Skip to content

feat(config): carry demand series, heat, cooling and gas to meme - #3

Closed
jravani wants to merge 3 commits into
mainfrom
feat/demand-series-and-heat
Closed

jravani wants to merge 3 commits into
mainfrom
feat/demand-series-and-heat

Conversation

@jravani

@jravani jravani commented Oct 16, 2026

Copy link
Copy Markdown
Member

Fixes #2.

Carries a building's demand per step (electricity, heat, cooling, natural gas) and its heat and cooling technologies from the EnerPlanET payload to MEME. MEME needs no change: it already accepts named series, any carrier, conversion techs and trade imports per carrier.

Mapping (version 1.2.0)

  • properties.demand_series.<carrier> (kW per step) becomes model.timeseries{demand_$k}, {demand_heat_$k}, {demand_cooling_$k} or {demand_natural_gas_$k} (MW), plus a demand technology whose demand_profile names it. An electricity series replaces the constant load of demand_energy; demand_$k keeps its key.
  • air_source_heat_pump, ground_source_heat_pump and electric_boilers convert electricity to heat. gas_boiler converts natural gas to heat, and air_conditioner converts electricity to cooling. All use cont_energy_eff as efficiency with the shared tech_capacity and tech_costs rules.
  • gas_supply becomes trade{gas_$k}, a natural gas import priced like households_supply. No gas network is modelled.
  • The heat, cooling and natural_gas carriers are added only when a rule uses them.

Effect on the reverse

  • A job without series or these technologies reverses exactly as before.
  • Series come back as kW arrays, rounded to six decimals, which is what the forward rounding to nine decimals in MW can represent. The new technologies come back under techs.<name>.
  • The constant electricity rule now has a reverse condition, demand_profile gte 0, so a series reference (a string) is left to the series rule instead of failing in linear.

Checks

  • make test-race: passes. New cases in pkg/t1k/mapping_test.go:
    • TestMappingDemandSeries: all four carriers; a series with demand_energy 0; an unknown carrier key; no carriers added without series.
    • TestMappingHeatTechnologies: each technology and the gas import.
    • TestMappingRoundTripAllKinds: now includes a building with series and every new technology.
  • make fuzz FUZZTIME=10s: passes. make golden-update and make example leave the golden files and examples unchanged.
  • golangci-lint was not available locally; CI runs it.
  • Against MEME (enerplanet/meme main, Calliope 0.7.0.dev7): the example payload extended to a full year (2018, 60 min), with one building given 8760-step BuEM series for electricity, heat and cooling, a gas cooking series, a heat pump, a gas boiler, an air conditioner and a gas supply. PV was removed from the payload because MEME requires a precomputed PV profile for Calliope.
    • /validate?target=calliope: valid: true, with only the two warnings the existing unmet-demand and solver constants already produce.
    • /simulate?target=calliope: succeeded. Calliope built the gas boiler (13.2 kW of heat from 14.6 kW of gas) and an 8.3 kW air conditioner, with no unmet heat, cooling or gas. The only unmet electricity is at n4, the example's building without a connection.
    • The reverse of that job, converted forward again, reproduces it apart from that standalone building.

Docs: the mapping page gains a Demand series section and rows for the new technologies; the CHANGELOG has the entry under Unreleased.

The default mapping carried a building's demand as one constant
electricity load derived from demand_energy and mapped no other
carrier. EnerPlanET now computes each building's demand per step with
a building thermal model and lets users assign heat and cooling
technologies, none of which reached MEME.

properties.demand_series maps electricity, heat, cooling and
natural_gas to series in kW. Each becomes a model.timeseries entry in
MW (rounded to nine decimals, six in kW on the way back) and a demand
technology whose demand_profile names it: demand_$k for electricity,
which replaces the constant load, and demand_heat_$k, demand_cooling_$k
and demand_natural_gas_$k for the others. Keys other than these four
are not carried.

Heat pumps and the electric boiler convert electricity to heat, the gas
boiler converts natural gas to heat and the air conditioner electricity
to cooling, each with cont_energy_eff as efficiency and the shared
capacity and cost rules. gas_supply becomes a gas import, trade
gas_$k, priced like the electricity tariffs; no gas network is
modelled. The heat, cooling and natural_gas carriers are added only by
the rules that use them.

A payload without series or these technologies produces the same job
as before: the examples and golden files are unchanged. The reverse
restores the series as kW arrays and the technologies under techs;
the constant electricity rule only reverses a numeric demand_profile,
so a series reference is left to the series rule. The mapping's
version is now 1.2.0.

Fixes #2
jravani added a commit to enerplanet/enerplanet that referenced this pull request Oct 16, 2026
EnerPlanET attaches each building's BuEM series to the MEME payload
(properties.demand_series), but T1K v0.1.0 ignores that field, so a
run still sent one constant electricity load per building. The mapping
that carries the series, heat, cooling and gas is enerplanet/T1K#3,
not yet released.

The backend now requires T1K at that commit (f21e43e, pseudo-version
v0.1.1-0.20261016020843-f21e43e03059). It moves to the release tag
once the PR is released. The comment on TranslatePayload no longer says
the mapping is electricity only.
A building's PV reached MEME as one pv_supply technology with physics
parameters and no profile. MEME's Calliope and PyPSA targets need a
precomputed profile for a physics technology, and a building can carry
PV on several roof surfaces with different orientations.

techs.pv_arrays lists the arrays of a building, one per surface. Array
$j becomes the series pv_${k}_$j (source inline, unit fraction, the
profile in kW AC per kW DC unchanged) and the supply technology
pv_supply_${k}_$j, whose performance.precomputed names that series. The
technology takes tilt, azimuth and losses as physics parameters and the
shared capacity and cost rules, so cont_energy_cap_max bounds the
array's size. surface_id is not carried. techs.pv_supply is mapped as
before.

A payload without pv_arrays produces the same job as before: the
examples and golden files are unchanged. The reverse restores the
arrays with their profiles. The mapping's version is now 1.3.0.
feat(config): map PV arrays with their own production profiles
@jravani

jravani commented Nov 1, 2026

Copy link
Copy Markdown
Member Author

Closing. These changes landed on jay/enerplanet-integration, the branch EnerPlanET builds T1K from: f21e43e (this PR) and f407466 (PR 4, merged into this branch).

@jravani jravani closed this Nov 1, 2026
@jravani
jravani deleted the feat/demand-series-and-heat branch November 1, 2026 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Carry hourly building demand and heat, cooling and gas technologies to MEME

1 participant