@@ -50,21 +50,23 @@ static float get_os_temperature(unsigned char *message)
50
50
{
51
51
float temp_c = 0 ;
52
52
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 ) {
54
55
temp_c = - temp_c ;
56
+ }
55
57
return temp_c ;
56
58
}
57
59
58
60
static float get_os_rain_rate (unsigned char * message )
59
61
{
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 ;
62
64
return rain_rate ;
63
65
}
64
66
65
67
static float get_os_total_rain (unsigned char * message )
66
68
{
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
68
70
total_rain = (message [8 ] & 0x0f ) * 100.0F
69
71
+ ((message [8 ] >> 4 ) & 0x0f ) * 10.0F + (message [7 ] & 0x0f )
70
72
+ ((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
380
382
else if (sensor_id == ID_THN132N && msg_bits == 64 ) {
381
383
if (validate_os_v2_message (decoder , msg , 64 , msg_bits , 12 ) != 0 )
382
384
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
+ }
383
390
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
+
384
397
/* clang-format off */
385
398
data = data_make (
386
399
"model" , "" , DATA_STRING , "Oregon-THN132N" ,
@@ -519,7 +532,18 @@ static int oregon_scientific_v2_1_decode(r_device *decoder, bitbuffer_t *bitbuff
519
532
else if (sensor_id == ID_UVR128 && msg_bits == 148 ) {
520
533
if (validate_os_v2_message (decoder , msg , 148 , msg_bits , 12 ) != 0 )
521
534
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
+ }
522
540
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
+
523
547
/* clang-format off */
524
548
data = data_make (
525
549
"model" , "" , DATA_STRING , "Oregon-UVR128" ,
@@ -634,8 +658,18 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
634
658
if (sensor_id == ID_THGR810 || sensor_id == ID_THGR810a ) {
635
659
if (validate_os_checksum (decoder , msg , 15 ) != 0 )
636
660
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
+ }
637
666
float temp_c = get_os_temperature (msg );
638
667
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
+ }
639
673
/* clang-format off */
640
674
data = data_make (
641
675
"model" , "" , DATA_STRING , "Oregon-THGR810" ,
@@ -684,16 +718,23 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
684
718
else if (sensor_id == ID_PCR800 ) {
685
719
if (validate_os_checksum (decoder , msg , 18 ) != 0 )
686
720
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
+
687
727
float rain_rate = get_os_rain_rate (msg );
688
728
float total_rain = get_os_total_rain (msg );
729
+
689
730
/* clang-format off */
690
731
data = data_make (
691
732
"model" , "" , DATA_STRING , "Oregon-PCR800" ,
692
733
"id" , "House Code" , DATA_INT , get_os_rollingcode (msg ),
693
734
"channel" , "Channel" , DATA_INT , get_os_channel (msg , sensor_id ),
694
735
"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 ,
697
738
NULL );
698
739
/* clang-format on */
699
740
decoder_output_data (decoder , data );
@@ -720,9 +761,22 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
720
761
else if (sensor_id == ID_WGR800 || sensor_id == ID_WGR800a ) {
721
762
if (validate_os_checksum (decoder , msg , 17 ) != 0 )
722
763
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
+
723
770
float gustWindspeed = (msg [5 ]& 0x0f ) /10.0F + ((msg [6 ]>>4 )& 0x0f ) * 1.0F + (msg [6 ]& 0x0f ) * 10.0F ;
724
771
float avgWindspeed = ((msg [7 ]>>4 )& 0x0f ) / 10.0F + (msg [7 ]& 0x0f ) * 1.0F + ((msg [8 ]>>4 )& 0x0f ) * 10.0F ;
725
772
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
+
726
780
/* clang-format off */
727
781
data = data_make (
728
782
"model" , "" , DATA_STRING , "Oregon-WGR800" ,
@@ -878,7 +932,7 @@ static char *output_fields[] = {
878
932
r_device oregon_scientific = {
879
933
.name = "Oregon Scientific Weather Sensor" ,
880
934
.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
882
936
.long_width = 0 , // not used
883
937
.reset_limit = 2400 ,
884
938
.decode_fn = & oregon_scientific_decode ,
0 commit comments