merbanan / rtl_433

Program to decode radio transmissions from devices on the ISM bands (and other frequencies)
GNU General Public License v2.0
5.98k stars 1.3k forks source link

Support for Auriol AFT 77 A1 temperature sensor #1422

Open aguedob opened 4 years ago

aguedob commented 4 years ago

Hi all,

I've just bought this outdoor temp sensor and after taking several samples I managed to identify the temp using rtl_433:

The second and the third byte (f4 01 34 02 27 c0 in this sample) represents the current temperature (0x134 -> 308 -> 30.8 degrees)

p_limit: 143 bitbuffer:: Number of rows: 12 [00] {42} f4 01 34 02 27 c0 : 11110100 00000001 00110100 00000010 00100111 11 [01] { 1} 00 : 0 [02] {42} f4 01 34 02 27 c0 : 11110100 00000001 00110100 00000010 00100111 11 [03] { 1} 00 : 0 [04] {42} f4 01 34 02 27 c0 : 11110100 00000001 00110100 00000010 00100111 11 [05] { 1} 00 : 0 [06] {42} f4 01 34 02 27 c0 : 11110100 00000001 00110100 00000010 00100111 11 [07] { 1} 00 : 0 [08] {42} f4 01 34 02 27 c0 : 11110100 00000001 00110100 00000010 00100111 11 [09] { 1} 00 : 0 [10] {42} f4 01 34 02 27 c0 : 11110100 00000001 00110100 00000010 00100111 11 [11] { 0} :

Would be great if someone can help supporting it.

Thanks!

zuckschwerdt commented 4 years ago

Can you grab some codes with slightly varying tempertures so we can see if there is a checksum in the last bytes? (just the {42} f4 01 34 02 27 c0 lines will do. Also try to grab a good sample with -S all (read it back in with -r g00... to check) and attach here as zip.

merbanan commented 4 years ago

Hi follow this instruction and we can add support:

https://github.com/merbanan/rtl_433/blob/master/docs/CONTRIBUTING.md#supporting-additional-devices-and-test-data

aguedob commented 4 years ago

I've attached a zip file with some samples and a txt file with the matching temps in C degrees.

AFT77A1.zip

Let me know if you need more samples. Thanks!

evilpete commented 4 years ago

@merbanan.
I was taking a look at this and noted there is reoccurring demodulation error in all the samples

Running the command :

rtl_433 \
    -f 433.92M -s 250k \
    -R 0 -a 4 \
    -W output.sr \
    -r g004_433.92M_250k.cu8 

See the highlighted (1st frame break) area in the attached screen shots Screen Shot 2020-07-04 at 7 43 22 PM

Here is a closeup :

Screen Shot 2020-07-04 at 7 51 43 PM

Enjoy.... :-)

evilpete commented 4 years ago

The breakdown so far :

                       temp_C                           sync         temperature  pad?    Checksum?
g0XX_433.92M_250k.txt: 30.8     : {42}f40 134 0227c     111101000000 000100110100 000000100010011111 00
g001_433.92M_250k.txt: 26.2     : {42}f40 106 02278     111101000000 000100000110 000000100010011110 00
g010_433.92M_250k.txt: 23.7     : {42}f40 0ed 022c8     111101000000 000011101101 000000100010110010 00
g009_433.92M_250k.txt: 23.6     : {42}f40 0ec 022c4     111101000000 000011101100 000000100010110001 00
g008_433.92M_250k.txt: 23.4     : {42}f40 0ea 022bc     111101000000 000011101010 000000100010101111 00
g007_433.92M_250k.txt: 23.3     : {42}f40 0e9 022b8     111101000000 000011101001 000000100010101110 00

for temperatures 23.3 -> 23.7 the checksum increments by one implying is it is a xor checksum of some type

zuckschwerdt commented 4 years ago

@evilpete That glitch is the boundary between sample buffers. I'm not sure if this really disturbs demod or is just an artifact of the data dumper?

zuckschwerdt commented 4 years ago

@aguedob the checksum isn't obvious, can we get more codes? Perhaps run rtl_433 with an added 2>&1 | grep ' {42} f' >mylogfile.txt

aguedob commented 4 years ago

Sorry @zuckschwerdt, I've been out for a couple of days. I attached a file with more codes. I hope it helps you verifying the checksum. I tried to put the outdoor sensor in the fridge to get wider range of temp samples :)

samples.txt

evilpete commented 4 years ago

@aguedob @zuckschwerdt

