Merge pull request #217 from tazounet/master

Update 2 drivers to new output format
This commit is contained in:
Benjamin Larsson
2015-12-05 00:57:05 +01:00
3 changed files with 233 additions and 136 deletions

View File

@@ -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);

View File

@@ -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
};

View File

@@ -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<BITBUF_COLS ; i++) fprintf(stdout, "%02x ", bb[0][i]); fprintf(stdout,"\n\n");}
}
return 0;
}
@@ -335,9 +394,9 @@ static int oregon_scientific_v3_parser(bitbuffer_t *bitbuffer) {
fprintf(stdout,"Energy Sensor CM180 Id %x%x power: %dW\n", msg[0], msg[1], ipower);
} else if ((msg[0] != 0) && (msg[1]!= 0)) { // sync nibble was found and some data is present...
fprintf(stdout, "Message received from unrecognized Oregon Scientific v3 sensor.\n");
fprintf(stdout, "Message: "); for (i=0 ; i<BITBUF_COLS ; i++) fprintf(stdout, "%02x ", msg[i]); fprintf(stdout, "\n");
fprintf(stdout, " Raw: "); for (i=0 ; i<BITBUF_COLS ; i++) fprintf(stdout, "%02x ", bb[0][i]); fprintf(stdout,"\n\n");
fprintf(stderr, "Message received from unrecognized Oregon Scientific v3 sensor.\n");
fprintf(stderr, "Message: "); for (i=0 ; i<BITBUF_COLS ; i++) fprintf(stdout, "%02x ", msg[i]); fprintf(stdout, "\n");
fprintf(stderr, " Raw: "); for (i=0 ; i<BITBUF_COLS ; i++) fprintf(stdout, "%02x ", bb[0][i]); fprintf(stdout,"\n\n");
} else if (bb[0][3] != 0 ) {
//fprintf(stdout, "\nPossible Oregon Scientific v3 message, but sync nibble wasn't found\n");
//fprintf(stdout, "Raw Data: "); for (i=0 ; i<BITBUF_COLS ; i++) fprintf(stdout, "%02x ", bb[0][i]); fprintf(stdout,"\n\n");
@@ -356,6 +415,19 @@ static int oregon_scientific_callback(bitbuffer_t *bitbuffer) {
return ret;
}
static char *output_fields[] = {
"time",
"model",
"id",
"channel",
"battery",
"temperature_C",
"humidity",
"rain_rate",
"rain_total",
NULL
};
r_device oregon_scientific = {
.name = "Oregon Scientific Weather Sensor",
.modulation = OOK_PULSE_MANCHESTER_ZEROBIT,
@@ -365,4 +437,5 @@ r_device oregon_scientific = {
.json_callback = &oregon_scientific_callback,
.disabled = 0,
.demod_arg = 0,
.fields = output_fields
};