Possible issue with thermopro_tp862b decoder
Full disclosure, I am not an expert on this stuff and after having no luck getting rtl_433 to work with my ThermPro [TP862B](https://fcc.report/FCC-ID/2AATP-TP862B/7710541) thermometer I asked Claude to take a look and it was able to get the thermometer to show up by fixing as per below.
Sharing in case it's helpful! feel free to delete if not, it did not work until this patch and now both probes show up perfectly :D
---
The TP862b decoder added in #3455 has an inverted-logic bug at
`src/devices/thermopro_tp862b.c:78`. The comment immediately above
correctly states the invariant ("Byte 7 must be equal to byte 8
inverted"), but the code returns `DECODE_FAIL_MIC` exactly when that
invariant **holds**, rejecting every packet whose CRC bytes satisfy the
documented `[CRC-8][~CRC-8]` form.
```c
// Validate Checksum format. Byte 7 must be equal to byte 8 inverted.
if (b[7] == (uint8_t)~b[8]) { // ← should be `!=`
decoder_logf(decoder, 2, __func__, "Checksum byte 7 is supposed to be equal to byte 8 inverted. Actual: %02x vs %02x (inverted %02x)", b[7], b[8], ~b[8]);
return DECODE_FAIL_MIC;
}
```
## How it surfaces
Out of the box (rtl_433 master `028879b9`, hertzg/rtl_433:master), my
TempSpike XR (FCC ID `2AATP-TP862B`, single transmitter unit purchased
2025) produces zero `ThermoPro-TP862b` decodes even at RSSI +1.16 dB /
SNR 33 dB co-located with a successfully-decoding TP829B. The signal is
clearly in-band: a flex decoder with the documented preamble fires 44
times in 120 s of capture (3× shorter truncated rows + 7× full-payload
rows + 30× TP829B sharing the same preamble byte sequence).
## Hand-verified packets
Three consecutive `{74}`-bit hits from a 120-s `cu8` capture at 1024k
sps centred on 915.1 MHz, replayed offline:
```
PKT dd9a2fc2f9141f32cd0
ID=0xdd probe=10011010 (white, undocked) flags=0x14 status_byte=0x1f
int_temp_raw=0x2fc=764 → 26.4°C / 79.5°F
amb_temp_raw=0x2f9=761 → 26.1°C / 79.0°F
CRC: stored=0x32 inverse=0xcd computed(crc8 poly 0x07 init 0x00 xor 0xdb)=0x32 ✓
PKT dd9a2fc2fa141f8f700
meat=26.4°C ambient=26.2°C status_byte=0x1f
CRC: stored=0x8f inverse=0x70 computed=0x8f ✓
PKT dd9a2fd2fa141fe8170
meat=26.5°C ambient=26.2°C status_byte=0x1f
CRC: stored=0xe8 inverse=0x17 computed=0xe8 ✓
```
Three independent CRC-8s all validate; the `[CRC-8][~CRC-8]` byte 7/8
inversion holds in every packet; temperatures match what the OEM
handheld receiver displays. The packets are well-formed TP862B
transmissions. The decoder rejects them solely because of the inverted
comparison.
## Secondary observation
Byte 6 — labelled "Separator (0x3f)" in the decoder header comment — is
**`0x1f`** on every packet from this unit (not 0x3f). The decoder
doesn't actually check this byte, so it has no functional impact, but
the comment overstates how fixed the value is. Probably worth surfacing
the byte as an output field so its meaning can be learned across more
users' hardware revisions.
## Suggested fix (one-line)
```diff
- if (b[7] == (uint8_t)~b[8]) {
- decoder_logf(decoder, 2, __func__, "Checksum byte 7 is supposed to be equal to byte 8 inverted. Actual: %02x vs %02x (inverted %02x)", b[7], b[8], ~b[8]);
+ if (b[7] != (uint8_t)~b[8]) {
+ decoder_logf(decoder, 2, __func__, "Checksum format failed: byte 7 (%02x) is not byte 8 (%02x) inverted (expected %02x)", b[7], b[8], (uint8_t)~b[8]);
return DECODE_FAIL_MIC;
}
```
With this single change applied as a local patch and the resulting image
deployed, my unit produces clean decodes at ~16-second cadence with
`color`, `is_docked`, `temperature_int_F`, `temperature_amb_F`, `flags`,
and `mic="CRC"` all populated correctly. CRC failures on noisy
truncated packets still get rejected normally by the subsequent
`crc8(b, 7, 0x07, 0x00) ^ 0xdb != b[7]` check (line 85).
## Reproducer attachments
I can upload a 1024k cu8 capture (~234 MB, contains 7 full-payload
TP862B transmissions plus surrounding traffic) if useful for CI / unit
test purposes.
Tested on:
- rtl_433 master `028879b9a8150643bc9866da310497a7446c27d8`
(built 2026-05-26 19:32 UTC)
- Debian bookworm-slim build, librtlsdr 1.x
- Nooelec NESDR SMArt v5 + generic RTL2838UHIDIR dongles
- TempSpike XR FCC ID `2AATP-TP862B`, paired with handheld OEM receiver
7 条评论