Ok I have the checksum worked out for when the 9th bit is '1' and 8th bit is '0' (38.3 C -> 25.6 C ) but i need more samples for when the 9th bit is '0' (<25.6C) and bit 6->8 differ under 16.8 C ( in the fridge ? )

This works when the 9th bit is '1' and and 8th bit is '0' :

t = int(bbuf[14:24], 2)             # temperature as 9bit int
csum = 0b10000000                   # 8th bit always 1 ?
csum ^= t & 0x000f                  # apply lower nibble to checksum
if t & 0b100000000 :                # if 9th bit is 1
   i = t & 0b111110000              # take upper nibble + 9th
   i ^=  (t & 0b100000000) >> 1     # Xor 9th bit with 8th bit from upper nibble ??
   csum ^= i >> 4                   # apply mutilated upper 5bit nibble to lower nibble of checksum

this was done with trial and error, I am sure I can simplify once I see the "full picture"

over 38C would be good also when the 9th and 8th bits are both '1' ( direct sunlight? )

evilpete commented 4 years ago

@aguedob

Ok this works for when the first 3 bits are 010 011 and 100 (17.5C -> 31.9C) anything outside that temperature range is unknown until I get a more complete sample set.

t = int(bbuf[12:24], 2)            # temperature as 12bit int
csum = (t ^ t >> 1) & 0b10000000   # bit 9 ^ bit 8 -> bit 8 (guesswork) 
csum ^= (t & 0b001000000) >> 4     # bit 7 -> bit 3
csum ^= (t & 0b010000000) >> 7     # bit 8 -> bit 1  (total guesswork) 
csum ^= (t & 0b010000000) >> 2     # bit 8 -> bit 6
csum ^= (t & 0b100000000) >> 5     # bit 9 -> bit 4 (guesswork)
if t & 0b100000000 :
    csum ^= t >> 4                 # upper nibble +1 xored to lower nibble
csum += t & 0x000f

I am sure I can simplify once I see the "full picture"

aguedob commented 4 years ago

I wasn't able to get temps these days outside that range (17.5-31.9C). It's really warm here :). I will try this weekend to check if Im able to force more extreme values

evilpete commented 4 years ago

@aguedob

have you considered placing the sensor in the fridge and/or in direct sunlight?

The manual states the supported temperature range is -20 °C to +60 °C.

60.0C would be stored as an 10bit number 1001011000 -20, stored as 2's complaint thus would require minimum 11 bits, i'm gonna guess 12bit as that is standard

aguedob commented 4 years ago

@evilpete

I managed to get some colder samples:

11.2C - {42} 03 00 70 02 23 80 : 00000011 00000000 01110000 00000010 00100011 10 12.8C - {42} 03 00 80 02 23 c0 : 00000011 00000000 10000000 00000010 00100011 11 13.9C - {42} 03 00 8b 02 26 80 : 00000011 00000000 10001011 00000010 00100110 10 14.8C - {42} 03 00 94 02 25 00 : 00000011 00000000 10010100 00000010 00100101 00 15.7C - {42} 03 00 9d 02 27 40 : 00000011 00000000 10011101 00000010 00100111 01 16.4C - {42} 03 00 a4 02 25 40 : 00000011 00000000 10100100 00000010 00100101 01

I hope these samples help. I tried to put it in the freezer and reached -5C, but I think was not a good idea. It stops sending data after a while and after removing and setting again the batteries, it's sending data every 2-3 secs instead of every minute as before. Trying to check what went wrong there :)

Finally solved it after leaving without batteries some minutes. Definitely, it didn't like to much the freezer XD

aguedob commented 4 years ago

More samples at direct sunlight (between 36-37C):

{42} ba 01 72 02 28 c0 : 10111010 00000001 01110010 00000010 00101000 11 {42} ba 01 6e 02 2b 80 : 10111010 00000001 01101110 00000010 00101011 10 {42} ba 01 6f 02 2b c0 : 10111010 00000001 01101111 00000010 00101011 11 {42} ba 01 71 02 28 80 : 10111010 00000001 01110001 00000010 00101000 10 {42} ba 01 73 02 29 00 : 10111010 00000001 01110011 00000010 00101001 00 {42} ba 01 75 02 29 80 : 10111010 00000001 01110101 00000010 00101001 10 {42} ba 01 76 02 29 c0 : 10111010 00000001 01110110 00000010 00101001 11 {42} ba 01 78 02 2a 40 : 10111010 00000001 01111000 00000010 00101010 01 {42} ba 01 77 02 2a 00 : 10111010 00000001 01110111 00000010 00101010 00

