Skip to content
Merged
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Decode Heater 2 pool setpoint (register `0xEA`) in both the touchscreen register broadcast and gateway register-write paths, instead of logging it as an unknown register
- Updated CMD 0x17 to show its payload is Spa and Pool temperature setpoints (see issue #31)
- Added HiNRG Gas Heater (0x0072) support (see issue #31)
- Note about CMD 0x05 observed with payload 0x00. Added to PROTOCOL.md and new sample trace.
- Note about CMD 0x12 observed with payload 0x01 0x00. Added to PROTOCOL.md and new sample trace.
- Parsing for CMD 0x12 updated so `0x01 0x00` no longer reported as unexpected.
- Added per-heater pool and spa temperature setpoints, exposed as separate Home Assistant Number entities per heater ("Heater N Pool/Spa Setpoint"); writable via CMD `0x19` for Heater 1 and register writes `0xEA`/`0xEB` for Heater 2
- Added Heater 2 on/off support: state decoded from register `0xE9` and controllable via the "Heater 2" switch
### Changed
Expand Down
12 changes: 6 additions & 6 deletions PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,18 +173,18 @@ Single-byte broadcast emitted by the Touchscreen (`0x0050`) immediately after a

```
02 00 50 FF FF 80 00 05 0D E2 01 01 03
^^ Always 0x01 in observed captures
^^ Always 0x00 or 0x01 in observed captures
```

**Data Fields:**

- Byte 10: Acknowledgement value (always `0x01` observed)
- Byte 10: Acknowledgement value (always `0x00` or `0x01` in observed captures)

**Notes:**

- Decoded in code by `handle_touchscreen_unknown3` — log-only, no `pool_state` update.
- Triggered by [0x2A Mode/Favourite Control Command](#0x2a--modefavourite-control-command-); see that section for the full activation sequence.
- Status ⚠️ because the meaning of the constant `0x01` is unconfirmed — it could be a fixed "ack" sentinel or a single-value-observed flags field.
- Status ⚠️ because the meaning of the constants `0x00` and `0x01` is unconfirmed — it could be a fixed "ack" sentinel or a single-value-observed flags field.

---

Expand Down Expand Up @@ -416,7 +416,7 @@ Status broadcast emitted by multiple devices. The CMD byte is shared but the **p

| Source | LENGTH | Payload shape | Status | Handler |
|---------------------------------|--------|------------------------------------------|--------|-------------------------------|
| `0x0050` Touchscreen | `0x0E` | 2 bytes — always `05 00` observed | ⚠️ | `handle_touchscreen_unknown1` |
| `0x0050` Touchscreen | `0x0E` | 2 bytes — always `01 00` or `05 00` observed | ⚠️ | `handle_touchscreen_unknown1` |
| `0x0062` Connect 8/10 Controller| `0x0F` | 3 bytes — heater state + unknowns | ⚠️ | `handle_heater` |
| `0x0074` ICI Gas Heater | `0x10` | 4 bytes — `{00, status, 00, 00}` | ✅ | `handle_ici_heater_status` |
| `0x0081` VX 11S v3 Salt Chlorinator | `0x0D` | 2 bytes — always `00 00` observed | ⚠️ | **No (doc only)** |
Expand All @@ -427,14 +427,14 @@ Status broadcast emitted by multiple devices. The CMD byte is shared but the **p

#### Touchscreen (`0x0050`) ⚠️

Broadcast consistently after the firmware version message. Currently appears to always carry data `05 00`.
Broadcast consistently after the firmware version message. Currently appears to always carry data `01 00` or `05 00`.

Pattern: `02 00 50 FF FF 80 00 12 0E F0`

Example: `02 00 50 FF FF 80 00 12 0E F0 05 00 05 03`

Data fields:
- Byte 10: Unknown (always `0x05` in observed samples)
- Byte 10: Unknown (always `0x01` or `0x05` in observed samples)
- Byte 11: Unknown (always `0x00` in observed samples)

Part of the regular touchscreen status sequence.
Expand Down
6 changes: 3 additions & 3 deletions main/message_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,8 +1236,8 @@ static bool handle_touchscreen_unknown1(
uint8_t data_byte1 = payload[0];
uint8_t data_byte2 = payload[1];

if (data_byte1 != 0x05 || data_byte2 != 0x00) {
ESP_LOGW(TAG, "%s Touchscreen other status - UNEXPECTED VALUE: Byte1: 0x%02X (%d), Byte2: 0x%02X (%d) (expected 0x05 0x00)",
if ((data_byte1 != 0x01 && data_byte1 != 0x05) || data_byte2 != 0x00) {
ESP_LOGW(TAG, "%s Touchscreen other status - UNEXPECTED VALUE: Byte1: 0x%02X (%d), Byte2: 0x%02X (%d) (expected 0x01|0x05 0x00)",
addr_info, data_byte1, data_byte1, data_byte2, data_byte2);
} else {
ESP_LOGI(TAG, "%s Touchscreen other status - Byte1: 0x%02X (%d), Byte2: 0x%02X (%d)",
Expand Down Expand Up @@ -1305,7 +1305,7 @@ static bool handle_touchscreen_unknown2(

/**
* Handler: Touchscreen unknown broadcast (CMD 0x05)
* Invariant across all captures: data byte always 0x01.
* Invariant across all captures: data byte always 0x00 or 0x01.
* Silenced here to avoid spurious "Unhandled" warnings.
*/
static bool handle_touchscreen_unknown3(
Expand Down
11 changes: 11 additions & 0 deletions test/samples/touchscreen.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# lawther - only ever sees cmd 0x05 with payload 0x00. Including firmware version for completeness.

I (12:29:10.087) MSG_DECODER: RX MSG: 02 00 50 FF FF 80 00 0A 0E E8 03 07 0A 03
I (12:29:10.089) MSG_DECODER: [Touch Screen -> Broadcast] Firmware version - 3.7
02 00 50 FF FF 80 00 0A 0E E8 03 07 0A 03
I (12:29:10.207) MSG_DECODER: RX MSG: 02 00 50 FF FF 80 00 12 0E F0 01 00 01 03
I (12:29:10.209) MSG_DECODER: [Touch Screen -> Broadcast] Touchscreen other status - Byte1: 0x01 (1), Byte2: 0x00 (0)
02 00 50 FF FF 80 00 12 0E F0 01 00 01 03
I (12:29:10.327) MSG_DECODER: RX MSG: 02 00 50 FF FF 80 00 05 0D E2 00 00 03
I (12:29:10.329) MSG_DECODER: [Touch Screen -> Broadcast] Touchscreen unknown (CMD 0x05): 0x00
02 00 50 FF FF 80 00 05 0D E2 00 00 03