Rustuya
Local-network control of Tuya-compatible devices, built in Rust with first-class Python bindings. Designed for fleets of hundreds to thousands of devices — a native Rust core handles the I/O while the Python facade releases the GIL on every blocking call, so threaded Python workers stay live.
Install
Rust
Python
Quick start
Rust (sync)
use Device;
let dev = new;
dev.set_value?; // turn on DP 1
println!; // read current DPS
for msg in dev.listener
Rust (async) — inside a tokio runtime
use Device;
use StreamExt;
async
Python
=
# turn on DP 1
# read current DPS
# real-time events
Features
- Local-only — talks directly to devices over LAN, no Tuya Cloud
- Rust core + Python bindings (PyO3) — same engine for both
- Built for fleet scale — per-device background tasks with automatic reconnection and exponential backoff
- Full protocol coverage — Tuya 3.1 / 3.2 / 3.3 / 3.4 / 3.5 + device22
Tested at fleet scale
Large-scale behavior is exercised against real mock devices — a 1000-device tuyamock fleet with actual TCP connections and handshakes, not just unit mocks:
- This repo stands up the 1000-device fleet and asserts every connection
establishes without deadlock under a bounded connect-concurrency cap, in CI
(
python/tests/test_fleet_scale.py). - The downstream rustuya-bridge goes further end-to-end: a 1000-device fleet onboards cleanly with zero retained orphans after a mass clear, and a separate test holds the fleet idle for 30s to prove the heartbeat keeps every connection alive (witnessed mock-side) before fanning a single name-addressed command out to the whole fleet.
It proves the fleet machinery (bounded connect with no deadlock, heartbeat survival, fan-out) holds with 1000 concurrent devices over real sockets, end to end.
See the Guide for the full API reference, design philosophy, and architecture notes.
Credits
The Tuya protocol layer in rustuya is derived from the specifications and error codes documented in tinytuya:
License
MIT