merbanan / rtl_433

Program to decode radio transmissions from devices on the ISM bands (and other frequencies)
GNU General Public License v2.0
6.04k stars 1.31k forks source link

Support for Inkbird IBS-P03R Pool Thermometer #3003

Open alefchak opened 1 month ago

alefchak commented 1 month ago

I recently purchased an Inkbird IBS-P03R pool thermometer with the hopes it would work with the existing ITH-20R/IBS-P01R decoder, but it does not. I dug into it a bit and found some differences.

This device seems to broadcast on 868 MHz rather than the 433 MHz of the older models. I'm able to capture some signals, for example:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2dd41080030100614942d410eb58e700018e5c

This lines up with similar messages from the older models, including the same sync word. I decoded a few of the fields - battery, temperature low byte, temperature high byte shown here. I haven't been able to find correlations with the other fields, or any sort of checksum algorithm that verifies the messages.

Anyone have this device or able to give insight on proceeding?

merbanan commented 1 month ago

Post a few signal recording and we should be able to help. Use -S unknown.

merbanan commented 1 month ago

The posted messages look very similar to what the existing Inkbird decoder handles.

2dd4 108003 0100 61 4942 d410 eb58 f500 01 2e58 0
2dd4 108003 0100 62 4942 d410 eb58 e800 01 4e51 0
2dd4 108003 0100 61 4942 d410 eb58 e800 01 be5e 0

There is one extra byte at the end before the CRC16 (I think).

Adjust the code for that extra byte and see what happens.

alefchak commented 1 month ago

I've been modifying the existing code to adjust for differing message length and layout, and its generally working, but not able to get the CRC to verify.

Attached some sample captures here: g001_868M_250k.zip

zuckschwerdt commented 1 month ago

The CRC from the messages above checks out, either CRC-16, reflected, poly 0x8005, either init=0x84c1 with 2dd4 sync-word or 0x227f without.

klohner commented 1 month ago

I see the same. Even better, if you drop that first 0x10 byte, you get a known "CRC-16/MODBUS" with init=0xffff. I suspect that 0x10 is just the byte length of the message.

This is backed up by re-examining the Inkbird ITH-20R messages. In those signals, if you consider 0x2dd4d391 as the preamble (instead of just 0x2dd4), the next byte is 0x0f, and that device's messages are 15 bytes after that value. And, I'm sure it's no coincidence, if you reveng the CRC-16 on just those 15 bytes, you also get a "CRC-16/MODBUS".

# A couple of the Inkbird-ITH-20R messages after dropping the 0x2dd4d391 sync and 0x0f length byte:
# reveng -w 16 -s 00080001533fdc1301f6660100e8ff 0002030130163f19012fff50014464
width=16  poly=0x8005  init=0xffff  refin=true  refout=true  xorout=0x0000  check=0x4b37  residue=0x0000  name="CRC-16/MODBUS"
# The Inkbird-IBS-P03R messages after dropping the 0x2dd4 sync and 0x10 length byte:
$ reveng -w 16 -s 80030100614942d410eb58f30001ce59 80030100614942d410eb58fd00006e5a 80030100614942d410eb58fe00015f9a
width=16  poly=0x8005  init=0xffff  refin=true  refout=true  xorout=0x0000  check=0x4b37  residue=0x0000  name="CRC-16/MODBUS"

I put together these flex decoders to get the messages from the Inkbird-ITH-20R devices (samples in rtl_433_tests/tests/inkbird/) and Inkbird-IBS-P03R messages in the .zip file posted above. Perhaps this might help to combine support for both devices into one device driver?

# byte_length (0x0f = 15) is not included in CRC-16/MODBUS
decoder {
  name        = Inkbird-ITH20R_flex,
  modulation  = FSK_PCM,
  short       = 100,
  long        = 100,
  reset       = 10000,
  preamble    = 2dd4d391,
  get         = sync_2DD4D391+byte_length:@0:{8}:%d,
  get         = flags:@8:{32}:%08x,
  get         = battery:@40:{8}:%d,
  get         = id:@48:{16}:%04x,
  get         = INT_TEMP_C_LE:@64:{16}:%04x,
  get         = EXT_TEMP_C_LE:@80:{16}:%04x,
  get         = HUMIDITY_LE:@96:{16}:%04x,
  get         = CRC-16/MODBUS:@112:{16}:%04x, 
}
# byte_length (0x10 = 16) is not included in CRC-16/MODBUS
decoder {
  name        = Inkbird-IBS-P03R_flex,
  modulation  = FSK_PCM,
  short       = 417,
  long        = 417,
  reset       = 10000,
  preamble    = aaaa2dd4,
  get         = sync_2DD4+byte_length:@0:{8}:%d,
  get         = UNKNOWN_1:@8:{32}:%08x,
  get         = battery:@40:{8}:%d,
  get         = id:@48:{16}:%04x,
  get         = UNKNOWN_2:@64:{32}:%08x,
  get         = WATER_TEMP_C_LE:@96:{16}:%04x,
  get         = UNKNOWN_3:@112:{8}:%02x,
  get         = CRC-16/MODBUS:@120:{16}:%04x, 
}

BitBench

klohner commented 1 month ago

The User Manual for the Inkbird IBS-P03R mentions that for initial setup, you should "press the black button on the thermometer to pair" with the base monitor. Upon pairing, the base monitor will "complete adding a sub-device and display the channel number of the pool thermometer."

It may be helpful to capture samples of what is sent when pressing that black button on the thermometer, and what the displayed "channel number" is on the base monitor for that pairing. Although, if "channel number" is just an arbitrary "1", "2", or "3" assigned by the base station, it likely wouldn't relate to the transmitter's device id.

Also, there may be a special message transmitted if the measured water temperature goes above or below its range of -40℃~70℃ (-40°F~158°F). Any chance you have an extremely cold freezer or hot cup of coffee and want to risk the health your new thermometer in the name of science? :-)

alefchak commented 1 month ago

The User Manual for the Inkbird IBS-P03R mentions that for initial setup, you should "press the black button on the thermometer to pair" with the base monitor. Upon pairing, the base monitor will "complete adding a sub-device and display the channel number of the pool thermometer."

It may be helpful to capture samples of what is sent when pressing that black button on the thermometer, and what the displayed "channel number" is on the base monitor for that pairing. Although, if "channel number" is just an arbitrary "1", "2", or "3" assigned by the base station, it likely wouldn't relate to the transmitter's device id.

Also, there may be a special message transmitted if the measured water temperature goes above or below its range of -40℃~70℃ (-40°F~158°F). Any chance you have an extremely cold freezer or hot cup of coffee and want to risk the health your new thermometer in the name of science? :-)

I captured some messages during the pairing process but the content appears identical to the regular messages. The channels are displayed on the base station as an arbitrary 1/2/3, I'm guessing that's all handled in the base station.

The only remaining changing data I've seen is the byte immediately before the CRC, sometimes 0x00 and sometimes 0x01, with no correlation that I can see.

And unfortunately not willing to turn this into a coffee thermometer at this time :D