rustuya-local 0.1.0.dev3__tar.gz → 0.1.0.dev4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/CHANGELOG.md +8 -0
  2. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/PKG-INFO +15 -13
  3. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/README.md +14 -12
  4. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/manifest.json +2 -2
  5. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/strings.json +1 -1
  6. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/translations/en.json +1 -1
  7. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/translations/ko.json +1 -1
  8. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/www/rustuya-panel.js +16 -16
  9. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/pyproject.toml +1 -1
  10. rustuya_local-0.1.0.dev4/release-notes.md +5 -0
  11. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/pack.py +2 -2
  12. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/manager_plugin/static/index.js +3 -3
  13. rustuya_local-0.1.0.dev3/release-notes.md +0 -6
  14. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.github/dependabot.yml +0 -0
  15. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.github/workflows/_test.yml +0 -0
  16. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.github/workflows/ci.yml +0 -0
  17. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.github/workflows/hacs.yml +0 -0
  18. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.github/workflows/hassfest.yml +0 -0
  19. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.github/workflows/release.yml +0 -0
  20. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/.gitignore +0 -0
  21. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/LICENSE +0 -0
  22. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/__init__.py +0 -0
  23. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/brand/icon.png +0 -0
  24. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/brand/icon.svg +0 -0
  25. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/brand/icon@2x.png +0 -0
  26. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/brand/logo.png +0 -0
  27. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/brand/logo.svg +0 -0
  28. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/brand/logo@2x.png +0 -0
  29. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/bridge_supervisor.py +0 -0
  30. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/bridge_sync.py +0 -0
  31. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/broker.py +0 -0
  32. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/config_flow.py +0 -0
  33. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/const.py +0 -0
  34. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/manager_session.py +0 -0
  35. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/panel.py +0 -0
  36. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/custom_components/rustuya/services.yaml +0 -0
  37. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/docs/MIGRATING.md +0 -0
  38. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/docs/REDESIGN.md +0 -0
  39. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/docs/ROADMAP.md +0 -0
  40. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/docs/STATUS.md +0 -0
  41. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/hacs.json +0 -0
  42. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/scripts/build_dropin.py +0 -0
  43. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/scripts/release_notes.py +0 -0
  44. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/__init__.py +0 -0
  45. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/__main__.py +0 -0
  46. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/async_tools.py +0 -0
  47. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/bridge_client.py +0 -0
  48. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/cli.py +0 -0
  49. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/config.py +0 -0
  50. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/files.py +0 -0
  51. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/__init__.py +0 -0
  52. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/devices.py +0 -0
  53. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/hub.py +0 -0
  54. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/il.py +0 -0
  55. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/memory.py +0 -0
  56. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/mqtt.py +0 -0
  57. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/overrides.py +0 -0
  58. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/rules.py +0 -0
  59. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/runner.py +0 -0
  60. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/host/transport.py +0 -0
  61. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/manager_plugin/__init__.py +0 -0
  62. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/manager_plugin/api.py +0 -0
  63. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/service.py +0 -0
  64. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/src/rustuya_local/validation.py +0 -0
  65. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/conftest.py +0 -0
  66. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/devices.py +0 -0
  67. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_bridge_registration.py +0 -0
  68. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_chain_in_process.py +0 -0
  69. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_chain_mqtt.py +0 -0
  70. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_daemon.py +0 -0
  71. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_full_stack.py +0 -0
  72. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_full_stack_custom_templates.py +0 -0
  73. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_full_stack_devices.py +0 -0
  74. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_manager_plugin.py +0 -0
  75. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_purge.py +0 -0
  76. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/e2e/test_service.py +0 -0
  77. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/conftest.py +0 -0
  78. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/fake_manager.py +0 -0
  79. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/test_bridge_probe.py +0 -0
  80. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/test_config_flow.py +0 -0
  81. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/test_init.py +0 -0
  82. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/test_manager_session.py +0 -0
  83. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/test_migrate.py +0 -0
  84. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/ha/test_panel.py +0 -0
  85. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_config.py +0 -0
  86. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_cover_settings.py +0 -0
  87. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_dropin.py +0 -0
  88. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_files.py +0 -0
  89. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_hazardous.py +0 -0
  90. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_host.py +0 -0
  91. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_hub.py +0 -0
  92. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_il_vectors.py +0 -0
  93. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_link_watcher.py +0 -0
  94. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_pack.py +0 -0
  95. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_panel_js.py +0 -0
  96. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_plugin_api.py +0 -0
  97. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_release_notes.py +0 -0
  98. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/test_rule_files.py +0 -0
  99. {rustuya_local-0.1.0.dev3 → rustuya_local-0.1.0.dev4}/tests/unit/tuya_samples.py +0 -0
