Cleanup LaCrosse LTV-WSDTH01 BreezePro
This commit is contained in:
parent
15c6d6e0a2
commit
9c1945885e
9 changed files with 68 additions and 59 deletions
|
@ -239,6 +239,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
|
||||||
[163] Acurite 590TX Temperature with optional Humidity
|
[163] Acurite 590TX Temperature with optional Humidity
|
||||||
[164] Security+ 2.0 (Keyfob)
|
[164] Security+ 2.0 (Keyfob)
|
||||||
[165] TFA Dostmann 30.3221.02 T/H Outdoor Sensor
|
[165] TFA Dostmann 30.3221.02 T/H Outdoor Sensor
|
||||||
|
[166] LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor
|
||||||
|
|
||||||
* Disabled by default, use -R n or -G
|
* Disabled by default, use -R n or -G
|
||||||
|
|
||||||
|
|
|
@ -347,6 +347,7 @@ stop_after_successful_events false
|
||||||
protocol 163 # Acurite 590TX Temperature with optional Humidity
|
protocol 163 # Acurite 590TX Temperature with optional Humidity
|
||||||
protocol 164 # Security+ 2.0 (Keyfob)
|
protocol 164 # Security+ 2.0 (Keyfob)
|
||||||
protocol 165 # TFA Dostmann 30.3221.02 T/H Outdoor Sensor
|
protocol 165 # TFA Dostmann 30.3221.02 T/H Outdoor Sensor
|
||||||
|
protocol 166 # LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor
|
||||||
|
|
||||||
## Flex devices (command line option "-X")
|
## Flex devices (command line option "-X")
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@
|
||||||
DECL(acurite_590tx) \
|
DECL(acurite_590tx) \
|
||||||
DECL(secplus_v2) \
|
DECL(secplus_v2) \
|
||||||
DECL(tfa_30_3221) \
|
DECL(tfa_30_3221) \
|
||||||
|
DECL(lacrosse_breezepro) \
|
||||||
/* Add new decoders here. */
|
/* Add new decoders here. */
|
||||||
|
|
||||||
#define DECL(name) extern r_device name;
|
#define DECL(name) extern r_device name;
|
||||||
|
|
|
@ -616,6 +616,9 @@ Security+ 2.0 (Keyfob)
|
||||||
.TP
|
.TP
|
||||||
[ \fB165\fI\fP ]
|
[ \fB165\fI\fP ]
|
||||||
TFA Dostmann 30.3221.02 T/H Outdoor Sensor
|
TFA Dostmann 30.3221.02 T/H Outdoor Sensor
|
||||||
|
.TP
|
||||||
|
[ \fB166\fI\fP ]
|
||||||
|
LaCrosse Technology View LTV\-WSDTH01 Breeze Pro Wind Sensor
|
||||||
|
|
||||||
* Disabled by default, use \-R n or \-G
|
* Disabled by default, use \-R n or \-G
|
||||||
.SS "Input device selection"
|
.SS "Input device selection"
|
||||||
|
|
|
@ -100,6 +100,7 @@ add_library(r_433 STATIC
|
||||||
devices/kerui.c
|
devices/kerui.c
|
||||||
devices/klimalogg.c
|
devices/klimalogg.c
|
||||||
devices/lacrosse.c
|
devices/lacrosse.c
|
||||||
|
devices/lacrosse_breezepro.c
|
||||||
devices/lacrosse_tx141x.c
|
devices/lacrosse_tx141x.c
|
||||||
devices/lacrosse_tx35.c
|
devices/lacrosse_tx35.c
|
||||||
devices/lacrosse_ws7000.c
|
devices/lacrosse_ws7000.c
|
||||||
|
|
|
@ -99,6 +99,7 @@ rtl_433_SOURCES = abuf.c \
|
||||||
devices/kerui.c \
|
devices/kerui.c \
|
||||||
devices/klimalogg.c \
|
devices/klimalogg.c \
|
||||||
devices/lacrosse.c \
|
devices/lacrosse.c \
|
||||||
|
devices/lacrosse_breezepro.c \
|
||||||
devices/lacrosse_tx141x.c \
|
devices/lacrosse_tx141x.c \
|
||||||
devices/lacrosse_tx35.c \
|
devices/lacrosse_tx35.c \
|
||||||
devices/lacrosse_ws7000.c \
|
devices/lacrosse_ws7000.c \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/** @file
|
/** @file
|
||||||
LaCrosse Breeze Pro LTV-WSDTH01 sensor.
|
LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor.
|
||||||
|
|
||||||
Copyright (C) 2020 Mike Bruski (AJ9X) <michael.bruski@gmail.com>
|
Copyright (C) 2020 Mike Bruski (AJ9X) <michael.bruski@gmail.com>
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
LaCrosse Breeze Pro LTV-WSDTH01 sensor.
|
LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor.
|
||||||
|
|
||||||
LaCrosse Color Forecast Station (model 79400) utilizes the remote temp/
|
LaCrosse Color Forecast Station (model 79400) utilizes the remote temp/
|
||||||
humidity/wind speed/wind direction sensor LTV-WSDTH01.
|
humidity/wind speed/wind direction sensor LTV-WSDTH01.
|
||||||
|
@ -18,6 +18,13 @@ Product pages:
|
||||||
https://www.lacrossetechnology.com/products/79400
|
https://www.lacrossetechnology.com/products/79400
|
||||||
https://www.lacrossetechnology.com/products/ltv-wsdth01
|
https://www.lacrossetechnology.com/products/ltv-wsdth01
|
||||||
|
|
||||||
|
Specifications:
|
||||||
|
- Wind Speed Range: 0 to 178 kmh
|
||||||
|
- Degrees of Direction: 360 deg with 16 Cardinal Directions
|
||||||
|
- Outdoor Temperature Range: -29 C to 60 C
|
||||||
|
- Outdoor Humidity Range: 10 to 99 %RH
|
||||||
|
- Update Interval: Every 31 Seconds
|
||||||
|
|
||||||
Internal inspection of the remote sensor reveals that the device
|
Internal inspection of the remote sensor reveals that the device
|
||||||
utilizes a HopeRF CMT2119A ISM transmitter chip which is capable of
|
utilizes a HopeRF CMT2119A ISM transmitter chip which is capable of
|
||||||
transmitting up to 32 bytes of data on any ISM frequency using OOK
|
transmitting up to 32 bytes of data on any ISM frequency using OOK
|
||||||
|
@ -37,76 +44,75 @@ CMT2219A.
|
||||||
(http://www.cmostek.com/download/CMT2219A.pdf)
|
(http://www.cmostek.com/download/CMT2219A.pdf)
|
||||||
(http://www.cmostek.com/download/AN138%20CMT2219A%20Configuration%20Guideline.pdf)
|
(http://www.cmostek.com/download/AN138%20CMT2219A%20Configuration%20Guideline.pdf)
|
||||||
|
|
||||||
|
|
||||||
Protocol Specification:
|
Protocol Specification:
|
||||||
|
|
||||||
Data bits are NRZ encoded with logical 1 and 0 bits 106.842us in length.
|
Data bits are NRZ encoded with logical 1 and 0 bits 106.842us in length.
|
||||||
|
|
||||||
SYN:32h ID:24h ?:4 SEQ:3b ?:1b TEMP:12d HUM:12d WSPD:12d WDIR:12d CHK:8h END:32h
|
SYN:32h ID:24h ?:4b SEQ:3d ?:1b TEMP:12d HUM:12d WSPD:12d WDIR:12d CHK:8h END:32h
|
||||||
|
|
||||||
Packet length is 264 bits according to inspectrum broken down as follows:
|
Packet length is 264 bits according to inspectrum broken down as follows:
|
||||||
|
|
||||||
preamble: 7 bytes (when aligned with sync word these are 0xaa)
|
- warm-up: 7 bytes (0x55, aligned with sync word these are 0xaa)
|
||||||
sync word: 4 bytes (0xd2aa2dd4)
|
- preamble/sync 4 bytes 0xd2aa2dd4 (see as 0x695516ea05)
|
||||||
device ID: 3 bytes (matches bar code underside of unit covering pgm port)
|
- device id: 3 bytes (matches bar code underside of unit covering pgm port)
|
||||||
x1: 4 bit (unknown, bit 0?00 might be 'battery low')
|
- x1: 4 bit (unknown, bit 0?00 might be 'battery low')
|
||||||
sequence: 3 bits (0-7, one up per packet, then repeats)
|
- sequence: 3 bits (0-7, one up per packet, then repeats)
|
||||||
x2: 1 bit (unknown)
|
- x2: 1 bit (unknown)
|
||||||
celsius: 12 bits (base 400, scale 10, range: -29°C to 60°C)
|
- celsius: 12 bits (offset 400, scale 10, range: -29 C to 60 C)
|
||||||
humidity: 12 bits (10 to 99% relative humidity)
|
- humidity: 12 bits (10 to 99% relative humidity)
|
||||||
wind speed: 12 bits (0.0 to 178.0 kMh)
|
- wind speed: 12 bits (0.0 to 178.0 kMh)
|
||||||
wind direction: 12 bits (0 to 359°)
|
- wind direction: 12 bits (0 to 359 deg)
|
||||||
checksum: 8 bits (CRC-8 poly 0x31 init 0x00 over 10 bytes after sync)
|
- checksum: 8 bits (CRC-8 poly 0x31 init 0x00 over 10 bytes after sync)
|
||||||
end: 32 bytes (0xd2d2d200)
|
- trailer: 32 bytes (0xd2d2d200)
|
||||||
|
|
||||||
|
|
||||||
The sensor generates a packet every 'n' seconds but only transmits if one or
|
The sensor generates a packet every 'n' seconds but only transmits if one or
|
||||||
more of the following conditions are satified:
|
more of the following conditions are satified:
|
||||||
|
|
||||||
temp changes +/- 0.8 degrees C
|
- temp changes +/- 0.8 degrees C
|
||||||
humidity changes +/- 1%
|
- humidity changes +/- 1%
|
||||||
wind speed changes +/- 0.5 kM/h
|
- wind speed changes +/- 0.5 kM/h
|
||||||
|
|
||||||
Thus, if there is a gap in sequencing, it is due to bad packet[s] (too short,
|
Thus, if there is a gap in sequencing, it is due to bad packet[s] (too short,
|
||||||
failed CRC) or packet[s] that didn't satisfy at least one of these three
|
failed CRC) or packet[s] that didn't satisfy at least one of these three
|
||||||
conditions. 'n' above varies with temperature. At 0C and above, 'n' is 31.
|
conditions. 'n' above varies with temperature. At 0C and above, 'n' is 31.
|
||||||
Between -17C and 0C, 'n' is 60. Below -17C, 'n' is 360.
|
Between -17C and 0C, 'n' is 60. Below -17C, 'n' is 360.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "decoder.h"
|
#include "decoder.h"
|
||||||
|
|
||||||
static const uint8_t sync_word[] = { 0xd2, 0xaa, 0x2d, 0xd4 };
|
|
||||||
|
|
||||||
static int lacrosse_breezepro_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
static int lacrosse_breezepro_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||||
{
|
{
|
||||||
|
uint8_t const preamble_pattern[] = { 0xd2, 0xaa, 0x2d, 0xd4 };
|
||||||
|
|
||||||
data_t *data;
|
data_t *data;
|
||||||
uint8_t p[32], l, *c, x1, x2, seq, offset, chk;
|
uint8_t b[11];
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint16_t raw_temp, humidity, raw_speed, direction;
|
int flags, seq, offset, chk;
|
||||||
|
int raw_temp, humidity, raw_speed, direction;
|
||||||
float temp_c, speed_kmh;
|
float temp_c, speed_kmh;
|
||||||
|
|
||||||
if (bitbuffer->bits_per_row[0] < 264) {
|
if (bitbuffer->bits_per_row[0] < 264) {
|
||||||
if (decoder->verbose) {
|
if (decoder->verbose) {
|
||||||
fprintf(stderr, "%s: Wrong packet length: %d\n", __func__, bitbuffer->bits_per_row[0]);
|
fprintf(stderr, "%s: Wrong packet length: %d\n", __func__, bitbuffer->bits_per_row[0]);
|
||||||
}
|
}
|
||||||
return DECODE_ABORT_LENGTH;
|
return DECODE_ABORT_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = bitbuffer_search(bitbuffer, 0, 0,
|
offset = bitbuffer_search(bitbuffer, 0, 0,
|
||||||
sync_word, sizeof(sync_word) * 8);
|
preamble_pattern, sizeof(preamble_pattern) * 8);
|
||||||
|
|
||||||
if (offset == bitbuffer->bits_per_row[0]) {
|
if (offset >= bitbuffer->bits_per_row[0]) {
|
||||||
if (decoder->verbose) {
|
if (decoder->verbose) {
|
||||||
fprintf(stderr, "%s: Sync word not found\n", __func__);
|
fprintf(stderr, "%s: Sync word not found\n", __func__);
|
||||||
}
|
}
|
||||||
return DECODE_FAIL_SANITY;
|
return DECODE_ABORT_EARLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset += sizeof(preamble_pattern) * 8;
|
||||||
|
bitbuffer_extract_bytes(bitbuffer, 0, offset, b, 11 * 8);
|
||||||
|
|
||||||
c = bitbuffer->bb[offset];
|
chk = crc8(b, 11, 0x31, 0x00);
|
||||||
|
|
||||||
chk = crc8(c, 10, 0x31, 0x00);
|
|
||||||
if (chk) {
|
if (chk) {
|
||||||
if (decoder->verbose) {
|
if (decoder->verbose) {
|
||||||
fprintf(stderr, "%s: CRC failed!\n", __func__);
|
fprintf(stderr, "%s: CRC failed!\n", __func__);
|
||||||
|
@ -118,35 +124,29 @@ static int lacrosse_breezepro_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||||
bitbuffer_print(bitbuffer);
|
bitbuffer_print(bitbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
l = bitbuffer->bits_per_row[0] - offset;
|
id = (b[0] << 16) | (b[1] << 8) | b[2];
|
||||||
offset += sizeof(sync_word) * 8;
|
flags = (b[3] & 0xf1); // masks off seq bits
|
||||||
bitbuffer_extract_bytes(bitbuffer, 0, offset, p, l);
|
seq = (b[3] & 0x0e) >> 1;
|
||||||
|
raw_temp = b[4] << 4 | ((b[5] & 0xf0) >> 4);
|
||||||
|
humidity = ((b[5] & 0x0f) << 8) | b[6];
|
||||||
|
raw_speed = b[7] << 4 | ((b[8] & 0xf0) >> 4);
|
||||||
|
direction = ((b[8] & 0x0f) << 8) | b[9];
|
||||||
|
|
||||||
id = (p[0] << 16) | (p[1] << 8) | p[2];
|
// base and/or scale adjustments
|
||||||
x1 = (p[3] & 0xf0) >> 4;
|
temp_c = (raw_temp - 400) * 0.1f;
|
||||||
seq = (p[3] & 0x0e) >> 1;
|
speed_kmh = raw_speed * 0.1f;
|
||||||
x2 = p[3] & 0x01;
|
|
||||||
raw_temp = p[4] << 4 | ((p[5] & 0xf0) >> 4);
|
|
||||||
humidity = ((p[5] & 0x0f) << 8) | p[6];
|
|
||||||
raw_speed = p[7] << 4 | ((p[8] & 0xf0) >> 4);
|
|
||||||
direction = ((p[8] & 0x0f) << 8) | p[9];
|
|
||||||
|
|
||||||
/* base and/or scale adjustments */
|
|
||||||
temp_c = (float)raw_temp * 0.1 - 40.0;
|
|
||||||
speed_kmh = (float)raw_speed * 0.1;
|
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
data = data_make(
|
data = data_make(
|
||||||
"model", "", DATA_STRING, "LaCrosse-LTV-WSDTH01",
|
"model", "", DATA_STRING, "LaCrosse-BreezePro",
|
||||||
"id", "Sensor ID", DATA_FORMAT, "%06x", DATA_INT, id,
|
"id", "Sensor ID", DATA_FORMAT, "%06x", DATA_INT, id,
|
||||||
"x1", "unknown", DATA_INT, x1,
|
|
||||||
"seq", "Sequence", DATA_FORMAT, "%01x", DATA_INT, seq,
|
"seq", "Sequence", DATA_FORMAT, "%01x", DATA_INT, seq,
|
||||||
"x2", "unknown", DATA_INT, x2,
|
"flags", "unknown", DATA_INT, flags,
|
||||||
"temperature_C", "Temperature", DATA_FORMAT, "%.1f C", DATA_DOUBLE, temp_c,
|
"temperature_C", "Temperature", DATA_FORMAT, "%.1f C", DATA_DOUBLE, temp_c,
|
||||||
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
|
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
|
||||||
"wind_avg_km_h", "Wind speed", DATA_FORMAT, "%.1f km/h", DATA_DOUBLE, speed_kmh,
|
"wind_avg_km_h", "Wind speed", DATA_FORMAT, "%.1f km/h", DATA_DOUBLE, speed_kmh,
|
||||||
"wind_dir_deg", "Wind direction", DATA_INT, direction,
|
"wind_dir_deg", "Wind direction", DATA_INT, direction,
|
||||||
"mic", "Integrity", DATA_STRING, "CRC8",
|
"mic", "Integrity", DATA_STRING, "CRC",
|
||||||
NULL);
|
NULL);
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
@ -157,26 +157,23 @@ static int lacrosse_breezepro_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||||
static char *output_fields[] = {
|
static char *output_fields[] = {
|
||||||
"model",
|
"model",
|
||||||
"id",
|
"id",
|
||||||
"x1",
|
"seq",
|
||||||
"seq",
|
"flags",
|
||||||
"x2",
|
|
||||||
"temperature_C",
|
"temperature_C",
|
||||||
"humidity",
|
"humidity",
|
||||||
"wind_avg_km_h",
|
"wind_avg_km_h",
|
||||||
"wind_dir_deg",
|
"wind_dir_deg",
|
||||||
"test",
|
|
||||||
"mic",
|
"mic",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
// flex decoder m=FSK_PCM, s=107, l=107, r=5900
|
// flex decoder m=FSK_PCM, s=107, l=107, r=5900
|
||||||
r_device lacrosse_breezepro = {
|
r_device lacrosse_breezepro = {
|
||||||
.name = "LaCrosse LTV-WSDTH01 sensor",
|
.name = "LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor",
|
||||||
.modulation = FSK_PULSE_PCM,
|
.modulation = FSK_PULSE_PCM,
|
||||||
.short_width = 107,
|
.short_width = 107,
|
||||||
.long_width = 107,
|
.long_width = 107,
|
||||||
.reset_limit = 5900,
|
.reset_limit = 5900,
|
||||||
.decode_fn = &lacrosse_breezepro_decode,
|
.decode_fn = &lacrosse_breezepro_decode,
|
||||||
.disabled = 0,
|
|
||||||
.fields = output_fields,
|
.fields = output_fields,
|
||||||
};
|
};
|
||||||
|
|
|
@ -223,6 +223,7 @@ COPY ..\..\libusb\MS64\dll\libusb*.dll $(TargetDir)</Command>
|
||||||
<ClCompile Include="..\src\devices\kerui.c" />
|
<ClCompile Include="..\src\devices\kerui.c" />
|
||||||
<ClCompile Include="..\src\devices\klimalogg.c" />
|
<ClCompile Include="..\src\devices\klimalogg.c" />
|
||||||
<ClCompile Include="..\src\devices\lacrosse.c" />
|
<ClCompile Include="..\src\devices\lacrosse.c" />
|
||||||
|
<ClCompile Include="..\src\devices\lacrosse_breezepro.c" />
|
||||||
<ClCompile Include="..\src\devices\lacrosse_tx141x.c" />
|
<ClCompile Include="..\src\devices\lacrosse_tx141x.c" />
|
||||||
<ClCompile Include="..\src\devices\lacrosse_tx35.c" />
|
<ClCompile Include="..\src\devices\lacrosse_tx35.c" />
|
||||||
<ClCompile Include="..\src\devices\lacrosse_ws7000.c" />
|
<ClCompile Include="..\src\devices\lacrosse_ws7000.c" />
|
||||||
|
|
|
@ -406,6 +406,9 @@
|
||||||
<ClCompile Include="..\src\devices\lacrosse.c">
|
<ClCompile Include="..\src\devices\lacrosse.c">
|
||||||
<Filter>Source Files\devices</Filter>
|
<Filter>Source Files\devices</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\devices\lacrosse_breezepro.c">
|
||||||
|
<Filter>Source Files\devices</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\src\devices\lacrosse_tx141x.c">
|
<ClCompile Include="..\src\devices\lacrosse_tx141x.c">
|
||||||
<Filter>Source Files\devices</Filter>
|
<Filter>Source Files\devices</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
Loading…
Add table
Reference in a new issue