tuya2mqtt is a Python script that connects Tuya smart devices to an MQTT broker. It acts as a backend service that maintains a 24-hour TCP connection with registered Tuya devices. This allows it to instantly publish state changes to MQTT and enable device control via MQTT commands.
tuya2mqtt is daemonized with python-daemon to run as a robust and lightweight background process, minimizing overhead and dependencies to maximize performance.
- Tuya Device Control: Device state can be set via MQTT.
- Status Monitoring: Real-time status updates (DPS) are received from Tuya devices and published to MQTT.
- Asyncio: Each device is handled in a separate task for stable, concurrent communication.
- Daemon Mode: Runs reliably in the background, with PID file management to prevent multiple instances.
- Dynamic Device Management: Add or remove devices on the fly using MQTT commands without restarting the daemon.
- Wide Device Support: Control various Tuya devices, including Wi-Fi, Zigbee, and BLE.
tuya2mqtt requires Python 3.8 or later.
Install the package and its dependencies using pip:
pip install tuya2mqttAlternatively, when running from a manual clone, install the required libraries manually:
pip install tinytuya aiomqtt python-daemon- Start: Run the script as a background daemon.
python -m tuya2mqtt --mode start
- Stop: Safely stop the running daemon.
python -m tuya2mqtt --mode stop
- Restart: Stop the current daemon instance and start a new one.
python -m tuya2mqtt --mode restart
- Foreground: Run the script in the foreground. Useful for use with service managers like systemd.
python -m tuya2mqtt --mode foreground
A pre-built image is available on Docker Hub for easy containerized deployment.
Create a tuya2mqtt.conf to change the MQTT broker information.
tuya2mqtt.conf Example:
{
"broker": {
"host": "localhost",
"port": 1883
"username": "",
"password": ""
}
}To add a new Tuya device, publish a JSON payload to the tuya2mqtt/intro/device/add topic.
- Tuya Wi-Fi Device: Requires
ip,key, andversion.idandnameare optional.{ "id": "ebed836691xxxxxxb", "ip": "192.168.1.100", "key": "b4e4776e1f0e21a2", "version": 3.3, "name": "My_Smart_Plug" } - Tuya Zigbee/BLE Device: Requires
node_id, andparent(the hub's ID).idandnameare optional.{ "id": "ebed836691xxxxxxb", "node_id": "01020202111111112222", "parent": "ebed836691xxxxxxb", "name": "My_Sub_Device" }
To control a device or request its status, publish a payload to the relevant topic. A device can be specified by either its id or name.
- Set State: Publish a JSON payload with
data(dict of datapoint: value pairs) to thetuya2mqtt/intro/device/settopic.- Using
id:{ "id": "ebed836691xxxxxxb", "data": { "1": true } } - Using
name:{ "name": "My_Smart_Plug", "data": { "1": true } }
- Using
- Get Status: Publish a JSON payload containing the device's
idornameto thetuya2mqtt/intro/device/gettopic.- Using
id:{ "id": "ebed836691xxxxxxb" } - Using
name:{ "name": "My_Smart_Plug" }
- Using
- Execute Direct Commands (Advanced Usage): To call specific
tinytuyamethods on a device (e.g.,turn_on(),set_value()), publish a payload to thetuya2mqtt/intro/device/commandtopic.- Using
name:{ "name": "My_Smart_Plug", "command": "turn_on", "data": { "switch": 1 } } - Using
id:{ "id": "ebed836691xxxxxxb", "command": "set_value", "data": { "1": true } }
- Using
tuya2mqtt provides two main topics for device monitoring. By subscribing to these topics, real-time updates on device status changes and command history can be obtained.
tuya2mqtt/extra/device/active: This topic is used for instant updates. It publishes when a Tuya device reports a state change on its own, like when a smart button is pressed or a switch is physically toggled.tuya2mqtt/extra/device/passive: This topic is for status reports. It publishes in response to atuya2mqtt/intro/device/getor as a part of a periodic device status check.tuya2mqtt/extra/device/error: This topic is for error messages. It publishes when daemon receives an error message from tuya device.
Data can be received in this format by subscribing to the topic:
$ mosquitto_sub -t tuya2mqtt/extra/device/#{"id": "ebed836691xxxxxxb", "name": "My_Smart_Plug", "data": {"1": true}}
{"id": "ebed836691xxxxxxb", "name": "My_Smart_Plug", "data": {"1": false}}The id field represents the id for Wi-Fi devices and the node_id for sub-devices.
To remove a device from the running instance, publish a JSON payload with the device's id or name to the tuya2mqtt/intro/device/delete topic. The device will be disconnected.
- Using
id:{ "id": "ebed836691xxxxxxb" } - Using
name:{ "name": "My_Smart_Plug" }
To query the daemon's status or manage its state, publish a payload to the tuya2mqtt/intro/daemon/query topic.
-
Query Daemon Status: Request a detailed status report.
{ "status": true }The response, published to
tuya2mqtt/extra/daemon/status, will include uptime, device counts, and a detailed list of all connected devices and their current state. -
Reset All Device Connections:
{ "reset": true }This command terminates communication with all currently connected devices. The daemon process itself remains active, but the
addcommand must be used to reconnect devices. -
Terminate All Connections and Shut Down Daemon:
{ "stop": true }This command is equivalent to
--mode stop. It terminates all device connections and shuts down the daemon completely.
This script is intentionally streamlined and focused on robustness. However, it relies on several external dependencies.
- External Module Dependencies:
tuya2mqttrelies entirely on thetinytuyaandaiomqttmodules. Unexpected updates to these modules can impact the script's stability, so keeping the module versions stable is recommended. - Network Resources: As the number of Tuya devices increases, a large number of TCP connections will be kept alive. This can put a significant load on a router's resources, so a router with sufficient capacity should be used.
- MQTT Broker Environment: As device connections and communication become more frequent, the MQTT broker may experience increased load. For maximum performance, it is recommended to be operated directly on
localhost.