@@ -8,6 +8,14 @@ stable release.
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.1.0.dev4] — 2026-10-11
12
+
13
+ ### Fixed
14
+ - Fetch dev4 builtin rule updates from its development branch; master does not yet contain the new rules directory.
15
+
16
+ ### Changed
17
+ - Label official rule updates as builtin rules in the HA panel and manager settings, and clarify that bundled rules remain available when online updates are off.
18
+
11
19
  ## [0.1.0.dev3] — 2026-10-11
12
20
 
13
21
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rustuya-local
3
- Version: 0.1.0.dev3
3
+ Version: 0.1.0.dev4
4
4
  Summary: Local Tuya control: rustuya-bridge -> tuya2ildevice -> IL (ildevice). HA-independent core.
5
5
  Project-URL: Homepage, https://github.com/3735943886/rustuya-local
6
6
  Project-URL: Repository, https://github.com/3735943886/rustuya-local
@@ -66,7 +66,7 @@ source are cleared (other sources on the prefix are left alone), so IL consumers
66
66
 
67
67
  The shared Rust core interprets one device and has no MQTT or rule-file loading API.
68
68
  `rustuya_local.host.Hub` owns the device registry and maps `TuyaDriver` outputs to IL MQTT wire data;
69
- `host.rules` discovers and loads the bundled pack and user layers, passing decoded rules to Rust for composition.
69
+ `host.rules` discovers and loads the bundled builtin rules and user layers, passing decoded rules to Rust for composition.
70
70
  The service preloads native code and rules in a worker thread before starting devices.
71
71
  Timers, retained-message policy, bridge `get` requests, presence and settings persistence remain in this host.
72
72
  MQTT and in-process transport tests exercise the same adapter and the bidirectional Rust driver.
@@ -102,12 +102,14 @@ config; integration: `<config>/rustuya_converters`; manager plugin: its data dir
102
102
  `{"overrides": {"product_id": {"cover": {"invert_position": true}}}}`.
103
103
  - Converters are JSON programs under `converters.declarative`; Python code plugins are not loaded.
104
104
 
