Repository navigation
Conversation
A control may now declare asset, strategy, zone and write timings in the
thermal contract's vocabulary, and a driver may list the metrics that are
a heat store's temperature. /api/drivers/{name} exposes both. Nothing
plans for or sends a heat command because of them; this is the
declaration step of the proposal in srcfl#1994.
A string control may declare a closed set of options, which the control
API now enforces. A misdeclared thermal field drops the control, as an
unrenderable declaration already does. nestedBlock now requires the whole
field name, so temp_sensors is not read as sensors.
Refs srcfl#520
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: hannesb90 <bruhn90@gmail.com>
The owner's answer on srcfl#1994: planned control needs the device to fall back on its own through a device-side timed hold; otherwise planned values stay a small step from the device default. A control may now declare device_hold_max_s, and a number input its default, so Core can own that lease rule. A zero or non-numeric hold, or a default outside min..max or on a non-number input, drops the control. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
The per-driver lock, hold, expiry and default path move unchanged from internal/api into internal/drivercontrol, so a planned value can later go through the same lock and expiry as an operator's (ADR 0012). The API keeps its routes, responses and SendDriverDefault; the registry lifecycle hook now clears holds through the package. As asked on srcfl#1994, the unused thermal policy draft goes with it: DecideIntent, DecisionInput, Intent, TemperatureBand, MarginalPrice and the synthetic_price strategy. The declaration vocabulary stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem and result
Step 2 of the proposal in #1994 (ADR 0012), toward #520. Stacked on #1995;
only the last commit is new here.
The operator hold (one bounded value per driver, sent and released under one
per-driver lock, handed back to the driver's own default when it ends) lived
inside
internal/api. A planned value will need the same lock and the sameexpiry, or an operator hold and a planned one would each expire into a default
that undoes the other. This moves that code, unchanged, into
internal/drivercontrol, and does nothing else with it yet.drivercontrol.Holdsowns the per-driver state,Send,ArmLocked,Expire,SendDefault,Active,PeekandClear. The bodies are theformer
Servermethods, with the server's registry passed in as a smallinterface.
Server.SendDriverDefault(used by the watchdog incmd/ftw). The registrylifecycle hook now calls
Holds.Clear.before.
Sendtakes adonecallback for that reason, so the status readthat explains a 404 or 409 cannot race a lifecycle change.
is removed:
DecideIntent,DecisionInput,Intent,IntentKind,TemperatureBand,MarginalPriceand thesynthetic_pricestrategy.Nothing outside the package used them. The declaration vocabulary that feat(drivers): let a control declare what it does to heat #1995
uses (
AssetKind,InfluenceStrategy,ValidAssetKind) stays.Scope and safety
No behaviour change is intended, and none is visible to a user.
hold, the non-blocking default from the control tick, and the 10-second
deadlines are all as they were.
request, a failed default on expiry, replaced timers) run unchanged apart
from calling the package instead of
Serverinternals.drivercontrolcover the package with a fake registry.api.go(feat(history): add calendar month selection #1866, fix(control): fuse protection as one function #1789, feat(history): show EV charging energy and cost for 7 and 30 days #1546) change other hunks; nooverlap. feat(drivers): let a control declare what it does to heat #1995 and feat(thermaltwin): learn each declared room's thermal twin in shadow #1996 are this series.
Verification
Run on a Raspberry Pi 4 (linux/arm64), Go 1.26.10:
With the Pi's default umask 002, seven
cmd/ftwnova key tests fail becausethe temporary key directory is group-writable. That is the environment, and
the same on
master. The race detector does not run on this Pi's 39-bit VMA;CI covers it.
Checklist
🤖 Generated with Claude Code