-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Fine Offset WN34 temperature sensor (#2122)
- Loading branch information
1 parent
b7b0f85
commit d0af8ea
Showing
5 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/** @file | ||
Fine Offset Electronics WN34 Temperature Sensor. | ||
Copyright (C) 2022 @anthyz | ||
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 Electronics WN34 Temperature Sensor. | ||
- also Ecowitt WN34S (soil), WN34L (water) | ||
- 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 | ||
- 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 | ||
*/ | ||
|
||
static int fineoffset_wn34_decode(r_device *decoder, bitbuffer_t *bitbuffer) | ||
{ | ||
data_t *data; | ||
uint8_t const preamble[] = {0xAA, 0x2D, 0xD4}; | ||
uint8_t b[9]; | ||
unsigned bit_offset; | ||
|
||
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 | ||
decoder_logf_bitbuffer(decoder, 2, __func__, bitbuffer, "short package. Row length: %u. Header index: %u", bitbuffer->bits_per_row[0], bit_offset); | ||
return DECODE_ABORT_LENGTH; | ||
} | ||
|
||
bitbuffer_extract_bytes(bitbuffer, 0, bit_offset, b, sizeof(b) * 8); | ||
|
||
decoder_log_bitrow(decoder, 1, __func__, b, sizeof (b) * 8, ""); | ||
|
||
// Verify family code | ||
if (b[0] != 0x34) { | ||
decoder_logf(decoder, 2, __func__, "Msg family unknown: %2x", b[0]); | ||
decoder_logf_bitbuffer(decoder, 2, __func__, bitbuffer, "Row length(bits_per_row[0]): %u", bitbuffer->bits_per_row[0]); | ||
return DECODE_ABORT_EARLY; | ||
} | ||
|
||
// Verify checksum, same as other FO Stations: Reverse 1Wire CRC (poly 0x131) | ||
uint8_t crc = crc8(b, 7, 0x31, 0x00); | ||
uint8_t chk = add_bytes(b, 8); | ||
|
||
if (crc != b[7] || chk != b[8]) { | ||
decoder_logf(decoder, 2, __func__, "Checksum error: %02x %02x", crc, chk); | ||
return DECODE_FAIL_MIC; | ||
} | ||
|
||
// 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 | ||
|
||
/* | ||
* A 5 bar battery indicator is shown in the Ecowitt WS View app. | ||
* Through observation of battery_mv values and the app indicator, | ||
* it was determined that battery_mv maps non-linearly to the number | ||
* of bars. Set battery_ok by mapping battery bars from 0 to 1 where | ||
* 1 bar = 0 and 5 bars = 1. | ||
*/ | ||
int battery_bars; | ||
|
||
if (battery_mv > 1440) | ||
battery_bars = 5; | ||
else if (battery_mv > 1380) | ||
battery_bars = 4; | ||
else if (battery_mv > 1300) | ||
battery_bars = 3; | ||
else if (battery_mv > 1200) | ||
battery_bars = 2; | ||
else | ||
battery_bars = 1; | ||
|
||
float battery_ok = (battery_bars - 1) * 0.25f; | ||
|
||
/* 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, "%.01f C", DATA_DOUBLE, temperature, | ||
"mic", "Integrity", DATA_STRING, "CRC", | ||
NULL); | ||
/* clang-format on */ | ||
|
||
decoder_output_data(decoder, data); | ||
return 1; | ||
} | ||
|
||
static char *output_fields[] = { | ||
"model", | ||
"id", | ||
"battery_ok", | ||
"battery_mV", | ||
"temperature_C", | ||
"mic", | ||
NULL, | ||
}; | ||
|
||
r_device fineoffset_wn34 = { | ||
.name = "Fine Offset Electronics WN34 temperature sensor", | ||
.modulation = FSK_PULSE_PCM, | ||
.short_width = 58, | ||
.long_width = 58, | ||
.reset_limit = 2500, | ||
.decode_fn = &fineoffset_wn34_decode, | ||
.fields = output_fields, | ||
}; |