Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Ecowitt WN34D and improve FineOffset WN34 #2944

Merged
merged 2 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
[218] Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK)
[219] Fine Offset Electronics WH45 air quality sensor
[220] Maverick XR-30 BBQ Sensor
[221] Fine Offset Electronics WN34 temperature sensor
[221] Fine Offset Electronics WN34S/L/D and Froggit DP150/D35 temperature sensor
[222] Rubicson Pool Thermometer 48942
[223] Badger ORION water meter, 100kbps (-f 916.45M -s 1200k)
[224] GEO minim+ energy monitor
Expand Down
54 changes: 33 additions & 21 deletions src/devices/fineoffset_wn34.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@
/**
Fine Offset Electronics WN34 Temperature Sensor.

- also Ecowitt WN34S (soil), WN34L (water)
- also Ecowitt WN34S (soil), WN34L (water), range is -40~60 °C (-40~140 °F)
- also Ecowitt WN34D (water), range is -55~125 °C (-67~257 °F)
- also Froggit DP150 (soil), DP35 (water)

Preamble is aaaa aaaa, sync word is 2dd4.

Packet layout:

0 1 2 3 4 5 6 7 8
YY II II II 0T TT BB XX AA
34 00 29 65 02 85 44 66 f3
0 1 2 3 4 5 6 7 8 9 10
YY II II II ST TT BB XX AA ZZ ZZ
34 00 29 65 02 85 44 66 f3 20 10

- Y: 8 bit fixed sensor type 0x34
- I: 24 bit device ID
- T: 11 bit temperature, offset 40, scale 10
- B: 7 bit battery level (unit of 20 mV)
- X: 8 bit CRC
- A: 8 bit checksum
- Y:{8} fixed sensor type 0x34
- I:{24} device ID
- S:{4} sub type, 0 = WN34L, 0x4 = WN34D
- T:{12} temperature, offset 40 (except WN34D), scale 10
- B:{7} battery level (unit of 20 mV)
- X:{8} bit CRC
- A:{8} bit checksum
- Z:{13} trail byte, not used.

*/

Expand All @@ -40,6 +43,7 @@ static int fineoffset_wn34_decode(r_device *decoder, bitbuffer_t *bitbuffer)
uint8_t const preamble[] = {0xAA, 0x2D, 0xD4};
uint8_t b[9];
unsigned bit_offset;
float temperature;

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
Expand Down Expand Up @@ -68,10 +72,17 @@ static int fineoffset_wn34_decode(r_device *decoder, bitbuffer_t *bitbuffer)
}

// Decode data
int id = (b[1] << 16) | (b[2] << 8) | (b[3]);
int temp_raw = (b[4] & 0x7) << 8 | b[5];
float temperature = (temp_raw - 400) * 0.1f; // range -40.0-60.0 C
int battery_mv = (b[6] & 0x7f) * 20; // mV
int id = (b[1] << 16) | (b[2] << 8) | (b[3]);
int temp_raw = (int16_t)((b[4] & 0x0F) << 12 | b[5] << 4); // use sign extend
int sub_type = (b[4] & 0xF0) >> 4;
decoder_logf(decoder, 1, __func__, "subtype : %d", sub_type);

if (sub_type == 4) // WN34D
temperature = (temp_raw >> 4) * 0.1f; // scale by 10 only.
else // WN34L/WN34S ...
temperature = ((temp_raw >> 4) * 0.1f) - 40; // scale by 10, offset 40

int battery_mv = (b[6] & 0x7f) * 20; // mV

/*
* A 5 bar battery indicator is shown in the Ecowitt WS View app.
Expand All @@ -97,12 +108,13 @@ static int fineoffset_wn34_decode(r_device *decoder, bitbuffer_t *bitbuffer)

/* clang-format off */
data = data_make(
"model", "", DATA_STRING, "Fineoffset-WN34",
"id", "ID", DATA_FORMAT, "%x", DATA_INT, id,
"battery_ok", "Battery", DATA_FORMAT, "%.1f", DATA_DOUBLE, battery_ok,
"battery_mV", "Battery Voltage", DATA_FORMAT, "%d mV", DATA_INT, battery_mv,
"temperature_C", "Temperature", DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature,
"mic", "Integrity", DATA_STRING, "CRC",
"model", "", DATA_COND, sub_type != 4, DATA_STRING, "Fineoffset-WN34",
"model", "", DATA_COND, sub_type == 4, DATA_STRING, "Fineoffset-WN34D",
"id", "ID", DATA_FORMAT, "%x", DATA_INT, id,
"battery_ok", "Battery", DATA_FORMAT, "%.1f", DATA_DOUBLE, battery_ok,
"battery_mV", "Battery Voltage", DATA_FORMAT, "%d mV", DATA_INT, battery_mv,
"temperature_C", "Temperature", DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature,
"mic", "Integrity", DATA_STRING, "CRC",
NULL);
/* clang-format on */

Expand All @@ -121,7 +133,7 @@ static char const *const output_fields[] = {
};

r_device const fineoffset_wn34 = {
.name = "Fine Offset Electronics WN34 temperature sensor",
.name = "Fine Offset Electronics WN34S/L/D and Froggit DP150/D35 temperature sensor",
.modulation = FSK_PULSE_PCM,
.short_width = 58,
.long_width = 58,
Expand Down
Loading