Skip to content

Commit 5b2a938

Browse files
elljay23zuckschwerdt
authored andcommitted
Fix Oregon Scientific negative temp, add BCD sanity checks (#2086)
1 parent e37fc5d commit 5b2a938

File tree

1 file changed

+61
-7
lines changed

1 file changed

+61
-7
lines changed

src/devices/oregon_scientific.c

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,23 @@ static float get_os_temperature(unsigned char *message)
5050
{
5151
float temp_c = 0;
5252
temp_c = (((message[5] >> 4) * 100) + ((message[4] & 0x0f) * 10) + ((message[4] >> 4) & 0x0f)) / 10.0F;
53-
if (message[5] & 0x0f)
53+
// Correct 0x0f to 0x08:
54+
if (message[5] & 0x08) {
5455
temp_c = -temp_c;
56+
}
5557
return temp_c;
5658
}
5759

5860
static float get_os_rain_rate(unsigned char *message)
5961
{
60-
float rain_rate = 0; // Nibbles 11..8 rain rate, LSD = 0.01 inches per hour
61-
rain_rate = (((message[5] & 0x0f) * 1000) + ((message[5] >> 4) * 100) + ((message[4] & 0x0f) * 10) + ((message[4] >> 4) & 0x0f)) / 100.0F;
62+
// Nibbles 11..8 rain rate, LSD = 0.1 units per hour, 4321 = 123.4 units per hour
63+
float rain_rate = (((message[5] & 0x0f) * 1000) + ((message[5] >> 4) * 100) + ((message[4] & 0x0f) * 10) + (message[4] >> 4)) / 100.0F;
6264
return rain_rate;
6365
}
6466

6567
static float get_os_total_rain(unsigned char *message)
6668
{
67-
float total_rain = 0.0F; // Nibbles 17..12 Total rain, LSD = 0.001, 543210 = 012.345 inches
69+
float total_rain = 0.0F; // Nibbles 17..12 Total rain, LSD = 0.001, 654321 = 123.456
6870
total_rain = (message[8] & 0x0f) * 100.0F
6971
+ ((message[8] >> 4) & 0x0f) * 10.0F + (message[7] & 0x0f)
7072
+ ((message[7] >> 4) & 0x0f) / 10.0F + (message[6] & 0x0f) / 100.0F
@@ -380,7 +382,18 @@ static int oregon_scientific_v2_1_decode(r_device *decoder, bitbuffer_t *bitbuff
380382
else if (sensor_id == ID_THN132N && msg_bits == 64) {
381383
if (validate_os_v2_message(decoder, msg, 64, msg_bits, 12) != 0)
382384
return 0;
385+
// Sanity check BCD digits
386+
if ( ((msg[5] >> 4) & 0x0F) > 9 || (msg[4] & 0x0F) > 9 || ((msg[4] >> 4) & 0x0F) > 9 ) {
387+
decoder_log(decoder, 1, __func__, "THN132N Message failed BCD sanity check.");
388+
return DECODE_FAIL_SANITY;
389+
}
383390
float temp_c = get_os_temperature(msg);
391+
// Sanity check value
392+
if (temp_c > 70 || temp_c < -50) {
393+
decoder_logf(decoder, 1, __func__, "THN132N Message failed values sanity check: temperature_C %3.1fC.", temp_c);
394+
return DECODE_FAIL_SANITY;
395+
}
396+
384397
/* clang-format off */
385398
data = data_make(
386399
"model", "", DATA_STRING, "Oregon-THN132N",
@@ -519,7 +532,18 @@ static int oregon_scientific_v2_1_decode(r_device *decoder, bitbuffer_t *bitbuff
519532
else if (sensor_id == ID_UVR128 && msg_bits == 148) {
520533
if (validate_os_v2_message(decoder, msg, 148, msg_bits, 12) != 0)
521534
return 0;
535+
// Sanity check BCD digits
536+
if ( ((msg[4] >> 4) & 0x0F) > 9 || (msg[4] & 0x0F) > 9 ) {
537+
decoder_log(decoder, 1, __func__, "UVR128 Message failed BCD sanity check.");
538+
return DECODE_FAIL_SANITY;
539+
}
522540
int uvidx = get_os_uv(msg);
541+
// Sanity check value
542+
if (uvidx < 0 || uvidx > 25) {
543+
decoder_logf(decoder, 1, __func__, "UVR128 Message failed values sanity check: uv %u.", uvidx);
544+
return DECODE_FAIL_SANITY;
545+
}
546+
523547
/* clang-format off */
524548
data = data_make(
525549
"model", "", DATA_STRING, "Oregon-UVR128",
@@ -634,8 +658,18 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
634658
if (sensor_id == ID_THGR810 || sensor_id == ID_THGR810a) {
635659
if (validate_os_checksum(decoder, msg, 15) != 0)
636660
return DECODE_FAIL_MIC;
661+
// Sanity check BCD digits
662+
if ( ((msg[5] >> 4) & 0x0F) > 9 || (msg[4] & 0x0F) > 9 || ((msg[4] >> 4) & 0x0F) > 9 || (msg[6] & 0x0F) > 9 || ((msg[6] >> 4) & 0x0F) > 9 ) {
663+
decoder_log(decoder, 1, __func__, "THGR810 Message failed BCD sanity check.");
664+
return DECODE_FAIL_SANITY;
665+
}
637666
float temp_c = get_os_temperature(msg);
638667
int humidity = get_os_humidity(msg);
668+
// Sanity check values
669+
if (temp_c > 70 || temp_c < -50 || humidity < 0 || humidity > 98) {
670+
decoder_logf(decoder, 1, __func__, "THGR810 Message failed values sanity check: temperature_C %3.1fC humidity %d%%.", temp_c, humidity);
671+
return DECODE_FAIL_SANITY;
672+
}
639673
/* clang-format off */
640674
data = data_make(
641675
"model", "", DATA_STRING, "Oregon-THGR810",
@@ -684,16 +718,23 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
684718
else if (sensor_id == ID_PCR800) {
685719
if (validate_os_checksum(decoder, msg, 18) != 0)
686720
return DECODE_FAIL_MIC;
721+
// Sanity check BCD digits
722+
if ( (msg[8] & 0x0F) > 9 || ((msg[8] >> 4) & 0x0F) > 9 || (msg[7] & 0x0F) > 9 || ((msg[7] >> 4) & 0x0F) > 9 || (msg[6] & 0x0F) > 9 || ((msg[6] >> 4) & 0x0F) > 9 || (msg[5] & 0x0F) > 9 || ((msg[5] >> 4) & 0x0F) > 9 || (msg[4] & 0x0F) > 9 || ((msg[4] >> 4) & 0x0F) > 9 ) {
723+
decoder_log(decoder, 1, __func__, "PCR800 Message failed BCD sanity check.");
724+
return DECODE_FAIL_SANITY;
725+
}
726+
687727
float rain_rate = get_os_rain_rate(msg);
688728
float total_rain = get_os_total_rain(msg);
729+
689730
/* clang-format off */
690731
data = data_make(
691732
"model", "", DATA_STRING, "Oregon-PCR800",
692733
"id", "House Code", DATA_INT, get_os_rollingcode(msg),
693734
"channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id),
694735
"battery_ok", "Battery", DATA_INT, !get_os_battery(msg),
695-
"rain_rate_in_h", "Rain Rate", DATA_FORMAT, "%3.1f in/h", DATA_DOUBLE, rain_rate,
696-
"rain_in", "Total Rain", DATA_FORMAT, "%3.1f in", DATA_DOUBLE, total_rain,
736+
"rain_rate_in_h", "Rain Rate", DATA_FORMAT, "%5.1f in/h", DATA_DOUBLE, rain_rate,
737+
"rain_in", "Total Rain", DATA_FORMAT, "%7.3f in", DATA_DOUBLE, total_rain,
697738
NULL);
698739
/* clang-format on */
699740
decoder_output_data(decoder, data);
@@ -720,9 +761,22 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
720761
else if (sensor_id == ID_WGR800 || sensor_id == ID_WGR800a) {
721762
if (validate_os_checksum(decoder, msg, 17) != 0)
722763
return DECODE_FAIL_MIC;
764+
// Sanity check BCD digits
765+
if ( (msg[5] & 0x0F) > 9 || ((msg[6] >> 4) & 0x0F) > 9 || (msg[6] & 0x0F) > 9 || ((msg[7] >> 4) & 0x0F) > 9 || (msg[7] & 0x0F) > 9 || ((msg[8] >> 4) & 0x0F) > 9 ) {
766+
decoder_log(decoder, 1, __func__, "WGR800 Message failed BCD sanity check.");
767+
return DECODE_FAIL_SANITY;
768+
}
769+
723770
float gustWindspeed = (msg[5]&0x0f) /10.0F + ((msg[6]>>4)&0x0f) *1.0F + (msg[6]&0x0f) * 10.0F;
724771
float avgWindspeed = ((msg[7]>>4)&0x0f) / 10.0F + (msg[7]&0x0f) *1.0F + ((msg[8]>>4)&0x0f) * 10.0F;
725772
float quadrant = (0x0f&(msg[4]>>4))*22.5F;
773+
774+
// Sanity check values
775+
if (gustWindspeed < 0 || gustWindspeed > 56 || avgWindspeed < 0 || avgWindspeed > 56 || quadrant < 0 || quadrant > 337.5) {
776+
decoder_logf(decoder, 1, __func__, "WGR800 Message failed values sanity check: wind_max_m_s %2.1f wind_avg_m_s %2.1f wind_dir_deg %3.1f.", gustWindspeed, avgWindspeed, quadrant);
777+
return DECODE_FAIL_SANITY;
778+
}
779+
726780
/* clang-format off */
727781
data = data_make(
728782
"model", "", DATA_STRING, "Oregon-WGR800",
@@ -878,7 +932,7 @@ static char *output_fields[] = {
878932
r_device oregon_scientific = {
879933
.name = "Oregon Scientific Weather Sensor",
880934
.modulation = OOK_PULSE_MANCHESTER_ZEROBIT,
881-
.short_width = 440, // Nominal 1024Hz (488µs), but pulses are shorter than pauses
935+
.short_width = 440, // Nominal 1024Hz (488us), but pulses are shorter than pauses
882936
.long_width = 0, // not used
883937
.reset_limit = 2400,
884938
.decode_fn = &oregon_scientific_decode,

0 commit comments

Comments
 (0)