diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e9191e..f33de4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ Driver versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html ## [Unreleased] +### Added +- **heishamon** 0.6.0 — **the pump now reports its electrical draw, and its outdoor temperature under the name every other heat pump uses.** FTW's heating view finds a heat pump by `hp_power_w` and finds nothing else if that metric is absent, so a working, hardware-verified driver had no page at all: not a chart, not a reading, not an entry. It emits `hp_power_w` from `main/Heat_Power_Consumption`, which `power_topic` overrides for a Heishamon build that names it differently, and only once that topic has arrived — a wrong name costs the power reading and nothing else. `hp_outside_temp_c` becomes `hp_outdoor_temp_c`, which is what nibe_local and myuplink report and what the view charts; the old name was read by nobody. Existing history under the old key stays where it is and stops growing +- The Lua `DRIVER` version said 0.4.0 while the manifest said 0.5.0. Both now say 0.6.0. The drift was invisible because nothing compares them outside `make bump-driver` +- The example config carried what reads like a real MQTT password. It is now a placeholder + ### Fixed - **sungrow** 1.5.6 — **the zero-power refusal is restored. 1.5.4 was wrong, on a premise that did not survive reading the driver.** The case for waving zero through was that it hands the device back to itself, so refusing it could strand an inverter in a forced state. Neither half holds. `set_battery_idle` writes EMS mode **2** — forced — with command `0xCC` and setpoint 0: it pins the battery at zero under the host's control rather than releasing it. The release is `driver_default_mode`, which FTW reaches through `SendDefault` on shutdown, lease expiry and the watchdog, never through `driver_command`, and which no guard touches. So refusing withholds nothing that is not reachable by a route that cannot refuse — while accepting put mode 2 and a setpoint back on an SG inverter that implements neither, and reported success, because the read-back that would catch it fails on that device too. That is the SG12RT bug through the one action nobody guarded - The two sungrow copies disagree about what zero writes — the catalog driver forces idle at mode 2, the FTW v2 target hands the inverter back at mode 0 and clears the lease — and they use different register maps throughout. That belongs to the register-map review `packages/v1/sungrow/PILOT.md` already requires before the v2 target ships; its `verification_status` is `experimental` and the signed package builds from `targets/ftw-observe.lua`, so nothing there reaches hardware today. Recorded because untested drift between these two files is how Pixii's 40288 came back diff --git a/SUPPORT_STATUS.md b/SUPPORT_STATUS.md index c577b4b..f2ec3c2 100644 --- a/SUPPORT_STATUS.md +++ b/SUPPORT_STATUS.md @@ -68,8 +68,8 @@ Catalog source is not proof that a target can install or run a driver. | growatt | 2.1.1 | blixt-l1 | not_assessed | — | — | not_recorded | — | not_assessed | no | | hardybarth | 1.0.1 | ftw-core | not_assessed | — | — | not_recorded | — | not_assessed | no | | hardybarth | 1.0.1 | blixt-l1 | not_assessed | — | — | not_recorded | — | not_assessed | no | -| heishamon | 0.5.0 | ftw-core | not_assessed | — | — | not_recorded | — | not_assessed | no | -| heishamon | 0.5.0 | blixt-l1 | not_assessed | — | — | not_recorded | — | not_assessed | no | +| heishamon | 0.6.0 | ftw-core | not_assessed | — | — | not_recorded | — | not_assessed | no | +| heishamon | 0.6.0 | blixt-l1 | not_assessed | — | — | not_recorded | — | not_assessed | no | | hello | 1.1.2 | ftw-core | not_assessed | — | — | not_recorded | — | not_assessed | no | | hello | 1.1.2 | blixt-l1 | not_assessed | — | — | not_recorded | — | not_assessed | no | | huawei | 2.1.1 | ftw-core | not_assessed | — | — | not_recorded | — | not_assessed | no | diff --git a/devices.yaml b/devices.yaml index a2d101b..3d4d04d 100644 --- a/devices.yaml +++ b/devices.yaml @@ -1015,7 +1015,7 @@ manufacturers: protocols: - protocol: mqtt driver: "heishamon" - version: "0.5.0" + version: "0.6.0" ders: [heatpump] control: true firmware_versions: "" diff --git a/drivers/lua/heishamon.lua b/drivers/lua/heishamon.lua index 2318aa5..c8919a2 100644 --- a/drivers/lua/heishamon.lua +++ b/drivers/lua/heishamon.lua @@ -18,12 +18,19 @@ -- host: core-mosquitto -- port: 1883 -- username: mqtt-user --- password: 42wenkel +-- password: -- config: -- base_topic: panasonic_heat_pump -- min_offset: -3 -- max_offset: 3 -- safe_offset: 0 +-- power_topic: Heat_Power_Consumption +-- +-- power_topic names the main/ topic carrying the pump's electrical draw in W. +-- Heishamon publishes it as Heat_Power_Consumption (TOP21) on the builds this +-- driver has been run against; set it if your build names it differently. The +-- driver emits hp_power_w only once that topic has arrived, so a wrong name +-- costs the power reading and nothing else. DRIVER = { host_api_min = 1, @@ -31,7 +38,7 @@ DRIVER = { id = "heishamon", name = "Panasonic Aquarea (Heishamon)", manufacturer = "Panasonic", - version = "0.4.0", + version = "0.6.0", protocols = { "mqtt" }, capabilities = { "heatpump" }, description = "Panasonic Aquarea H/J/K/L/M-series heat pump via Heishamon MQTT bridge. Controls Zone 1 heat curve offset (Z1_Heat_Request_Temp) in range -3..+3 °C.", @@ -52,6 +59,7 @@ local outlet_temp = nil local inlet_temp = nil local target_temp = nil local z1_offset = nil +local power_w = nil local last_msg_ts = 0 local STALE_AFTER_MS = 60000 @@ -60,6 +68,7 @@ local base_topic = "panasonic_heat_pump" local min_offset = -3 local max_offset = 3 local safe_offset = 0 +local power_topic = "Heat_Power_Consumption" ---------------------------------------------------------------------------- -- Lifecycle @@ -73,6 +82,7 @@ function driver_init(config) if config.min_offset then min_offset = tonumber(config.min_offset) or -3 end if config.max_offset then max_offset = tonumber(config.max_offset) or 3 end if config.safe_offset then safe_offset = tonumber(config.safe_offset) or 0 end + if config.power_topic then power_topic = config.power_topic end end -- Subscribe broadly to all Heishamon topics @@ -85,7 +95,8 @@ function driver_init(config) host.log("info", "Heishamon: initialized, base_topic=" .. base_topic .. " offset_range=[" .. min_offset .. ".." .. max_offset .. "]" - .. " safe_offset=" .. safe_offset) + .. " safe_offset=" .. safe_offset + .. " power_topic=" .. power_topic) end function driver_poll() @@ -111,6 +122,9 @@ function driver_poll() elseif msg.topic == base_topic .. "/main/Z1_Heat_Request_Temp" then z1_offset = val last_msg_ts = now + elseif msg.topic == base_topic .. "/main/" .. power_topic then + power_w = val + last_msg_ts = now end end end @@ -124,14 +138,18 @@ function driver_poll() inlet_temp = nil target_temp = nil z1_offset = nil + power_w = nil end - -- Emit metrics - if outside_temp ~= nil then host.emit_metric("hp_outside_temp_c", outside_temp, "°C") end + -- Emit metrics. Names are the ones FTW's heating view reads: it finds a + -- heat pump by hp_power_w and charts the outdoor temperature under + -- hp_outdoor_temp_c, the same names nibe_local and myuplink report. + if outside_temp ~= nil then host.emit_metric("hp_outdoor_temp_c", outside_temp, "°C") end if outlet_temp ~= nil then host.emit_metric("hp_outlet_temp_c", outlet_temp, "°C") end if inlet_temp ~= nil then host.emit_metric("hp_inlet_temp_c", inlet_temp, "°C") end if target_temp ~= nil then host.emit_metric("hp_target_temp_c", target_temp, "°C") end if z1_offset ~= nil then host.emit_metric("hp_z1_heat_offset", z1_offset, "°C") end + if power_w ~= nil then host.emit_metric("hp_power_w", power_w, "W") end return 5000 end diff --git a/index.yaml b/index.yaml index acaa556..0ac8c86 100644 --- a/index.yaml +++ b/index.yaml @@ -257,13 +257,13 @@ drivers: size_bytes: 2193 sha256: "517e086af899dc511c86b00460cd8ce052a8d4973edee8b018e5824d4b550d6e" - name: "heishamon" - version: "0.5.0" + version: "0.6.0" tier: core protocol: mqtt ders: [heatpump] control: true - size_bytes: 6973 - sha256: "01a8bc73689715531cfc0f21963c045b2144fa54715690949b44a578ee821a88" + size_bytes: 8065 + sha256: "410f947f4eca8c4ab1436604c1cdc879a94057b7f9e345fb7cc8c07e70517dc9" - name: "hello" version: "1.1.2" tier: community diff --git a/manifests/heishamon.yaml b/manifests/heishamon.yaml index 85d0263..7ec4162 100644 --- a/manifests/heishamon.yaml +++ b/manifests/heishamon.yaml @@ -1,5 +1,5 @@ name: "heishamon" -version: "0.5.0" +version: "0.6.0" tier: core author: "Sourceful Labs AB" protocol: mqtt @@ -14,9 +14,9 @@ tested_devices: notes: "Panasonic Aquarea H/J/K/L/M-series heat pump via Heishamon MQTT bridge. Controls Zone 1 heat curve offset (Z1_Heat_Request_Temp) in range -3..+3 °C." min_driver_version: "0.4.0" min_host_version: "2.0.0" -size_bytes: 6973 +size_bytes: 8065 dkb_id: "heishamon" -sha256: "01a8bc73689715531cfc0f21963c045b2144fa54715690949b44a578ee821a88" +sha256: "410f947f4eca8c4ab1436604c1cdc879a94057b7f9e345fb7cc8c07e70517dc9" signature: "" bytecode_sha256: "" diff --git a/support-status.json b/support-status.json index 90368a2..f5bd6ed 100644 --- a/support-status.json +++ b/support-status.json @@ -898,7 +898,7 @@ }, { "catalog_source": true, - "catalog_version": "0.5.0", + "catalog_version": "0.6.0", "driver_id": "heishamon", "package_id": null, "targets": {