Hi all,
This follows on from two older threads here — OpenTherm / ATAG ONE from 2019, which clarified that the ATAG ONE doesn’t need an OpenTherm gateway since it has its own local API, and ATAG ONE support via Homie/MQTT, where @ArdKuijpers has been maintaining atagone-mqtt as a bridge for the past few years.
TL;DR: I built a native openHAB binding for the ATAG ONE. No more Docker container, no MQTT broker, no Homie topic mapping — openHAB talks to the thermostat directly over its local LAN API.
Why move off the MQTT bridge
atagone-mqtt has done its job for years, but the more I leaned on it, the more the architecture itself became the problem, not the code in it:
- It’s three moving parts (the bridge process, an MQTT broker, openHAB’s MQTT binding) standing between openHAB and a device that’s sitting on the same LAN.
- Everything comes through as generic MQTT/Homie topics, so you lose proper typing — no native Units of Measurement, no proper
DateTime/Number:Temperaturechannels, just strings and numbers you have to interpret yourself in item configs. - Timing-sensitive stuff (the vacation/duration handling, the boiler’s post-write restart window) is genuinely fiddly to get right, and doing it correctly through an extra hop made debugging much harder than it needed to be.
A native binding removes all of that. It’s a direct client for the same local HTTP API (port 10000) the bridge and kozmoz/atag-one-api already talk to — it just cuts out everything in between.
What it does today
- Discovery: passive UDP listener (the thermostat broadcasts on port 11000), auto-populates the Inbox. Manual Thing configuration also works if you’d rather skip that.
- Reads: room/outside/CH/DHW temperatures, water pressure, burner status and modulation, burning hours, weather status, device/boiler error codes, plus a set of advanced diagnostic channels (WiFi signal, voltage, PCB temp, etc.) behind “show advanced.”
- Writes: target temperature, HVAC mode, holiday (vacation) mode — with real start/end date channels, not a hardcoded duration — and fireplace mode, where writing a duration activates it for exactly that duration.
Over in the Homie/MQTT thread, @ArdKuijpers made a good point about weather compensation: the ATAG ONE already does this natively if you set Operating mode to weather-dependent, so there’s no need to reimplement it. That’s actually part of why I went this direction — the binding just reads weather-status and hvac-mode straight off the device, so whatever mode you’ve configured on the thermostat is exactly what shows up, no separate logic to keep in sync.
Extend mode is exposed read-only for the same reason — it activates automatically when you write a setpoint while in auto mode, so there’s no separate “activate extend” API call to expose; the channel just reflects what the device is already doing.
Small shoutout to @herikw’s home-assistant-custom-components — it was one of my references for the protocol’s enum values while building this.
How it compares to atagone-mqtt
I went back through the bridge’s actual source, so here’s a grounded comparison including two places the bridge is currently ahead:
atagone-mqtt (bridge) |
atagone binding (native) |
|
|---|---|---|
| Architecture | Bridge process + MQTT broker + Homie mapping | Talks to the device directly |
| Discovery | Auto-discovered via Homie MQTT | Auto-discovered via its own UDP listener — equivalent, not an advantage |
| Typing | Generic MQTT payloads | Native Number:Temperature, Number:Time, DateTime with proper Units of Measurement |
| Vacation mode | Day-count only, held in a Python variable | Real vacation-start/vacation-end DateTime channels derived from the device’s own state |
| Extend mode | Settable directly (ch_mode=4 + duration) |
Exposed read-only — in my testing, writing ch_mode=4 directly caused problems; the channel instead reflects the device’s real auto-activate-on-setpoint behavior |
| Fireplace/extend duration | In-process default (60 min), forgotten on bridge restart, never reads the device’s stored value | Reads the device’s actual stored default; writing activates for exactly the duration given |
| Enum/mode mapping | Inherited from pyatag’s STATES table |
Independently re-verified against live device captures, cross-checked against kozmoz/atag-one-api, pyatag, and herikw’s HA integration |
Status
It’s been through several rounds of testing against my own unit (including the write paths — vacation, fireplace, target temp) and a full code-quality/hardening pass. The PR is up: [atagone] Initial contribution by Ltty · Pull Request #21481 · openhab/openhab-addons · GitHub (opened as a draft for now — I’ll mark it ready for review shortly).
If anyone wants to try it early or has an ATAG ONE and is up for testing before it merges, here’s the JAR: Release ATAG ONE binding v0.1.0-beta (pre-release, for testing) · Ltty/openhab-addons · GitHub
@higgers — this should answer where things stand since your question in the other thread.