evilpete commented 4 years ago

thanks. this will keep me busy.

evilpete commented 4 years ago

@aguedob

does the first byte change with the temperature? or with time or something?

it is different in every batch but is unchanged in within each sample.

evilpete commented 4 years ago

Ok.. the "crc" is a generated by adding constant to the temperature, this "constant" increments by 1 every 1.6 degrees ( int 16 ), this "constant" also shifts by 29 or 17 so at a semi regular intervals that I still need to pin down.

a few samples in the 32C or 34C and 14.X range can help,

current data set: (approximate)

14? -> 159 add 144    at 15.8C CRC = 158 + 144 = 302
160 -> 175 add 161
...
224 -> 239 add 165
240 -> 255 add 181
256 -> 271 add 152    at 26.1C CRC = 261 + 144 = 405
272 -> 287 add 153
288 -> 303 add 154
304 -> 319 add 155
...
352 -> 367 add 160
368 -> 384 add 161
...
????
evilpete commented 4 years ago

UPDATE: I think I have a working model for 0°C thru 50°C

I have no idea what todo, or what kind of binary number to expect below 0°C( supported temperature range is -20 °C to +60 °C )

# python 
t = int(bbuf[12:24], 2)    # temperature as 12bit int

# code not covering below 0
i = t >> 4.       # discard lower nibble
if i < 10:        # 16.°C
    csum = 135
elif i < 16:      # 25.6°C
    csum = 151
elif i < 20:      # 35.1°C
    csum = 136
else:
    csum = 138

csum += i
csum += t & 0x000f   # add lower nibble

I am unsure if this is correct over 51.3°C when the 10th bit is gets set since the constant changed with the 9th bit

Also the first byte seems to change with every sample set, but be constant with in the set,
byte 3 seems to be a constant, i'm guessing it's padding for a optional humidity sensor.

evilpete commented 4 years ago

@aguedob @merbanan

I have enough to throw something together that should mostly work between 0°C -> 51.3°C.

I have no clue what to do with the 1st & 4th byte, but should be able to detect / validate a data frame by length and "CRC"/checksum.

What setting are you using to acquire demodulated samples (yea I can figure it out from the ,cu8 files you posted but i figured i'd ask as you're working with live data for the gap sync & reset settings

zuckschwerdt commented 4 years ago

Great detective work to get something out of that mess of bits ;) There should be some general mechanism to make the bits "naturally" give up the temperature number. Ideas are "remove parity bits", "4-to-5 encoding", ... but that's just hints, not even guesses. What is the timing spec here, did I overlook that? Do we have an .ook file for https://triq.org/pdv/ ?

evilpete commented 4 years ago

@zuckschwerdt

I am putting together a driver now, I'll submit a pull request with what I have in day or to.

If you are interested, I've attached the python3 script I wrote to "display" the data as I analyzed it.

If you can figure out how to derive the checksum base number/mask (or whatever you want to call it) without hardcoding it will help.. I think I've been starring at it too long to see it...

aft_csum_test.py.gz

I've been working off data sample provided by @aguedob that have been posted to this thread

evilpete commented 4 years ago

created a pull request with the current checksum knowledge #1438

aguedob commented 4 years ago

I will try again once I have some time to get negative temperatures and post here the samples. Thanks again for your great effort, @evilpete.

zuckschwerdt commented 4 years ago

Prepending 6 bits to align the checksum yields some success with revdgst. It looks like a broken LFSR: Every data bit toggles one bit in the checksum with a pseudo key stream of five bits shifting left, e.g. (excluding prepended 0-bits) 80 -> 08 -> 10 -> 20 -> 40 -> 80 … seems to work out. Note that this assumes bits read in opposite direction (bit reflect) and a final xor of 0x7c (but chk_computed ^ chk should be some constant anyway). Not sure what to make of this. @evilpete can you run this idea in your Python test and compare?

evilpete commented 4 years ago

FYI: my samples ranges are : 11.2,12.8, 13.9,14.8, 15.7, 16.8, 17.5, 22.4 -> 23.7 , 25.6->31.1, 36.6->37.6

evilpete commented 4 years ago

@aguedob

have you reset / change batteries in the sensor between the times you took the samples? if so then the first 8bit is the ID that changes on power-loss (common behavior for some sensors)

aguedob commented 4 years ago

Yes, I swapped the batteries between tests. Also repaired it with the main unit.

— Andrés Guerrero andres@meigal.com

