Skip to content

Commit

Permalink
Add support for Fine Offset / Ecowitt WH55 water leak sensor (closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
zuckschwerdt committed Dec 24, 2023
1 parent 0815dd1 commit 7b88ef5
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion conf/rtl_433.example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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")

Expand Down
1 change: 1 addition & 0 deletions include/rtl_433_devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
DECL(tpms_nissan) \
DECL(bresser_lightning) \
DECL(schou_72543_rain) \
DECL(fineoffset_wh55) \

/* Add new decoders here. */

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/devices/fineoffset_wh1050.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
};
119 changes: 119 additions & 0 deletions src/devices/fineoffset_wh55.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/** @file
Fine Offset / Ecowitt WH55 water leak sensor.
Copyright (C) 2023 Christian W. Zuckschwerdt <[email protected]>
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,
};

0 comments on commit 7b88ef5

Please sign in to comment.