105
- See tuya2ildevice's README ("User overrides") for the format. A curated set ships in tuya2ildevice, and fixes published
106
- between its releases (its [override pack](https://github.com/3735943886/tuya2ildevice/tree/master/rules/builtin)) are copied
107
- into `rules/builtin/` inside the overrides directory at start and daily. These include `00-default.json`; your own
108
- files are applied after all official rules. The bundled defaults update with tuya2ildevice, even when pack sync is off.
109
- Turn online updates off with `"pack": false` (daemon), the Rustuya panel's *Options* (integration), or the plugin tab. The pack only replaces or removes the files it
110
- put there, and leaves a file alone once you edit it.
105
+ See tuya2ildevice's README ("User overrides") for the format. Official builtin rules, including `00-default.json`,
106
+ ship with tuya2ildevice and update when that package is upgraded. They are applied before your own rule files.
107
+
108
+ Online updates fetch the latest [builtin rules](https://github.com/3735943886/tuya2ildevice/tree/feat/rust-rule-engine/rules/builtin)
109
+ into `rules/builtin/` inside the overrides directory at start and daily. In the Rustuya panel, use *Update builtin rules*
110
+ to fetch them now or *Automatically update builtin rules* to control automatic updates. The daemon uses `"pack": false`
111
+ to disable online updates; the manager plugin has the same option in its settings. Installed builtin rules remain
112
+ available when online updates are off. Updates only replace or remove files they downloaded, preserving user edits.
111
113
 
112
114
  ### Cover settings
113
115
 
@@ -128,7 +130,7 @@ device settings are enabled, unless an override selects another source. A settin
128
130
  the setting is saved as the device's block in `zz_settings.json` in the converters directory and applied at once, so it
129
131
  survives a restart and can be edited there too. Without a converters directory (a daemon with no
130
132
  `custom_converters`) the switches are not offered; `"options": {"device_settings": false}` turns them off.
131
- A block with the same `cover` keys in your own file or the pack sets a model's starting point; the saved settings win.
133
+ A block with the same `cover` keys in your own file or the builtin rules sets a model's starting point; the saved settings win.
132
134
  Older `cover.infer_motion` and `converters.cover_motion` blocks are upgraded on loading to `cover.state_source`
133
135
  (`inferred`, or `none` for `infer_motion: false`) and `cover.settle`; see [migration notes](docs/MIGRATING.md).
134
136
 
@@ -138,10 +140,10 @@ bridge's devices against the cloud list as rustuya-manager does (missing, bridge
138
140
  turn off; sub-devices under their gateway; each device's bridge connection, live while the panel is open) with add /
139
141
  update / remove. *Register manually* adds Wi-Fi devices or sub-devices without a cloud login, using the same
140
142
  fields as rustuya-manager. Devices absent from the cloud list appear under *Bridge only*; their removal is not
141
- preselected in bulk sync. The panel lists the converter files with the pack's
142
- marked, edits and deletes them (drop JSON rule files on it to copy them in), runs the pack sync on demand, has the
143
+ preselected in bulk sync. The panel lists, edits and deletes user converter files (drop JSON rule files on it to copy them in),
144
+ updates builtin rules on demand, and has the
143
145
  *Options* (remote control of locks, alarms and garage doors; data points Home Assistant core would not classify; the
144
- override pack), and the *Settings* setup leaves at their defaults: the bridge topic root, the IL prefix and source, the device file, and
146
+ automatic builtin rule updates), and the *Settings* setup leaves at their defaults: the bridge topic root, the IL prefix and source, the device file, and
145
147
  the embedded bridge's state file and log level. Saving restarts the integration; moving the IL prefix or source first
146
148
  clears what the old one left on the broker. *Hide panel* in its toolbar turns it off again. The integration and the panel follow Home Assistant's
147
149
  language: Korean, or English.
@@ -149,7 +151,7 @@ language: Korean, or English.
149
151
  ## rustuya-manager plugin
150
152
 
151
153
  Installed next to rustuya-manager, as a pip package (`pip install rustuya-local` in the manager's environment) or as
152
- the drop-in zip each release carries (`rustuya_local-<version>-dropin.zip`, tuya2ildevice binding, native library and rule pack vendored inside, built by
154
+ the drop-in zip each release carries (`rustuya_local-<version>-dropin.zip`, tuya2ildevice binding, native library and builtin rules vendored inside, built by
153
155
  `scripts/build_dropin.py`; unpack it into the manager's plugin directory, or install it from the manager's plugin
154
156
  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
155
157
  list (followed). Its data dir (`rustuya-local/` next to the manager's plugins) holds `settings.json` (`il`,
@@ -40,7 +40,7 @@ source are cleared (other sources on the prefix are left alone), so IL consumers
40
40
 
41
41
  The shared Rust core interprets one device and has no MQTT or rule-file loading API.
42
42
  `rustuya_local.host.Hub` owns the device registry and maps `TuyaDriver` outputs to IL MQTT wire data;
43
- `host.rules` discovers and loads the bundled pack and user layers, passing decoded rules to Rust for composition.
43
+ `host.rules` discovers and loads the bundled builtin rules and user layers, passing decoded rules to Rust for composition.
44
44
  The service preloads native code and rules in a worker thread before starting devices.
45
45
  Timers, retained-message policy, bridge `get` requests, presence and settings persistence remain in this host.
46
46
  MQTT and in-process transport tests exercise the same adapter and the bidirectional Rust driver.
@@ -76,12 +76,14 @@ config; integration: `<config>/rustuya_converters`; manager plugin: its data dir
76
76
  `{"overrides": {"product_id": {"cover": {"invert_position": true}}}}`.
77
77
  - Converters are JSON programs under `converters.declarative`; Python code plugins are not loaded.
78
78
 
79
- See tuya2ildevice's README ("User overrides") for the format. A curated set ships in tuya2ildevice, and fixes published
80
- between its releases (its [override pack](https://github.com/3735943886/tuya2ildevice/tree/master/rules/builtin)) are copied
81
- into `rules/builtin/` inside the overrides directory at start and daily. These include `00-default.json`; your own
82
- files are applied after all official rules. The bundled defaults update with tuya2ildevice, even when pack sync is off.
83
- Turn online updates off with `"pack": false` (daemon), the Rustuya panel's *Options* (integration), or the plugin tab. The pack only replaces or removes the files it
84
- put there, and leaves a file alone once you edit it.
79
+ See tuya2ildevice's README ("User overrides") for the format. Official builtin rules, including `00-default.json`,
80
+ ship with tuya2ildevice and update when that package is upgraded. They are applied before your own rule files.
81
+
82
+ Online updates fetch the latest [builtin rules](https://github.com/3735943886/tuya2ildevice/tree/feat/rust-rule-engine/rules/builtin)
83
+ into `rules/builtin/` inside the overrides directory at start and daily. In the Rustuya panel, use *Update builtin rules*
84
+ to fetch them now or *Automatically update builtin rules* to control automatic updates. The daemon uses `"pack": false`
85
+ to disable online updates; the manager plugin has the same option in its settings. Installed builtin rules remain
86
+ available when online updates are off. Updates only replace or remove files they downloaded, preserving user edits.
85
87
 
86
88
  ### Cover settings
87
89
 
@@ -102,7 +104,7 @@ device settings are enabled, unless an override selects another source. A settin
102
104
  the setting is saved as the device's block in `zz_settings.json` in the converters directory and applied at once, so it
103
105
  survives a restart and can be edited there too. Without a converters directory (a daemon with no
104
106
  `custom_converters`) the switches are not offered; `"options": {"device_settings": false}` turns them off.
105
- A block with the same `cover` keys in your own file or the pack sets a model's starting point; the saved settings win.
107
+ A block with the same `cover` keys in your own file or the builtin rules sets a model's starting point; the saved settings win.
106
108
  Older `cover.infer_motion` and `converters.cover_motion` blocks are upgraded on loading to `cover.state_source`
107
109
  (`inferred`, or `none` for `infer_motion: false`) and `cover.settle`; see [migration notes](docs/MIGRATING.md).
108
110
 
@@ -112,10 +114,10 @@ bridge's devices against the cloud list as rustuya-manager does (missing, bridge
112
114
  turn off; sub-devices under their gateway; each device's bridge connection, live while the panel is open) with add /
113
115
  update / remove. *Register manually* adds Wi-Fi devices or sub-devices without a cloud login, using the same
114
116
  fields as rustuya-manager. Devices absent from the cloud list appear under *Bridge only*; their removal is not
115
- preselected in bulk sync. The panel lists the converter files with the pack's
116
- marked, edits and deletes them (drop JSON rule files on it to copy them in), runs the pack sync on demand, has the
117
+ preselected in bulk sync. The panel lists, edits and deletes user converter files (drop JSON rule files on it to copy them in),
118
+ updates builtin rules on demand, and has the
117
119
  *Options* (remote control of locks, alarms and garage doors; data points Home Assistant core would not classify; the
118
- override pack), and the *Settings* setup leaves at their defaults: the bridge topic root, the IL prefix and source, the device file, and
120
+ automatic builtin rule updates), and the *Settings* setup leaves at their defaults: the bridge topic root, the IL prefix and source, the device file, and
119
121
  the embedded bridge's state file and log level. Saving restarts the integration; moving the IL prefix or source first
120
122
  clears what the old one left on the broker. *Hide panel* in its toolbar turns it off again. The integration and the panel follow Home Assistant's
121
123
  language: Korean, or English.
@@ -123,7 +125,7 @@ language: Korean, or English.
123
125
  ## rustuya-manager plugin
124
126
 
125
127
  Installed next to rustuya-manager, as a pip package (`pip install rustuya-local` in the manager's environment) or as
126
- the drop-in zip each release carries (`rustuya_local-<version>-dropin.zip`, tuya2ildevice binding, native library and rule pack vendored inside, built by
128
+ the drop-in zip each release carries (`rustuya_local-<version>-dropin.zip`, tuya2ildevice binding, native library and builtin rules vendored inside, built by
127
129
  `scripts/build_dropin.py`; unpack it into the manager's plugin directory, or install it from the manager's plugin
128
130
  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
129
131
  list (followed). Its data dir (`rustuya-local/` next to the manager's plugins) holds `settings.json` (`il`,
@@ -13,8 +13,8 @@
13
13
  "paho-mqtt>=2.0",
14
14
  "rustuya-manager>=0.2.2",
15
15
  "pyrustuyabridge>=0.4",
16
- "rustuya-local>=0.1.0.dev3"
16
+ "rustuya-local>=0.1.0.dev4"
17
17
  ],
18
18
  "single_config_entry": true,
19
- "version": "0.1.0.dev3"
19
+ "version": "0.1.0.dev4"
20
20
  }
@@ -138,7 +138,7 @@
138
138
  "wizard_failed": "Fetching from Tuya Cloud failed: {error}",
139
139
  "no_devices": "There are no devices in the cloud list or on the bridge.",
140
140
  "manager_busy": "Another Tuya Cloud fetch or device sync window is still open. Close it and try again.",
141
- "panel_shown": "The Rustuya panel was added to the sidebar: [open it]({url}). Its Options hold remote control of locks, alarms and garage doors, unused data points and the override pack.",
141
+ "panel_shown": "The Rustuya panel was added to the sidebar: [open it]({url}). Its Options hold remote control of locks, alarms and garage doors, unused data points and automatic builtin rule updates.",
142
142
  "panel_open": "[Open the Rustuya panel]({url})."
143
143
  },
144
144
  "error": {
@@ -138,7 +138,7 @@
138
138
  "wizard_failed": "Fetching from Tuya Cloud failed: {error}",
139
139
  "no_devices": "There are no devices in the cloud list or on the bridge.",
140
140
  "manager_busy": "Another Tuya Cloud fetch or device sync window is still open. Close it and try again.",
141
- "panel_shown": "The Rustuya panel was added to the sidebar: [open it]({url}). Its Options hold remote control of locks, alarms and garage doors, unused data points and the override pack.",
141
+ "panel_shown": "The Rustuya panel was added to the sidebar: [open it]({url}). Its Options hold remote control of locks, alarms and garage doors, unused data points and automatic builtin rule updates.",
142
142
  "panel_open": "[Open the Rustuya panel]({url})."
143
143
  },
144
144
  "error": {
@@ -138,7 +138,7 @@
138
138
  "wizard_failed": "Tuya Cloud에서 가져오지 못했습니다: {error}",
139
139
  "no_devices": "클라우드 목록에도 브리지에도 기기가 없습니다.",
140
140
  "manager_busy": "다른 Tuya Cloud 가져오기 또는 기기 동기화 창이 아직 열려 있습니다. 그 창을 닫고 다시 시도하세요.",
141
- "panel_shown": "사이드바에 Rustuya 패널이 추가되었습니다: [열기]({url}). 패널의 Options에서 잠금장치·경보·차고문 원격 제어, 분류되지 않는 데이터 포인트, 오버라이드 팩을 설정합니다.",
141
+ "panel_shown": "사이드바에 Rustuya 패널이 추가되었습니다: [열기]({url}). 패널의 Options에서 잠금장치·경보·차고문 원격 제어, 분류되지 않는 데이터 포인트, Builtin 규칙 자동 업데이트를 설정합니다.",
142
142
  "panel_open": "[Rustuya 패널 열기]({url})"
143
143
  },
144
144
  "error": {
@@ -183,17 +183,17 @@ const I18N = {
183
183
  opt_allow_hazardous_hint: "Off: their state is shown, but IL and rustuya.send_command refuse writes to them.",
184
184
  opt_expose_unused: "Expose data points Home Assistant core would not classify",
185
185
  opt_expose_unused_hint: "Every data point the cloud schema lists, not only the ones a standard entity uses.",
186
- opt_pack: "Download fixes for non-standard devices published between releases",
187
- opt_pack_hint: "The override pack: copied into the converters directory at start and daily.",
186
+ opt_pack: "Automatically update builtin rules",
187
+ opt_pack_hint: "Check for official rule updates at start and daily.",
188
188
  save_restart: "Save and restart", options_title: "Options", options_intro: "Saving restarts the integration.",
189
189
  options_unreadable: "Cannot read the options: {error}", nothing_changed: "Nothing changed",
190
190
  saving_restarting: "Saving; Rustuya is restarting…", not_saved: "Not saved: {error}",
191
191
  settings_title: "Settings",
192
192
  settings_intro: "Set up with their defaults. Saving restarts the integration; moving the IL prefix or source clears what the old one left on the broker, so IL consumers drop those devices and see them again under the new one.",
193
193
  settings_unreadable: "Cannot read the settings: {error}", confirm_settings: "Save {names} and restart Rustuya?",
194
- sync_now: "Sync now", hide_title: "Remove this panel from the sidebar; the integration's Configure adds it back",
195
- hide: "Hide panel", pack_title: "Override pack",
196
- pack_intro: "Fixes for non-standard devices, published between releases and copied into the converters directory.",
194
+ sync_now: "Update builtin rules", hide_title: "Remove this panel from the sidebar; the integration's Configure adds it back",
195
+ hide: "Hide panel", pack_title: "Builtin rules",
196
+ pack_intro: "Official rules included with tuya2ildevice. Fetch the latest rules without updating the integration.",
197
197
  converters_title: "Custom converters",
198
198
  converters_intro: "Rule files (*.json: override blocks and declarative converters) in rustuya_converters/. Saved files apply within seconds. See tuya2ildevice's README, \"User overrides\". Drop files here to copy them in.",
199
199
  new_file: "New file", save: "Save", delete: "Delete",
@@ -204,15 +204,15 @@ const I18N = {
204
204
  confirm_hide_unsaved: "Unsaved changes in {names} will be lost. Remove the Rustuya panel from the sidebar anyway?",
205
205
  and: " and ", not_hidden: "Not hidden: {error}", files_unreadable: "Cannot list the files: {error}",
206
206
  no_files: "No files yet. Built-in fixes apply without any.",
207
- pack_syncing: "Syncing…", pack_off: "Off. Turn it on in Options below.", pack_never: "Not synced yet.",
207
+ pack_syncing: "Updating…", pack_off: "Online updates are off. Using the installed rules.", pack_never: "Using bundled rules; no online update yet.",
208
208
  pack_added: "added", pack_updated: "updated", pack_removed: "removed", pack_kept: "kept",
209
- pack_failed: "; failed: {list}", pack_error: "Not synced ({error}), {when}", pack_synced: "Synced {when}",
209
+ pack_failed: "; failed: {list}", pack_error: "Update failed ({error}), {when}", pack_synced: "Updated {when}",
210
210
  origin_note_pack: "From the override pack: the next sync updates it. Saving an edit makes it yours.",
211
211
  origin_note_pack_edited: "An edited pack file: the pack no longer updates it. Delete it to get the pack's copy back at the next sync.",
212
212
  name_first: "Name the file first (*.json)",
213
213
  confirm_edit_pack: "{name} comes from the override pack. Once edited it is yours: the pack no longer updates or removes it.",
214
214
  saved: "Saved {name}", confirm_delete: "Delete {name}?", deleted: "Deleted {name}", not_deleted: "Not deleted: {error}",
215
- pack_is_off: "The pack is off", cannot_sync: "Cannot sync: {error}", pack_changed: "The pack changed the converter files",
215
+ pack_is_off: "Builtin rule updates are off", cannot_sync: "Cannot update: {error}", pack_changed: "Builtin rules updated",
216
216
  },
217
217
  ko: {
218
218
  origin_pack: "팩", origin_pack_edited: "팩, 수정됨",
@@ -252,17 +252,17 @@ const I18N = {
252
252
  opt_allow_hazardous_hint: "끄면 상태는 보이지만 IL과 rustuya.send_command가 쓰기를 거부합니다.",
253
253
  opt_expose_unused: "Home Assistant core가 분류하지 않는 데이터 포인트도 노출",
254
254
  opt_expose_unused_hint: "표준 엔티티가 쓰는 것만이 아니라 클라우드 스키마의 모든 데이터 포인트.",
255
- opt_pack: "릴리즈 사이에 나온 비표준 기기 수정 다운로드",
256
- opt_pack_hint: "오버라이드 팩: 시작할 때와 매일 컨버터 디렉터리에 복사됩니다.",
255
+ opt_pack: "Builtin 규칙 자동 업데이트",
256
+ opt_pack_hint: "시작할 때와 매일 공식 규칙 업데이트를 확인합니다.",
257
257
  save_restart: "저장하고 재시작", options_title: "옵션", options_intro: "저장하면 통합구성요소가 재시작됩니다.",
258
258
  options_unreadable: "옵션을 읽을 수 없습니다: {error}", nothing_changed: "바뀐 것이 없습니다",
259
259
  saving_restarting: "저장하는 중. Rustuya를 재시작합니다…", not_saved: "저장하지 못했습니다: {error}",
260
260
  settings_title: "설정",
261
261
  settings_intro: "설정 과정에서 기본값으로 정해진 값들입니다. 저장하면 통합구성요소가 재시작됩니다. IL prefix나 source를 옮기면 예전 값으로 브로커에 남은 것을 지워서, IL 소비자가 그 기기를 지우고 새 값으로 다시 보게 됩니다.",
262
262
  settings_unreadable: "설정을 읽을 수 없습니다: {error}", confirm_settings: "{names}을(를) 저장하고 Rustuya를 재시작할까요?",
263
- sync_now: "지금 동기화", hide_title: "사이드바에서 이 패널을 없앱니다. 통합구성요소의 구성(Configure)에서 다시 추가할 수 있습니다",
264
- hide: "패널 숨기기", pack_title: "오버라이드 팩",
265
- pack_intro: "릴리즈 사이에 나온 비표준 기기 수정으로, 컨버터 디렉터리에 복사됩니다.",
263
+ sync_now: "Builtin 규칙 업데이트", hide_title: "사이드바에서 이 패널을 없앱니다. 통합구성요소의 구성(Configure)에서 다시 추가할 수 있습니다",
264
+ hide: "패널 숨기기", pack_title: "Builtin 규칙",
265
+ pack_intro: "tuya2ildevice에 포함된 공식 규칙입니다. 통합구성요소 업데이트 없이 최신 규칙을 가져옵니다.",
266
266
  converters_title: "커스텀 컨버터",
267
267
  converters_intro: "rustuya_converters/ 안의 규칙 파일(*.json: 오버라이드 블록과 선언형 컨버터). 저장한 파일은 몇 초 안에 적용됩니다. tuya2ildevice README의 \"User overrides\"를 참고하세요. 여기에 파일을 끌어다 놓으면 복사됩니다.",
268
268
  new_file: "새 파일", save: "저장", delete: "삭제",
@@ -273,15 +273,15 @@ const I18N = {
273
273
  confirm_hide_unsaved: "{names}의 저장하지 않은 변경이 사라집니다. 그래도 사이드바에서 Rustuya 패널을 없앨까요?",
274
274
  and: ", ", not_hidden: "숨기지 못했습니다: {error}", files_unreadable: "파일 목록을 읽을 수 없습니다: {error}",
275
275
  no_files: "아직 파일이 없습니다. 기본 수정은 파일 없이도 적용됩니다.",
276
- pack_syncing: "동기화하는 중…", pack_off: "꺼져 있습니다. 아래 옵션에서 켜세요.", pack_never: "아직 동기화하지 않았습니다.",
276
+ pack_syncing: "업데이트하는 중…", pack_off: "온라인 업데이트가 꺼져 있습니다. 설치된 규칙을 사용합니다.", pack_never: "패키지에 포함된 규칙 사용 중; 아직 온라인 업데이트하지 않았습니다.",
277
277
  pack_added: "추가", pack_updated: "갱신", pack_removed: "삭제", pack_kept: "유지",
278
- pack_failed: "; 실패: {list}", pack_error: "동기화하지 못함 ({error}), {when}", pack_synced: "{when}에 동기화함",
278
+ pack_failed: "; 실패: {list}", pack_error: "업데이트 실패 ({error}), {when}", pack_synced: "{when}에 업데이트함",
279
279
  origin_note_pack: "오버라이드 팩의 파일입니다. 다음 동기화 때 갱신됩니다. 수정해서 저장하면 내 파일이 됩니다.",
280
280
  origin_note_pack_edited: "수정한 팩 파일입니다. 팩이 더 이상 갱신하지 않습니다. 지우면 다음 동기화 때 팩의 파일이 다시 들어옵니다.",
281
281
  name_first: "먼저 파일 이름을 정하세요 (*.json)",
282
282
  confirm_edit_pack: "{name}은(는) 오버라이드 팩의 파일입니다. 수정하면 내 파일이 되어 팩이 더 이상 갱신하거나 지우지 않습니다.",
283
283
  saved: "{name} 저장함", confirm_delete: "{name}을(를) 삭제할까요?", deleted: "{name} 삭제함", not_deleted: "삭제하지 못했습니다: {error}",
284
- pack_is_off: "팩이 꺼져 있습니다", cannot_sync: "동기화할 수 없습니다: {error}", pack_changed: "팩이 컨버터 파일을 바꿨습니다",
284
+ pack_is_off: "Builtin 규칙 업데이트가 꺼져 있습니다", cannot_sync: "업데이트할 수 없습니다: {error}", pack_changed: "Builtin 규칙이 업데이트되었습니다",
285
285
  },
286
286
  };
287
287
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rustuya-local"
7
- version = "0.1.0.dev3"
7
+ version = "0.1.0.dev4"
8
8
  description = "Local Tuya control: rustuya-bridge -> tuya2ildevice -> IL (ildevice). HA-independent core."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -0,0 +1,5 @@
1
+ ### Fixed
2
+ - Fetch dev4 builtin rule updates from its development branch; master does not yet contain the new rules directory.
3
+
4
+ ### Changed
5
+ - Label official rule updates as builtin rules in the HA panel and manager settings, and clarify that bundled rules remain available when online updates are off.
@@ -1,4 +1,4 @@
1
- """The override pack: fixes for non-standard devices published on tuya2ildevice's `master` (`rules/builtin/`) and copied into
1
+ """The override pack: fixes for non-standard devices published on tuya2ildevice's `feat/rust-rule-engine` branch (`rules/builtin/`) and copied into
2
2
  the host's rule directory, so a fix reaches users without a release. `OverrideWatcher` then loads the copied files
3
3
  like the user's own. The files are rule layers (JSON); fetching them is the host's, the engine only merges them.
4
4
 
@@ -38,7 +38,7 @@ from .overrides import SETTINGS_FILE
38
38
  _LOGGER = logging.getLogger(__name__)
39
39
 
40
40
  LEVEL = 4 # 2: `cover` settings; 3: `delta`; 4: rule-layer files (tuya2ildevice 0.4)
41
- BASE_URL = "https://raw.githubusercontent.com/3735943886/tuya2ildevice/master/rules/builtin/"
41
+ BASE_URL = "https://raw.githubusercontent.com/3735943886/tuya2ildevice/feat/rust-rule-engine/rules/builtin/"
42
42
  MANIFEST = "manifest.json"
43
43
  LEDGER = ".tuya2ildevice_pack.json"
44
44
  MAX_BYTES = 1024 * 1024
@@ -56,8 +56,8 @@ function paintStatus(box, data) {
56
56
  const p = data.pack;
57
57
  if (p) {
58
58
  const when = new Date(p.at * 1000).toLocaleString();
59
- const text = p.error ? `Override pack: not synced (${p.error}), ${when}`
60
- : `Override pack: synced ${when}` + PACK_CHANGES
59
+ const text = p.error ? `Builtin rules: update failed (${p.error}), ${when}`
60
+ : `Builtin rules: updated ${when}` + PACK_CHANGES
61
61
  .filter((k) => p[k] && p[k].length).map((k) => `; ${k} ${p[k].join(", ")}`).join("");
62
62
  box.append(el("p", { class: `text-sm mt-2 ${p.error || (p.failed && p.failed.length) ? "text-amber-600" : "text-gray-500"}` }, text));
63
63
  for (const f of p.failed || []) box.append(el("p", { class: "text-sm text-amber-600" }, f));
@@ -70,7 +70,7 @@ const OPTIONS = [
70
70
  ["use_quirks", "Apply the built-in fixes for known non-standard devices"],
71
71
  ["expose_unused", "Show dps no entity uses, as plain properties"],
72
72
  ["allow_hazardous", "Allow controlling hazardous covers (garage doors, gates)"],
73
- ["pack", "Download fixes for non-standard devices published between releases (into custom converters)"],
73
+ ["pack", "Automatically update builtin rules at start and daily"],
74
74
  ];
75
75
 
76
76
  async function settingsBox(ctx) {
@@ -1,6 +0,0 @@
1
- ### Changed
2
- - Require tuya2ildevice 0.4.0.dev4 in the package and Home Assistant integration.
3
- - Load bundled official rules from `rules/builtin/`, exclude the manifest from rule layers, and apply user files after official rules regardless of filename.
4
- - Fetch the complete official pack into `rules/builtin/` inside the overrides directory and watch it for live reloads.
5
- - Retire unedited files owned by the old flat override pack while preserving user edits.
6
- - Include the official rule layers and manifest in the manager drop-in archive.