Repository navigation
Conversation
One GET of /data/domain/ per minute: each room's temperature and setpoint, each smoke alarm's temperature, and each heating channel's demand and relay state. The hub's secret is a masked config value and its self-signed certificate is pinned with tls_pin_sha256. A room with nothing assigned reports -32768 and a -20.0 °C setpoint; neither is emitted. An offline device's cached temperature is left out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
The host caps an interval returned from driver_poll at 30 s, so returning 60000 alone polled the hub every 30 s, twice as often as meant. Each poll now sets its next interval with host.set_poll_interval (60 s, or 30 s after a failure) and returns the same value. The test checks the interval the host is told, not only the one returned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
miravoss26
left a comment
There was a problem hiding this comment.
Adds a read-only Schneider/Drayton Wiser hub driver over the hub's local HTTPS API: room temps and setpoints, smoke alarm temps, heating channel demand.
- Security: the hub secret is read from config and masked via
config_secrets, and sent only as aSECRETheader to the configured hub. The self-signed cert is handled withtls_pin_sha256andallowed_hosts, which is the right way to do it. No writes, no new dependencies. - Correctness: a failed or non-JSON answer emits only
wiser_poll_ok=0, so stale values are not republished. Good. - Question: the
base_urloverride is described as a test hook. If it can be set in a production config it bypasses the host-built URL, thoughallowed_hostsshould still fence it. Worth confirming that is enforced. - Note: room temperatures from real thermostats are decoded but not yet seen on hardware (stated in verification_notes). The
experimentalstatus fits.
Safe to merge from my read. No CI checks were attached when I looked.
A Renova CFMT 16 A floor thermostat is now paired with the test hub, so room temperatures from a real thermostat are seen on hardware. Each room also reports its demand, its output state and whether its temperature is floor or air (room_<id>_temp_is_floor): in a floor-control preset the room temperature is the floor sensor's. Each heating actuator with a floor sensor reports the floor temperature, while the sensor is in normal operation, and its upper and lower limits. An offline thermostat's cached values are left out. The hub reports the configured floor sensor type but cannot see the probe. On the test site a 15 kOhm probe configured as 10 kOhm read 17.4 °C against 26.6-27.5 °C measured on the floor; the type is logged when it changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
The base_url test hook could also be set in a site's config. The request carries the hub's secret, and FTW lets a driver with an empty allowed_hosts reach any address, so a base_url could send the secret elsewhere or over clear-text HTTP. The URL is now always https://<host>[:port]/data/domain/, and the tests configure host instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
|
Thanks. It was not fenced: FTW's |
A Renova CFMT switches its load with a relay and measures nothing: the hub reports InstantaneousDemand 0 with the relay on. The owner can now state the load per actuator, as rated_w or as area_m2 x w_per_m2 (default 110 W/m²), and the driver emits heating_actuator_<id>_power_est_w, the load times the room's PercentageDemand. The thermostat runs the relay time-proportionally over a ten-minute cycle, so that is the average draw over the cycle. It is a metric, not a power stream, so an estimate never enters a measured site balance. A load outside 16 A x 230 V, an area over 200 m² or over 300 W/m² is refused and logged. Nothing is emitted for an actuator with no stated load, an offline thermostat, or a poll the hub did not answer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hannesb90 <bruhn90@gmail.com>
…he output A Renova CFMT held off by its floor limit reports Output_Thermal_Limit, and its probe still reads (23.8 °C on the entrance floor on 2026-11-11). The driver dropped the floor temperature exactly then. It is now kept, and heating_actuator_<id>_floor_limit_active says the limit is holding. Also documented from the same site: the air setpoint range follows the floor limits, notes for a later timed-override control, and three thermostats with 10, 12 and 15 kOhm probes in the verification notes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Two more site findings in 93d6cac. A bug fix: a Renova CFMT held off by its floor limit reports |
miravoss26
left a comment
There was a problem hiding this comment.
Read-only Wiser heating hub driver: one GET of /data/domain/ per poll, metrics only, no control path.
- Security screen: clean from my read. Hub secret is a masked config value, the self-signed cert is pinned via
tls_pin_sha256, and no new hosts beyond the configured hub. TheGET http://<hub>/secretsetup-mode step is documented operator-side only, not driver code. Good. - Sentinels (-32768 / -200 / 2000) are dropped rather than emitted, and offline devices don't serve stale temps. Nice, that's the failure mode that usually bites.
- Nit:
power_est_wis documented as an estimate that must not enter a measured site balance. Worth making sure nothing downstream sums*_power_est_wwith real power metrics.
Safe to merge from my read (I did not run the Lua harness; trust CI for that).
Summary
A new read-only driver for the Schneider Electric / Drayton Wiser heating
hub over its local HTTPS API. Toward srcfl/ftw#520: room temperatures from a
thermostat system FTW cannot read today, for a later heat planner to judge
comfort by.
One GET of
https://<hub>/data/domain/per minute, the hub's whole state asJSON. The minute is set with
host.set_poll_interval(30 s after afailure): an interval returned from
driver_pollis capped at 30 s by thehost, which the first commit relied on by mistake. It emits metrics only, no power stream:
room_<id>_temp_candroom_<id>_setpoint_cfor each room, plusroom_<id>_demand_pct,room_<id>_output_onandroom_<id>_temp_is_floor(1 when the room is controlled on floor temperature, 0 on air)
heating_actuator_<id>_floor_temp_c,_floor_max_cand_floor_min_cforeach floor thermostat with a floor sensor
heating_actuator_<id>_power_est_wwhen the owner states the load(
floor_heating: [{actuator, rated_w | area_m2 [, w_per_m2 = 110]}]): theload times the room's demand, the average draw over the relay's ten-minute
cycle. The CFMT measures no power (the hub reports
InstantaneousDemand: 0with the relay on), so this is an estimate and stays a metric, never a power
stream. On the hub with a stated 4.5 m² it emitted 0 W at 0 % demand; a
non-zero value is covered in the harness only.
smoke_alarm_<id>_temp_cfor each smoke alarmheating_channel_<id>_demand_pctandheating_channel_<id>_relay_onforeach heating channel
wiser_poll_okIds are the hub's own. Room names are owner text and stay out of metric names.
Driver evidence
wiser_heat0.1.0, community tier.(firmware 2.7.6) and, since 2026-11-11, one Renova Connected Thermostat
16 A (WDE011680, firmware 1.0.59) on electric floor heating with a 15 kOhm
floor sensor. No radiator valve or room stat is paired.
/data/domain/answer, read onhardware. Schneider publishes no document for this local API, so the
manifest has no
upstream_docs. The sensor-error value 2000 comes from theWiser community libraries, not from the test hub.
POST /api/drivers/testagainst the hub,with the hub's certificate pinned via
tls_pin_sha256and the secret inconfig: smoke alarm 21.0 °C, heating channel demand 0 % and relay off,
and the empty room correctly not emitted. With a wrong secret the hub
answers 401, and the driver emits only
wiser_poll_ok = 0.POST /api/drivers/teston FTW v0.157.3-beta.1 against the same hub, inpreset P6 (room control with floor limit): room 24.2 °C, setpoint
20.0 °C,
temp_is_floor0, demand 0 % and output off, floor sensor26.2 °C, floor upper limit 30.0 °C. The room air reading matched the
thermostat's display, and the floor reading matched an IR reading of the
floor surface (26.6-27.5 °C). Before, in preset P8 (floor control), the
hub showed the room temperature as the floor sensor's
(
InputTemperatureType: Floor) with demand 100 % and output on, loggedover 20 minutes; that state is covered in the harness.
probe configured as NTC_10K read 17.4 °C against 26.6-27.5 °C on the
floor, and 27.0 °C once set to NTC_15K. The driver logs the type when it
changes.
make test-driver ID=wiser_heatandmake checkpass.invented-number-report: nothing invented.varies single fields for what the hub could not show: a room with a
thermostat, a relay that is on, a sensor error, an offline device, no
answer, a non-JSON answer, and no secret configured. A deliberate break of
the "no temperature" check fails it.
seen on hardware. The floor lower limit is decoded but was not
configured on the test thermostat. A room with nothing
assigned reports
CalculatedTemperature: -32768andCurrentSetPoint: -200, and neither is emitted. Wiser also uses -200(-20.0 °C) for a room set to off, so a setpoint at or below it is
treated as no setpoint.
its cache, so a device whose
DisplayedSignalStrengthisOfflineorNoSignalhas its temperature left out. How quickly the hub marks asilent device offline is not measured.
GET http://<hub>/secretonly in setup mode (the Setup button; it endsitself after 15 minutes). The driver comment states the steps. A setup
flow in FTW's UI would be a separate Core change.
ders: [heatpump]is the closest of the allowed DER kinds; the hub is aheating controller, not a heat pump.
Safety
The secret is declared in
config_secrets, so FTW masks it. Only GET is used.Control evidence
required: not applicable, read-only.Checks
Signed-off-by.make test-driver ID=wiser_heatmake check🤖 Generated with Claude Code