1 /** @file
2     RF-tech decoder (INFRA 217S34).
3 
4     Copyright (C) 2016 Erik Johannessen
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 */
11 /**
12 RF-tech decoder (INFRA 217S34).
13 
14 Also marked INFRA 217S34
15 Ewig Industries Macao
16 
17 Example of message:
18 
19     01001001 00011010 00000100
20 
21 - First byte is unknown, but probably id.
22 - Second byte is the integer part of the temperature.
23 - Third byte bits 0-3 is the fraction/tenths of the temperature.
24 - Third byte bit 7 is 1 with fresh batteries.
25 - Third byte bit 6 is 1 on button press.
26 
27 More sample messages:
28 
29     {24} ad 18 09 : 10101101 00011000 00001001
30     {24} 3e 17 09 : 00111110 00010111 00001001
31     {24} 70 17 03 : 01110000 00010111 00000011
32     {24} 09 17 01 : 00001001 00010111 00000001
33 
34 With fresh batteries and button pressed:
35 
36     {24} c5 16 c5 : 11000101 00010110 11000101
37 
38 */
39 
40 #include "decoder.h"
41 
rftech_callback(r_device * decoder,bitbuffer_t * bitbuffer)42         static int rftech_callback(r_device *decoder, bitbuffer_t *bitbuffer)
43 {
44     int r = bitbuffer_find_repeated_row(bitbuffer, 3, 24);
45 
46     if (r < 0 || bitbuffer->bits_per_row[r] != 24)
47         return DECODE_ABORT_LENGTH;
48     uint8_t *b = bitbuffer->bb[r];
49 
50     int sensor_id = b[0];
51     float temp_c = (b[1] & 0x7f) + (b[2] & 0x0f) * 0.1f;
52     if (b[1] & 0x80)
53         temp_c = -temp_c;
54 
55     int battery = (b[2] & 0x80) == 0x80;
56     int button = (b[2] & 0x60) != 0;
57 
58     /* clang-format off */
59     data_t *data = data_make(
60             "model",            "",             DATA_STRING, "RF-tech",
61             "id",               "Id",           DATA_INT,    sensor_id,
62             "battery_ok",       "Battery",      DATA_INT,    battery,
63             "temperature_C",    "Temperature",  DATA_FORMAT, "%.01f C", DATA_DOUBLE, temp_c,
64             "button",           "Button",       DATA_INT,    button,
65             NULL);
66     /* clang-format on */
67 
68     decoder_output_data(decoder, data);
69     return 1;
70 }
71 
72 static char *csv_output_fields[] = {
73         "model",
74         "id",
75         "battery_ok",
76         "temperature_C",
77         "button",
78         NULL,
79 };
80 
81 r_device rftech = {
82         .name        = "RF-tech",
83         .modulation  = OOK_PULSE_PPM,
84         .short_width = 2000,
85         .long_width  = 4000,
86         .gap_limit   = 5000,
87         .reset_limit = 10000,
88         .decode_fn   = &rftech_callback,
89         .disabled    = 1,
90         .fields      = csv_output_fields,
91 };
92