Add support for WS2032 weather station (#1208)
This commit is contained in:
parent
cbe18f7b44
commit
2736df3762
9 changed files with 137 additions and 0 deletions
|
@ -220,6 +220,7 @@ Read the Test Data section at the bottom.
|
|||
[142] Fine Offset Electronics/ECOWITT WH51 Soil Moisture Sensor
|
||||
[143] Holman Industries iWeather WS5029 weather station (older PWM)
|
||||
[144] TBH weather sensor
|
||||
[145] WS2032 weather station
|
||||
|
||||
* Disabled by default, use -R n or -G
|
||||
|
||||
|
|
|
@ -331,6 +331,7 @@ stop_after_successful_events false
|
|||
protocol 142 # Fine Offset Electronics/ECOWITT WH51 Soil Moisture Sensor
|
||||
protocol 143 # Holman Industries iWeather WS5029 weather station (older PWM)
|
||||
protocol 144 # TBH weather sensor
|
||||
protocol 145 # WS2032 weather station
|
||||
|
||||
## Flex devices (command line option "-X")
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
DECL(fineoffset_WH51) \
|
||||
DECL(holman_ws5029pwm) \
|
||||
DECL(archos_tbh) \
|
||||
DECL(ws2032) \
|
||||
|
||||
/* Add new decoders here. */
|
||||
|
||||
|
|
|
@ -559,6 +559,9 @@ Holman Industries iWeather WS5029 weather station (older PWM)
|
|||
.TP
|
||||
[ \fB144\fI\fP ]
|
||||
TBH weather sensor
|
||||
.TP
|
||||
[ \fB145\fI\fP ]
|
||||
WS2032 weather station
|
||||
|
||||
* Disabled by default, use \-R n or \-G
|
||||
.SS "Input device selection"
|
||||
|
|
|
@ -144,6 +144,7 @@ add_executable(rtl_433
|
|||
devices/vaillant_vrt340f.c
|
||||
devices/waveman.c
|
||||
devices/wg_pb12v1.c
|
||||
devices/ws2032.c
|
||||
devices/wssensor.c
|
||||
devices/wt0124.c
|
||||
devices/wt450.c
|
||||
|
|
|
@ -145,6 +145,7 @@ rtl_433_SOURCES = abuf.c \
|
|||
devices/vaillant_vrt340f.c \
|
||||
devices/waveman.c \
|
||||
devices/wg_pb12v1.c \
|
||||
devices/ws2032.c \
|
||||
devices/wssensor.c \
|
||||
devices/wt0124.c \
|
||||
devices/wt450.c \
|
||||
|
|
125
src/devices/ws2032.c
Normal file
125
src/devices/ws2032.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/** @file
|
||||
WS2032 weather station.
|
||||
|
||||
Copyright (C) 2019 Christian W. Zuckschwerdt <zany@triq.net>
|
||||
|
||||
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.
|
||||
*/
|
||||
/**
|
||||
WS2032 weather station.
|
||||
|
||||
- Outdoor temperature range: -40F to 140F (-40C to 60C)
|
||||
- Temperature accuracy: +- 1.0 C
|
||||
- Humidity range: 20% to 90%
|
||||
- Humidity accuracy: +-5%
|
||||
- Wind direction: E,S,W,N,SE,NE,SW,NW
|
||||
- Wind direction accuracy: +- 10 deg
|
||||
- Wind speed: 0 to 50m/s, Accuracy: 0.1 m/s
|
||||
|
||||
Data format:
|
||||
|
||||
1x PRE:8h ID:16h ?8h DIR:4h TEMP:12d HUM:8d AVG?8d GUST?8d 24h SUM8h CHK8h TRAIL:3b
|
||||
|
||||
OOK with PWM. Long = 1000 us, short = 532 us, gap = 484 us.
|
||||
The overlong and very short pulses are sync, see the Pulseview.
|
||||
|
||||
Temp, not 2's complement but a dedicated sign-bit, i.e. 1 bit sign, 11 bit temp.
|
||||
|
||||
*/
|
||||
|
||||
#include "decoder.h"
|
||||
|
||||
static int fineoffset_ws2032_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||
{
|
||||
uint8_t const preamble[] = {0x0a}; // 8 bits, 0xf5 inverted
|
||||
|
||||
data_t *data;
|
||||
uint8_t b[14];
|
||||
|
||||
// find a proper row
|
||||
int row = bitbuffer_find_repeated_row(bitbuffer, 2, 14 * 8); // expected: 3 rows of 113 bits
|
||||
if (row < 0) {
|
||||
return DECODE_ABORT_EARLY;
|
||||
}
|
||||
|
||||
unsigned offset = bitbuffer_search(bitbuffer, row, 0, preamble, 8);
|
||||
if (offset + 14 * 8 > bitbuffer->bits_per_row[row]) {
|
||||
return DECODE_ABORT_LENGTH;
|
||||
}
|
||||
|
||||
// invert and align the row
|
||||
bitbuffer_invert(bitbuffer);
|
||||
bitbuffer_extract_bytes(bitbuffer, row, offset, b, 14 * 8);
|
||||
|
||||
// verify the checksums
|
||||
int sum = add_bytes(b, 12);
|
||||
if (sum == 0) {
|
||||
return DECODE_FAIL_SANITY; // discard all zeros
|
||||
}
|
||||
if ((sum & 0xff) != b[12]) {
|
||||
return DECODE_FAIL_MIC; // sum mismatch
|
||||
}
|
||||
if (crc8(b, 14, 0x31, 0x00)) {
|
||||
return DECODE_FAIL_MIC; // crc mismatch
|
||||
}
|
||||
|
||||
// get weather sensor data
|
||||
// 1x PRE:8h ID:16h ?8h DIR:4h TEMP:12d HUM:8d AVG?8d GUST?8d 24h SUM8h CHK8h TRAIL:3b
|
||||
int device_id = (b[1] << 8) | (b[2]);
|
||||
int flags = (b[3]);
|
||||
//int battery_low = b[3] & 0x80;
|
||||
float dir = (b[4] >> 4) * 22.5f;
|
||||
int temp_sign = (b[4] & 0x08) ? -1 : 1;
|
||||
int temp_raw = ((b[4] & 0x07) << 8) | b[5];
|
||||
float temperature = temp_sign * temp_raw * 0.1;
|
||||
int humidity = b[6];
|
||||
float speed = (b[7] * 0.43f) * 3.6f; // m/s -> km/h
|
||||
float gust = (b[8] * 0.43f) * 3.6f; // m/s -> km/h
|
||||
int rain_raw = (b[9] << 16) | (b[10] << 8) | b[11]; // maybe?
|
||||
|
||||
/* clang-format off */
|
||||
data = data_make(
|
||||
"model", "", DATA_STRING, "WS2032",
|
||||
"id", "StationID", DATA_FORMAT, "%04X", DATA_INT, device_id,
|
||||
//"battery_ok", "Battery", DATA_INT, !battery_low,
|
||||
"temperature_C", "Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temperature,
|
||||
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
|
||||
"direction_deg", "Wind direction", DATA_FORMAT, "%.01f", DATA_DOUBLE, dir,
|
||||
"wind_avg_km_h", "Wind avg speed", DATA_FORMAT, "%.01f", DATA_DOUBLE, speed,
|
||||
"wind_max_km_h", "Wind gust", DATA_FORMAT, "%.01f", DATA_DOUBLE, gust,
|
||||
"maybe_flags", "Flags?", DATA_FORMAT, "%02x", DATA_INT, flags,
|
||||
"maybe_rain", "Rain?", DATA_FORMAT, "%06x", DATA_INT, rain_raw,
|
||||
"mic", "Integrity", DATA_STRING, "CRC",
|
||||
NULL);
|
||||
/* clang-format on */
|
||||
|
||||
decoder_output_data(decoder, data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *output_fields[] = {
|
||||
"model",
|
||||
"id",
|
||||
"battery",
|
||||
"temperature_C",
|
||||
"humidity",
|
||||
"direction_deg",
|
||||
"wind_avg_km_h",
|
||||
"wind_max_km_h",
|
||||
NULL,
|
||||
};
|
||||
|
||||
r_device ws2032 = {
|
||||
.name = "WS2032 weather station",
|
||||
.modulation = OOK_PULSE_PWM,
|
||||
.short_width = 500,
|
||||
.long_width = 1000,
|
||||
.gap_limit = 750,
|
||||
.reset_limit = 4000,
|
||||
.decode_fn = &fineoffset_ws2032_decode,
|
||||
.disabled = 0,
|
||||
.fields = output_fields,
|
||||
};
|
|
@ -260,6 +260,7 @@
|
|||
<ClCompile Include="..\src\devices\vaillant_vrt340f.c" />
|
||||
<ClCompile Include="..\src\devices\waveman.c" />
|
||||
<ClCompile Include="..\src\devices\wg_pb12v1.c" />
|
||||
<ClCompile Include="..\src\devices\ws2032.c" />
|
||||
<ClCompile Include="..\src\devices\wssensor.c" />
|
||||
<ClCompile Include="..\src\devices\wt0124.c" />
|
||||
<ClCompile Include="..\src\devices\wt450.c" />
|
||||
|
|
|
@ -541,6 +541,9 @@
|
|||
<ClCompile Include="..\src\devices\wg_pb12v1.c">
|
||||
<Filter>Source Files\devices</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\devices\ws2032.c">
|
||||
<Filter>Source Files\devices</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\devices\wssensor.c">
|
||||
<Filter>Source Files\devices</Filter>
|
||||
</ClCompile>
|
||||
|
|
Loading…
Add table
Reference in a new issue