Bugfixes
[rtl-433.git] / src / devices / oregon_scientific_v1.c
1 #include "rtl_433.h"
2 #include "data.h"
3 #include "util.h"
4
5 #define OSV1_BITS       32
6
7 static int rev_nibble(int nib)
8 {
9         int revnib = 0;
10
11         revnib += (nib >> 3) & 0x1;
12         revnib += (nib >> 1) & 0x2;
13         revnib += (nib << 1) & 0x4;
14         revnib += (nib << 3) & 0x8;
15
16         return(revnib);
17 }
18
19 static int oregon_scientific_callback_v1(bitbuffer_t *bitbuffer) {
20         int ret = 0;
21         char time_str[LOCAL_TIME_BUFLEN];
22         int row;
23         int cs;
24         int i;
25         int nibble[OSV1_BITS/4];
26         int sid, channel, uk1;
27         float tempC;
28         int battery, uk2, sign, uk3, checksum;
29         data_t *data;
30
31         local_time_str(0, time_str);
32
33         for(row = 0; row < bitbuffer->num_rows; row++) {
34                 if(bitbuffer->bits_per_row[row] == OSV1_BITS) {
35                         cs = 0;
36                         for(i = 0; i < OSV1_BITS / 8; i++) {
37                                 nibble[i * 2    ] = rev_nibble((bitbuffer->bb[row][i] >> 4));
38                                 nibble[i * 2 + 1] = rev_nibble((bitbuffer->bb[row][i] & 0x0f));
39                                 if(i < ((OSV1_BITS / 8) - 1))
40                                         cs += nibble[i * 2] + 16 * nibble[i * 2 + 1];
41                         }
42                         cs = (cs & 0xFF) + (cs >> 8);
43                         checksum = nibble[6] + (nibble[7] << 4);
44                         if(checksum == cs) {
45                                 sid      = nibble[0];
46                                 channel  = ((nibble[1] >> 2) & 0x03) + 1;
47                                 uk1      = (nibble[1] >> 0) & 0x03;     /* unknown.  Seen change every 60 minutes */
48                                 tempC    =  nibble[2] / 10. + nibble[3] + nibble[4] * 10.;
49                                 battery  = (nibble[5] >> 3) & 0x01;
50                                 uk2      = (nibble[5] >> 2) & 0x01;     /* unknown.  Always zero? */
51                                 sign     = (nibble[5] >> 1) & 0x01;
52                                 uk3      = (nibble[5] >> 0) & 0x01;     /* unknown.  Always zero? */
53
54                                 if(sign) tempC = -tempC;
55
56                                 data = data_make(
57                                         "time",                 "",                             DATA_STRING,    time_str,
58                                         "model",                "",                             DATA_STRING,    "OSv1 Temperature Sensor",
59                                         "sid",                  "SID",                  DATA_INT,               sid,
60                                         "channel",              "Channel",              DATA_INT,               channel,
61                                         "battery",              "Battery",              DATA_STRING,    battery ? "LOW" : "OK",
62                                         "temperature_C","Temperature",  DATA_FORMAT,    "%.01f C",                              DATA_DOUBLE,    tempC,
63                                         NULL);
64                                 data_acquired_handler(data);
65                                 ret++;
66                         }
67                 }
68         }
69         return ret;
70 }
71
72 static char *output_fields[] = {
73   "time",
74   "model",
75   "id",
76   "channel",
77   "battery",
78   "temperature_C",
79   NULL
80 };
81
82 r_device oregon_scientific_v1 = {
83   .name           = "OSv1 Temperature Sensor",
84   .modulation     = OOK_PULSE_PWM_OSV1, 
85   .short_limit        = 300,
86   .long_limit         = 430, 
87   .reset_limit        = 14000,
88   .json_callback  = &oregon_scientific_callback_v1,
89   .disabled       = 0,
90   .demod_arg      = 0,
91   .fields         = output_fields
92 };