1 /* Efergy e2 classic (electricity meter)
3 * This electricity meter periodically reports current power consumption
4 * on frequency ~433.55 MHz. The data that is transmitted consists of 8
7 * Byte 1-4: Start bits (0000), then static data (probably device id)
8 * Byte 5-7: Current power consumption
11 * Power calculations come from Nathaniel Elijah's program EfergyRPI_001.
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.
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];
26 if (num_bits < 64 || num_bits > 80) {
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) {
40 for (unsigned i = 0; i < (num_bits + 7) / 8; ++i) {
42 bytes[i] |= (bytes[i + 1] & 0x80) >> 7;
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) {
54 unsigned checksum = 0;
55 for (unsigned i = 0; i < 7; ++i) {
59 if (checksum != bytes[7]) {
63 const unsigned VOLTAGES[] = {110, 115, 120, 220, 230, 240, 0};
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);
75 r_device efergy_e2_classic = {
76 .name = "Efergy e2 classic",
77 .modulation = FSK_PULSE_PWM_RAW,
81 .json_callback = &efergy_e2_classic_callback,