Cracking Weather Station Checksum

[BaronVonSchnowzer] is spinning up some home automation and settled on an inexpensive ambient temperature sensor which is sold to augment the data a home weather station collects. He found that the RF protocol had been reverse engineered and will use this information to harvest data from a sensor in each room. In true hacker fashion, he rolled his own advances out to the Internet so that others may benefit. Specifically, he reverse engineered the checksum used by the Ambient F007TH.

He got onto this track after trying out the Arduino sketch written to receive the sensor’s RF communications. One peculiar part of the code turned out to be a filter for corrupt messages as the protocol’s checksum hadn’t yet been worked out. Figuring out how the checksum byte owrks wasn’t an easy process. The adventure led him to dump 13k samples into a spreadsheet to see if sorting similar sets of 5-byte message and 1-byte checksum would shed some light on the situation. The rest of the story is some impressive pattern matching that led to the final algorithm. Now [BaronVonSchnowzer] and anyone else using these modules can filter out corrupt data in the most efficient way possible.

7 thoughts on “Cracking Weather Station Checksum

  1. The reverse-engineered checksum code makes me think that the original code was intended to be a CRC, written by someone who didn’t understand CRCs. It does the LFSR thing, but the message doesn’t actually feed into the LFSR itself. Weird.

    1. It’s the same thing, just written a different way. It’s a property of the CRC method that any bit flip in the message, flips a number of bits in the checksum, independent of other bits.

      1. Oooh, now I’ve got to think hard… ah, yes, I think you’re right. Thanks!

        It’s not like a ‘normal’ CRC, in that appending a pile of zeros on the end doesn’t change the CRC value calculated. However… So, ‘mask’ holds powers of two modulo the primitive polynomial, and these get added into ‘checksum’ as needed… is this just CRC calculated least-significant-bytes first, rather than most-significant-bytes first? I guess that explains why trailing zeros make no difference, if that just means you’re adding zero leading digits?

        I don’t suppose you’ve got any references on this approach, have you? A quick google failed for me. Or have I just missed the point?


Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.