mirror of
https://github.com/merbanan/rtl_433.git
synced 2026-04-23 11:07:09 -04:00
Merge pull request #217 from tazounet/master
Update 2 drivers to new output format
This commit is contained in:
84
src/data.c
84
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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user