Skip to content

fix(control): liveCurtailLimitW must require a fresh site meter #1135

Closed

Description

@frahlg

liveCurtailLimitW documents that it needs a fresh site-meter reading, then only checks that a reading struct exists.

Found on master 6eadec3f in go/internal/control/dispatch.go.

What happens

The comment says: without a fresh meter, defer to the planner's static cap. The body uses store.Get(...) != nil and RawW. No UpdatedAt, no IsOnline(), no watchdog age.

It also falls back to DerBattery as grid if DerMeter is missing (Ferroamp combined owner). After the main freshness gate in go/cmd/ftw/main.go a named meter exists, so this is mostly defense-in-depth. If any caller skips that gate, battery watts are treated as grid.

Live curtail uses RawW while the rest of dispatch uses SmoothedW.

ComputeDispatch itself is fail-open on a missing meter (rawGridW = 0). Production is saved by evaluateSiteDispatchFreshnessAt in main, not by control.

What a fix needs

  • liveCurtailLimitW must return ok=false when the meter is missing, offline, or older than the watchdog.
  • Do not treat DerBattery as grid unless that driver is also the configured site meter and the meter channel is absent by contract.
  • Test: stale UpdatedAt on DerMeter → no live cap. Meter missing + battery present → not grid.
  • Optional follow-up: ComputeDispatch fail-closed when there is no usable meter, so tests cannot accidentally PI against grid=0.

The main-loop freshness gate must stay. This issue is the inner function lying about its precondition.

Open PR overlap: none on dispatch.go.

Activity

  1. frahlg commented on Oct 18, 2026

    @frahlg
    MemberAuthor

    Resolved by #1170 (89b3b2c1). Current master retains liveSiteMeter and the stale, missing and offline meter regressions for live PV curtailment. TestLiveCurtailLimitW* passed three times with the race detector during this review; the outer dispatch freshness gate remains in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions