Namron Edge Thermostat (4566702 / 4512783): some exposes became read-only or stopped populating after #12385
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.7k
- Forks
- 2k
- Avg merge
- 18h 55m
- Merged PRs (30d)
- 35
Description
What happened?
Edited 2026-08-14: originally attributed this to #12117 and claimed the legacy payload keys were still live data. Both were wrong; corrected below.
After zigbee-herdsman-converters#12385 my Namron Edge Thermostat was re-identified from 4512783 to 4566702 — the same physical device; per Namron/Elektroimportøren the two are identical apart from an extra Elko One frame in the box (#29836).
Thanks for the refactor — typed cluster definitions are a real improvement over the old untyped converters, and the ENUM8 → INT8 correction looks like a genuine fix. While working through the change on my device I ran into a few things I wanted to report. Some may well be intentional, and I have flagged where I am guessing rather than measuring. Happy to split this up if separate issues are easier to action, and glad to test patches or put up a PR for any of it.
1. Four exposes are readable but no longer writable
sensor_mode, regulation_mode, summer_winter_switch and vacation_mode are still read correctly — all four appear in every published payload — but writes are refused.
Publishing each property back at its current value (so the write is a no-op) to zigbee2mqtt/<FRIENDLY_NAME>/set, while watching zigbee2mqtt/bridge/logging:
regulation_mode "heat" -> error: No converter available for 'regulation_mode' on '<FRIENDLY_NAME>': ("heat")
sensor_mode "floor" -> error: No converter available for 'sensor_mode' on '<FRIENDLY_NAME>': ("floor")
summer_winter_switch "OFF" -> error: No converter available for 'summer_winter_switch' on '<FRIENDLY_NAME>': ("OFF")
vacation_mode "OFF" -> error: No converter available for 'vacation_mode' on '<FRIENDLY_NAME>': ("OFF")
Was this intentional? I could not tell from the PR whether these were dropped on purpose or simply not carried across, so I did not want to assume either way.
For context on the impact: this thermostat reports a single local_temperature, and sensor_mode (floor / air / external) selects which physical sensor that value comes from. Without write access the sensor can only be changed on the device itself, so there is no way to switch it from Zigbee2MQTT or Home Assistant. That is the one I would most like to get back, if it is not deliberate.
(@svhelge has confirmed below that regulation_mode was implemented as namron.edgeThermostat.regulationMode() and was removed by https://github.com/Koenkk/zigbee-herdsman-converters/pull/12385.)
2. boost_time_set is exposed as numeric but the device reports "off"
The published discovery config declares:
{ "name": "Boost time set", "min": 0, "max": 24, "step": 1,
"unit_of_measurement": "h",
"value_template": "{{ value_json[\"boost_time_set\"] }}" }
and when boost is not running the device reports:
"boost_time_set": "off"
Home Assistant then logs a warning on every published message:
WARNING (MainThread) [homeassistant.components.mqtt.number] Payload '{...entire payload...}' is not a Number
To be sure I was blaming the right expose, I correlated publishes against warnings over 150 s: 2 messages produced 2 warnings, a ratio of 1.0, and boost_time_set is the only number whose template renders a non-empty non-numeric value. (Numbers rendering null are skipped silently by HA, so they do not contribute.)
Mapping "off" to 0 or null in fromZigbee, or exposing it as an enum, would both resolve it — whichever fits the converter better.
3. frost, firmware_version and firmware_date have no get converter
They are exposed but never populate, and an explicit read is refused:
frost -> error: No converter available for 'get' 'frost' ()
firmware_version -> error: No converter available for 'firmware_version' on '<FRIENDLY_NAME>': ("")
firmware_date -> error: No converter available for 'firmware_date' on '<FRIENDLY_NAME>': ("")
frost is exposed as a switch, so it shows up as a control that stays unknown. I do not know whether these attributes are readable on this firmware at all.
4. New exposes stay null until something explicitly reads them
Five exposes sat at null after the definition change. They turned out to be supported — nothing had read them yet. A single {"<property>": ""} to …/get returned values immediately, and those values persisted in every subsequent publish:
max_heat_temp -> 23
panel_brightness -> 66
regulator_cycle -> 0
local_temperature_calibration -> 0
screen_on_time -> "always_on"
Would it make sense for configure to read the attributes behind newly introduced exposes when a device's definition changes? Without that, the entities look empty and it is easy to conclude the features are unsupported — which is what I assumed at first.
What did you expect to happen?
- Writes to
sensor_mode,regulation_mode,summer_winter_switchandvacation_modeto be accepted, as they were before the refactor — or, if the removal was deliberate, for that to be noted so users know to stop expecting it. boost_time_setto publish a value that matches its declarednumerictype.frost,firmware_versionandfirmware_dateeither to populate, or not to be exposed if they cannot be read on this firmware.- Newly introduced exposes to populate on their own, without a manual
/get.
How to reproduce it (minimal and precise)
Against any 4512783 / 4512784 / 4566702 / 4566703 on 2.12.1:
mosquitto_sub -t 'zigbee2mqtt/bridge/logging' -vin one terminal.mosquitto_pub -t 'zigbee2mqtt/<FRIENDLY_NAME>/set' -m '{"sensor_mode":"floor"}'— substitute the value the device currently reports, so the write is a no-op. ObserveNo converter available.mosquitto_pub -t 'zigbee2mqtt/<FRIENDLY_NAME>/get' -m '{"max_heat_temp":""}'— observe a previously-nullvalue populate.- With Home Assistant connected, watch the log for
[mqtt.number] Payload ... is not a Number, once per published message.
Zigbee2MQTT version
2.12.1 (commit aa909a8a62f76e2dd98ace3a172bca88ee56f5fe) — zigbee-herdsman-converters 26.76.0, zigbee-herdsman 10.6.1
Adapter firmware version
20220219
Adapter
Sonoff Zigbee USB dongle — TI Z-Stack (zstack, coordinator type ZStack3x0)
Setup
Zigbee2MQTT 2.12.1 on Ubuntu (x64, Node v24.17.0), with Mosquitto as the MQTT broker. Home Assistant 2026.8.1 connects to the same broker and consumes the Zigbee2MQTT Home Assistant discovery topics.
Device database.db entry
Happy to add this on request.
Debug log
The relevant zigbee2mqtt/bridge/logging output is quoted inline in each section above. Happy to attach a full debug-level log if useful.
Notes
One further point, more of a design question than a bug, and I am not asking for a revert — the new names are better. keypad_lockout is the actual ZCL attribute name, and the others are similarly closer to the spec.
The difficulty is that Zigbee2MQTT derives the Home Assistant discovery unique_id from the expose property name:
0x70c59cfffe61076b _ switch_keypad_lockout _ zigbee2mqtt
└─ ieee (stable) └─ property name └─ base topic
So a rename inside the converter does not rename the entity in Home Assistant — it creates a new one and leaves the old one behind as an orphan (restored: true, permanently unavailable), with dashboards and automations still pointing at the old id. On my install this affected 19 entities, and I only noticed weeks later when I went looking for why things had gone grey.
| Renamed | old → new |
|---|---|
| operating mode | operating_mode → thermostat_mode |
| child lock | child_lock → keypad_lockout |
| vacation dates | vacation_start_date / vacation_end_date → vacation_start / vacation_end |
| frost | anti_frost → frost |
| time sync | time_sync → auto_time |
| backlight | display_active_backlight → panel_brightness |
| display timeout | display_auto_off → screen_on_time |
| Changed type | |
|---|---|
boost_time_set |
enum → numeric |
time_sync_value |
numeric → sensor + sync_time button |
window_state |
binary → enum sensor |
vacation_mode |
switch → binary (see item 1) |
system_mode + state |
folded into the climate expose |
| No longer exposed | |
|---|---|
regulation_mode, sensor_mode, summer_winter_switch, fault, work_days |
still present in every published payload |
I do not know what the right answer is here, but two things would have helped me:
- some way to express "this expose used to be called X", so discovery can keep a stable
unique_idor publish a removal for the old one across a rename; or - failing that, a note in the release notes when exposes are renamed, so users get a heads-up rather than discovering it later.
If there is already a recommended way to handle renames that I have missed, I am happy to be pointed at it.
One observation that may be useful for item 1: the legacy keys are still present in the published payload alongside the new ones (display_active_backlight: 66 next to panel_brightness: 66, display_auto_off next to screen_on_time), so the underlying data still appears to be flowing.
Corrected. Those legacy keys are zigbee2mqtt's state cache from the previous definition, not live data — the same effect #12385's description notes for hzc_* fields. A read of every one is refused:
fault, work_days, regulation_mode, sensor_mode,
summer_winter_switch, operating_mode, display_active_backlight
-> No converter available
So the removal is total, and the leftover values are frozen.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing zigbee-herdsman-converters PR #12385 and reproducing the reported behavior on the listed thermostat models using the MQTT /set and /get topics. Trace the converter handling for the named properties and configure behavior for newly introduced exposes, then verify writes, numeric payloads, reads, and initial population against the expected outcomes in the report.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100