On 21 Jul 2020, at 08:13, Peter Shipley notifications@github.com wrote:

 @aguedob

have you reset / change batteries in the sensor between the times you took the samples? if so then the first 8bit is the ID that changes on power-loss (common behavior for some sensors)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

evilpete commented 4 years ago

Thansk, I'll mark the first 8bits as the "Id"

aguedob commented 4 years ago

Hi @evilpete. I downloaded your branch and seems that there's some issue with the checksum. Here are two samples: aft77a1_callback packet{42} ba 01 38 02 29 40 : 10111010 00000001 00111000 00000010 00101001 01 aft77a1_callback checksum_dat = 165 00A5{ 8} a5 : 10100101 aft77a1_callback temp_raw = 312 0138 buf = 1 0038{16} 01 38 : 00000001 00111000 aft77a1_callback chk_sum{ 8} a3 : 10100011 aft77a1_callback: checksum 163 != 165

aft77a1_callback packet{42} ba 01 39 02 29 80 : 10111010 00000001 00111001 00000010 00101001 10 aft77a1_callback checksum_dat = 166 00A6{ 8} a6 : 10100110 aft77a1_callback temp_raw = 313 0139 buf = 1 0039{16} 01 39 : 00000001 00111001 aft77a1_callback chk_sum{ 8} a4 : 10100100 aft77a1_callback: checksum 164 != 166

Let me know if you need more data.

evilpete commented 4 years ago

thanks.. (I'm not surprised)

take a look at the my samples ranges above, any large gaps have the potential to miss a transition

evilpete commented 4 years ago

@aguedob

UPDATE: yea, the ID (first byte) has an minor effect. I didn;t see this before because each sampled temperature range has a unique first byte without overlap. The error between two samples crc with equal to Xor'ing the two different first bytes then Xor the upper nibble & lower nibble of the result

I'll have to stare at this over the weekend to derive a formula modification.

in the mean time, please send more sample the more the better to test against

aguedob commented 4 years ago

@evilpete

More data attached. Samples from 22.9 to 40 degrees. It's a verbose output, so you can check your checksum vs the received one. It seems that above 32C, the checksums are fine.

datawithchk.txt

Thanks again for your help!

evilpete commented 4 years ago

@aguedob

It seems that above 32C, the checksums are fine.

I Suspect the samples i work with above 32C have the same first byte / ID your device Is currently using (kinda sounds obvious when i say it)

If you were to remove the batteries (reseting the ID) i bet crc's above 32 will not work anymore.

Thanks again for the puzzle

aguedob commented 4 years ago

I Suspect the samples i work with above 32C have the same first byte / ID your device Is currently using (kinda sounds obvious when i say it)

If you were to remove the batteries (reseting the ID) i bet crc's above 32 will not work anymore.

You were totally right. I removed the batteries for a while and now none of the samples get the right checksum. More data attached.

newdatawithchk.txt

evilpete commented 4 years ago

thanks ( I am getting closer)

evilpete commented 4 years ago

Still need samples under 0°C

Also new ID's crossing 25.6°C (behavior changes with the 9th but)

Also

evilpete commented 4 years ago

I am getting closer. can use more with new IDs in the range. crossing the 25.6° mark (there a change in the bit suffering at 25.6° as the 9bit is set

aguedob commented 4 years ago

I've been out some days. I will try today to get some samples below 0 degrees and some crossing 25.6

evilpete commented 4 years ago

@aguedob take your time, we'll crack this eventually and discover it was something annoyingly trivial

Celphor commented 3 years ago

I can add the following observations:

The first 8 bits are a rolling device ID. It not only changes when changing batteries. Maybe every day or so. The next 4 bits are (abcd): a : battery low (1), battery ok(0) => verified using one old and one good battery b : always 0 cd : 00 = Channel 1, 01 = Channel 2, 10 = Channel 3 (can be set on the device) Next 12 bits are the temperature in twos complement, so negative values have a 1 high bit. Subtract one and invert all bits for the absolute value.

The rest is ??? for now

There is no difference in code when pressing the submit button in the case compared to the automatic submission

zuckschwerdt commented 3 years ago

@Celphor great! If you are testing this, 2's complement on 12 bits is also easy to get with

int temp_raw = (int16_t)((b[1] << 12) | (b[2] << 4));
float temp_c = (temp_raw >> 4) * 0.1f;
gdt commented 10 months ago

Status? Does this work with up-to-date git master? The PR above is still DRAFT and thus won't really be looked at. Is anybody looking at this?