rustuya-local
Local control of Tuya devices through rustuya-bridge, as IL (ildevice) devices, and in Home Assistant. It replaces rustuya-homeassistant.
rustuya-bridge ──MQTT──► rustuya-local ──MQTT (il/…)──► il-ha (Home Assistant integration), or any IL consumer
raw LAN dps Service:
BridgeClient + tuya2ildevice.Hub
- tuya2ildevice is the only place that interprets Tuya: Home Assistant core's
tuyabehaviour, the user overrides for non-standard devices, and the host parts (runner, transports, file watchers). - rustuya-local is one
Service(src/rustuya_local/service.py) and three thin shells that run it: therustuya-local rundaemon, thecustom_components/rustuyaHome Assistant integration, and a rustuya-manager plugin. It only produces IL and knows nothing of Home Assistant entities. - il-ha turns IL descriptors into Home Assistant entities.
Daemon
uv venv && uv pip install -e . # sibling checkouts: see pyproject.toml's [tool.uv.sources]
rustuya-local run --config config.json
config.json (see src/rustuya_local/config.py): the bridge and IL brokers, the IL prefix, the device list, a
custom_converters directory, and options for the Hub (allow_hazardous, expose_unused, overrides).
The device list is the tuyadevices.json that rustuya-manager keeps (its QR-login wizard writes
it, with each device's cloud category/function/status_range/local_strategy); rustuya-local follows it as it
changes and never writes it. IL carries only the devices that are also registered on the bridge. The bridge's own
topic templates are read from its retained {root}/bridge/config.
Home Assistant
Install il-ha, and run one IL producer per bridge: the daemon, the integration below, or the manager plugin (two producers show every device twice; the service warns when another one is already online).
The rustuya integration (HACS: add this repository as a custom repository of type Integration, install
Rustuya, restart, then Add Integration → Rustuya) is the service tied to a config entry, with the QR login
wizard, bridge registration and an optional embedded bridge. It creates no entities itself.
Overrides for non-standard devices
Tuya's cloud schemas are fragmented; fixes go in a custom_converters/ directory (daemon: custom_converters in the
config; integration: <config>/rustuya_converters; manager plugin: its data dir), followed live:
*.json: tuya2ildevice override blocks by product or device id: rename a dp, define one the schema lacks, map the device's words to the standard ones (remap.alias), invert a direction (remap.invert), fix labels and classes, turn on a code converter. rustuya-homeassistant'scustom_convertersJSON files load as they are.*.py: code converters (CONVERTERS = {"name": factory}).
See tuya2ildevice's README ("User overrides") for the format. A curated set ships in tuya2ildevice.
rustuya-manager plugin
Installed next to rustuya-manager, as a pip package (pip install rustuya-local in the manager's environment) or as
the drop-in zip each release carries (rustuya_local-<version>-dropin.zip, tuya2ildevice vendored inside, built by
scripts/build_dropin.py; unpack it into the manager's plugin directory, or install it from the manager's plugin
catalog once listed there), it appears as a Tuya (IL) tab and runs the service under the manager: the manager's broker and bridge root, the manager's device
list (followed). Its data dir (rustuya-local/ next to the manager's plugins) holds an optional settings.json
(il, options) and custom_converters/.
The drop-in zip freezes the tuya2ildevice it was built with: a tuya2ildevice fix reaches manager users with the next rustuya-local release (bump the patch version and tag; the manager's catalog follows the release). Installed both ways (pip and the plugin directory), the plugin runs once.
Tests
.venv/bin/python -m pytest
Everything here needs the sibling repos and, for the last two groups, mosquitto, pyrustuya-bridge and tuyamock
(pip install -e ".[test,fullstack]"); those are skipped when missing. Parity with Home Assistant core's fixtures lives in
tuya2ildevice/tests/chain, the wire and topic vectors in ildevice/vectors.
tests/unit/: the configuration.tests/e2e/test_service.py: the service on in-memory brokers (overrides directory, a failed start).tests/e2e/test_chain_*.py,test_daemon.py: the runner with il-ha's consumer model on the other side, in one process and over a real broker; the daemon as a subprocess.tests/e2e/test_manager_plugin.py: the plugin under rustuya-manager's real plugin host (skipped without it).tests/ha/: the integration (config flow, setup).tests/e2e/test_full_stack*.py: the real rustuya-bridge (pyrustuyabridge, in process) and Tuya device emulators (tuyamock) around the daemon: state, commands, rejections, a device dropping off and returning, a daemon restart, and a differential check that 38 real device shapes come out of the whole chain exactly astuya2ildevicecomputes them.
Status
Planning, progress and open decisions: docs/REDESIGN.md.
Licence: LICENSE (MIT).
Metadata
Release files for rustuya-local 0.0.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rustuya_local-0.0.12.tar.gz | 154.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rustuya_local-0.0.12-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 173.1 kB
Release files / rustuya_local-0.0.12.tar.gz
| Download URL | rustuya_local-0.0.12.tar.gz |
|---|---|
| Size | 154.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
502aa93b152e5fbc2f3c98bfc66e0bd10d99bcdfd220048ba01bf8696876767c
|
|
BLAKE2b-256 checksum How to use checksums |
2d3a044a8838a49fbf767a9e0f5bb6cefa2fa17de5d0cc535205233d820a0559
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logRelease files / rustuya_local-0.0.12-py3-none-any.whl
| Download URL | rustuya_local-0.0.12-py3-none-any.whl |
|---|---|
| Size | 18.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
801578b2ff8997aa3d8fdcad7f9dd841aa4d0c48f9ee1e6898e2f9aec11fb641
|
|
BLAKE2b-256 checksum How to use checksums |
7f74c53271f1f86d33d15c542fc8c3d0a041a8322ecc735d031ddf9c2b3884b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency log