FUE-T08: defer daily fixed-fee/heffingskorting settlement to local 01:05 in summarize()
This commit is contained in:
@@ -123,6 +123,10 @@ _READING_MAX_STALENESS = timedelta(minutes=_PERIOD_MINUTES)
|
||||
# degraded to prevent negative costs or grossly inflated charges.
|
||||
_MAX_DELTA_KWH = Decimal("100")
|
||||
|
||||
# 每日固定费/税补在"本地午夜后多久"才结算入账。延后到 01:05 是为了让累计成本的
|
||||
# 整天阶跃落在新一天、且避开 01:00 整点(HA 长期统计的小时桶边界)。
|
||||
_SETTLEMENT_OFFSET = timedelta(hours=1, minutes=5)
|
||||
|
||||
# DSMR payload register keys (cumulative kWh, JSON string values).
|
||||
_KEY_D1 = "electricity_delivered_1" # delivered low-tariff (dal / _1)
|
||||
_KEY_D2 = "electricity_delivered_2" # delivered high-tariff (normal / _2)
|
||||
@@ -764,7 +768,8 @@ def summarize(session: Session, start: datetime, end: datetime) -> dict[str, Any
|
||||
days = _to_decimal(str(total_seconds)) / _to_decimal("86400")
|
||||
|
||||
# --- Fixed costs and credits: Principle C cross-version whole-day counting ---
|
||||
today_local: _date = local_now().date()
|
||||
_now_local = local_now()
|
||||
today_local: _date = _now_local.date()
|
||||
|
||||
# --- Compute [first_counted, last_counted] local date range (inclusive) ---
|
||||
#
|
||||
@@ -811,8 +816,16 @@ def summarize(session: Session, start: datetime, end: datetime) -> dict[str, Any
|
||||
else:
|
||||
last_counted = local_end_date - _td(days=1)
|
||||
|
||||
# Cap: only elapsed or today's days.
|
||||
last_counted = min(last_counted, today_local)
|
||||
# Settlement cap: "today" is only counted once the local clock has passed the
|
||||
# settlement offset since midnight (01:05). This defers the daily standing-charge
|
||||
# step from 00:00 to 01:05, ensuring the cumulative-cost adiabatic jump lands
|
||||
# inside the new calendar day and avoids the HA 01:00 hourly-bucket boundary.
|
||||
_today_midnight_utc = _lmu(today_local)
|
||||
if _now_local >= _today_midnight_utc + _SETTLEMENT_OFFSET:
|
||||
settled_cap = today_local
|
||||
else:
|
||||
settled_cap = today_local - _td(days=1)
|
||||
last_counted = min(last_counted, settled_cap)
|
||||
|
||||
# If the range is empty (first_counted > last_counted), no days are counted.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user