mirror of
https://github.com/merbanan/rtl_433.git
synced 2026-05-24 09:46:17 -04:00
efergy_optical with CRC checks (#400)
* Updated README for new efergy_optical sensor and missing recent devices.
* Added support for efergy_optical.c with crc checksum calculation.
whilst the code does validate the checksum it does not reject data based on invalid checksum.
New library added for checksum calculations.
* Changed code to output results on a good checksum.
* Added header file for lib_crc to include directory
* Updated README for new efergy_optical sensor and missing recent devices.
Added support for efergy_optical.c with crc checksum calculation.
whilst the code does validate the checksum it does not reject data based on invalid checksum.
New library added for checksum calculations.
Changed code to output results on a good checksum.
Added header file for lib_crc to include directory
* Changed CRC calculation to use new function in util.h
no longer using lib_crc
* added file output support and changed energy to power.
only output crc values when using -D argument.
* Only output crc when using -D argument
* I have kept the crc calculation to be the first 10 bytes. Bytes 11 and 12 are the CRC16_CCITT.
The only puzzle left is why does the last byte does as it sometimes change to 80.
Byte Count 1 2 3 4 5 6 7 8 9 10 11 12 13
Bytes Array [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]
[00] {97} 0a a2 ba 40 00 00 00 00 07 0f d5 5d 00
Calculated crc is 0xD55D
Received csum1 is 0xD55D
* Efergy Optical device added.
Multiple changes to combine several files into one commit.
* Removing lib_crc files
This commit is contained in:
committed by
Benjamin Larsson
parent
1473dbf517
commit
a8f1639e01
12
README.md
12
README.md
@@ -122,8 +122,16 @@ Supported devices:
|
||||
[50] Proove
|
||||
[51] Bresser Thermo-/Hygro-Sensor 3CH
|
||||
[52] Springfield PreciseTemp Temperature and Soil Moisture
|
||||
[53] Oregon Scientific SL109H Temperature & Humidity Sensor
|
||||
[54] TFA Pool thermometer
|
||||
[53] Oregon Scientific SL109H Temperature & Humidity Sensor
|
||||
[54] Acurite 606TX Temperature Sensor
|
||||
[55] TFA pool temperature sensor
|
||||
[56] Kedsum Temperature & Humidity Sensor
|
||||
[57] blyss DC5-UK-WH (433.92 MHz)
|
||||
[58] Steelmate TPMS
|
||||
[59] Schraeder TPMS
|
||||
[60] LightwaveRF
|
||||
[61] Elro DB286A Doorbell
|
||||
[62] Efergy Optical
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#define DEFAULT_LEVEL_LIMIT 8000 // Theoretical high level at I/Q saturation is 128x128 = 16384 (above is ripple)
|
||||
#define MINIMAL_BUF_LENGTH 512
|
||||
#define MAXIMAL_BUF_LENGTH (256 * 16384)
|
||||
#define MAX_PROTOCOLS 60
|
||||
#define MAX_PROTOCOLS 61
|
||||
#define SIGNAL_GRABBER_BUFFER (12 * DEFAULT_BUF_LENGTH)
|
||||
|
||||
/* Supported modulation types */
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
DECL(schraeder) \
|
||||
DECL(lightwave_rf) \
|
||||
DECL(elro_db286a) \
|
||||
DECL(efergy_optical) \
|
||||
DECL(template)
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ add_executable(rtl_433
|
||||
pulse_detect.c
|
||||
rtl_433.c
|
||||
util.c
|
||||
devices/acurite.c
|
||||
devices/acurite.c
|
||||
devices/alecto.c
|
||||
devices/ambient_weather.c
|
||||
devices/blyss.c
|
||||
@@ -79,6 +79,7 @@ add_executable(rtl_433
|
||||
devices/steelmate.c
|
||||
devices/schraeder.c
|
||||
devices/elro_db286a.c
|
||||
devices/efergy_optical.c
|
||||
devices/new_template.c
|
||||
|
||||
)
|
||||
|
||||
142
src/devices/efergy_optical.c
Normal file
142
src/devices/efergy_optical.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/* Efergy IR is a devices that periodically reports current power consumption
|
||||
* on frequency ~433.55 MHz. The data that is transmitted consists of 8
|
||||
* bytes:
|
||||
*
|
||||
* Byte 1-4: Start bits (0000), then static data (probably device id)
|
||||
* Byte 5-7: all zeros
|
||||
* Byte 8: Pulse Count
|
||||
* Byte 9: sample frequency (15 seconds)
|
||||
* Byte 10: seconds
|
||||
* Byte 11: bytes0-10 crc16 xmodem XOR with FF
|
||||
* Byte 12: ?crc16 xmodem
|
||||
* if pulse count <3 then power =(( pulsecount/impulse-perkwh) * (3600/seconds))
|
||||
* else power= ((pulsecount/n_imp) * (3600/seconds))
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "rtl_433.h"
|
||||
#include "util.h"
|
||||
#include "data.h"
|
||||
|
||||
static int efergy_optical_callback(bitbuffer_t *bitbuffer) {
|
||||
unsigned num_bits = bitbuffer->bits_per_row[0];
|
||||
uint8_t *bytes = bitbuffer->bb[0];
|
||||
double power, n_imp;
|
||||
double pulsecount;
|
||||
double seconds;
|
||||
data_t *data;
|
||||
char time_str[LOCAL_TIME_BUFLEN];
|
||||
uint16_t crc;
|
||||
uint16_t csum1;
|
||||
|
||||
if (num_bits < 64 || num_bits > 100){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The bit buffer isn't always aligned to the transmitted data, so
|
||||
// search for data start and shift out the bits which aren't part
|
||||
// of the data. The data always starts with 0000 (or 1111 if
|
||||
// gaps/pulses are mixed up).
|
||||
while ((bytes[0] & 0xf0) != 0xf0 && (bytes[0] & 0xf0) != 0x00)
|
||||
{
|
||||
num_bits -= 1;
|
||||
if (num_bits < 64)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < (num_bits + 7) / 8; ++i)
|
||||
{
|
||||
bytes[i] <<= 1;
|
||||
bytes[i] |= (bytes[i + 1] & 0x80) >> 7;
|
||||
}
|
||||
}
|
||||
|
||||
// Sometimes pulses and gaps are mixed up. If this happens, invert
|
||||
// all bytes to get correct interpretation.
|
||||
if (bytes[0] & 0xf0){
|
||||
for (unsigned i = 0; i < 12; ++i)
|
||||
{
|
||||
bytes[i] = ~bytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_output){
|
||||
fprintf(stdout,"Possible Efergy Optical: ");
|
||||
bitbuffer_print(bitbuffer);
|
||||
}
|
||||
|
||||
// Calculate checksum for bytes[0..10]
|
||||
// crc16 xmodem with start value of 0x00 and polynomic of 0x1021 is same as CRC-CCITT (0x0000)
|
||||
// start of data, length of data=10, polynomic=0x1021, init=0x0000
|
||||
|
||||
csum1 = ((bytes[10]<<8)|(bytes[11]));
|
||||
|
||||
crc = crc16_ccitt(bytes, 10, 0x1021, 0x0);
|
||||
|
||||
if (crc == csum1)
|
||||
{
|
||||
if (debug_output) {
|
||||
fprintf (stdout, "Checksum OK :) :)\n");
|
||||
fprintf (stdout, "Calculated crc is 0x%02X\n", crc);
|
||||
fprintf (stdout, "Received csum1 is 0x%02X\n", csum1);
|
||||
}
|
||||
// this setting depends on your electricity meter's optical output
|
||||
n_imp = 3200;
|
||||
|
||||
pulsecount = bytes[8];
|
||||
seconds = bytes[10];
|
||||
|
||||
//some logic for low pulse count not sure how I reached this formula
|
||||
if (pulsecount < 3)
|
||||
{
|
||||
power = ((pulsecount/n_imp) * (3600/seconds));
|
||||
}
|
||||
else
|
||||
{
|
||||
power = ((pulsecount/n_imp) * (3600/30));
|
||||
}
|
||||
/* Get time now */
|
||||
local_time_str(0, time_str);
|
||||
|
||||
data = data_make("time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Efergy Optical",
|
||||
"power", "Power KWh", DATA_FORMAT,"%.03f KWh", DATA_DOUBLE, power,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug_output)
|
||||
{
|
||||
fprintf (stdout, "Checksum not OK !!!\n");
|
||||
fprintf(stdout, "Calculated crc is 0x%02X\n", crc);
|
||||
fprintf(stdout, "Received csum1 is 0x%02X\n", csum1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *output_fields[] = {
|
||||
"time",
|
||||
"model",
|
||||
"power",
|
||||
NULL
|
||||
};
|
||||
|
||||
r_device efergy_optical = {
|
||||
.name = "Efergy Optical",
|
||||
.modulation = FSK_PULSE_PWM_RAW,
|
||||
.short_limit = 92,
|
||||
.long_limit = 400,
|
||||
.reset_limit = 400,
|
||||
.json_callback = &efergy_optical_callback,
|
||||
.disabled = 0,
|
||||
.demod_arg = 0,
|
||||
.fields = output_fields
|
||||
};
|
||||
Reference in New Issue
Block a user