Adding a pool pump to Homeassistant (The disadvantage of closed IoT Eco-systems and “hacking” a Smart Home App to do so)

Adding a pool pump to Home Assistant is usually not that difficult. There are many smart plugs available that almost work with Home Assistant out of the box, like the Shelly Plug or the TP-Link Kasa plugs. However, there are some plugs that are a bit more difficult to use, mostly because of the manufacturer’s decision to limit them to their own ecosystem.
In my case, I have a Luminea smart plug that is only compatible with Tuya. It does not support any other protocols like MQTT, and the app that was used to initially configure it is no longer available on the iOS App Store. Of course, there is always the option of resetting it and using it with another Tuya-compatible app, but where’s the challenge in that? I could also buy a Shelly Plug and configure it, but what do you really learn by doing so?
So here is my challenge:
- Understand how the Tuya Ecosystem work
- Install the App in an android emulator
- Extract the keys
- Code a bridge to control it via MQTT
- Deploy
- Enjoy
1. What is Tuya?
Tuya is a Chinese company, which founded an Internet of Things (IoT) platform back in 2014. This cloud-based platform enables manufacturers to quickly and easily create and manage smart devices, such as plugs, lights, cameras, and other home automation products.
They provide ready-made solutions for smart device development, including hardware modules, firmware, and software development kits (SDKs). This allows manufacturers to rapidly design and prototype smart products without having to build the technology from scratch. In addition to that, Manufacturers can use Tuya’s firmware templates and customize them to suit their product needs. They also provide a white-label mobile app platform, allowing manufacturers to quickly deploy branded apps without needing to develop their own.
There are many devices out there, that use Tuya because of its Wide Range of Compatible Devices, Ease of Use, its Interoperability with Major Smart Home Platforms, Scalability and Automation features.
if you want to quickly setup a handful of plugs, turn on a pump every night or monitor energy consumption without the hassle of setting up a server or even the know-how of doing such things, this is a not so bad system to use.
If you don’t want to be dependent on Chinese infrastructure and want easy integration with other ecosystems, Tuya is probably not the solution. Additionally there is always the possibility of them shutting down their services and you ending up with a bunch of unusable electronic waste. This of course applies to all closed ecosystems.
I also want to mention, that Tuya can use different protocols and implementations for each protocol may very. This article is focused on WiFi Tuya devices because that’s what I have.
How does Tuya over WiFi work?
When I started the project, I had no Idea that Tuya even exists. All I had is a configured smart plug that I am not allowed to rest or re-flash. So the first thing I did was scanning the ports with nmap:
tarting Nmap 7.80 ( https://nmap.org ) at 2024-08-03 21:20 CEST
Nmap scan report for 10.110.0.125
Host is up (0.086s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
6668/tcp open irc
Nmap done: 1 IP address (1 host up) scanned in 2.96 seconds
As you can see, there is only one port open. Port 6668 which is typically used for Internet Relay Chat (IRC). I was surprised at first. I have heard about botnets being controlled over IRC but never smart home devices. Ironically the Botnet Mirai targeted IoT devices, so there is some distant connection but none that plays any role here. Further investigation revealed, that port 6668 is also used by Tuya to control IoT devices. The protocol is used to setup and configure the device and can also be used to query the status and set properties on the device. Once the device is setup, it connects to the Tuya cloud which allows access to these device from all around the world. Unfortunately, this communication is encrypted. There are some people who already wrote library to decrypt/encrypt those messages. We will take a look at this later. For now, let`s continue to investigate.
Since this is the only way in, lets have a look at what going out. I enabled a packet sniffer for all packets that are sent by or sent to this device but there is not much going on:

There are a lot of broadcast packets sent out to port 6666, most likely to announce it’s presence to apps in the network and some ARP stuff. Port 6666 is used to broadcast the device information to all devices in the network. A smartphone app can use this information to discover new devices and get the ip address of a specific device. This will help us later. For now, there is one connection to 18.184.187.186 on port 1883. This one is more interesting. Port 1883 is used by the Message Queuing Telemetry Transport (MQTT) Protocol. This is used to send status updates and receive commands.

A quick search on Shodan revealed nothing of interest. An AWS Instance running in Frankfurt am Main.
Opening the capture in Wireshark verified that this is indeed an MQTT connection but no data was transferred. Only a ping.
An uneasy feeling
There is something about those closed Ecosystems that makes ma feel uneasy. A device in my network, which won`t receive security updates, constantly talking to external servers, waiting for commands. No way of knowing, what this device is capable of or if it has vulnerable APIs, weak passwords, limited security integration as it is often the case in the IoT world. And this black box runs in your network 24/7 and can be abused to run a botnet or spy on your network.
My analysis concluded that this is not the case here, but this has been the case in the past and in the interconnected and digitalized world we live in, with smart appliances all around (fridges, TVs, phones,…) my smart-plug is probably the least significant issue. For example: hacked baby cameras, smart TVs watching your activities, or smart speakers listening to your conversations.
If you want to be secure, these closed Eco-Systems are difficult to put behind a firewall without breaking their functionality.
So how can I talk to this device?
The way to go is over port 6668 using the Tuya custom protocol. There is a useful implementation for JavaScript called TuyAPI. The Library listens to those UDP broadcast packets on port 6666 to identify all present devices on the network. It then determines the unique ID and IP of each device and stores it in a table.
If I create a device and dump the object to the console, I can see all devices present on the network:

To finally connect to the device, all I need is the id, which I already extracted from the network, and the key. And this is where the next issue starts. I don’t have the key. The key is setup once during the first installation and registration with on of those Tuya apps. The only way to retrieve those is to either reset the plug, which would kick out all other users, or to somehow extract the data from the app.
Without these keys, I was only able to read some information from the plugs but unable to change the power state or other properties.
The next step was to get the credentials for the app and try to login and find out if there is a ways to retrieve the keys. The app in question is called ‘iO.e’. I tried to install it on my iPhone but unfortunately it was no longer available in the German AppStore. Why? i don’t know, but I found some APK files for android. Since I don’t have an android device, I decided to install an Android Emulator on my machine and try to run the app inside the emulator.
The painful experience of installing an android emulator
After some research, I decided to install Anbox, an android emulator for Linux. There is plenty of documentation available and it seemed like a good option. Unfortunately, there was no package available for my distro so I tried to compile it from source. After some tweaking, it compiled successfully but I was not able to run anything on it. Not even the operating system. Anbox being unmaintained since 2017 just was not compatible with PopOS 22.04. Next up was Waydroid. Installation was much easier with an official repository available. You can check out the installation Instructions here.
If you want to avoid the painful experience I had, here is the way I got it working.
First of all, you have to install the Waydroid package:
sudo apt install curl ca-certificates -y
curl https://repo.waydro.id | sudo bash
sudo apt install waydroid -y
Do not forget to initialize the Waydroid. This will download the android image and can take a while.
sudo waydroid init
#in case you need you use iptables instead of nftables:
sudo sed -i~ -E 's/=.\$\(command -v (nft|ip6?tables-legacy).*/=/g' \
/usr/lib/waydroid/data/scripts/waydroid-net.sh
sudo systemctl restart waydroid-container.service
Next step was to compile the missing kernel modules for ashmem and binderfs. The original source files from the Anbox rep (https://github.com/anbox/anbox-modules.git) would not compile on my OS. I found another repo with a fix: https://github.com/choff/anbox-modules.git
git clone https://github.com/choff/anbox-modules.git
cd anbox-modules
./INSTALL.sh
lsmod | grep -e "binder\|ashmem"
binder_linux 221184 0
ashmem_linux 16384 0
Success, but when I started Waydroid, I received the following error message:
22:42:47] Starting waydroid session
[22:42:47] WAYLAND_DISPLAY is not set, defaulting to "wayland-0"
[22:42:47] Wayland socket '/run/user/1000/wayland-0' doesn't exist; are you running a Wayland compositor?
I’m running Xorg but Waydroid is only compatible with the Wayland window manager. Of course I read it before but I tried it anyways and there is always the option of running it using Weston, which is a reference Wayland implementation. You can pass different screen resolutions to Weston to resemble to configuration of an standard phone in horizontal orientation:
sudo apt install weston
weston --xwayland --width=720 --height=1000 &
export WAYLAND_DISPLAY=wayland-0
sleep 2
waydroid show-full-ui

Here we go! Almost there. Only thing left was to install the iO.e App!

Looking around in the app revealed nothing of interest. No device IDs, no keys, no API keys. Only a network test which further underlines that this app is basically a variant of the Tuya app and it communicates with the Tuya-Servers in the background. This was a dead end, but I had another Idea. Since this basically connects to the Tuya servers, the app must know the device IDs and keys and maybe it is dumb enough to store them on the device… So I had a look at the file system:

This XML file contains all IDs, Keys, Schemas. Everything I need! HUGE Success! Only one more thing to do: Convert it into a format I can read. The original file contains an XML entry containing an URL encoded JSON string. Nothing to difficult to convert into an usable format:
WAYDROID_ROOT_FS="$HOME/.local/share/waydroid/data/data/com.iosmart.app/shared_prefs"
sudo bash -c "grep s_home_data $WAYDROID_ROOT_FS/preferences_global_key* > /tmp/dump.raw"
sudo chown $USER /tmp/dump.raw
ls -l /tmp/dump.raw
Now remove the url encoding and the remaining XML elements:
sed -i 's/\"\;/\"/gm' /tmp/dump.raw
sed -i 's/^.*deviceRespBeen/\{\"data/' /tmp/dump.raw
sed -i 's/<\/string>$//' /tmp/dump.raw
And dump the file:
jq '.' /tmp/dump.raw

We have IDs and Keys. Now I can start writing the software to integrate it into home assistant or pretty much any other home automation platform.
The next step …
In the next article, I will show you how I implemented an Tuya to MQTT bridge to onboard this plug to Homeassistant. If you have any questions, feel free to comment or contact me.
Thanks for reading!
Leave a Reply