A few years ago, I bought the XIAOMI Mijia LYWSDCGQ which was nice but not really cheap. Its fun characteristic was its ability to broadcast the data (temperature, humidity, battery) as well as having a connected/polled mode.
And another one
Then XIAOMI released a smaller & cheaper version (LYWSD03MMC) running on 3V lithium batteries. Trouble was, they also introduced a "bindkey". Apparently the idea behind was two-fold: To force people to use the official app only and to avoid broadcasting unencrypted data. Well.... whatever...
It wasn't long before someone found a way to intercept the key. The method was awkward at the begining but the process rapidly became easier.
Security aspects aside, this is absolutely awesome!!!
ESPHome and OpenMQTTGateway
So I decided to try them and started using ESPHome. Even if the technology is Bluetooth Low Energy, the reaching distance is quite impressive.
ESPHome ecosystem is not bad (far from it) but one needs to define all bluetooth addresses and push a new configuration to the gateway everytime a new thermometer is added (or switched from one protocol to another). I quickly grew tired of it and started to use OpenMQTTGateway instead.
The documentation and the different websites/blog/repositories/libraries make it a little bit messy but the product works quite well and the basic idea is simple:
One board (predominantly ESP8266/ESP32 based) is acting as a gateway between a type of device (RF or BLE mainly -- others are also available) and a MQTT broker.
There is nothing to change on the gateway to add new sensors or if you switch from ATC to Xiaomi native protocol (or vice-versa). You only have to select the MQTT messages you want to keep (although there is a white-list feature, should the local laws require filtering).
From an Android Mobile
Aside from the gateway, there is (on Google Play) a handy application called MijiaTemp which is useful to debug and/or check what the sensors are doing.
For information, an new paying one Theengs BLE as appeared recently. I haven't tested it, so I am only mentioning it.
While shopping for a Zigbee receiver (more about it another time), I spotted a fridge sensor Telldus (312716) looking exactly like my F007TH sensors but with a cable and measuring temperature only.
Honestly, the information gathered on different sources about these was totally unclear but I decided to buy one for my chest freezer.
And... obviously, the casing is identical BUT the protocol (F007TP here) is absolutely not compatible with the F007TH. To be clear: they have nothing in common!
Yet, this new sensor was recognised by my RTL-SDR adapter running rtl_433 (but with the wrong temperature -- according to the source code there may be a conflit bitween WH2 & WH5 which are part of the same family).
It appears that the protocol was described more than 10 years ago by Luc Small on his blog, so at least the heavy lifting was done. I only had to use the decoding and CRC calculation in my own code.
As I didn't want to requisition a specific ESP8266 just for one sensor and because it was in the same area as the rain gauge, I decided to merge the decoding functions even if there is very little in common between these 2 applications.
It is unfortunate that the WH2/F007TP protocol doesn't have an easy synchronisation preamble but at least the rain gauge do, so the main loop now checks if there are a number of ~500ns pulses followed by one ~1500ns or if it detects one ~7500ns pulse.
If it's the latter, then it records 64 pulses then calls the rain gauge decoder.
If it's the former, then it records 40 pulses then calls the F007TP decoder.
Having bought a Wireless Rain Gauge from Pearl Diffusion, and since they looked alike, I was hoping that even if the model number was different, its protocol would be similar to the TFA DROP 47.3005 which is implemented/documented by rtl_433.
It turns out that they are similarities (they might come from the same factory) and also quite a few differences.
For reference, here is the inFactory FWS-275 (aka NX-6331-675):
And here the TFA 47.3005 (aka TFA 30.3233.01):
Looking for the data
I decoded several protocols in the past, mainly using dumps of timing on Arduino serial port. Here, the author of the TFA device's code (helped by one of the maintainers of rtl_433) gives a few clues in how to proceed rapidly in the issue associated.
The signal seems to be composed of 2700µS and 970µS pulses with 7340µS synchronisation pulses. One suprising thing is that it doesn't seem to be regular (for example long HIGH + short LOW or the opposite). It is a mix of long HIGH + short/long LOW or short HIGH + short/long LOW). But it we take into account only the HIGH side, it doesn't matter much.
When decoded (PWM slicer), the first chunk is always different (values divided by 2), probably due to a shifted bit. The second and the third are almost identical, except the last byte. Best is to ignore it and see.
bitbench is another handy tool to carry on with the decoding.
One (obvious) difference between the two gauges mentionned above is that the one I own also a outdoors temperature display, so the protocol has to transmit the value.
The 2 first bytes never change except after a change of batteries on the outdoor unit, so it is certainly a random ID.
The third byte follows the pattern 00, 02, 04, 06, 08, 0a, 0c, 0e already found in the TFA unit. Like on the TFA, bit 7 is the battery indicator (tested using a variable power supply to lower the voltage) and bit 6 a reset indicator.
The fourth and fifth bytes seem to be the counter of the bucket tips, using the same weird initial value (-10). More about it later
The sixth and seventh values are the temperature. Since, they didn't really match the Celcius display, I switched the display to Farenheit and in this case a change of value is also a change of display. This mean the transmission is in Farenheit (like in the F007TH protocol) but the encoding is diffent. After toying a bit, it appeared that the format is 16 bits Little Endian and that the value is in tenth of degrees Farenheit with an offset of 900.
Last but not least, the checksum... I was expecting something like on the TFA unit (it took me a while to understand zuckschwerdt's answers to be honnest) but after trying the referenced tools it turns out that the checksum is just that... a sum of the first 7 bytes!
All was fine... except that the main reason of this apparatus is to mesure the amount of rain, and there was not an obvious link between the counter values and the display!
Knowing that the base is 25.4mm (top of the tube on the display), it is almost certain that the mesurement is with imperial units too.
After tiping the bucket (by hand) a few hundred times, it seems that the value is 1 tip = 0.0425 in of rain. Converted in metric, this gives 1 tip = 0.108 mm.
How on earth did they managed to select this kind of value??? Well never mind...
In order to complete and replace the old TX2/TX3 sensors, I found some new ones using a similar technology (still RF 433 Mhz). These are the TFA ref 30.3208.02 and can be bought with a very handy external housing (ref 98.1114.02):
They also come in sets of 3 sensors + a "climate monitor".
(Edit 27/07/2022: PEARL Diffusion's rebranded NX-6185-675 sensors (sold for Infactory FWS-1000 station) are fully compatible too).
The sensors themselves measure and display the temperature as well as the relative humidity. Up to 8 sensors can be used at the same time and their address is set (thus fixed) using microswitches, which is a huge improvement over the previous models (either IDs changing at reboot or limited to 3).
The communication protocol seems to be known as F007TH (from Ambient Weather) and presents 2 singular characteristics:
Various implementations exists and can be found on the Internet; last but not least my version, adaption of one of the different sources and for which I use on a ESP8266 as a gateway to the MQTT broker.
My current ecosystem as a diagram
So far the described ecosystem can be represented as: