X-Git-Url: https://git.rvb.name/rtl-433.git/blobdiff_plain/337eb4ba945097205fbb6a3ca7912fb0697092d1..a3166201c6f1fa7e56c7e4b86083a42fffb0c568:/src/devices/oregon_scientific.c~ diff --git a/src/devices/oregon_scientific.c~ b/src/devices/oregon_scientific.c~ deleted file mode 100644 index bbba586..0000000 --- a/src/devices/oregon_scientific.c~ +++ /dev/null @@ -1,287 +0,0 @@ -#include "rtl_433.h" - -float get_os_temperature(unsigned char *message, unsigned int sensor_id) { - // sensor ID included to support sensors with temp in different position - float temp_c = 0; - temp_c = (((message[5]>>4)*100)+((message[4]&0x0f)*10) + ((message[4]>>4)&0x0f)) /10.0F; - if (message[5] & 0x0f) - temp_c = -temp_c; - return temp_c; -} -unsigned int get_os_humidity(unsigned char *message, unsigned int sensor_id) { - // sensor ID included to support sensors with temp in different position - int humidity = 0; - humidity = ((message[6]&0x0f)*10)+(message[6]>>4); - return humidity; -} - -static int validate_os_checksum(unsigned char *msg, int checksum_nibble_idx) { - // Oregon Scientific v2.1 and v3 checksum is a 1 byte 'sum of nibbles' checksum. - // with the 2 nibbles of the checksum byte swapped. - int i; - unsigned int checksum, sum_of_nibbles=0; - for (i=0; i<(checksum_nibble_idx-1);i+=2) { - unsigned char val=msg[i>>1]; - sum_of_nibbles += ((val>>4) + (val &0x0f)); - } - if (checksum_nibble_idx & 1) { - sum_of_nibbles += (msg[checksum_nibble_idx>>1]>>4); - checksum = (msg[checksum_nibble_idx>>1] & 0x0f) | (msg[(checksum_nibble_idx+1)>>1]&0xf0); - } else - checksum = (msg[checksum_nibble_idx>>1]>>4) | ((msg[checksum_nibble_idx>>1]&0x0f)<<4); - sum_of_nibbles &= 0xff; - - if (sum_of_nibbles == checksum) - return 0; - else { - fprintf(stderr, "Checksum error in Oregon Scientific message. Expected: %02x Calculated: %02x\n", checksum, sum_of_nibbles); - fprintf(stderr, "Message: "); int i; for (i=0 ;i<((checksum_nibble_idx+4)>>1) ; i++) fprintf(stderr, "%02x ", msg[i]); fprintf(stderr, "\n\n"); - return 1; - } -} - -static int validate_os_v2_message(unsigned char * msg, int bits_expected, int valid_v2_bits_received, - int nibbles_in_checksum) { - // Oregon scientific v2.1 protocol sends each bit using the complement of the bit, then the bit for better error checking. Compare number of valid bits processed vs number expected - if (bits_expected == valid_v2_bits_received) { - return (validate_os_checksum(msg, nibbles_in_checksum)); - } else { - fprintf(stderr, "Bit validation error on Oregon Scientific message. Expected %d bits, received error after bit %d \n", bits_expected, valid_v2_bits_received); - fprintf(stderr, "Message: "); int i; for (i=0 ;i<(bits_expected+7)/8 ; i++) fprintf(stderr, "%02x ", msg[i]); fprintf(stderr, "\n\n"); - } - return 1; -} - -static int oregon_scientific_v2_1_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int16_t bits_per_row[BITBUF_ROWS]) { - // Check 2nd and 3rd bytes of stream for possible Oregon Scientific v2.1 sensor data (skip first byte to get past sync/startup bit errors) - if ( ((bb[0][1] == 0x55) && (bb[0][2] == 0x55)) || - ((bb[0][1] == 0xAA) && (bb[0][2] == 0xAA))) { - int i,j; - unsigned char msg[BITBUF_COLS] = {0}; - - // Possible v2.1 Protocol message - int num_valid_v2_bits = 0; - - unsigned int sync_test_val = (bb[0][3]<<24) | (bb[0][4]<<16) | (bb[0][5]<<8) | (bb[0][6]); - int dest_bit = 0; - int pattern_index; - // Could be extra/dropped bits in stream. Look for sync byte at expected position +/- some bits in either direction - for(pattern_index=0; pattern_index<8; pattern_index++) { - unsigned int mask = (unsigned int) (0xffff0000>>pattern_index); - unsigned int pattern = (unsigned int)(0x55990000>>pattern_index); - unsigned int pattern2 = (unsigned int)(0xaa990000>>pattern_index); - - //fprintf(stderr, "OS v2.1 sync byte search - test_val=%08x pattern=%08x mask=%08x\n", sync_test_val, pattern, mask); - - if (((sync_test_val & mask) == pattern) || - ((sync_test_val & mask) == pattern2)) { - // Found sync byte - start working on decoding the stream data. - // pattern_index indicates where sync nibble starts, so now we can find the start of the payload - int start_byte = 5 + (pattern_index>>3); - int start_bit = pattern_index & 0x07; - //fprintf(stderr, "OS v2.1 Sync test val %08x found, starting decode at byte index %d bit %d\n", sync_test_val, start_byte, start_bit); - int bits_processed = 0; - unsigned char last_bit_val = 0; - j=start_bit; - for (i=start_byte;i> j)) >> (7-j)); - - // check if last bit received was the complement of the current bit - if ((num_valid_v2_bits == 0) && (last_bit_val == bit_val)) - num_valid_v2_bits = bits_processed; // record position of first bit in stream that doesn't verify correctly - last_bit_val = bit_val; - - // copy every other bit from source stream to dest packet - msg[dest_bit>>3] |= (((bb[0][i] & (0x80 >> j)) >> (7-j)) << (7-(dest_bit & 0x07))); - - //fprintf(stderr,"i=%d j=%d dest_bit=%02x bb=%02x msg=%02x\n",i, j, dest_bit, bb[0][i], msg[dest_bit>>3]); - if ((dest_bit & 0x07) == 0x07) { - // after assembling each dest byte, flip bits in each nibble to convert from lsb to msb bit ordering - int k = (dest_bit>>3); - unsigned char indata = msg[k]; - // flip the 4 bits in the upper and lower nibbles - msg[k] = ((indata & 0x11) << 3) | ((indata & 0x22) << 1) | - ((indata & 0x44) >> 1) | ((indata & 0x88) >> 3); - } - dest_bit++; - } - else - last_bit_val = ((bb[0][i] & (0x80 >> j)) >> (7-j)); // used for v2.1 bit error detection - bits_processed++; - j++; - } - j=0; - } - break; - } //if (sync_test_val... - } // for (pattern... - - - int sensor_id = (msg[0] << 8) | msg[1]; - if ((sensor_id == 0x1d20) || (sensor_id == 0x1d30)) { - if (validate_os_v2_message(msg, 153, num_valid_v2_bits, 15) == 0) { - int channel = ((msg[2] >> 4)&0x0f); - if (channel == 4) - channel = 3; // sensor 3 channel number is 0x04 - float temp_c = get_os_temperature(msg, sensor_id); - if (sensor_id == 0x1d20) fprintf(stderr, "Weather Sensor THGR122N Channel %d ", channel); - else fprintf(stderr, "Weather Sensor THGR968 Outdoor "); - fprintf(stderr, "Temp: %3.1f°C %3.1f°F Humidity: %d%%\n", temp_c, ((temp_c*9)/5)+32,get_os_humidity(msg, sensor_id)); - } - return 1; - } else if (sensor_id == 0x5d60) { - if (validate_os_v2_message(msg, 185, num_valid_v2_bits, 19) == 0) { - unsigned int comfort = msg[7] >>4; - char *comfort_str="Normal"; - if (comfort == 4) comfort_str = "Comfortable"; - else if (comfort == 8) comfort_str = "Dry"; - else if (comfort == 0xc) comfort_str = "Humid"; - unsigned int forecast = msg[9]>>4; - char *forecast_str="Cloudy"; - if (forecast == 3) forecast_str = "Rainy"; - else if (forecast == 6) forecast_str = "Partly Cloudy"; - else if (forecast == 0xc) forecast_str = "Sunny"; - float temp_c = get_os_temperature(msg, 0x5d60); - fprintf(stderr,"Weather Sensor BHTR968 Indoor Temp: %3.1f°C %3.1f°F Humidity: %d%%", temp_c, ((temp_c*9)/5)+32, get_os_humidity(msg, 0x5d60)); - fprintf(stderr, " (%s) Pressure: %dmbar (%s)\n", comfort_str, ((msg[7] & 0x0f) | (msg[8] & 0xf0))+856, forecast_str); - } - return 1; - } else if (sensor_id == 0x2d10) { - if (validate_os_v2_message(msg, 161, num_valid_v2_bits, 16) == 0) { - float rain_rate = (((msg[4] &0x0f)*100)+((msg[4]>>4)*10) + ((msg[5]>>4)&0x0f)) /10.0F; - float total_rain = (((msg[7]&0xf)*10000)+((msg[7]>>4)*1000) + ((msg[6]&0xf)*100)+((msg[6]>>4)*10) + (msg[5]&0xf))/10.0F; - fprintf(stderr, "Weather Sensor RGR968 Rain Gauge Rain Rate: %2.0fmm/hr Total Rain %3.0fmm\n", rain_rate, total_rain); - } - return 1; - } else if (sensor_id == 0xec40 && num_valid_v2_bits==153) { - if ( validate_os_v2_message(msg, 153, num_valid_v2_bits, 12) == 0) { - int channel = ((msg[2] >> 4)&0x0f); - if (channel == 4) - channel = 3; // sensor 3 channel number is 0x04 - float temp_c = get_os_temperature(msg, sensor_id); - if (sensor_id == 0xec40) fprintf(stderr, "Thermo Sensor THR228N Channel %d ", channel); - fprintf(stderr, "Temp: %3.1f°C %3.1f°F\n", temp_c, ((temp_c*9)/5)+32); - } - return 1; - } else if (sensor_id == 0xec40 && num_valid_v2_bits==129) { - if ( validate_os_v2_message(msg, 129, num_valid_v2_bits, 12) == 0) { - int channel = ((msg[2] >> 4)&0x0f); - if (channel == 4) - channel = 3; // sensor 3 channel number is 0x04 - int battery_low = (msg[3] >> 2 & 0x01); - unsigned char rolling_code = ((msg[2] << 4)&0xF0) | ((msg[3] >> 4)&0x0F); - float temp_c = get_os_temperature(msg, sensor_id); - if (sensor_id == 0xec40) fprintf(stderr, "Thermo Sensor THN132N, Channel %d, Battery: %s, Rolling-code 0x%0X, ", channel, battery_low?"Low":"Ok", rolling_code); - fprintf(stderr, "Temp: %3.1f°C %3.1f°F\n", temp_c, ((temp_c*9)/5)+32); - } - return 1; - } else if (num_valid_v2_bits > 16) { -fprintf(stderr, "%d bit message received from unrecognized Oregon Scientific v2.1 sensor with device ID %x.\n", num_valid_v2_bits, sensor_id); -fprintf(stderr, "Message: "); for (i=0 ; i<20 ; i++) fprintf(stderr, "%02x ", msg[i]); fprintf(stderr,"\n\n"); - } else { -//fprintf(stderr, "\nPossible Oregon Scientific v2.1 message, but sync nibble wasn't found\n"); fprintf(stderr, "Raw Data: "); for (i=0 ; i>pattern_index); - unsigned int pattern = (unsigned int)(0xffa00000>>pattern_index); - unsigned int pattern2 = (unsigned int)(0xff500000>>pattern_index); - unsigned int pattern3 = (unsigned int)(0x00500000>>pattern_index); -//fprintf(stderr, "OS v3 Sync nibble search - test_val=%08x pattern=%08x mask=%08x\n", sync_test_val, pattern, mask); - if (((sync_test_val & mask) == pattern) || - ((sync_test_val & mask) == pattern2) || - ((sync_test_val & mask) == pattern3)) { - // Found sync byte - start working on decoding the stream data. - // pattern_index indicates where sync nibble starts, so now we can find the start of the payload - int start_byte = 3 + (pattern_index>>3); - int start_bit = (pattern_index+4) & 0x07; -//fprintf(stderr, "Oregon Scientific v3 Sync test val %08x ok, starting decode at byte index %d bit %d\n", sync_test_val, start_byte, start_bit); - j = start_bit; - for (i=start_byte;i> j)) >> (7-j)); - - // copy every bit from source stream to dest packet - msg[dest_bit>>3] |= (((bb[0][i] & (0x80 >> j)) >> (7-j)) << (7-(dest_bit & 0x07))); - -//fprintf(stderr,"i=%d j=%d dest_bit=%02x bb=%02x msg=%02x\n",i, j, dest_bit, bb[0][i], msg[dest_bit>>3]); - if ((dest_bit & 0x07) == 0x07) { - // after assembling each dest byte, flip bits in each nibble to convert from lsb to msb bit ordering - int k = (dest_bit>>3); - unsigned char indata = msg[k]; - // flip the 4 bits in the upper and lower nibbles - msg[k] = ((indata & 0x11) << 3) | ((indata & 0x22) << 1) | - ((indata & 0x44) >> 1) | ((indata & 0x88) >> 3); - } - dest_bit++; - j++; - } - j=0; - } - break; - } - } - - if ((msg[0] == 0xf8) && (msg[1] == 0x24)) { - if (validate_os_checksum(msg, 15) == 0) { - int channel = ((msg[2] >> 4)&0x0f); - float temp_c = get_os_temperature(msg, 0xf824); - int humidity = get_os_humidity(msg, 0xf824); - fprintf(stderr,"Weather Sensor THGR810 Channel %d Temp: %3.1f°C %3.1f°F Humidity: %d%%\n", channel, temp_c, ((temp_c*9)/5)+32, humidity); - } - return 1; - } else if ((msg[0] == 0x19) && (msg[1] == 0x84)) { - if (validate_os_checksum(msg, 17) == 0) { - float gustWindspeed = (msg[11]+msg[10])/100; - float quadrant = msg[8]*22.5; - fprintf(stderr, "Weather Sensor WGR800 Wind Gauge Gust Wind Speed : %2.0f m/s Wind direction %3.0f dgrs\n", gustWindspeed, quadrant); - } - return 1; - } else if ((msg[0] != 0) && (msg[1]!= 0)) { // sync nibble was found and some data is present... -fprintf(stderr, "Message received from unrecognized Oregon Scientific v3 sensor.\n"); -fprintf(stderr, "Message: "); for (i=0 ; i