From 7b88ef5af89836243bce3d685c6b95060fc336aa Mon Sep 17 00:00:00 2001 From: "Christian W. Zuckschwerdt" Date: Sun, 24 Dec 2023 16:07:41 +0100 Subject: [PATCH] Add support for Fine Offset / Ecowitt WH55 water leak sensor (closes #2756) --- README.md | 1 + conf/rtl_433.example.conf | 3 +- include/rtl_433_devices.h | 1 + src/CMakeLists.txt | 1 + src/devices/fineoffset_wh1050.c | 3 + src/devices/fineoffset_wh55.c | 119 ++++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 src/devices/fineoffset_wh55.c diff --git a/README.md b/README.md index 0b91a0cee5..64f49246c4 100644 --- a/README.md +++ b/README.md @@ -336,6 +336,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md). [248]* Nissan TPMS [249] Bresser lightning [250] Schou 72543 Day Rain Gauge, Motonet MTX Rain, MarQuant Rain Gauge + [251] Fine Offset / Ecowitt WH55 water leak sensor * Disabled by default, use -R n or a conf file to enable diff --git a/conf/rtl_433.example.conf b/conf/rtl_433.example.conf index 098caa35b4..5f8a67c81d 100644 --- a/conf/rtl_433.example.conf +++ b/conf/rtl_433.example.conf @@ -441,7 +441,7 @@ convert si protocol 212 # Renault 0435R TPMS protocol 213 # Fine Offset Electronics WS80 weather station protocol 214 # EMOS E6016 weatherstation with DCF77 - protocol 215 # Emax W6, rebrand Altronics x7063/4, Optex 990040/50/51, Orium 13093/13123, Infactory FWS-1200, Newentor Q9, Otio 810025, Protmex PT3390A, Jula Marquant 014331/32, Weather Station or temperature/humidity sensor + protocol 215 # Emax W6, rebrand Altronics x7063/4, Optex 990040/50/51, Orium 13093/13123, Infactory FWS-1200, Newentor Q9, Otio 810025, Protmex PT3390A, Jula Marquant 014331/32, TechniSat IMETEO X6 76-4924-00, Weather Station or temperature/humidity sensor # protocol 216 # ANT and ANT+ devices protocol 217 # EMOS E6016 rain gauge protocol 218 # Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK) @@ -477,6 +477,7 @@ convert si # protocol 248 # Nissan TPMS protocol 249 # Bresser lightning protocol 250 # Schou 72543 Day Rain Gauge, Motonet MTX Rain, MarQuant Rain Gauge + protocol 251 # Fine Offset / Ecowitt WH55 water leak sensor ## Flex devices (command line option "-X") diff --git a/include/rtl_433_devices.h b/include/rtl_433_devices.h index 0fd12552a0..3561c4d748 100644 --- a/include/rtl_433_devices.h +++ b/include/rtl_433_devices.h @@ -258,6 +258,7 @@ DECL(tpms_nissan) \ DECL(bresser_lightning) \ DECL(schou_72543_rain) \ + DECL(fineoffset_wh55) \ /* Add new decoders here. */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dde1f90312..55c4469abc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,6 +110,7 @@ add_library(r_433 STATIC devices/fineoffset_wh1080.c devices/fineoffset_wh31l.c devices/fineoffset_wh45.c + devices/fineoffset_wh55.c devices/fineoffset_wn34.c devices/fineoffset_ws80.c devices/fineoffset_ws90.c diff --git a/src/devices/fineoffset_wh1050.c b/src/devices/fineoffset_wh1050.c index d740207c4d..64c06155b2 100644 --- a/src/devices/fineoffset_wh1050.c +++ b/src/devices/fineoffset_wh1050.c @@ -49,6 +49,8 @@ weather data as usual. TFA 30.3151 Sensor is FSK version and decodes here. See issue #2538: Preamble is aaaa2dd4 and Temperature is not offset and rain gauge is 0.5 mm by pulse. +Note there is a collison with WH55 which starts with `aa aa aa 2d d4 55` + To recognize which message is received (weather or time) you can use the 'msg_type' field on json output: - msg_type 5 = weather data - msg_type 6 = time data @@ -270,5 +272,6 @@ r_device const tfa_303151 = { .long_width = 60, .reset_limit = 2500, .decode_fn = &fineoffset_wh1050_callback, + .priority = 10, // Eliminate false positives by letting Fineoffset/Ecowitt WH55 go earlier .fields = output_fields, }; diff --git a/src/devices/fineoffset_wh55.c b/src/devices/fineoffset_wh55.c new file mode 100644 index 0000000000..c070bc5547 --- /dev/null +++ b/src/devices/fineoffset_wh55.c @@ -0,0 +1,119 @@ +/** @file + Fine Offset / Ecowitt WH55 water leak sensor. + + Copyright (C) 2023 Christian W. Zuckschwerdt + Protocol analysis by @cdavis289, test data by @AhrBee + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + */ + +#include "decoder.h" + +/** +Fine Offset / Ecowitt WH55 water leak sensor. + +Test decoding with: rtl_433 -f 433.92M -X 'n=wh55,m=FSK_PCM,s=60,l=60,g=1000,r=2500' + +Note there is a collison with Fine Offset WH1050 / TFA 30.3151 weather station which starts with `aa aa aa 2d d4 5` + +Data format: + + 00 01 02 03 04 05 06 07 08 09 10 11 + aa aa aa 2d d4 55 30 cf 55 04 02 89 be ae a4 20 10 + MM FI II II BB VV VV AD XX ?? ?? ?? + +- Preamble: aa aa aa +- Sync: 2d d4 +- M: 8 bit Family code 0x55 (ECOWITT/FineOffset WH55) +- F: 4 bit Flags, Channel (1 byte): (0=CH1, 1 = CH2, 2 = CH3, 3 = CH4) +- I: 20 bit ID, shown with leading channel in Ecowitt Web App +- B: 8 bit Battery (1 byte): 0x01 = 20%, 0x02 = 40%, 0x03 = 60%, 0x04 = 80%, 0x05 = 100% +- V: 16 bit Raw sensor measurement +- A: 2 bit Sensitivity and Alarm Setting: Left bit, 1 = High Sensitivity, 0 = Low Sensitivity, Right Bit: 1 = Alarm On, 0 = Alarm Off +- D: 6 bit Unknown? +- X: 8 bit CRC poly 0x31, init 0 +- ?: 24 bit Unknown? + +Format string: + + TYPE:8h FLAGS?2b CH:2d ID:20h BATT:8d RAW:16h SENS:b ALARM:b ?:6b CRC:8h ?:hh hh hh + +*/ + +static int fineoffset_wh55_decode(r_device *decoder, bitbuffer_t *bitbuffer) +{ + uint8_t const preamble[] = {0xAA, 0x2D, 0xD4, 0x55}; // part of preamble, sync word, and message type + + if (bitbuffer->num_rows != 1) { + return DECODE_ABORT_EARLY; // We expect a single row + } + + unsigned bitpos = bitbuffer_search(bitbuffer, 0, 0, preamble, 32); + bitpos += 24; // Start at message type + if (bitpos + 12 * 8 > bitbuffer->bits_per_row[0]) { + return DECODE_ABORT_EARLY; // No full message found + } + + uint8_t b[12]; + bitbuffer_extract_bytes(bitbuffer, 0, bitpos, b, 12 * 8); + + if (crc8(b, 9, 0x31, 0x00)) { + return 0; // DECODE_FAIL_MIC; + } + + decoder_log_bitrow(decoder, 1, __func__, b, 12*8, "Message data"); + + // GETTING MESSAGE TYPE + // int msg_type = b[0]; + // int flags = (b[1] & 0xf); + int channel = (b[1] >> 4) + 1; + int device_id = (b[2] << 8) | b[3]; + float battery = b[4] * 0.2f; // 0x01 = 20%, 0x02 = 40%, 0x03 = 60%, 0x04 = 80%, 0x05 = 100% + int raw_value = (b[5] << 8) | b[6]; + + // Left bit, 1 = High Sensitivity, 0 = Low Sensitivity, Right Bit: 1 = Alarm On, 0 = Alarm Off + // int settings = (b[7] >> 4); + int sensitivity = (b[7] >> 7) & 1; + int alarm = (b[7] >> 6) & 1; + + /* clang-format off */ + data_t *data = data_make( + "model", "", DATA_STRING, "Fineoffset-WH55", + "id", "ID", DATA_FORMAT, "%05X", DATA_INT, device_id, + "channel", "Channel", DATA_INT, channel, + "battery_ok", "Battery", DATA_DOUBLE, battery, + "raw_value", "Raw Value", DATA_INT, raw_value, + "sensitivity", "Sensitivity", DATA_INT, sensitivity, + "alarm", "Alarm", DATA_INT, alarm, + "mic", "Integrity", DATA_STRING, "CRC", + NULL); + /* clang-format on */ + + decoder_output_data(decoder, data); + return 1; +} + +static char const *const output_fields[] = { + "model", + "id", + "channel", + "battery_ok", + "raw_value", + "sensitivity", + "alarm", + "mic", + NULL, +}; + +r_device const fineoffset_wh55 = { + .name = "Fine Offset / Ecowitt WH55 water leak sensor", + .modulation = FSK_PULSE_PCM, + .short_width = 60, + .long_width = 60, + .reset_limit = 2500, + .decode_fn = &fineoffset_wh55_decode, + .fields = output_fields, +};