ThermoPro reverse engineering 1: Nothing ever changes

Summary
- The TP25 presents a single GATT service with a read-write and a read-notify characteristic
- It appears they remain constant, even when the temperature changes
- Clearly the device needs to be prodded somehow in order to provide temperatures
Next steps: Get more into Bluetooth Low Energy
First light
For a while now, I've been quite taken by the idea of getting better at barbecuing. Not necessarily in a strictly Texan or even American sense. Instead, for me it's about being better at controlling a grill, understanding flavours and trying new meats.
With that in mind, when my old simple meat thermometer died, I bought myself a ThermoPro TP25 bluetooth thermometer. I like it! It's a good product. But I wish two things:
- That the range was better. It struggles with the many brick walls of my house. But, realistically, this is a limitation of Bluetooth.
- That I could use it without the app. Maybe through Home Assistant, or some other web-based thing.
I had a decent look on Google and it doesn't seem like anyone has published any code or documentation for the TP25. Various other ThermoPro products yes, but not the TP25. So the only option is to Do It Myself.
Early thoughts
I could see by looking at the Home Assistant codebase, or in
ble_monitor
that other ThermoPro thermometers use Bluetooth Low
Energy, and broadcast the temperature in the advertising packets.
I won't describe the various bits of Bluetooth Low Energy here. For a summary of the crash course I gave myself, see the next blog post
It seemed like a good guess that the TP25 would do the same, or similar.
Node.js and Ubuntu
Since I plan to create some form of web API for the thermometer, I figured I'd start with a Node.js-based script to try
and get the data out. A bit of poking around led me to node-ble
. There are
other Node-based BLE libraries, but I want one that can be used within a Docker container. Since it uses D-Bus,
node-ble
doesn't need direct hardware access, which makes Dockerising it a lot less painful.
After a few false-starts, I got a script that could see the device being advertised, and print out the data from the characteristics. This is great! It's definitely a bluetooth low energy device. I can see a read-write characteristic, and a read-notify characteristic. The data makes no sense yet, but baby steps.
On the other hand I couldn't get it to reliably connect to the device, and any connection dropped after a few seconds anyway. There's also no obvious temperature in the advertisements.
Bah. I know the Wifi/Bluetooth controller in my PC doesn't play great with Ubuntu - for ages the default Intel-provided firmware simply didn't boot the device properly. When that happened it meant no Wifi or Bluetooth. The fix? Delete all firmware files produced after a certain date. (Fortunately, it seems to have been fixed with the newest version).
So I'm suspicious that my trouble is Ubuntu-related.
Switching to Windows
The landscape of Node.js BLE libraries doesn't look so great on Windows. But I know I want a Linux-based solution eventually. So there's no need to write a script - let's see if there's an existing app that can do what I want.
Enter Bluetooth LE Explorer. It's a classic developer's hacked together app - it has a non-intuitive interface and it crashes a lot. But, it does what I want it to do - lets me poke at the thermometer.
Some things stand out.
- It also struggles to maintain a connection to the thermometer
- I can see the same two characteristics as when using Ubuntu.
- I cannot make them change. I spend ages heating and cooling the temperature probes (usually in-between my fingers, sometimes by just holding it in my mouth) but the read-only characteristic remains constant.
- The read-write characteristic doesn't seem to do anything. I try a putting random values into it, but they just stay there - the thermometer doesn't change the value there. Nor does it change the read-notify value.
- The advertising data is just the manufacturer's name - "Thermopro". So unlike other ThermoPro devices, this one definitely doesn't transmit its data in the advertisements. (Or I can't get it to do so...)
- The device isn't keen to hold a connection - a few seconds after each connection its "connected" indicator starts flashing again, indicating that it's waiting for a connection.
So not a huge amount of progress compared to what I already had!
Conclusions
Ultimately, this was a frustrating and chastening experience. I realise:
- I need to send something to the thermometer to get it to send back the data I want. Obviously it's waiting for some special code, or sequence of codes, before it transmits the temperatures.
I also know there's some things I need to work on:
- What does 'connected' or 'paired' mean in this context? It's clearly different to regular Bluetooth.
- Why are passive and active advertising different?
- How can I figure out what the thermometer needs to be told before it sends data?
- I briefly wonder about trying to create a "fake thermometer" in
bleno
to connect the app to, but decide that probably just sniffing the traffic is easier - provided that it's unencrypted!
- I briefly wonder about trying to create a "fake thermometer" in
Which leads me nicely on to a crash course in Bluetooth Low Energy