Bugfixes
[rtl-433.git] / src / devices / efergy_e2_classic.c
1 /* Efergy e2 classic (electricity meter)
2  *
3  * This electricity meter periodically reports current power consumption
4  * on frequency ~433.55 MHz. The data that is transmitted consists of 8
5  * bytes:
6  *
7  * Byte 1-4: Start bits (0000), then static data (probably device id)
8  * Byte 5-7: Current power consumption
9  * Byte 8: Checksum
10  *
11  * Power calculations come from Nathaniel Elijah's program EfergyRPI_001.
12  *
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  */
19
20 #include "rtl_433.h"
21
22 static int efergy_e2_classic_callback(bitbuffer_t *bitbuffer) {
23         unsigned num_bits = bitbuffer->bits_per_row[0];
24         uint8_t *bytes = bitbuffer->bb[0];
25
26         if (num_bits < 64 || num_bits > 80) {
27                 return 0;
28         }
29
30         // The bit buffer isn't always aligned to the transmitted data, so
31         // search for data start and shift out the bits which aren't part
32         // of the data. The data always starts with 0000 (or 1111 if
33         // gaps/pulses are mixed up).
34         while ((bytes[0] & 0xf0) != 0xf0 && (bytes[0] & 0xf0) != 0x00) {
35                 num_bits -= 1;
36                 if (num_bits < 64) {
37                         return 0;
38                 }
39
40                 for (unsigned i = 0; i < (num_bits + 7) / 8; ++i) {
41                         bytes[i] <<= 1;
42                         bytes[i] |= (bytes[i + 1] & 0x80) >> 7;
43                 }
44         }
45
46         // Sometimes pulses and gaps are mixed up. If this happens, invert
47         // all bytes to get correct interpretation.
48         if (bytes[0] & 0xf0) {
49                 for (unsigned i = 0; i < 8; ++i) {
50                         bytes[i] = ~bytes[i];
51                 }
52         }
53
54         unsigned checksum = 0;
55         for (unsigned i = 0; i < 7; ++i) {
56                 checksum += bytes[i];
57         }
58         checksum &= 0xff;
59         if (checksum != bytes[7]) {
60                 return 0;
61         }
62
63         const unsigned VOLTAGES[] = {110, 115, 120, 220, 230, 240, 0};
64
65         double current_adc = 256 * bytes[4] + bytes[5];
66         for (unsigned i = 0; VOLTAGES[i] != 0; ++i) {
67                 double power  = (VOLTAGES[i] * current_adc * (1 << bytes[6])) / 32768;
68                 fprintf(stderr, "Power consumption at %u volts: %.2f watts\n", VOLTAGES[i], power);
69         }
70
71         return 1;
72 }
73
74
75 r_device efergy_e2_classic = {
76         .name           = "Efergy e2 classic",
77         .modulation     = FSK_PULSE_PWM_RAW,
78         .short_limit    = 92,
79         .long_limit     = 400,
80         .reset_limit    = 400,
81         .json_callback  = &efergy_e2_classic_callback,
82         .disabled       = 1,
83         .demod_arg      = 0,
84 };