Add support for ECODHOME smart socket ()

This commit is contained in:
Christian W. Zuckschwerdt 2020-11-10 15:15:24 +01:00 committed by GitHub
parent c4d9e95e3e
commit cdad2eb269
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 212 additions and 0 deletions

View file

@ -248,6 +248,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
[171] LaCrosse Technology View LTV-TH Thermo/Hygro Sensor
[172] Bresser Weather Center 6-in-1
[173] Bresser Weather Center 7-in-1
[174] EcoDHOME Smart Socket and MCEE Solar monitor
* Disabled by default, use -R n or -G

View file

@ -355,6 +355,7 @@ stop_after_successful_events false
protocol 171 # LaCrosse Technology View LTV-TH Thermo/Hygro Sensor
protocol 172 # Bresser Weather Center 6-in-1
protocol 173 # Bresser Weather Center 7-in-1
protocol 174 # EcoDHOME Smart Socket and MCEE Solar monitor
## Flex devices (command line option "-X")

View file

@ -181,6 +181,7 @@
DECL(lacrosse_th3) \
DECL(bresser_6in1) \
DECL(bresser_7in1) \
DECL(ecodhome) \
/* Add new decoders here. */
#define DECL(name) extern r_device name;

View file

@ -59,6 +59,7 @@ add_library(r_433 STATIC
devices/directv.c
devices/dish_remote_6_3.c
devices/dsc.c
devices/ecodhome.c
devices/ecowitt.c
devices/efergy_e2_classic.c
devices/efergy_optical.c

View file

@ -58,6 +58,7 @@ rtl_433_SOURCES = abuf.c \
devices/directv.c \
devices/dish_remote_6_3.c \
devices/dsc.c \
devices/ecodhome.c \
devices/ecowitt.c \
devices/efergy_e2_classic.c \
devices/efergy_optical.c \

203
src/devices/ecodhome.c Normal file
View file

@ -0,0 +1,203 @@
/** @file
Decoder for EcoDHOME Smart Socket and MCEE Solar monitor.
Copyright (C) 2020 Christian W. Zuckschwerdt <zany@triq.net>
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 "decoder.h"
/**
Decoder for EcoDHOME Smart Socket and MCEE Solar monitor.
(the Smart Switch should be the same as the Smart Socket.)
Smart Socket receives and implements the switching on/off instruction remotely from the Controller.
The Transmitters with sensor clamps collect home energy consumption data for the MCEE Solar monitor.
see https://github.com/merbanan/rtl_433/issues/1525
The transmission is FSK PCM with 250 us bit width.
## PV Transmitter (P/N 01333-5847-00)
Example data:
{144}aaaaaa 2dd4 8c74 d4b9 3eb3 223844 51 550000
{144}aaaaaa 2dd4 8c74 d4b9 3eb3 c53344 ef 550000
{144}aaaaaa 2dd4 8c76 d4b9 71b3 863363 04 550000 (every 71 seconds)
Other device:
{144}aaaaaa 2dd4 8c74 12d6 Type: 3eb3 bc3544
{144}aaaaaa 2dd4 8c76 12d6 Type: 71b3 333363 (also 863363)
- 3eb3 messages are a power reading of LL HH 0x44, LL and HH start at 0x33 (=0) and wrap up to 0x32 (=255)
- 71b3 messages (arrive every 71 seconds)
- 71b3 863363 04 550000 which might be some kind of status then and not a reading.
The checksum is: add all bytes after the sync word plus 0x35 (mod 0xff).
## Smart Socket (P/N 01333-5840-00)
Example data:
{155}2ad455555516ea2918ae353b802b2d3f8029a12
{154}55a8 aaaaaa 2dd4 5231 5c6a 7700 565a 7f00 53 42 4
Data Seen:
52315c6a 7700 565a 007f00
52315c6a 7700 565a 007e00
52315c6a 7700 565a 007d00
46315c6a 7700 414b 000000
52315c6a 7700 565a 008000
46315c6a 7700 5053 000000
52315c6a 7700 414b 000000
52315c6a 7700 565a 008100
52315c6a 7700 565a 008200
52315c6a 7700 565a 008300
52315c6a 7700 414b 003209
52315c6a 7700 414b 003d03
52315c6a 7700 565a 007c00
52315c6a 7700 565a 007b00
52315c6a 7700 565a 007a00
Removing the first 1 or 2 bits gives a prefix of 55a8aaaaaa2dd4, the leading bits are likely warmup or garbage.
The next bytes of 5231 5c6a 7700 are likely a serial number (id).
Then we have messages with 414b or 565a or 5053 which likely is a message type.
On 414b the two byte (little endian) power value follows. For the other types it is unknonwn, maybe kWh or state.
Lastly there is a fixed 53 (status? stop?) and a checksum byte.
Interesting to note that 414b, 565a, and 53 are "AK", "VZ", and "S" which might not be a coincidence.
The checksum is: add all bytes after the sync word (mod 0xff).
*/
static int ecodhome_decode(r_device *decoder, bitbuffer_t *bitbuffer)
{
uint8_t const preamble_pattern[] = {0xaa, 0xaa, 0x2d, 0xd4};
data_t *data;
uint8_t msg[13];
if (bitbuffer->num_rows != 1 || bitbuffer->bits_per_row[0] < 128) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: to few bits (%u)\n", __func__, bitbuffer->bits_per_row[0]);
return DECODE_ABORT_LENGTH; // unrecognized
}
unsigned start_pos = bitbuffer_search(bitbuffer, 0, 0,
preamble_pattern, sizeof(preamble_pattern) * 8);
start_pos += sizeof(preamble_pattern) * 8;
if (start_pos >= bitbuffer->bits_per_row[0]) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: preamble not found\n", __func__);
return DECODE_ABORT_EARLY; // no preamble found
}
//if (start_pos + sizeof (msg) * 8 >= bitbuffer->bits_per_row[0]) {
if (start_pos + 12 * 8 >= bitbuffer->bits_per_row[0]) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: message too short (%u)\n", __func__, bitbuffer->bits_per_row[0] - start_pos);
return DECODE_ABORT_LENGTH; // message too short
}
bitbuffer_extract_bytes(bitbuffer, 0, start_pos, msg, sizeof(msg) * 8);
if (decoder->verbose > 1) {
bitrow_printf(msg, sizeof(msg) * 8, "%s: MSG: ", __func__);
}
uint32_t id = ((uint32_t)msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
int m_type = (msg[4] << 8) | (msg[5]);
int m_subtype = (msg[6] << 8) | (msg[7]); // only Smart Socket
if (m_type == 0x7700) {
int sum = add_bytes(msg, 11); // socket
if ((sum & 0xff) != msg[11]) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: checksum fail %02x vs %02x\n", __func__, sum, msg[9]);
return DECODE_FAIL_MIC;
}
if (msg[10] != 0x53) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: wrong stop byte %02x\n", __func__, msg[10]);
return DECODE_FAIL_SANITY;
}
int raw = (msg[8] << 8) | (msg[9]);
int power_w = (msg[9] << 8) | (msg[8]);
/* clang-format off */
data = data_make(
"model", "", DATA_STRING, "EcoDHOME-SmartSocket",
"id", "", DATA_FORMAT, "%08x", DATA_INT, id,
"message_type", "Message Type", DATA_FORMAT, "%04x", DATA_INT, m_type,
"message_subtype", "Message Subtype", DATA_FORMAT, "%04x", DATA_INT, m_subtype,
"power_W", "Power", DATA_COND, m_subtype == 0x414b, DATA_FORMAT, "%.1f W", DATA_DOUBLE, (double)power_w,
"raw", "Raw data", DATA_FORMAT, "%06x", DATA_INT, raw,
"mic", "Integrity", DATA_STRING, "CHECKSUM",
NULL);
/* clang-format on */
}
else {
int sum = add_bytes(msg, 9) + 0x35; // transmitter
if ((sum & 0xff) != msg[9]) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: checksum fail %02x vs %02x\n", __func__, sum, msg[9]);
return DECODE_FAIL_MIC;
}
if (msg[10] != 0x55) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: wrong stop byte %02x\n", __func__, msg[10]);
return DECODE_FAIL_SANITY;
}
if (msg[11] != 0x00) {
if (decoder->verbose > 1)
fprintf(stderr, "%s: wrong poststop byte %02x\n", __func__, msg[11]);
return DECODE_FAIL_SANITY;
}
int raw = (msg[6] << 16) | (msg[7] << 8) | (msg[8]);
int power_w = ((uint8_t)(msg[7] - 0x33) << 8) | (uint8_t)(msg[6] - 0x33);
/* clang-format off */
data = data_make(
"model", "", DATA_STRING, "EcoDHOME-Transmitter",
"id", "", DATA_FORMAT, "%08x", DATA_INT, id,
"message_type", "Message Type", DATA_FORMAT, "%04x", DATA_INT, m_type,
"power_W", "Power", DATA_COND, m_type == 0x3eb3, DATA_FORMAT, "%.1f W", DATA_DOUBLE, (double)power_w,
"raw", "Raw data", DATA_FORMAT, "%06x", DATA_INT, raw,
"mic", "Integrity", DATA_STRING, "CHECKSUM",
NULL);
/* clang-format on */
}
decoder_output_data(decoder, data);
return 1;
}
static char *output_fields[] = {
"model",
"id",
"message_type",
"message_subtype",
"power_W",
"raw",
"mic",
NULL,
};
r_device ecodhome = {
.name = "EcoDHOME Smart Socket and MCEE Solar monitor",
.modulation = FSK_PULSE_PCM,
.short_width = 250,
.long_width = 250,
.reset_limit = 6000,
.decode_fn = &ecodhome_decode,
.fields = output_fields,
};

View file

@ -184,6 +184,7 @@ COPY ..\..\libusb\MS64\dll\libusb*.dll $(TargetDir)</Command>
<ClCompile Include="..\src\devices\directv.c" />
<ClCompile Include="..\src\devices\dish_remote_6_3.c" />
<ClCompile Include="..\src\devices\dsc.c" />
<ClCompile Include="..\src\devices\ecodhome.c" />
<ClCompile Include="..\src\devices\ecowitt.c" />
<ClCompile Include="..\src\devices\efergy_e2_classic.c" />
<ClCompile Include="..\src\devices\efergy_optical.c" />

View file

@ -283,6 +283,9 @@
<ClCompile Include="..\src\devices\dsc.c">
<Filter>Source Files\devices</Filter>
</ClCompile>
<ClCompile Include="..\src\devices\ecodhome.c">
<Filter>Source Files\devices</Filter>
</ClCompile>
<ClCompile Include="..\src\devices\ecowitt.c">
<Filter>Source Files\devices</Filter>
</ClCompile>