rtl_433
rtl_433 copied to clipboard
Add support for Vauno EN8822C
Some work to be done on CRC and humidity needs moving to 7 bits. Have commented out battery while we're unsure where it is (copied from Esperanza EWS).
Humidity should be b[3] >> 1
(top 7 bits from byte 3), right?
And checksum was nibble addition IIRC?
int chk = ((b[4] & 0x0f) << 2) | (b[5] & 0x03);
if (add_nibbles(b, 4) != chk) {
// checksum error
}
Made updates as above - is there an easy way for me to check that it works with the output? I'm also a bit confused at the width/limit values, different message captures had similar but different values!
- The
uint8_t b[5];
needs to beuint8_t b[6];
-
"mic", "Integrity", DATA_STRING, "CRC",
needs to be"mic", "Integrity", DATA_STRING, "CHECKSUM",
- You need to change
r_device esperanza_ews
tor_device vauno_en8822c
- Approximate timings are ok. E.g. here 2000, 4000, 5000, 9500
- I'd say 4200, 9100 is too narrow. Round up by 10-20%, e.g. 5000, 9500.
- Fix the trailing whitespace error (line 29)
- There is no bit offset, right? Remove
uint8_t b[6];
and replacebitbuffer_extract_bytes();
byuint8_t *b = bitbuffer->bb[row];
- The row selection seems wrong (L50 to 66), a bitbuffer looks like below. You'll want
int row = bitbuffer_find_repeated_prefix(bitbuffer, 4, 42)
, see https://github.com/merbanan/rtl_433/blob/master/include/bitbuffer.h#L139-L142 and other devices how it's used to get and checkrow
.
bitbuffer:: Number of rows: 13
[00] {42} 85 10 f9 74 0c 40 : 10000101 00010000 11111001 01110100 00001100 01
[01] { 0} :
[02] { 0} :
[03] {42} 85 10 f9 74 0c 40 : 10000101 00010000 11111001 01110100 00001100 01
[04] { 1} 00 : 0
[05] {42} 85 10 f9 74 0c 40 : 10000101 00010000 11111001 01110100 00001100 01
[06] { 1} 00 : 0
[07] {42} 85 10 f9 74 0c 40 : 10000101 00010000 11111001 01110100 00001100 01
[08] { 1} 00 : 0
[09] {42} 85 10 f9 74 0c 40 : 10000101 00010000 11111001 01110100 00001100 01
[10] { 1} 00 : 0
[11] {42} 85 10 f9 74 0c 40 : 10000101 00010000 11111001 01110100 00001100 01
[12] { 0} :
Thanks - these are all making sense! Had tried to work out what the whitespace error was myself but couldn't track that down.
I've set the minimum as 4 as per your suggestion - could this vary? I think I've always seen 6, but guess we're happy with less if they're the same length.
I've set the minimum as 4 as per your suggestion - could this vary? I think I've always seen 6
The idea is to require (only) a majority: 6/2+1
-- this allows for bad reception of some packets
I guess you can now remove if (bitbuffer->num_rows != 13)
as that might vary with bad reception and just the (minimum 4 identical rows with valid checksum look solid enough.
Line 59 uint8_t *b = bitbuffer->bb[row]
needs a ;
at the end ;)
Much more Python than C recently!
Much more Python than C recently!
;) Your identation was spot on!
Line 59 needs to be data_t *data = data_make(
-- should be all good then.
Looks good (ignore the "symbol errors", that's another decoder).
LGTM
By reading in temp_raw as int, will this handle the Two's complement? Or do I need to declare as signed int, or convert...?
Yes, you will need to align the bits to 16 bit, then use the sign extend to go from 16 bit to int width.
int temp_raw = (int16_t)(((b[2] & 0x0f) << 12) | ((b[2] & 0xf0) << 4) | ((b[1] & 0x0f) << 4)); // use sign extend
float temp_c = (temp_raw >> 4) * 0.1f;
or for legibility perhaps
int temp_raw = ((b[2] & 0x0f) << 8) | (b[2] & 0xf0) | (b[1] & 0x0f);
temp_raw = (int16_t)(temp_raw << 4); // use sign extend
float temp_c = (temp_raw >> 4) * 0.1f;
Just wanted to make sure, is there anything else I need to do on this? Is the simplest way for me to test it to build myself presumably?
Just giving other people the chance to weight in. Good for merge, and will do so shortly.
As someone who coincidentally bought one of these sensors pretty much the same day that this pull request was submitted I would just like to say thank you to everyone who worked on adding support for it. I look forward to it being merged so I can test it out. Any guess on how long it might take for this change to filter down into the Home Assistant RTL_433 add-on? In the mean time what is the best way to make it work? Will I need to download the source and compile it? Anyway, thanks again.
Thanks for your efforts on this! Unfortunately, I do not think it is correct for my EN8822C device from amazon labelled on the front "EN8822 Model T21".
I tried this pull and ran into some problems where I think the alignment is off. See attached analysis files:
This one kind of works, but the temp is not correct. Actual temp/humidity = approximately 75F / 55% (sorry, do not have the display) vs. reported 177.6C: g005_433.92M_250k.cu8.analysis.txt
Placed it in the freezer at 8F. This one is shifted somehow and does not decode/report: g116_433.92M_250k.cu8.analysis.txt
Your first example: {42} 6d 00 f6 66 0d 00 - this would be 24.6C, which is 76.3F...?
Not sure where the problem lies, but the first file has:
[00] {42} 6d 00 f6 66 0d 00 : 01101101 00000000 11110110 01100110 00001101 00
with the output of decoder as:
Channel : 1 Temperature: 177.6 C Humidity : 12 % Integrity : CHECKSUM
The second file has:
[00] {42} 6d 0f 78 5e 01 00 : 01101101 00001111 01111000 01011110 00000001 00
I am a noob at this, but following the ~/docs/Analysis.md using BitBench I think the structure might be more like:
ID:109 CH:0 TEMP_C: 246 HUM:052 CRC:00
ID:109 CH:0 TEMP_C: -136 HUM:004 CRC:00
https://triq.net/bitbench#c=6d%2000%20f6%2066%200d%2000&c=6d%200f%2078%205e%2001%2000&f=ID%3Ad%20CH%3Ah%20TEMP_C%3A12s%20xxxxxxxxxx%20HUM%3Ad%20CRC%3A8h%20%7C%208h%2016h%2016h%20&cw=4
That gives me a consistent id, channel (0, actually 0+1), temp (24.6C, -13.6C), and humidity (52%, 4%) with what I would expect from the two above data points. Not sure what is in all of those x's, but at least probably battery.
Maybe that is what you already have identified, but my compiled version gives incorrect decoding.
Not sure where the problem lies, but the first file has:
[00] {42} 6d 00 f6 66 0d 00 : 01101101 00000000 11110110 01100110 00001101 00
with the output of decoder as:Channel : 1 Temperature: 177.6 C Humidity : 12 % Integrity : CHECKSUM
The second file has:[00] {42} 6d 0f 78 5e 01 00 : 01101101 00001111 01111000 01011110 00000001 00
I am a noob at this, but following the ~/docs/Analysis.md using BitBench I think the structure might be more like:
ID:109 CH:0 TEMP_C: 246 HUM:052 CRC:00 ID:109 CH:0 TEMP_C: -136 HUM:004 CRC:00
https://triq.net/bitbench#c=6d%2000%20f6%2066%200d%2000&c=6d%200f%2078%205e%2001%2000&f=ID%3Ad%20CH%3Ah%20TEMP_C%3A12s%20xxxxxxxxxx%20HUM%3Ad%20CRC%3A8h%20%7C%208h%2016h%2016h%20&cw=4
That gives me a consistent id, channel (0, actually 0+1), temp (24.6C, -13.6C), and humidity (52%, 4%) with what I would expect from the two above data points. Not sure what is in all of those x's, but at least probably battery.
Maybe that is what you already have identified, but my compiled version gives incorrect decoding.
Adding more data points with a different analysis (row 4 is from the pull .c file).
ID and Chan and temp are definitely correct. Is the humidity 2x the measurement? (i.e. row 4: 124/2=62% same as in .c file)
https://triq.net/bitbench#c=6d%2000%20f6%2066%200d%2000&c=6d%200f%2078%205e%2001%2000&c=af%200f%20a2%207c%2001%20c0&c=6d%2000%20bf%207c%2000%2000&c=9b%2001%2011%2062%2007%20c0&c=9b%2011%2011%2062%2008%2000&c=9b%2021%2011%2062%2008%2040&f=ID%3Ad%20CH%3Ah%20TEMP_C%3A12s%20HUM%3Ad%20CRC%3A8h%20%7C%208h&cw=4
At a quick glance I'd say int humidity = ((b[3] & 0xf0) >> 3);
is a typo, it should be int humidity = ((b[3] & 0xfe) >> 1);
(or simply int humidity = (b[3] >> 1);
)
Is there a good resource/tutorial for coding the results from the bitbench?
i.e.:
ID:d CH:h TEMP_C:12s HUM:d xxxxxxxx xxxxxxxx
Trying to use as a learning exercise. Thanks!
We have the template https://github.com/merbanan/rtl_433/blob/master/src/devices/new_template.c Not much about converting bits in there though.
I'll have another go and compile tonight, unless you get there with the fix first!
I got the temperature and humidity working with the following replacing lines 64-67. Thanks for the suggestions!
int temp_raw = (((b[1] & 0x0f) <<8) | (b[2] & 0xff)); // combine bits
float temp_c = (int16_t)(temp_raw - ((temp_raw & 0x800) <<1)) * 0.1f ; // sign bit
int humidity = (b[3] >> 1);
or following the example from here: https://github.com/merbanan/rtl_433/blob/master/src/devices/generic_temperature_sensor.c
temp_raw = (int16_t)(((b[1] & 0x0f) << 12) | ((b[2] & 0xff) << 4));
temp_c = (temp_raw >> 4) * 0.1f;
int humidity = (b[3] >> 1);
Seems like there remains some problems in checksum.
Any idea how to get the checksum working properly?
In bitbench here I see that the ID, CH, TEMP_C, HUM all work out nicely with this scheme:
ID:8d CH:4h TEMP_C:12s HUM:7d x xxxx CRC:6d xxxxxx
according to the presumed structure:
Byte: 0 1 2 3 4
Nibble: 1 2 3 4 5 6 7 8 9 10 11
Type: IIIIIIII ??CCTTTT TTTTTTTT HHHHHHH? FFFFXXXX XX
6d 0 f6 66 0d 0 ID:109 CH:0 TEMP_C:246 HUM:051 CRC:52 = 65
6d 0f 78 5e 1 0 ID:109 CH:0 TEMP_C:-136 HUM:047 CRC:04 = 69
af 0f a2 7c 1 c0 ID:175 CH:0 TEMP_C:-94 HUM:062 CRC:07 = 84
6d 0 bf 7c 0 0 ID:109 CH:0 TEMP_C:191 HUM:062 CRC:00 = 64
9b 1 11 62 7 c0 ID:155 CH:0 TEMP_C:273 HUM:049 CRC:31 = 50
9b 11 11 62 8 0 ID:155 CH:1 TEMP_C:273 HUM:049 CRC:32 = 40
9b 21 11 62 8 40 ID:155 CH:2 TEMP_C:273 HUM:049 CRC:33 = 45
But, as you can see the CRC add result does not work out. Any idea based on experience how to fix this? Thanks!
I see this works now (based on your issue - missed that) :
ID:8d CH:4h TEMP_C:12s HUM:7d ?5b CRC:6h xxxxxx
side note: CRC is a specific kind of checksum, here it's not a CRC but a plain sum (addition with carry).
I am finding a lot of missed decodes due to miscalculation of the checksum. Based on a lot of samples, it looks like decoding only works where the last two bits are 00.
For example the following gets decoded properly (presumably because the last two bits are zero):
{42} 4b 0f 6e 64 0f 00 : 01001011 00001111 01101110 01100100 00001111 00 ==> ID:075 CH:0 TEMP_C: -146 HUM:050
While the following had add_nibbles(b,4)=59
and chk=((b[4] & 0x0f) << 2) | (b[5] & 0x03)=56
and does not get processed (possibly because of the last two bits not being zero):
{42} 4b 0f 6d 64 0e c0 : 01001011 00001111 01101101 01100100 00001110 11 ==> ID:075 CH:0 TEMP_C: -147 HUM:050
Anyone see how to change the calculations so that it works in both circumstances?
A typo, that should really be int chk = ((b[4] & 0x0f) << 2) | (b[5] >> 6);
i.e. the top 2 bit, not the bottom ones.