iobroker.fid-smartlife 0.8.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 fiducerion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ <img src="admin/fid-smartlife.png" alt="logo" width="120" align="right"/>
2
+
3
+ # ioBroker.fid-smartlife
4
+
5
+ Tuya / Smart Life cloud + local LAN adapter for ioBroker.
6
+
7
+ > ⚠️ **ALPHA / EXPERIMENTAL** ⚠️
8
+ >
9
+ > This adapter is in active development on a single production system.
10
+ > Breaking changes between versions are expected. There is no support
11
+ > guarantee. Issues are welcome but response time is voluntary. Use at
12
+ > your own risk.
13
+
14
+ ## Features
15
+
16
+ - Reads device list, schemas and live status from the Tuya OpenAPI v2
17
+ - Local LAN control (Tuya protocol 3.3) — most write commands run without
18
+ hitting the cloud, no quota burn even for blink scripts
19
+ - LAN-Discovery picks up device IPs automatically from broadcast announces
20
+ - Cloud-IP-Import command as fallback when discovery doesn't catch a device
21
+ - Online state based on actual local reachability with hysteresis (50 fails
22
+ or 60 minutes without local-OK before flipping to offline) — battery /
23
+ sub-devices fall back to cloud-reported online state
24
+ - Optional Pulsar/MQTT push subscriber for cloud status events (experimental,
25
+ off by default)
26
+ - Schema database with ~8000 entries as fallback for devices where the cloud
27
+ spec is sparse
28
+ - Bitmap, RGB-color and energy-plug enhanced derived states (compatible with
29
+ the iobroker.tuya state layout: state under both code-name and DPS-id)
30
+
31
+ ## Requirements
32
+
33
+ 1. A Tuya Smart / Smart Life account (the same one used by the mobile app)
34
+ 2. A Tuya IoT Platform cloud project (free, see "Tuya account setup" below)
35
+ 3. ioBroker with js-controller 5+ and Node.js 18+
36
+
37
+ ## Tuya account setup
38
+
39
+ You need a Tuya Developer cloud project with your Smart Life app account
40
+ linked. This is the same procedure as for `iobroker.tuya`'s cloud mode.
41
+
42
+ 1. Sign in at https://platform.tuya.com (or `iot.tuya.com`)
43
+ 2. **Cloud → Development → Create Cloud Project**
44
+ - Name: anything you like
45
+ - Industry: *Smart Home*
46
+ - Development Method: *Smart Home*
47
+ - Data Center: pick the one matching your Smart Life region (Central
48
+ Europe → EU, North America → US, ...)
49
+ 3. After creating, the project shows **Access ID** and **Access Secret** —
50
+ copy both.
51
+ 4. **Service API** tab → make sure these API services are subscribed and
52
+ authorized to the project:
53
+ - **IoT Core** (required)
54
+ - **Authorization** (required)
55
+ - **Smart Home Basic Service** (required)
56
+ - **Device Status Notification** (only needed for the optional Pulsar
57
+ push subscriber)
58
+ 5. **Devices → Link Tuya App Account → Add App Account** — scan the QR with
59
+ your Smart Life app. After confirming, your devices appear under
60
+ *All Devices*.
61
+
62
+ If you have a Tuya **Trial Edition** (the default for new accounts), the
63
+ "controllable device pool quota" is limited — typically renewed monthly.
64
+ With many devices, prefer local control (which fid-smartlife uses by
65
+ default) to keep cloud calls minimal.
66
+
67
+ ## Installation
68
+
69
+ ### Option A: via Admin UI (recommended for testing)
70
+
71
+ In ioBroker admin: *Adapters → Install via URL* and enter:
72
+
73
+ ```
74
+ https://github.com/fiducerion/ioBroker.fid-smartlife
75
+ ```
76
+
77
+ ioBroker pulls the latest commit on `main` and installs it.
78
+
79
+ ### Option B: via CLI
80
+
81
+ ```bash
82
+ iobroker url https://github.com/fiducerion/ioBroker.fid-smartlife
83
+ ```
84
+
85
+ ### Option C: pin a specific release tag
86
+
87
+ ```bash
88
+ iobroker url https://github.com/fiducerion/ioBroker.fid-smartlife/tarball/v0.7.7
89
+ ```
90
+
91
+ ## Configuration
92
+
93
+ Open the instance settings in the admin UI:
94
+
95
+ - **Access ID** + **Access Secret** + **Region**: from the Tuya cloud project
96
+ - **Polling interval**: how often to refresh status from devices (default 60s).
97
+ Lower for faster updates, but more cloud calls.
98
+ - **Enable LAN discovery**: should stay on — without it no local IPs
99
+ - **Enable Pulsar/MQTT Push** (experimental): subscribe to device status
100
+ push from Tuya cloud. Default off. Requires "Device Status Notification"
101
+ API in the cloud project.
102
+
103
+ After saving, the adapter discovers all devices from the cloud and creates
104
+ states under:
105
+
106
+ ```
107
+ fid-smartlife.0.<deviceId>.<dpId> # primary state, matches iobroker.tuya layout
108
+ fid-smartlife.0.<deviceId>.<codeName> # alias for the same data point
109
+ fid-smartlife.0.<deviceId>.ip # local IP (set by LAN-Discovery)
110
+ fid-smartlife.0.<deviceId>.localKey # AES key for local control
111
+ fid-smartlife.0.<deviceId>.online # local reachability with hysteresis
112
+ fid-smartlife.0.<deviceId>.noLocalConnection # set to true to disable local writes
113
+ fid-smartlife.0.<deviceId>._noCloudStatusPoll # set to true to skip cloud polling
114
+ ```
115
+
116
+ Plus diagnostic states under `fid-smartlife.0.info.*`:
117
+
118
+ ```
119
+ info.connection # adapter healthy
120
+ info.cloudQuotaPaused # Tuya quota guard active (60min backoff)
121
+ info.pulsarConnected # Pulsar/MQTT push subscriber active
122
+ info.pulsarMessages # decrypted push messages counter
123
+ info.localResetV065 # one-time migration marker (don't touch)
124
+ ```
125
+
126
+ ## Diagnostic sendto commands
127
+
128
+ ```bash
129
+ # How many writes went local vs cloud, plus list of devices without local IP
130
+ iobroker sendto fid-smartlife.0 writeStats
131
+
132
+ # Import IPs from cloud for devices that LAN discovery hasn't caught
133
+ iobroker sendto fid-smartlife.0 importCloudIPs
134
+
135
+ # Find devices that used to be in the cloud but aren't anymore
136
+ iobroker sendto fid-smartlife.0 findMissingDevices
137
+
138
+ # Raw device list from Tuya cloud
139
+ iobroker sendto fid-smartlife.0 listDevicesRaw
140
+ ```
141
+
142
+ ## Heavy switching scripts (alarm blink, etc)
143
+
144
+ If you have scripts that rapidly toggle devices (e.g. blink lights every
145
+ 3 seconds during an alarm), make sure those devices:
146
+
147
+ 1. Have a `local.ip` set (check with `iobroker state get
148
+ fid-smartlife.0.<deviceId>.ip`)
149
+ 2. Are reachable from the ioBroker host (no VLAN/firewall isolation)
150
+ 3. Optionally have `_noCloudStatusPoll = true` to skip the periodic cloud
151
+ status read
152
+
153
+ If `local.ip` is empty, run `importCloudIPs` once. After that the adapter
154
+ writes locally and burns no cloud quota for these scripts.
155
+
156
+ ## Internet block as quota protection
157
+
158
+ A nice trick: block internet access to specific Tuya devices in your
159
+ router (e.g. AVM FRITZ!Box → Network → Devices → tick "deny internet").
160
+ The device stays reachable locally, broadcasts its presence to the LAN,
161
+ and `fid-smartlife` controls it via the local protocol. Tuya cloud will
162
+ report the device as offline (which is fine — the local online state
163
+ based on reachability is authoritative). No more accidental cloud calls
164
+ for that device, ever.
165
+
166
+ ## What is NOT supported (yet)
167
+
168
+ - Tuya protocol v3.4 (HMAC-SHA256 handshake + session key) — affects a
169
+ small number of newer devices, they fall back to cloud-only
170
+ - Camera streams (RTSPS allocation, snapshot URLs)
171
+ - Tuya Bluetooth gateway sub-devices via local protocol (cloud only)
172
+ - Multi-instance setups
173
+
174
+ ## License
175
+
176
+ MIT
Binary file
@@ -0,0 +1,7 @@
1
+ {
2
+ "Tuya Cloud (IoT Platform)": "Tuya Cloud (IoT Platform)",
3
+ "Polling": "Polling",
4
+ "Schreiben (Commands)": "Schreiben (Commands)",
5
+ "Geraete-Eigenheiten": "Geräte-Eigenheiten",
6
+ "Debug": "Debug"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "Tuya Cloud (IoT Platform)": "Tuya Cloud (IoT Platform)",
3
+ "Polling": "Polling",
4
+ "Schreiben (Commands)": "Write (Commands)",
5
+ "Geraete-Eigenheiten": "Device quirks",
6
+ "Debug": "Debug"
7
+ }
@@ -0,0 +1,195 @@
1
+ {
2
+ "type": "panel",
3
+ "i18n": true,
4
+ "items": {
5
+ "_header_cloud": {
6
+ "newLine": true,
7
+ "type": "header",
8
+ "size": 3,
9
+ "text": "Tuya Cloud (IoT Platform)"
10
+ },
11
+ "_info_cloud": {
12
+ "newLine": true,
13
+ "type": "staticText",
14
+ "text": "Lege dir auf iot.tuya.com einen Cloud-Project an, linke deine SmartLife-App und kopiere Access ID / Access Secret hierher. Die Region muss zu deinem App-Account passen.",
15
+ "style": { "fontStyle": "italic", "marginBottom": "12px", "color": "#666" }
16
+ },
17
+ "clientId": {
18
+ "newLine": true,
19
+ "type": "text",
20
+ "label": "Access ID (Client ID)",
21
+ "help": "Dein Tuya Cloud Access ID",
22
+ "sm": 12, "md": 6
23
+ },
24
+ "clientSecret": {
25
+ "type": "password",
26
+ "label": "Access Secret (Client Secret)",
27
+ "help": "Dein Tuya Cloud Access Secret",
28
+ "sm": 12, "md": 6
29
+ },
30
+ "region": {
31
+ "newLine": true,
32
+ "type": "select",
33
+ "label": "Region",
34
+ "options": [
35
+ { "value": "eu", "label": "Europe (openapi.tuyaeu.com)" },
36
+ { "value": "us", "label": "America (openapi.tuyaus.com)" },
37
+ { "value": "cn", "label": "China (openapi.tuyacn.com)" },
38
+ { "value": "in", "label": "India (openapi.tuyain.com)" }
39
+ ],
40
+ "sm": 12, "md": 4
41
+ },
42
+ "_header_poll": {
43
+ "newLine": true,
44
+ "type": "header",
45
+ "size": 3,
46
+ "text": "Polling"
47
+ },
48
+ "pollIntervalSec": {
49
+ "newLine": true,
50
+ "type": "number",
51
+ "min": 10,
52
+ "max": 3600,
53
+ "label": "Poll-Intervall (Sekunden)",
54
+ "help": "Wie oft Geraetestatus aus der Cloud abgerufen wird. Default 60.",
55
+ "sm": 12, "md": 3
56
+ },
57
+ "rediscoverIntervalMin": {
58
+ "type": "number",
59
+ "min": 0,
60
+ "max": 10080,
61
+ "label": "Rediscovery (Minuten)",
62
+ "help": "0 = keine periodische Rediscovery. Default 720 (alle 12 Stunden).",
63
+ "sm": 12, "md": 3
64
+ },
65
+ "maxParallelPolls": {
66
+ "type": "number",
67
+ "min": 1,
68
+ "max": 5,
69
+ "label": "Parallele Polls",
70
+ "help": "Wie viele Geraete gleichzeitig gepollt werden. Default 1 (sequentiell, schonend).",
71
+ "sm": 12, "md": 3
72
+ },
73
+ "requestTimeoutMs": {
74
+ "type": "number",
75
+ "min": 2000,
76
+ "max": 60000,
77
+ "label": "Request-Timeout (ms)",
78
+ "help": "HTTP-Timeout fuer einzelne Cloud-Aufrufe. Default 12000.",
79
+ "sm": 12, "md": 3
80
+ },
81
+ "_header_write": {
82
+ "newLine": true,
83
+ "type": "header",
84
+ "size": 3,
85
+ "text": "Schreiben (Commands)"
86
+ },
87
+ "writeDebounceMs": {
88
+ "newLine": true,
89
+ "type": "number",
90
+ "min": 0,
91
+ "max": 5000,
92
+ "label": "Write-Debounce (ms)",
93
+ "help": "Zusammenfassen schnell aufeinanderfolgender Writes. Default 400.",
94
+ "sm": 12, "md": 4
95
+ },
96
+ "optimisticAck": {
97
+ "type": "checkbox",
98
+ "label": "Optimistic ACK",
99
+ "help": "Beim Schreiben den State sofort mit ack=true zurueckschreiben, bevor das Geraet bestaetigt. Schnelle UI-Reaktion. Default an.",
100
+ "sm": 12, "md": 4
101
+ },
102
+ "_header_quirks": {
103
+ "newLine": true,
104
+ "type": "header",
105
+ "size": 3,
106
+ "text": "Geraete-Eigenheiten"
107
+ },
108
+ "noCloudStatusPollIds": {
109
+ "newLine": true,
110
+ "type": "text",
111
+ "label": "Geraete-IDs ohne Cloud-Status-Poll",
112
+ "help": "Komma-getrennte Liste von deviceIds die NICHT regelmaessig per Cloud gepollt werden sollen (z.B. weil sie 'function not support' werfen). Default enthaelt zwei bekannte Problemgeraete.",
113
+ "sm": 12, "md": 12,
114
+ "noTranslation": true
115
+ },
116
+ "_header_local": {
117
+ "newLine": true,
118
+ "type": "header",
119
+ "size": 3,
120
+ "text": "Lokale Steuerung (LAN, Tuya v3.3)"
121
+ },
122
+ "_info_local": {
123
+ "newLine": true,
124
+ "type": "staticText",
125
+ "text": "Pro Geraet kann via fid-smartlife.0.<deviceId>._local.preferLocal=true aktiviert werden, dass Schreibbefehle ueber LAN statt Cloud gehen. localKey wird aus der Cloud-Discovery uebernommen. IP+Version koennen aus tuya.0 importiert werden, falls dieser Adapter noch parallel laeuft, oder per UDP-Broadcast erkannt werden.",
126
+ "style": { "fontStyle": "italic", "marginBottom": "12px", "color": "#666" }
127
+ },
128
+ "enableLanDiscovery": {
129
+ "newLine": true,
130
+ "type": "checkbox",
131
+ "label": "LAN-Discovery aktivieren (UDP 6666/6667/7000)",
132
+ "help": "Lauscht auf Tuya-Geraete-Broadcasts und uebernimmt IP+Version automatisch in die _local-States.",
133
+ "sm": 12, "md": 6
134
+ },
135
+ "importLocalFromTuyaAdapter": {
136
+ "type": "checkbox",
137
+ "label": "Import lokaler IPs aus tuya.0",
138
+ "help": "Falls iobroker.tuya parallel laeuft, werden lokale IPs/Versionen beim Start uebernommen.",
139
+ "sm": 12, "md": 6
140
+ },
141
+ "_header_pulsar": {
142
+ "newLine": true,
143
+ "type": "header",
144
+ "text": "Pulsar / MQTT Push (experimentell)",
145
+ "size": 4
146
+ },
147
+ "_help_pulsar": {
148
+ "newLine": true,
149
+ "type": "staticText",
150
+ "text": "Wenn aktiviert, verbindet sich der Adapter via MQTT mit dem Tuya-Pulsar-Broker und empfaengt Device-Status-Updates per Push (statt per Polling). Voraussetzung: In der Tuya IoT Platform muss unter dem Cloud-Project der Message Service abonniert sein. Spart massiv Cloud-Quota - besonders fuer Battery-/Subdevices wichtig.",
151
+ "style": { "fontStyle": "italic", "marginBottom": "12px", "color": "#666" }
152
+ },
153
+ "enablePulsar": {
154
+ "newLine": true,
155
+ "type": "checkbox",
156
+ "label": "Pulsar/MQTT Push aktivieren",
157
+ "help": "Voraussetzung: Message Service in Tuya IoT Platform abonniert. Status sichtbar unter info.pulsarConnected.",
158
+ "sm": 12, "md": 6
159
+ },
160
+ "localTimeoutMs": {
161
+ "newLine": true,
162
+ "type": "number",
163
+ "min": 500,
164
+ "max": 30000,
165
+ "label": "Lokales Timeout (ms)",
166
+ "help": "TCP-Timeout fuer Local-Schreibbefehle. Default 2500.",
167
+ "sm": 12, "md": 3
168
+ },
169
+ "_header_compat": {
170
+ "newLine": true,
171
+ "type": "header",
172
+ "size": 3,
173
+ "text": "State-Layout"
174
+ },
175
+ "_info_compat": {
176
+ "newLine": true,
177
+ "type": "staticText",
178
+ "text": "Datenpunkte werden nach iobroker.tuya-Konvention angelegt: <device>.<dps-id> mit common.name = Code-Name. Bestehende Skripte/VIS-Bindings die 'tuya.0.<dev>.20' lesen koennen 1:1 auf 'fid-smartlife.0.<dev>.20' umgestellt werden. Zusaetzlich gibt es lesbare Aliase pro Geraet (on, brightness, temperature, ...) wo sinnvoll. Lokale Settings sind direkt unter dem Geraet: <dev>.ip, <dev>.noLocalConnection, <dev>.localKey, <dev>.localVersion, <dev>.localPort.",
179
+ "style": { "fontStyle": "italic", "marginBottom": "12px", "color": "#666" }
180
+ },
181
+ "_header_debug": {
182
+ "newLine": true,
183
+ "type": "header",
184
+ "size": 3,
185
+ "text": "Debug"
186
+ },
187
+ "debug": {
188
+ "newLine": true,
189
+ "type": "checkbox",
190
+ "label": "Debug-Logging aktivieren",
191
+ "help": "Zusaetzliche Debug-Meldungen. Loglevel muss auf 'debug' stehen.",
192
+ "sm": 12, "md": 4
193
+ }
194
+ }
195
+ }