Cutting the ☁️ away
The initial aim of this project was to create a visual narrative on the displays of smart home temperature sensors. Think of it like the visuals at the top of the website. Each dot that materialises on a screen symbolises a unit sold, representing the effort of an individual behind that product. Every ten minutes represents a month’s sales.
With this vision, I started on a journey trying to modify a temperature sensor to access its display. It all started with learning about Tuya Convert.
Learning about Tuya Convert
Tuya Convert is an open source project for flashing firmware on Tuya-based devices. The exploit was discovered by Michael Steigerwald, the founder of VTRUST, a German IT security startup. He presented the exploit during a talk at 35C3 in Leibzig. After the talk, VTRUST worked with the German tech magazine c’t to refine the exploit and subsequently open source it on GitHub.
In particular, Tuya Convert helps you with flash the Tasmota firmware wirelessly (often referred to as over-the-air). Tasmota, an open source firmware tailored for devices equipped with the ESPXXXX WiFi chip, enables users to locally manage their devices without relying on cloud integration. It allows for creating automations and installing customized firmware. Tasmota offers a wide range of APIs for data points, even for screen-based devices such as the temperature sensors.
Knowing Tasmota’s ability to control screen-based devices, I was confident that I could flash a temperature sensor with custom firmware. To be on the safe side, I ordered a selection of different temperature sensors from Aliexpress. I ended up with the following devices:
Device | Price (€) | Source |
---|---|---|
TH08 | 7,26 | Aliexpress |
TH1 | 2 pieces for 17,03 | Aliexpress |
TH05 | 4,94 | Aliexpress |
WL-WIFI-HT | 21,99 | Amazon |
SNZB-02D | 13,65 | Aliexpress |
KCTW1Z-02 | 14,47 | Aliexpress |
Several of the devices in my order were ZigBee based. Because they use the ZigBee protocol rather than WiFi, they couldn’t be reprogrammed using Tuya Convert. The other devices communicated via WiFi and were therefore theoretically compatible with the Tuya Convert exploit.
Following the instructions in the README, I tried the exploit on each device. Each one failed, not one device was compatible with the Tuya Convert exploit. By dismantling the sensors, I discovered that none of the devices were based on an ESPXXXX chip. Instead of continuing to rely on the ESPXXXX chips, Tuya switched to their proprietary chips such as CBU or CB3S, which are based on BEKEN chips. This was a big setback, as I cloud not flash the BEKEN chips with Tuya Convert.
Luckily, there was a new open source project on the horizon.
Tuya Cloudcutter
Tuya Cloudcutter is the successor to Tuya Convert for BEKEN-based devices. The exploit discovered found by Khaled Nassar and Tom Clement and Jilles Groenendijk. It works in a similar way to Tuya convert in that it allows someone to flash new firmware to smart home devices over the air. With Tuya Cloudcutter it is possible to flash either ESPHome or OpenBeken firmware, which are similar in use to Tasmota. As ESPHome also has documentation for controlling screen-based devices, I opted for this option.
Again following the instructions in the INSTRUCTIONS.md and HOST_SPECIFIC_INSTRUCTIONS.md, I tried the exploit and this time it worked! The exploit was run on two devices, the TH08 temperature sensor and the WL-WIFI-HT temperature sensor, using the bk7231n-lowpower-common-ty-1.0.10 device profile. This uploaded a firmware called ESPHome Kickstart to the devices, which is a base firmware that enables the subsequent installation of custom ESPHome firmware.
Typically, devices flashed with ESPHome Kickstart would initiate a WiFi access point that hosts a website. This website allows users to set network settings and upload the custom ESPHome firmware. Once completed, the device would be added to the user’s local network and the user would be able to control the device via their ESPHome dashboard.
However, my experience with the two temperature sensors was different. Despite being successfully exploited, neither device would open a WiFi access point. As a result, I was unable to upload any custom firmware and therefore unable to add them to my local network and control them via ESPHome.
Another setback, and this one was even more difficult. Figuring out what the problem was was not easy, as there were many factors at play. It could have been the wrong device profile, something with the device itself or a problem with ESPHome Kickstart. In the end, I learnt that the problem was probably due to the fact that the devices are battery powered. To conserve battery power, the devices only connect to WiFi sporadically. For example, the TH08 temperature sensor connects to the cloud every hour to update its readings. This is probably controlled by the internal RTC, although I cannot prove it. 1
As none of the options to flash the devices wirelessly worked, I had no other option but to open them up and solder some wires to them.
Soldering
To upload the ESPHome firmware directly, you can solder wires to the appropriate pins on the WiFi module and then connect them to a USB to TTL UART converter. This allows the chip to be read and written to via USB.
The ESPHome Kickstart method failed, so a custom ESPHome firmware had to be flashed directly. This firmware had to be created beforehand. f Kickstart had been successful, ltchiptool could have been used to read the datapoints from a device already providing an open WiFi signal. A custom ESPHome firmware could then have been built using this data. However, as this option was not available, an alternative method of creating firmware was used.
To proceed a dumb of the original firmware had to be obtained. Utilizing ltchiptool’s reading function I created a dump of the original firmware of the TH08 temperature sensor. With the help of kuba2k2 and Cossid a device profile was created based on that dum. This profile was also added to the Tuya Cloudcutter project. Once the device profile was added, a firmware could be created using UPK2ESPHome. This website creates a YAML file for ESPHome based on the device profile.
After the YAML file was created, the firmware could be compiled and flashed with the ESPHome CLI using this command:
python -m esphome run yourdevice.yml
The device was now added successfully to my local network and it appeared in my ESPHome dashboard. However, the device was not working as expected. On one hand it very quickly lost connection to the network. This is because of the issue with battery powered devices I already mentioned above. However, this was not as bad because through clicking the button on top of the temperature sensor very often I could keep it awake.
So with that workaround, I was able to keep the device on the network, even if only for a certain time. However, as the device now appears in my ESPHome dashboard, I was able to compile new firmware wirelessly from here and send it to the device.
However, at this point I was still not able to control the unit as I had imagined. This is due to another chip inside the device, the TuyaMCU chip. This chip is responsible for translating the software signals from the WiFi chip and passing them on to the hardware components and vice versa. Unfortunately, this chip cannot be addressed via the ESPHome Flash, which is why I did not get anywhere further at this point.
I tried out some other ways of hacking the device physically, for example I was able to read different data over the control pins of the PCB with an Arduino. But none of the approaches led to really gaining control over the device let alone the screen.
tinytuya
As I was unable to flash firmware or control the device in any other way, I had to find an alternative. Fortunately, I came across another project called tinytuya by Jason Cox. tinytuya serves as a Python API that interfaces with Tuya WiFi devices on a local network, eliminating the need to flash any new firmware.
To connect to the device, it uses various parameters such as the device’s network address (IPv4), device ID, Tuya protocol version, and a unique local key.
To obtain these different parameters I followed the instructions in the README.md. Unfortunately, this step is only possible if the devices are connected to the cloud once. This step is crucial because the local key is generated once the device is connected to the cloud. After that the device can be controlled locally without the need for the cloud.
With the parameters ready, I could then simply write a Python script to read different values from the device. You can find the script in the repository of this project. This is the same script that is used to control how much research is visible on this site.
Acknowledgements
This project would not have been possible without the help of some amazing people from the open source community. ❤
Thanks to digiblurDIY and his Discord family for their helpful hints and messages. Also, without the tutorials from digiblurDIY I would never have gotten this far:
- Tuya CloudCutter & ESPHome Libretuya LibreTiny How To Guide for Beken Chips | No soldering!
- UPDATED Tuya-CloudCutter with ESPHome Beken Devices | How To Guide Home Assistant
- How To Install ESPHome on Tuya Beken BK7231 w/ ltchiptool
Thanks to kuba2k2 and Cossid for helping me create the device profiles for Tuya Cloudcutter. I have never seen anyone respond so quickly to a GitHub issue. ⚡️
Last but not least, thanks to my amazing friends Mohar Kalra, Clemens Hornemann and Omar Zaki for helping me along the way. ❤
If you have questions, ideas or feedback about this project, I would love to here from you! Feel free to reach out.