1 /* WG-PB12V1 Temperature Sensor
3 * Device method to decode a generic wireless temperature probe. Probe marked
4 * with WG-PB12V1-2016/11.
8 * The packet format appears to be similar those the Lacrosse format.
9 * (http://fredboboss.free.fr/articles/tx29.php)
11 * AAAAAAAA ????TTTT TTTTTTTT ???IIIII HHHHHHHH CCCCCCCC
13 * A = Preamble - 11111111
14 * ? = Unknown - possibly battery charge
15 * T = Temperature - see below
16 * I = ID of probe is set randomly each time the device is powered off-on,
17 * Note, base station has and unused "123" symbol, but ID values can be
19 * H = Humidity - not used, is always 11111111
20 * C = Checksum - CRC8, polynomial 0x31, initial value 0x0, final value 0x0
24 * Temperature value is "milli-celcius", ie 1000 mC = 1C, offset by -40 C.
26 * 0010 01011101 = 605 mC => 60.5 C
27 * Remove offset => 60.5 C - 40 C = 20.5 C
31 * Possbible uses could be weak battey, or new battery.
33 * At the moment it this device cannot distinguish between a Fine Offset
34 * device, see fineoffset.c.
36 * Copyright (C) 2015 Tommy Vestermark
37 * Modifications Copyright (C) 2017 Ciarán Mooney
39 * This program is free software; you can redistribute it and/or modify
40 * it under the terms of the GNU General Public License as published by
41 * the Free Software Foundation; either version 2 of the License, or
42 * (at your option) any later version.
49 static int wg_pb12v1_callback(bitbuffer_t *bitbuffer) {
50 /* This function detects if the packet (bitbuffer) is from a WG-PB12V1
51 * sensor, and decodes it if it passes the checks.
54 bitrow_t *bb = bitbuffer->bb;
57 char time_str[LOCAL_TIME_BUFLEN];
65 const uint8_t polynomial = 0x31; // x8 + x5 + x4 + 1 (x8 is implicit)
68 if (bitbuffer->bits_per_row[0] >= 48 && // Don't waste time on a short packages
69 bb[0][0] == 0xFF && // Preamble
70 bb[0][5] == crc8(&bb[0][1], 4, polynomial, 0) && // CRC (excluding preamble)
71 bb[0][4] == 0xFF // Humitidy set to 11111111
75 local_time_str(0, time_str);
77 // Nibble 7,8 contains id
78 id = ((bb[0][3]&0x1F));
80 // Nibble 5,6,7 contains 12 bits of temperature
81 // The temperature is "milli-celcius", ie 1000 mC = 1C, offset by -40 C.
82 temp = ((bb[0][1] & 0x0F) << 8) | bb[0][2];
83 temperature = ((float)temp / 10)-40;
85 // Populate string array with raw packet bits.
86 for (uint16_t bit = 0; bit < bitbuffer->bits_per_row[0]; ++bit){
87 if (bb[0][bit/8] & (0x80 >> (bit % 8))){
94 io[48] = 0; // terminate string array.
96 if (debug_output > 1) {
97 fprintf(stderr, "ID = 0x%2X\n", id);
98 fprintf(stderr, "temperature = %.1f C\n", temperature);
101 data = data_make("time", "", DATA_STRING, time_str,
102 "model", "", DATA_STRING, "WG-PB12V1",
103 "id", "ID", DATA_INT, id,
104 "temperature_C", "Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temperature,
105 "io", "io", DATA_STRING, io,
107 data_acquired_handler(data);
113 static char *output_fields[] = {
114 /* Defines the output files for this device function.
124 r_device wg_pb12v1 = {
125 /* Defines object information for use in other parts of RTL_433.
128 .modulation = OOK_PULSE_PWM_RAW,
129 .short_limit = 650, // Short pulse 564µs, long pulse 1476µs, fixed gap 960µs
130 .long_limit = 1550, // Maximum pulse period (long pulse + fixed gap)
131 .reset_limit = 2500, // We just want 1 package
132 .json_callback = &wg_pb12v1_callback,
135 .fields = output_fields