Added support for FineOffset/ECOWITT WH51 (#1242)
* Added support for FineOffset/ECOWITT WH51
This commit is contained in:
parent
3de2c414ac
commit
084e8f3033
2 changed files with 125 additions and 0 deletions
|
@ -149,6 +149,7 @@
|
|||
DECL(norgo) \
|
||||
DECL(tpms_elantra2012) \
|
||||
DECL(auriol_hg02832) \
|
||||
DECL(fineoffset_WH51) \
|
||||
|
||||
/* Add new decoders here. */
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Copyright (C) 2017 Tommy Vestermark
|
||||
Enhanced (C) 2019 Christian W. Zuckschwerdt <zany@triq.net>
|
||||
Added WH51 Soil Moisture Sensor (C) 2019 Marco Di Leo
|
||||
|
||||
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
|
||||
|
@ -508,6 +509,108 @@ static int fineoffset_WH25_callback(r_device *decoder, bitbuffer_t *bitbuffer)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Fine Offset WH51, ECOWITT WH51, MISOL/1 Soil Moisture Sensor
|
||||
|
||||
Test decoding with: rtl_433 -f 433920000 -X "n=soil_sensor,m=FSK_PCM,s=58,l=58,t=5,r=5000,g=4000,preamble=aa2dd4"
|
||||
|
||||
Data format:
|
||||
|
||||
00 01 02 03 04 05 06 07 08 09 10 11 12 13
|
||||
aa aa aa 2d d4 51 00 6b 58 6e 7f 24 f8 d2 ff ff ff 3c 28 8
|
||||
FF II II II TB YY MM ZA AA XX XX XX CC SS
|
||||
|
||||
Sync: aa aa aa ...
|
||||
Preamble: 2d d4
|
||||
FF: Family code 0x51 (ECOWITT/FineOffset WH51)
|
||||
IIIIII: ID (3 bytes)
|
||||
T: Transmission period boost: highest 3 bits set to 111 on moisture change and decremented each transmission;
|
||||
if T = 0 period is 70 sec, if T > 0 period is 10 sec
|
||||
B: Battery voltage: lowest 5 bits are battery voltage * 10 (e.g. 0x0c = 12 = 1.2V). Transmitter works down to 0.7V (0x07)
|
||||
YY: ? Fixed: 0x7f
|
||||
MM: Moisture percentage 0%-100% (0x00-0x64) MM = (AD - 70) / (450 - 70)
|
||||
Z: ? Fixed: leftmost 7 bit 1111 100
|
||||
AAA: 9 bit AD value MSB byte[07] & 0x01, LSB byte[08]
|
||||
XXXXXX: ? Fixed: 0xff 0xff 0xff
|
||||
CC: CRC of the preceding 12 bytes (Polynomial 0x31, Initial value 0x00, Input not reflected, Result not reflected)
|
||||
SS: Sum of the preceding 13 bytes % 256
|
||||
|
||||
See http://www.ecowitt.com/upfile/201904/WH51%20Manual.pdf for relationship between AD and moisture %
|
||||
|
||||
Short explanation:
|
||||
Soil Moisture Percentage = (Moisture AD – 0%AD) / (100%AD – 0%AD) * 100
|
||||
0%AD = 70
|
||||
100%AD = 450 (manual states 500, but sensor internal computation are closer to 450)
|
||||
If sensor-calculated moisture percentage are inaccurate at low/high values, use the AD value and the above formaula
|
||||
changing 0%AD and 100%AD to cover the full scale from dry to damp
|
||||
*/
|
||||
|
||||
static int fineoffset_WH51_callback(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||
{
|
||||
data_t *data;
|
||||
uint8_t const preamble[] = {0xAA, 0x2D, 0xD4};
|
||||
uint8_t b[14];
|
||||
unsigned bit_offset;
|
||||
|
||||
// Validate package
|
||||
if (bitbuffer->bits_per_row[0] < 136) { // Minimum length 14 bytes data + 3 bytes preamble
|
||||
return DECODE_ABORT_LENGTH;
|
||||
}
|
||||
|
||||
// Find a data package and extract data payload
|
||||
bit_offset = bitbuffer_search(bitbuffer, 0, 0, preamble, sizeof(preamble) * 8) + sizeof(preamble) * 8;
|
||||
if (bit_offset + sizeof(b) * 8 > bitbuffer->bits_per_row[0]) { // Did not find a big enough package
|
||||
if (decoder->verbose)
|
||||
bitbuffer_printf(bitbuffer, "Fineoffset_WH51: short package. Header index: %u\n", bit_offset);
|
||||
return DECODE_ABORT_LENGTH;
|
||||
}
|
||||
bitbuffer_extract_bytes(bitbuffer, 0, bit_offset, b, sizeof(b) * 8);
|
||||
|
||||
// Verify family code
|
||||
if (b[0] != 0x51) {
|
||||
if (decoder->verbose)
|
||||
fprintf(stderr, "Fineoffset_WH51: Msg family unknown: %2x\n", b[0]);
|
||||
return DECODE_ABORT_EARLY;
|
||||
}
|
||||
|
||||
// Verify checksum
|
||||
if ((add_bytes(b, 13) & 0xff) != b[13]) {
|
||||
if (decoder->verbose)
|
||||
bitrow_printf(b, sizeof (b) * 8, "Fineoffset_WH51: Checksum error: ");
|
||||
return DECODE_FAIL_MIC;
|
||||
}
|
||||
|
||||
// Verify crc
|
||||
if (crc8(b, 12, 0x31, 0) != b[12]) {
|
||||
if (decoder->verbose)
|
||||
bitrow_printf(b, sizeof (b) * 8, "Fineoffset_WH51: Bitsum error: ");
|
||||
return DECODE_FAIL_MIC;
|
||||
}
|
||||
|
||||
// Decode data
|
||||
char id[7];
|
||||
sprintf( id, "%2.2x%2.2x%2.2x", b[1], b[2], b[3]);
|
||||
int boost = (b[4] & 0xe0) >> 5;
|
||||
float battery = (b[4] & 0x1f) * 0.1;
|
||||
int ad = (((int)b[7] & 0x01) << 8) | (int)b[8];
|
||||
uint8_t moisture = b[6];
|
||||
|
||||
/* clang-format off */
|
||||
data = data_make(
|
||||
"model", "", DATA_STRING, "Fineoffset-WH51",
|
||||
"id", "ID", DATA_STRING, id,
|
||||
"boost", "Transmission boost", DATA_FORMAT, "%u", DATA_INT, boost,
|
||||
"battery", "Battery", DATA_FORMAT, "%.01f V", DATA_DOUBLE, battery,
|
||||
"moisture", "Moisture", DATA_FORMAT, "%u %%", DATA_INT, moisture,
|
||||
"ad", "AD", DATA_FORMAT, "%u", DATA_INT, ad,
|
||||
NULL);
|
||||
/* clang-format on */
|
||||
|
||||
decoder_output_data(decoder, data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Alecto WS-1200 V1.0 decoder by Christian Zuckschwerdt, documentation by Andreas Untergasser, help by curlyel.
|
||||
|
||||
|
@ -846,6 +949,16 @@ static char *output_fields_WH25[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static char *output_fields_WH51[] = {
|
||||
"model",
|
||||
"id",
|
||||
"boost",
|
||||
"battery",
|
||||
"moisture",
|
||||
"ad",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static char *output_fields_WH0530[] = {
|
||||
"model",
|
||||
"id",
|
||||
|
@ -882,6 +995,17 @@ r_device fineoffset_WH25 = {
|
|||
.fields = output_fields_WH25,
|
||||
};
|
||||
|
||||
r_device fineoffset_WH51 = {
|
||||
.name = "Fine Offset Electronics/ECOWITT WH51 Soil Moisture Sensor",
|
||||
.modulation = FSK_PULSE_PCM,
|
||||
.short_width = 58, // Bit width = 58µs (measured across 580 samples / 40 bits / 250 kHz )
|
||||
.long_width = 58, // NRZ encoding (bit width = pulse width)
|
||||
.reset_limit = 5000,
|
||||
.decode_fn = &fineoffset_WH51_callback,
|
||||
.disabled = 0,
|
||||
.fields = output_fields_WH51,
|
||||
};
|
||||
|
||||
r_device fineoffset_WH0530 = {
|
||||
.name = "Fine Offset Electronics, WH0530 Temperature/Rain Sensor",
|
||||
.modulation = OOK_PULSE_PWM,
|
||||
|
|
Loading…
Add table
Reference in a new issue