Skip to content

fix: propagate contract offpeak hours to usage_points - #626

Open
Germwalker wants to merge 1 commit into
MyElectricalData:mainfrom
Germwalker:fix/offpeak-hours-propagation
Open

fix: propagate contract offpeak hours to usage_points#626
Germwalker wants to merge 1 commit into
MyElectricalData:mainfrom
Germwalker:fix/offpeak-hours-propagation

Conversation

@Germwalker

Copy link
Copy Markdown

Symptom

The offpeak/peak cost simulation always reports 0 EUR for the offpeak share, no matter the
contract, and 100% of the energy is billed at the peak-hour rate.

Root cause

Contract.run() (src/models/query_contract.py) parses the offpeak/peak time ranges Enedis
returns for the contract and writes them with set_contract() into the contracts table
only. But Stat.get_mesure_type() — the only place that classifies a given timestamp as
offpeak or peak — reads these ranges from usage_points, not from contracts. Unless a user
manually fills in the "force offpeak hours" field in the point configuration, usage_points
never receives the ranges Enedis sent, and every reading falls back to peak hours.

Fix

In Contract.run(), right after set_contract(), if Enedis returned a non-empty
offpeak_hours, propagate the same 7 daily ranges to usage_points via
self.db.set_usage_point(). No change when Enedis returns nothing, so behavior is unchanged
for delivery points without offpeak/peak metering.

Proof (measured on real data)

2.7 years of history, one 15 kVA delivery point, year 2025:

before after
offpeak (HC) 0 EUR 281.02 EUR
peak (HP) 1396.17 EUR 1028.43 EUR

offpeak + peak in kWh is exactly equal to the BASE total (6761.14 kWh) both before and
after — this is a reclassification, not a change in total consumption. 35112 of 35272 readings
changed classification (the contract's offpeak window, 21:36-05:36, covers 26.3% of the
energy for this point).

Scope

One file, src/models/query_contract.py, +17 lines. No other file touched.

The offpeak/peak time ranges returned by Enedis in Contract.run() were
only written to the contracts table, never to usage_points, which is
the only table read by Stat.get_mesure_type() when classifying a
measure as offpeak or peak.

As a result, every consumption reading is classified as peak hours
unless the "force offpeak hours" field is filled in by hand in the
configuration, and the offpeak/peak cost simulation reports 0 EUR for
the offpeak share.

Measured on 2.7 years of real data for one 15 kVA delivery point,
year 2025: before this fix, offpeak = 0 EUR / peak = 1396.17 EUR;
after, offpeak = 281.02 EUR / peak = 1028.43 EUR, with offpeak + peak
in kWh exactly equal to the BASE total (6761.14 kWh). 35112 of 35272
readings changed classification (26.3% of the energy falls in the
21:36-05:36 offpeak window of this contract).

Fix: after set_contract() runs and Enedis returned a non-empty offpeak
range, propagate the same range to usage_points via set_usage_point().
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.

1 participant