diff --git a/src/data.c b/src/data.c index 83f03f46..007e49ef 100644 --- a/src/data.c +++ b/src/data.c @@ -72,39 +72,39 @@ typedef struct data_printer_context { static data_meta_type_t dmt[DATA_COUNT] = { // DATA_DATA - { array_element_size : sizeof(data_t*), - array_is_boxed : true, - array_elementwise_import : NULL, - array_element_release : (array_element_release_fn) data_free, - value_release : (value_release_fn) data_free }, + { .array_element_size = sizeof(data_t*), + .array_is_boxed = true, + .array_elementwise_import = NULL, + .array_element_release = (array_element_release_fn) data_free, + .value_release = (value_release_fn) data_free }, // DATA_INT - { array_element_size : sizeof(int), - array_is_boxed : false, - array_elementwise_import : NULL, - array_element_release : NULL, - value_release : (value_release_fn) free }, + { .array_element_size = sizeof(int), + .array_is_boxed = false, + .array_elementwise_import = NULL, + .array_element_release = NULL, + .value_release = (value_release_fn) free }, // DATA_DOUBLE - { array_element_size : sizeof(double), - array_is_boxed : false, - array_elementwise_import : NULL, - array_element_release : NULL, - value_release : (value_release_fn) free }, + { .array_element_size = sizeof(double), + .array_is_boxed = false, + .array_elementwise_import = NULL, + .array_element_release = NULL, + .value_release = (value_release_fn) free }, // DATA_STRING - { array_element_size : sizeof(char*), - array_is_boxed : true, - array_elementwise_import : (array_elementwise_import_fn) strdup, - array_element_release : (array_element_release_fn) free, - value_release : (value_release_fn) free }, + { .array_element_size = sizeof(char*), + .array_is_boxed = true, + .array_elementwise_import = (array_elementwise_import_fn) strdup, + .array_element_release = (array_element_release_fn) free, + .value_release = (value_release_fn) free }, // DATA_ARRAY - { array_element_size : sizeof(data_array_t*), - array_is_boxed : true, - array_elementwise_import : NULL, - array_element_release : (array_element_release_fn) data_array_free , - value_release : (value_release_fn) data_array_free }, + { .array_element_size = sizeof(data_array_t*), + .array_is_boxed = true, + .array_elementwise_import = NULL, + .array_element_release = (array_element_release_fn) data_array_free , + .value_release = (value_release_fn) data_array_free }, }; static void print_json_data(data_printer_context_t *printer_ctx, data_t *data, char *format, FILE *file); @@ -128,27 +128,27 @@ static void print_csv_data(data_printer_context_t *printer_ctx, data_t *data, ch static void print_csv_string(data_printer_context_t *printer_ctx, const char *data, char *format, FILE *file); data_printer_t data_json_printer = { - print_data : print_json_data, - print_array : print_json_array, - print_string : print_json_string, - print_double : print_json_double, - print_int : print_json_int + .print_data = print_json_data, + .print_array = print_json_array, + .print_string = print_json_string, + .print_double = print_json_double, + .print_int = print_json_int }; data_printer_t data_kv_printer = { - print_data : print_kv_data, - print_array : print_json_array, - print_string : print_kv_string, - print_double : print_kv_double, - print_int : print_kv_int + .print_data = print_kv_data, + .print_array = print_json_array, + .print_string = print_kv_string, + .print_double = print_kv_double, + .print_int = print_kv_int }; data_printer_t data_csv_printer = { - print_data : print_csv_data, - print_array : print_json_array, - print_string : print_csv_string, - print_double : print_json_double, - print_int : print_json_int + .print_data = print_csv_data, + .print_array = print_json_array, + .print_string = print_csv_string, + .print_double = print_json_double, + .print_int = print_json_int }; static _Bool import_values(void* dst, void* src, int num_values, data_type_t type) { @@ -312,8 +312,8 @@ void data_free(data_t *data) { void data_print(data_t* data, FILE *file, data_printer_t *printer, void *aux) { data_printer_context_t ctx = { - printer : printer, - aux : aux + .printer = printer, + .aux = aux }; ctx.printer->print_data(&ctx, data, NULL, file); fputc('\n', file); diff --git a/src/devices/alecto.c b/src/devices/alecto.c index 92c823b3..0e1d7757 100644 --- a/src/devices/alecto.c +++ b/src/devices/alecto.c @@ -1,4 +1,5 @@ #include "rtl_433.h" +#include "data.h" #include "util.h" /* Documentation also at http://www.tfd.hu/tfdhu/files/wsprotocol/auriol_protocol_v20.pdf @@ -59,8 +60,13 @@ static int alectov1_callback(bitbuffer_t *bitbuffer) { int16_t temp; uint8_t humidity, csum = 0, csum2 = 0; int i; - time_t time_now; - char time_str[LOCAL_TIME_BUFLEN]; + + data_t *data; + time_t time_now; + char time_str[LOCAL_TIME_BUFLEN]; + time(&time_now); + local_time_str(time_now, time_str); + if (bb[1][0] == bb[5][0] && bb[2][0] == bb[6][0] && (bb[1][4] & 0xf) == 0 && (bb[5][4] & 0xf) == 0 && (bb[5][0] != 0 && bb[5][1] != 0)) { @@ -80,8 +86,6 @@ static int alectov1_callback(bitbuffer_t *bitbuffer) { /* Quit if checksup does not work out */ if (csum != (bb[1][4] >> 4) || csum2 != (bb[5][4] >> 4)) { //fprintf(stdout, "\nAlectoV1 CRC error"); - time(&time_now); - local_time_str(time_now, time_str); if(debug_output) { fprintf(stderr, "%s AlectoV1 Checksum/Parity error\n", @@ -92,24 +96,20 @@ static int alectov1_callback(bitbuffer_t *bitbuffer) { uint8_t wind = 0; + uint8_t channel = (bb[1][0] & 0xc) >> 2; + uint8_t sensor_id = reverse8(bb[1][0]); + uint8_t battery_low = bb[1][1]&0x80; if ((bb[1][1] & 0xe0) == 0x60) { wind = ((bb[1][1] & 0xf) == 0xc) ? 0 : 1; - time(&time_now); - local_time_str(time_now, time_str); - time(&time_now); - local_time_str(time_now, time_str); - fprintf(stdout, - "%s AlectoV1 %s Sensor %d", - time_str, - wind ? "Wind" : "Rain", - reverse8(bb[1][0]) - ); + //left out data (not needed): //bb[1][1]&0x10 ? "timed event":"Button generated "); //fprintf(stdout, "Protocol = AlectoV1 bpr1: %d bpr2: %d\n", bits_per_row[1], bits_per_row[5]); //fprintf(stdout, "Button = %d\n", bb[1][1]&0x10 ? 1 : 0); + if (wind) { + // Wind sensor int skip = -1; /* Untested code written according to the specification, may not decode correctly */ if ((bb[1][1]&0xe) == 0x8 && bb[1][2] == 0) { @@ -121,18 +121,30 @@ static int alectov1_callback(bitbuffer_t *bitbuffer) { double speed = reverse8(bb[1 + skip][3]); double gust = reverse8(bb[5 + skip][3]); int direction = (reverse8(bb[5 + skip][2]) << 1) | (bb[5 + skip][1] & 0x1); - fprintf(stdout, ": Wind speed %.0f units = %.2f m/s", speed, speed * 0.2); - fprintf(stdout, ": Wind gust %.0f units = %.2f m/s", gust, gust * 0.2); - fprintf(stdout, ": Direction %.2i degrees", direction); - fprintf(stdout, ": Battery %s\n", bb[1][1]&0x80 ? "Low" : "OK"); + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "AlectoV1 Wind Sensor", + "id", "House Code", DATA_INT, sensor_id, + "channel", "Channel", DATA_INT, channel, + "battery", "Battery", DATA_STRING, battery_low ? "LOW" : "OK", + "wind_speed", "Wind speed", DATA_FORMAT, "%.2f m/s", DATA_DOUBLE, speed * 0.2F, + "wind_gust", "Wind gust", DATA_FORMAT, "%.2f m/s", DATA_DOUBLE, gust * 0.2F, + "wind_direction", "Direction", DATA_INT, direction, + NULL); + data_acquired_handler(data); } } else { - - double rain_mm = ((reverse8(bb[1][3]) << 8)+reverse8(bb[1][2])) * 0.25; - unsigned int rain1=0; - rain1 = (reverse8(bb[1][3]) << 8)+reverse8(bb[1][2]); - fprintf(stdout, ": Rain %.02f mm/m2", rain_mm); - fprintf(stdout, ": Battery %s\n", bb[1][1]&0x80 ? "Low" : "OK"); + // Rain sensor + double rain_mm = ((reverse8(bb[1][3]) << 8)+reverse8(bb[1][2])) * 0.25F; + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "AlectoV1 Rain Sensor", + "id", "House Code", DATA_INT, sensor_id, + "channel", "Channel", DATA_INT, channel, + "battery", "Battery", DATA_STRING, battery_low ? "LOW" : "OK", + "rain_total", "Total Rain", DATA_FORMAT, "%.02f mm", DATA_DOUBLE, rain_mm, + NULL); + data_acquired_handler(data); } } else if (bb[2][0] == bb[3][0] && bb[3][0] == bb[4][0] && bb[4][0] == bb[5][0] && bb[5][0] == bb[6][0] && (bb[3][4] & 0xf) == 0 && (bb[5][4] & 0xf) == 0) { @@ -141,22 +153,18 @@ static int alectov1_callback(bitbuffer_t *bitbuffer) { if ((temp & 0x800) != 0) { temp |= 0xf000; } - temperature_before_dec = abs(temp / 10); - temperature_after_dec = abs(temp % 10); humidity = bcd_decode8(reverse8(bb[1][3])); - time(&time_now); - local_time_str(time_now, time_str); - fprintf(stdout, - "%s AlectoV1 Sensor %d Channel %d", - time_str, - reverse8(bb[1][0]), - (bb[1][0] & 0xc) >> 2 - ); if (humidity>100) return 0;//extra detection false positive!! prologue is also 36bits and sometimes detected as alecto - fprintf(stdout, ": Temperature %s%d.%d C", temp < 0 ? "-" : "", temperature_before_dec, temperature_after_dec); - fprintf(stdout, ": Humidity %d %%", humidity); - fprintf(stdout, ": Battery %s\n", bb[1][1]&0x80 ? "Low" : "OK"); - + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "AlectoV1 Temperature Sensor", + "id", "House Code", DATA_INT, sensor_id, + "channel", "Channel", DATA_INT, channel, + "battery", "Battery", DATA_STRING, battery_low ? "LOW" : "OK", + "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, (float) temp / 10.0F, + "humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity, + NULL); + data_acquired_handler(data); } if (debug_output){ fprintf(stdout, "Checksum = %01x (calculated %01x)\n", bb[1][4] >> 4, csum); @@ -171,6 +179,21 @@ static int alectov1_callback(bitbuffer_t *bitbuffer) { return 0; } +static char *output_fields[] = { + "time", + "model", + "id", + "channel", + "battery", + "temperature_C", + "humidity", + "rain_total", + "wind_speed", + "wind_gust", + "wind_direction", + NULL +}; + //Timing based on 250000 r_device alectov1 = { .name = "AlectoV1 Weather Sensor (Alecto WS3500 WS4500 Ventus W155/W044 Oregon)", @@ -181,4 +204,5 @@ r_device alectov1 = { .json_callback = &alectov1_callback, .disabled = 0, .demod_arg = 0, + .fields = output_fields }; diff --git a/src/devices/oregon_scientific.c b/src/devices/oregon_scientific.c index 1edb4f9e..64142d97 100644 --- a/src/devices/oregon_scientific.c +++ b/src/devices/oregon_scientific.c @@ -1,33 +1,54 @@ #include "rtl_433.h" +#include "data.h" +#include "util.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; + temp_c = (((message[5]>>4)*100)+((message[4]&0x0f)*10) + ((message[4]>>4)&0x0f)) / 10.0F; if (message[5] & 0x0f) - temp_c = -temp_c; + 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; + // sensor ID included to support sensors with humidity in different position + int humidity = 0; + humidity = ((message[6]&0x0f)*10)+(message[6]>>4); + return humidity; } + unsigned int get_os_uv(unsigned char *message, unsigned int sensor_id) { - // sensor ID included to support sensors with temp in different position - int uvidx = 0; - uvidx = ((message[4]&0x0f)*10)+(message[4]>>4); - return uvidx; + // sensor ID included to support sensors with uv in different position + int uvidx = 0; + uvidx = ((message[4]&0x0f)*10)+(message[4]>>4); + return uvidx; } -unsigned int get_os_rollingcode(unsigned char *message, unsigned int sensor_id){ - int rc = 0; - rc = (message[2]&0x0F) + (message[3]&0xF0); - return rc; +unsigned int get_os_channel(unsigned char *message, unsigned int sensor_id) { + // sensor ID included to support sensors with channel in different position + int channel = 0; + channel = ((message[2] >> 4)&0x0f); + if ((channel == 4) && ! ((sensor_id >= 0x0cc3) && (sensor_id <= 0xfcc3))) + channel = 3; // sensor 3 channel number is 0x04 + return channel; } -unsigned short int power(const unsigned char* d){ +unsigned int get_os_battery(unsigned char *message, unsigned int sensor_id) { + // sensor ID included to support sensors with battery in different position + int battery_low = 0; + battery_low = (message[3] >> 2 & 0x01); + return battery_low; +} + +unsigned int get_os_rollingcode(unsigned char *message, unsigned int sensor_id) { + // sensor ID included to support sensors with rollingcode in different position + int rc = 0; + rc = (message[2]&0x0F) + (message[3]&0xF0); + return rc; +} + +unsigned short int power(const unsigned char* d) { unsigned short int val = 0; val = ( d[4] << 8) + d[3]; val = val & 0xFFF0; @@ -35,7 +56,7 @@ unsigned short int power(const unsigned char* d){ return val; } -unsigned long long total(const unsigned char* d){ +unsigned long long total(const unsigned char* d) { unsigned long long val = 0; if ( (d[1]&0x0F) == 0 ){ // Sensor returns total only if nibble#4 == 0 @@ -68,8 +89,8 @@ static int validate_os_checksum(unsigned char *msg, int checksum_nibble_idx) { if (sum_of_nibbles == checksum) return 0; else { - fprintf(stdout, "Checksum error in Oregon Scientific message. Expected: %02x Calculated: %02x\n", checksum, sum_of_nibbles); - fprintf(stdout, "Message: "); int i; for (i=0 ;i<((checksum_nibble_idx+4)>>1) ; i++) fprintf(stdout, "%02x ", msg[i]); fprintf(stdout, "\n\n"); + 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(stdout, "%02x ", msg[i]); fprintf(stdout, "\n\n"); return 1; } } @@ -80,8 +101,8 @@ static int validate_os_v2_message(unsigned char * msg, int bits_expected, int va if (bits_expected == valid_v2_bits_received) { return (validate_os_checksum(msg, nibbles_in_checksum)); } else { - fprintf(stdout, "Bit validation error on Oregon Scientific message. Expected %d bits, received error after bit %d \n", bits_expected, valid_v2_bits_received); - fprintf(stdout, "Message: "); int i; for (i=0 ;i<(bits_expected+7)/8 ; i++) fprintf(stdout, "%02x ", msg[i]); fprintf(stdout, "\n\n"); + 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(stdout, "%02x ", msg[i]); fprintf(stdout, "\n\n"); } return 1; } @@ -153,21 +174,38 @@ static int oregon_scientific_v2_1_parser(bitbuffer_t *bitbuffer) { } //if (sync_test_val... } // for (pattern... + data_t *data; + time_t time_now; + char time_str[LOCAL_TIME_BUFLEN]; + time(&time_now); + local_time_str(time_now, time_str); 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); - unsigned int rc = get_os_rollingcode(msg, sensor_id); + if (sensor_id == 0x1d20) { - fprintf(stdout, "Weather Sensor THGR122N RC %x Channel %d ", rc, channel); - //fprintf(stdout, "Message: "); for (i=0 ; i<20 ; i++) fprintf(stdout, "%02x ", msg[i]); + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "Weather Sensor THGR122N", + "id" "House Code", DATA_INT, get_os_rollingcode(msg, sensor_id), + "channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id), + "battery", "Battery", DATA_STRING, get_os_battery(msg, sensor_id) ? "LOW" : "OK", + "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, get_os_temperature(msg, sensor_id), + "humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, get_os_humidity(msg, sensor_id), + NULL); + data_acquired_handler(data); } - else fprintf(stdout, "Weather Sensor THGR968 Outdoor "); - fprintf(stdout, "Temp: %3.1fC %3.1fF Humidity: %d%%\n", temp_c, ((temp_c*9)/5)+32,get_os_humidity(msg, sensor_id)); + else { + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "Weather Sensor THGR968 Outdoor", + "id" "House Code", DATA_INT, get_os_rollingcode(msg, sensor_id), + "channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id), + "battery", "Battery", DATA_STRING, get_os_battery(msg, sensor_id) ? "LOW" : "OK", + "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, get_os_temperature(msg, sensor_id), + "humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, get_os_humidity(msg, sensor_id), + NULL); + data_acquired_handler(data); + } } return 1; } else if (sensor_id == 0x5d60) { @@ -189,41 +227,61 @@ static int oregon_scientific_v2_1_parser(bitbuffer_t *bitbuffer) { 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(stdout, "Weather Sensor RGR968 Rain Gauge Rain Rate: %2.0fmm/hr Total Rain %3.0fmm\n", rain_rate, total_rain); + 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; + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "Weather Sensor RGR968 Rain Gauge", + "id" "House Code", DATA_INT, get_os_rollingcode(msg, sensor_id), + "channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id), + "battery", "Battery", DATA_STRING, get_os_battery(msg, sensor_id) ? "LOW" : "OK", + "rain_rate", "Rain Rate", DATA_FORMAT, "%.02f mm/hr", DATA_DOUBLE, rain_rate, + "rain_total", "Total Rain", DATA_FORMAT, "%.02f mm", DATA_DOUBLE, total_rain, + NULL); + data_acquired_handler(data); } 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(stdout, "Thermo Sensor THR228N Channel %d ", channel); - fprintf(stdout, "Temp: %3.1fC %3.1fF\n", temp_c, ((temp_c*9)/5)+32); + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "Thermo Sensor THR228N", + "id" "House Code", DATA_INT, get_os_rollingcode(msg, sensor_id), + "channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id), + "battery", "Battery", DATA_STRING, get_os_battery(msg, sensor_id) ? "LOW" : "OK", + "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, get_os_temperature(msg, sensor_id), + NULL); + data_acquired_handler(data); } 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(stdout, "Thermo Sensor THN132N, Channel %d, Battery: %s, Rolling-code 0x%0X, ", channel, battery_low?"Low":"Ok", rolling_code); - fprintf(stdout, "Temp: %3.1fC %3.1fF\n", temp_c, ((temp_c*9)/5)+32); + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "Thermo Sensor THN132N", + "id" "House Code", DATA_INT, get_os_rollingcode(msg, sensor_id), + "channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id), + "battery", "Battery", DATA_STRING, get_os_battery(msg, sensor_id) ? "LOW" : "OK", + "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, get_os_temperature(msg, sensor_id), + NULL); + data_acquired_handler(data); } return 1; } else if ((sensor_id >= 0x0cc3) && (sensor_id <= 0xfcc3)) { - if (validate_os_v2_message(msg, 153, num_valid_v2_bits, 15) == 0) { - int channel = ((msg[2] >> 4)&0x0f); - 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); - fprintf(stdout, "Thermo Hygro RF Clock Sensor RTGN318, Channel %d, Battery: %s, Rolling-code 0x%0X, ", channel, battery_low?"Low":"Ok", rolling_code); - fprintf(stdout, "Temp: %3.1fC %3.1fF Humidity: %d%%\n", temp_c, ((temp_c*9)/5)+32, get_os_humidity(msg, sensor_id)); + if (num_valid_v2_bits==153 && (validate_os_v2_message(msg, 153, num_valid_v2_bits, 15) == 0)) { + + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "Thermo Hygro RF Clock Sensor RTGN318", + "id" "House Code", DATA_INT, get_os_rollingcode(msg, sensor_id), + "channel", "Channel", DATA_INT, get_os_channel(msg, sensor_id), // 1 to 5 + "battery", "Battery", DATA_STRING, get_os_battery(msg, sensor_id) ? "LOW" : "OK", + "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, get_os_temperature(msg, sensor_id), + "humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, get_os_humidity(msg, sensor_id), + NULL); + data_acquired_handler(data); + } else if (num_valid_v2_bits==201 && (validate_os_v2_message(msg, 201, num_valid_v2_bits, 21) == 0)) { + + // RF Clock message ?? } return 1; } else if (num_valid_v2_bits > 16) { @@ -235,6 +293,7 @@ static int oregon_scientific_v2_1_parser(bitbuffer_t *bitbuffer) { } else { //if (bb[0][3] != 0) int i; fprintf(stdout, "\nBadly formatted OS v2.1 message encountered."); for (i=0 ; i