Skip to content
Draft
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
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
### Changed
### Removed
### Fixed
- Fixed light zones 5–8 being dropped on installs that have them: the firmware supported only 4 zones, so the upper half of each 8-wide slot-0x01 light zone register family (0x90 enabled, 0xA0 multicolor, 0xB0 name, 0xC0 state, 0xD0 color, 0xE0 active) fell through as unhandled — a real install was seen reporting zone 5–8 state and color registers hundreds of times per capture. Zones 5–8 now decode and reach Home Assistant like the first four, and the zone index in CMD 0x06 light config, CMD 0x07 color broadcast and CMD 0x3C resync accepts 0x00–0x07 (the resync cap also rejected the firmware's own zone 5–8 Resync buttons) — documented in PROTOCOL.md, where the observations confirming 8 zones replace the previous note that only zones 1–4 had been seen
### Removed
### Deprecated
### Security

## [1.11.2] - 2026-07-27
### Fixed
- Fixed light zones 5–8 being dropped on installs that have them: the firmware supported only 4 zones, so the upper half of each 8-wide slot-0x01 light zone register family (0x90 enabled, 0xA0 multicolor, 0xB0 name, 0xC0 state, 0xD0 color, 0xE0 active) fell through as unhandled — a real install was seen reporting zone 5–8 state and color registers hundreds of times per capture. Zones 5–8 now decode and reach Home Assistant like the first four, and the zone index in CMD 0x06 light config, CMD 0x07 color broadcast and CMD 0x3C resync accepts 0x00–0x07 (the resync cap also rejected the firmware's own zone 5–8 Resync buttons) — documented in PROTOCOL.md, where the observations confirming 8 zones replace the previous note that only zones 1–4 had been seen

## [1.11.1] - 2026-07-26
### Fixed
- Fixed heater setpoint changes made from Home Assistant never being confirmed back to it: the setpoint's own register (0xE7/0xE8 for Heater 1, 0xEA/0xEB for Heater 2) is now read back with a CMD 0x39 request a second after the write, since the controller does not announce the change itself and the Internet Gateway's polling cycle turns out to be install-dependent — read-backs are served whether or not a Gateway is present, unlike the requester's existing polling for missing data
Expand Down
4 changes: 4 additions & 0 deletions PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2054,7 +2054,9 @@ The register ID and slot together determine the message meaning. The slot distin
| `0xE8` | `0x00` | Spa Temperature Setpoint (Heater 1) | 1-byte °C value |
| `0xE9` | `0x00` | Heater 2 State | 1-byte (`0x00`=Off, `0x01`=On) — writable via gateway CMD `0x3A`. See note below. |
| `0xE8`–`0xE9` ⚠️| `0x03` | Unknown | Only `0x01` observed. Repeats ~every 8 minutes |
| `0xE9` ⚠️ | `0x0B` | Unknown Countdown (Chlorinator) | 2-byte little-endian countdown + 2 unknown bytes (always `00 00`); 300 units = 1 minute — see note below |
| `0xEA` | `0x00` | Heater 2 Pool Setpoint | 1-byte °C value — writable via gateway CMD `0x3A`. See note below. |
| `0xEA` ⚠️ | `0x0B` | Unknown (Chlorinator) | 2-byte little-endian value + 2 unknown bytes (always `00 00`), answered by the Viron Chlorinator — see note below |
| `0xEB` | `0x00` | Heater 2 Spa Setpoint | 1-byte °C value — writable via gateway CMD `0x3A`. See note below. |
| `0xEC` ⚠️ | `0x00` | Unknown | Only `0x01` observed. Repeats ~every 8 minutes |
| `0xF0` | `0x01` | Multicolor Light Type | 1-byte system-wide light model index: `0x00`=SLX, `0x01`=Delta, `0xFF`=none selected — see note below |
Expand All @@ -2070,6 +2072,8 @@ The register ID and slot together determine the message meaning. The slot distin
- **`0xE9`/`0xEA`/`0xEB` (Heater 2 trio) — confirmed ✅**: Slot `0x00` holds the Heater 1 trio at `0xE6` (state), `0xE7` (Pool setpoint), `0xE8` (Spa setpoint), and `0xE9`/`0xEA`/`0xEB` are the analogous trio for the second heater: `0xE9` = state (`0x00`=Off, `0x01`=On), `0xEA` = Pool setpoint, `0xEB` = Spa setpoint (1-byte °C). All three are writable via the gateway register-write command (CMD `0x3A` / second-byte `0xB9`). `0xEA` was confirmed by UI capture — changing the setpoint in the UI sends a `0x3A` write to `0xEA`/slot `0x00` and the touchscreen rebroadcasts the new value via CMD `0x38` (observed 21°C `EA 00 15`, 22°C `EA 00 16`, 27°C `EA 00 1B`; the 27°C value matched the **H2** value in the heater's `0x0070` CMD `0x17` broadcast). `0xE9` and `0xEB` are confirmed as Heater 2 state and spa setpoint respectively. (On the test install the second heater is a heat pump; "Heater 2" is kept as the generic name since another install's second heater may be a different type.)
- **Mutually exclusive broadcast**: in captures observed so far the touchscreen broadcasts *either* the `E6/E7/E8` trio *or* the `E9/EA/EB` trio in slot `0x00`, but not both — consistent with a config-dependent enable (likely [0x26](#0x26--configuration-️) byte 10 bit 3 = heater count).
- **`0xEB` default**: when the second heater isn't plumbed to spa, `0xEB` reads `0x0A` (10°C) — an unused default at the minimum setpoint rather than a live value.
- **`0xE9`/slot `0x0B` — tentative ⚠️**: a 2-byte little-endian value followed by 2 bytes that have only ever read `00 00`. Answered by the Viron Chlorinator (`0x0084`) rather than the Touchscreen, in response to the Internet Gateway's [0x39](#0x39--register-read-request-) poll. The value is a linear countdown in units of 1/5 second — **300 units = 1 minute**. Measured across 13 consecutive reads in one capture: 12700 → 5500 over 24 minutes, a rate of 298 units/minute with a residual spread of only 275 units (55 s), which is the one-minute quantisation expected from a value the chlorinator refreshes once a minute. Extrapolating the zero-crossing and cross-referencing the Touchscreen clock ([0xFD](#0xfd--controller-daytimeclock-)) shows the countdown targeting a fixed wall-clock time (~10:45 in that capture). What it counts down *to* is unknown — that install's only configured timer runs 09:00–13:00 daily, so it is not the timer's stop time. A separate capture from the same install reads `00 00 00 00` at 15:36–15:40, outside the timer window, consistent with the counter only running while the equipment does. On the other install the Gateway polls this register every cycle but the chlorinator never answers it.
- **`0xEA`/slot `0x0B` — tentative ⚠️**: same payload shape and source as `0xE9`/slot `0x0B` above — a 2-byte little-endian value followed by 2 bytes that have only ever read `00 00`, answered by the Viron Chlorinator (`0x0084`) in response to the Gateway's [0x39](#0x39--register-read-request-) poll (`02 00 F0 FF FF 80 00 39 0E B7 EA 0B F5 03`). Two installs report different but entirely static values: `94 11 00 00` = 4500 (141 responses over ~18.5 hours) and `28 23 00 00` = 9000 (18 responses across three captures). It reads as a stored setting rather than a live measurement — 4500 would be a plausible salt level in ppm, but 9000 is high for the same units, so the meaning is unconfirmed. The Gateway polls it back-to-back with `0xE9` (~1.5 s apart, every cycle), but the two are not related as total and remaining: `0xEA` held at 9000 while `0xE9` swept 12700 → 0, including passing straight through 9000 with no effect.
- **`0x20` (Active Favourite) — confirmed ✅**: slot `0x03` is the Favourite slot, and `0x20` sits immediately before the Favourite Enable block (`0x21`–`0x28`). Reports which favourite is currently active, using the same value space as CMD [`0x2A`](#0x2a--favourite-control-command-): `0x00`=Pool, `0x01`=Spa, `0x02`–`0x07`=user Favourites 1–6; `0xFF` = no favourite active. The All Off/All Auto command values (`0x80`/`0x81`) never appear here — the controller does not remember them as states: All Off reports as `0x00` (it is implemented as Pool mode with all channels off; the accompanying [0x14 Mode](#0x14--mode-spapool-) broadcast also says Pool) and All Auto reports as `0xFF`. Broadcast ~1 s after a gateway-commanded activation ([0x2A](#0x2a--favourite-control-command-)), when an active favourite is knocked out by a manual channel change, and in the periodic ~8-minute register dump — but **not** when a favourite is activated at the touchscreen itself (the new value then only appears in the next dump).
- **`0xF0` (Multicolor Light Type) — confirmed ✅**: system-wide multicolor light model selection from the touchscreen's light setup. Confirmed by UI experiment: setting the light type to SLX multicolor rebroadcasts `0x00`, Delta rebroadcasts `0x01`, and with no multicolor light configured the register reads `0xFF` (none selected — same sentinel convention as Active Favourite `0x20`). A single global register, not per-zone (no `0xF1`–`0xF3` siblings exist, and the Gateway's periodic polling requests `0xF0` only), sitting at the front of the slot-`0x01` system-config block (`0xF4` channel count, `0xF5`–`0xFC` channel categories). Only the SLX and Delta indexes have been mapped; other models in the setup list presumably take further values. The selected model determines which subset of the shared color code table applies to the Light Zone Color registers and [CMD 0x07](#0x07--lighting-zone-color-broadcast-️) — full table in [Light Zone Color Control](#light-zone-color-control-register-0xd00xd7-slot-0x01-️).
- **Light zone families — 8 zones confirmed ✅**: the six slot-`0x01` per-zone blocks (`0x90` enabled, `0xA0` multicolor, `0xB0` name, `0xC0` state, `0xD0` color, `0xE0` active) each span 8 zones. An install with more than four light zones exercises the upper half: its Touchscreen reports `0xC4`–`0xC7` (state, all `0x00`) and `0xD4`–`0xD7` (color, all `0x05`) for zones 5–8, and its Internet Gateway polls the upper-half siblings `0x96`, `0xA5` and `0xB5`–`0xB7` via [0x39](#0x39--register-read-request-) in the same cycle as the lower four. Responses to those enabled/multicolor/name polls have not themselves been captured yet, so only the state and color blocks are directly confirmed across zones 5–8.
Expand Down