Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions SUPPORT_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
2 changes: 1 addition & 1 deletion devices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ manufacturers:
protocols:
- protocol: mqtt
driver: "heishamon"
version: "0.5.0"
version: "0.6.0"
ders: [heatpump]
control: true
firmware_versions: ""
Expand Down
28 changes: 23 additions & 5 deletions drivers/lua/heishamon.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,27 @@
-- host: core-mosquitto
-- port: 1883
-- username: mqtt-user
-- password: 42wenkel
-- password: <your mqtt 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,
host_api_max = 1,
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.",
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track power-topic freshness separately

When Heat_Power_Consumption stops arriving while any temperature or offset topic continues, those unrelated messages keep refreshing the shared last_msg_ts, so power_w is never cleared and the driver emits the last power reading indefinitely. Give the power topic its own timestamp, or clear it unless that topic itself arrived within the freshness window.

AGENTS.md reference: AGENTS.md:L58-L60

Useful? React with 👍 / 👎.

end
end
end
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions manifests/heishamon.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "heishamon"
version: "0.5.0"
version: "0.6.0"
tier: core
author: "Sourceful Labs AB"
protocol: mqtt
Expand All @@ -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: ""
2 changes: 1 addition & 1 deletion support-status.json
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@
},
{
"catalog_source": true,
"catalog_version": "0.5.0",
"catalog_version": "0.6.0",
"driver_id": "heishamon",
"package_id": null,
"targets": {
Expand Down