ef0cf45ce6d4815efcaa2cb3cefad3efa6ccb572
[rtl-433.git] / src / devices / wh2.c
1 #include "rtl_433.h"
2
3 // ** WH2 Temperature and Humidity Outdoor Sensor **
4
5 uint8_t crc8( uint8_t *addr, uint8_t len)
6 {
7   uint8_t crc = 0;
8   
9   // Indicated changes are from reference CRC-8 function in OneWire library
10   while (len--) {
11     uint8_t inbyte = *addr++;
12     int i;
13     for (i = 8; i; i--) {
14       uint8_t mix = (crc ^ inbyte) & 0x80; // changed from & 0x01
15       crc <<= 1; // changed from right shift
16       if (mix) crc ^= 0x31;// changed from 0x8C;
17         inbyte <<= 1; // changed from right shift
18     }
19   }
20   return crc;
21 }
22                                                       
23 static int wh2_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS],int16_t bits_per_row[BITBUF_ROWS]) {
24     int i,j,k;
25
26     uint8_t payload[4];
27     int received_crc8,payload_crc8;
28
29     int wh2_id;
30     float wh2_temp;
31     float wh2_humidity;
32
33     if (bb[0][0] != 0xFE) return 0;
34
35     payload[0] = bb[0][1]>>1;
36     payload[1] = bb[0][2]>>1 | ((bb[0][1]&1) << 7 );
37     payload[2] = bb[0][3]>>1 | ((bb[0][2]&1) << 7 );
38     payload[3] = bb[0][4]>>1 | ((bb[0][3]&1) << 7 );
39     
40     received_crc8 = (bb[0][5]>>1) | ((bb[0][4]&1) << 7 );
41
42     payload_crc8 = crc8(payload,4);
43     
44     if (payload_crc8 != received_crc8) {
45         fprintf(stderr,"Bad WH2 payload CRC, skipping...\n");
46         return 0;
47     }
48     
49     wh2_id = (payload[0] << 4) + (payload[1] >> 4);
50     wh2_temp = ((payload[1] & 0x7) << 8) + payload[2];
51     if (payload[1] & 0x8) {
52         wh2_temp = -wh2_temp;
53     }
54     wh2_temp = wh2_temp/10;
55     
56     wh2_humidity = payload[3];
57     
58     fprintf(stdout, "SENSOR:TYPE=WH2,ID=%X,HUMIDITY=%g,TEMPERATURE=%g\n",wh2_id,wh2_humidity,wh2_temp);
59
60     return 1;
61         
62 }
63
64 r_device wh2 = {
65     /* .id             = */ 19,
66     /* .name           = */ "WH2 Weather Station",
67     /* .modulation     = */ OOK_PWM_P,
68     /* .short_limit    = */ 150,
69     /* .long_limit     = */ 400, 
70     /* .reset_limit    = */ 20000,
71     /* .json_callback  = */ &wh2_callback,
72 };