iobroker.assistant 0.1.2

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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -0
  3. package/admin/assistant.svg +19 -0
  4. package/admin/custom/.vite/manifest.json +169 -0
  5. package/admin/custom/assets/Components-DcnuVFM6.js +1 -0
  6. package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomAssistant__mf_owner__1-DogEjv3U.js +1 -0
  7. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js +1 -0
  8. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js +1 -0
  9. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js +1243 -0
  10. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js +1494 -0
  11. package/admin/custom/assets/hostInit-DKMI-sLp.js +1 -0
  12. package/admin/custom/assets/index-B8wW0kQx.js +1 -0
  13. package/admin/custom/assets/lib-DpE8sc4h.js +3 -0
  14. package/admin/custom/assets/mf-entry-bootstrap-0-e7fa582d.js +36 -0
  15. package/admin/custom/assets/rolldown-runtime-C0FnF6B9.js +1 -0
  16. package/admin/custom/assets/virtualExposes-DOTO22UK.js +1 -0
  17. package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js-CQa59yVi.js +1 -0
  18. package/admin/custom/assets/virtual_mf-exposes-ssr___mfe_internal__ConfigCustomAssistant__customComponents_js-9g2Fj8tk.js +2 -0
  19. package/admin/custom/assets/virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js-BTUQTbYo.js +2 -0
  20. package/admin/custom/assets/vite-preload-helper-B7qeedMF.js +1 -0
  21. package/admin/custom/customComponents.js +1 -0
  22. package/admin/custom/customComponents.ssr.js +1 -0
  23. package/admin/custom/i18n/de.json +58 -0
  24. package/admin/custom/i18n/en.json +58 -0
  25. package/admin/custom/i18n/es.json +34 -0
  26. package/admin/custom/i18n/fr.json +34 -0
  27. package/admin/custom/i18n/it.json +34 -0
  28. package/admin/custom/i18n/nl.json +34 -0
  29. package/admin/custom/i18n/pl.json +34 -0
  30. package/admin/custom/i18n/pt.json +34 -0
  31. package/admin/custom/i18n/ru.json +34 -0
  32. package/admin/custom/i18n/uk.json +34 -0
  33. package/admin/custom/i18n/zh-cn.json +34 -0
  34. package/admin/custom/index.html +32 -0
  35. package/admin/custom/mf-manifest.json +1 -0
  36. package/admin/custom/mf-stats.json +1 -0
  37. package/admin/i18n/de.json +130 -0
  38. package/admin/i18n/en.json +130 -0
  39. package/admin/i18n/es.json +106 -0
  40. package/admin/i18n/fr.json +106 -0
  41. package/admin/i18n/it.json +106 -0
  42. package/admin/i18n/nl.json +106 -0
  43. package/admin/i18n/pl.json +106 -0
  44. package/admin/i18n/pt.json +106 -0
  45. package/admin/i18n/ru.json +106 -0
  46. package/admin/i18n/uk.json +106 -0
  47. package/admin/i18n/zh-cn.json +106 -0
  48. package/admin/jsonConfig.json +743 -0
  49. package/admin/sounds/alarm.wav +0 -0
  50. package/admin/sounds/timer.wav +0 -0
  51. package/build/lib/alarms.js +281 -0
  52. package/build/lib/alarms.js.map +1 -0
  53. package/build/lib/context.js +52 -0
  54. package/build/lib/context.js.map +1 -0
  55. package/build/lib/credentials.js +121 -0
  56. package/build/lib/credentials.js.map +1 -0
  57. package/build/lib/llm.js +303 -0
  58. package/build/lib/llm.js.map +1 -0
  59. package/build/lib/localLlm.js +221 -0
  60. package/build/lib/localLlm.js.map +1 -0
  61. package/build/lib/memory.js +190 -0
  62. package/build/lib/memory.js.map +1 -0
  63. package/build/lib/nlu.js +929 -0
  64. package/build/lib/nlu.js.map +1 -0
  65. package/build/lib/timers.js +245 -0
  66. package/build/lib/timers.js.map +1 -0
  67. package/build/lib/tools.js +299 -0
  68. package/build/lib/tools.js.map +1 -0
  69. package/build/lib/voice/aws.js +102 -0
  70. package/build/lib/voice/aws.js.map +1 -0
  71. package/build/lib/voice/azure.js +144 -0
  72. package/build/lib/voice/azure.js.map +1 -0
  73. package/build/lib/voice/download.js +76 -0
  74. package/build/lib/voice/download.js.map +1 -0
  75. package/build/lib/voice/engines.js +89 -0
  76. package/build/lib/voice/engines.js.map +1 -0
  77. package/build/lib/voice/lang.js +33 -0
  78. package/build/lib/voice/lang.js.map +1 -0
  79. package/build/lib/voice/piper.js +191 -0
  80. package/build/lib/voice/piper.js.map +1 -0
  81. package/build/lib/voice/protocol.js +35 -0
  82. package/build/lib/voice/protocol.js.map +1 -0
  83. package/build/lib/voice/stt.js +116 -0
  84. package/build/lib/voice/stt.js.map +1 -0
  85. package/build/lib/voice/tts.js +36 -0
  86. package/build/lib/voice/tts.js.map +1 -0
  87. package/build/lib/voice/voiceServer.js +249 -0
  88. package/build/lib/voice/voiceServer.js.map +1 -0
  89. package/build/lib/voice/vosk.js +260 -0
  90. package/build/lib/voice/vosk.js.map +1 -0
  91. package/build/lib/voice/wyoming.js +320 -0
  92. package/build/lib/voice/wyoming.js.map +1 -0
  93. package/build/lib/weather.js +423 -0
  94. package/build/lib/weather.js.map +1 -0
  95. package/build/main.js +3152 -0
  96. package/build/main.js.map +1 -0
  97. package/io-package.json +528 -0
  98. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Denis Haev <dogafox@gmail.com>
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/assistant.svg" alt="ioBroker.assistant" width="200"/>
2
+
3
+ # ioBroker.assistant
4
+
5
+ An LLM-based assistant for ioBroker. Ask questions in natural language and let the
6
+ assistant read or control **any ioBroker state** — it uses an LLM with **tool-calling**
7
+ over the native ioBroker API, so there is no rigid rule engine and no virtual-device tree.
8
+
9
+ > Status: **early proof-of-concept.** Text in → answer out. Audio (satellites, STT/TTS)
10
+ > and on-device wake word are planned next (see Roadmap).
11
+
12
+ ## What works today
13
+
14
+ - Provider: **OpenAI** (and OpenAI-compatible endpoints via Base URL) or **Anthropic (Claude)**.
15
+ - The LLM can call these tools, all backed by the native adapter API:
16
+ - `list_rooms`, `list_functions` — read `enum.rooms` / `enum.functions`
17
+ - `find_states({ room?, func?, query? })` — find states + current values
18
+ - `get_state({ id })` — read one value
19
+ - `set_state({ id, value })` — control a device (can be disabled in settings)
20
+ - Text interface via two states:
21
+ - write your question to `assistant.0.text.request`
22
+ - read the answer from `assistant.0.text.response`
23
+ - Or from a script: `sendTo('assistant.0', 'ask', { text: 'Wie warm ist es im Wohnzimmer?' }, cb)`
24
+
25
+ ## Configuration
26
+
27
+ In the adapter admin (Instances → assistant → ⚙):
28
+
29
+ | Setting | Meaning |
30
+ |--------------------------|---------------------------------------------------|
31
+ | Provider | `openai` or `anthropic` |
32
+ | Model | e.g. `gpt-4o-mini`, `gpt-4o`, `claude-sonnet-4-6` |
33
+ | API key | your provider API key |
34
+ | Base URL | optional endpoint override (e.g. Groq) |
35
+ | Allow controlling states | if off, the assistant is read-only |
36
+ | System prompt | persona / behaviour |
37
+
38
+ ## Voice satellites (Hannah)
39
+
40
+ The adapter runs a UDP voice server that speaks the **Hannah** satellite protocol
41
+ (`0x01` control / `0x02` mic audio / `0x03` TTS), so an existing Hannah Pi/ESP satellite can
42
+ talk to it directly. STT → LLM → TTS runs in the adapter; the satellite only captures audio,
43
+ detects the wake word and plays the reply.
44
+
45
+ **On the adapter side:** open the **Voice** tab, tick *Enable voice server*, pick the STT/TTS
46
+ providers + credentials, keep the port (default `7775`). When the instance starts the log shows:
47
+
48
+ ```
49
+ Voice server listening on UDP 7775
50
+ ```
51
+
52
+ Recognised text and the reply also appear in `assistant.0.text.request` / `.text.response`, with
53
+ the origin in `assistant.0.text.querySource` (satellite name, `chat`, or empty for a direct state write).
54
+
55
+ **Announcements / TTS:** write to `assistant.0.tts.text` to speak on **all** satellites, or to
56
+ `assistant.0.satellites.<id>.tts` for **one**. The value is spoken as text (via the configured TTS engine),
57
+ or — if it is a URL/path to an audio file (`.mp3`/`.wav`/…) — played back.
58
+
59
+ > **Playing audio files needs [ffmpeg](https://ffmpeg.org/) on the host** (Windows and Linux):
60
+ > Linux → `sudo apt install ffmpeg`; Windows → install ffmpeg and add it to the `PATH`.
61
+ > Plain-text TTS does not need it — only audio-file playback (mp3/wav/…) does.
62
+
63
+ ### Start a Hannah satellite pointed at this adapter
64
+
65
+ Match the audio rates to your device (`--sample-rate` = mic, `--tts-rate` = speaker); list devices
66
+ and supported rates with `python3 -c "import pyaudio; p=pyaudio.PyAudio(); [print(i, p.get_device_info_by_index(i)) for i in range(p.get_device_count())]"`.
67
+
68
+ The stock Hannah satellite locates the server via **MQTT discovery**, so it needs a broker reachable
69
+ and one retained discovery message. Point `--host` at the ioBroker host explicitly:
70
+
71
+ ```bash
72
+ # 1. publish the adapter address once (retained) so the satellite finds it:
73
+ mosquitto_pub -h <broker-ip> -t hannah/server -r -m '{"host":"<iobroker-ip>","port":7775}'
74
+
75
+ # 2. start the satellite (venv), --broker = MQTT broker, --host = this adapter:
76
+ /opt/Hannah/satellite-pi/venv/bin/python3 /opt/Hannah/satellite-pi/satellite.py \
77
+ --device wohnzimmer --room Wohnzimmer \
78
+ --broker <broker-ip> --host <iobroker-ip> --port 7775 \
79
+ --mic 0 --speaker 0 --sample-rate 16000 --tts-rate 48000
80
+ ```
81
+
82
+ Success looks like `Registrierung bestätigt (ACK empfangen)` in the satellite log and
83
+ `Satellite registered: wohnzimmer` in the adapter log. Then say the wake word → speak → the answer
84
+ is spoken back.
85
+
86
+ ### Without an MQTT broker
87
+
88
+ The stock Hannah satellite always connects to MQTT (even with `--host`) and exits if no broker is
89
+ reachable. To run **fully broker-free**, skip that one call — in `satellite.py`,
90
+ `_resolve_hannah_address()`:
91
+
92
+ ```python
93
+ if self.cfg.hannah_host:
94
+ self._hannah_addr = (self.cfg.hannah_host, self.cfg.hannah_port)
95
+ # self._mqtt.connect() # ← comment out to run without a broker (disables MQTT status/LWT only)
96
+ else:
97
+ self._hannah_addr = self._mqtt.connect()
98
+ ```
99
+
100
+ Registration, audio and TTS all run over UDP, so only the (optional) MQTT status reporting is lost.
101
+ Then start with just `--host` (no `--broker` needed):
102
+
103
+ ```bash
104
+ /opt/Hannah/satellite-pi/venv/bin/python3 /opt/Hannah/satellite-pi/satellite.py \
105
+ --device wohnzimmer --room Wohnzimmer --host <iobroker-ip> --port 7775 \
106
+ --mic 0 --speaker 0 --sample-rate 16000 --tts-rate 48000
107
+ ```
108
+
109
+ ### Native Node.js satellite
110
+
111
+ A standalone **Node.js satellite** is available — no ioBroker, no MQTT broker required. On a Pi (or any
112
+ Linux/Windows/macOS box) with a mic + speaker:
113
+
114
+ ```bash
115
+ npx @iobroker/assistant-satellite # writes a default config, then edit "host"
116
+ npx @iobroker/assistant-satellite config.json
117
+ ```
118
+
119
+ It runs the wake word (OpenWakeWord) on the device and streams to this adapter's voice server. See
120
+ [`@iobroker/assistant-satellite`](https://github.com/ioBroker/assistant-satellite) for setup, the
121
+ `check` diagnostics and `install` (systemd service).
122
+
123
+ ### Wyoming endpoint (experimental)
124
+
125
+ [Wyoming](https://github.com/rhasspy/wyoming) is the open voice protocol from the Home Assistant /
126
+ Rhasspy project (JSONL events over **TCP**), used by `wyoming-satellite`, the **Home Assistant Voice PE**
127
+ puck and **ESPHome** voice devices.
128
+
129
+ Enable **Also accept Wyoming clients (TCP)** in the Voice tab (default port `10700`). The adapter then
130
+ exposes a Wyoming server that bridges to the same pipeline: `audio-start`/`audio-chunk`/`audio-stop` →
131
+ STT → answer → TTS streamed back as `audio-*` (plus a `transcript` event); `describe` → `info`;
132
+ `synthesize` → TTS.
133
+
134
+ > The protocol framing is unit-tested, but interop with real HA Voice PE / `wyoming-satellite` is still
135
+ > **experimental** — please report what works. Uses the same STT/TTS providers as the UDP voice server.
136
+
137
+ ## Roadmap
138
+
139
+ 1. **Text assistant (done)** — LLM + tool-calling over ioBroker states.
140
+ 2. **Fast-path** for common commands (on/off/timer) without an LLM round-trip.
141
+ 3. **TTS / STT engines** (Polly / Azure / OpenAI / AWS Transcribe) as adapter modules + config.
142
+ 4. **Satellite endpoint** — UDP audio + MQTT control, so ESP/Pi satellites talk to the adapter directly.
143
+ 5. **Wake word** — trained/managed via ioBroker, running on the device.
144
+ 6. **Wyoming server endpoint** — accept Home Assistant Voice PE / `wyoming-satellite` / ESPHome voice devices.
145
+
146
+ ## Changelog
147
+ <!--
148
+ Placeholder for the next version (at the beginning of the line):
149
+ ### **WORK IN PROGRESS**
150
+ -->
151
+ ### 0.1.2 (2026-08-03)
152
+ * (@GermanBluefox) Initial commit
153
+
154
+ ## License
155
+
156
+ MIT License
157
+
158
+ Copyright (c) 2026 Denis Haev <dogafox@gmail.com>
159
+
160
+ Permission is hereby granted, free of charge, to any person obtaining a copy
161
+ of this software and associated documentation files (the "Software"), to deal
162
+ in the Software without restriction, including without limitation the rights
163
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
164
+ copies of the Software, and to permit persons to whom the Software is
165
+ furnished to do so, subject to the following conditions:
166
+
167
+ The above copyright notice and this permission notice shall be included in all
168
+ copies or substantial portions of the Software.
169
+
170
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
172
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
173
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
174
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
175
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
176
+ SOFTWARE.
@@ -0,0 +1,19 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128" height="128" role="img" aria-label="Assistant">
2
+ <defs>
3
+ <linearGradient id="assistantBg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#6366f1"/>
5
+ <stop offset="1" stop-color="#a855f7"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect x="4" y="4" width="120" height="120" rx="26" fill="url(#assistantBg)"/>
9
+ <!-- speech bubble -->
10
+ <rect x="30" y="36" width="68" height="46" rx="12" fill="#ffffff"/>
11
+ <path d="M44 82 v16 l17 -16 z" fill="#ffffff"/>
12
+ <!-- voice waveform inside the bubble -->
13
+ <g fill="#7c3aed">
14
+ <rect x="44" y="52" width="6" height="14" rx="3"/>
15
+ <rect x="56" y="46" width="6" height="26" rx="3"/>
16
+ <rect x="68" y="50" width="6" height="18" rx="3"/>
17
+ <rect x="80" y="55" width="6" height="8" rx="3"/>
18
+ </g>
19
+ </svg>
@@ -0,0 +1,169 @@
1
+ {
2
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js": {
3
+ "file": "assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js",
4
+ "name": "_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js",
5
+ "imports": [
6
+ "_rolldown-runtime-C0FnF6B9.js"
7
+ ]
8
+ },
9
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js": {
10
+ "file": "assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js",
11
+ "name": "_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js",
12
+ "imports": [
13
+ "_rolldown-runtime-C0FnF6B9.js",
14
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js"
15
+ ]
16
+ },
17
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js": {
18
+ "file": "assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js",
19
+ "name": "_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js",
20
+ "imports": [
21
+ "_rolldown-runtime-C0FnF6B9.js",
22
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js",
23
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js"
24
+ ]
25
+ },
26
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js": {
27
+ "file": "assets/_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js",
28
+ "name": "_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js",
29
+ "imports": [
30
+ "_rolldown-runtime-C0FnF6B9.js",
31
+ "_vite-preload-helper-B7qeedMF.js",
32
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js",
33
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js"
34
+ ],
35
+ "dynamicImports": [
36
+ "node_modules/react-qr-code/lib/index.mjs"
37
+ ]
38
+ },
39
+ "_rolldown-runtime-C0FnF6B9.js": {
40
+ "file": "assets/rolldown-runtime-C0FnF6B9.js",
41
+ "name": "rolldown-runtime"
42
+ },
43
+ "_virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js-CQa59yVi.js": {
44
+ "file": "assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js-CQa59yVi.js",
45
+ "name": "virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js",
46
+ "imports": [
47
+ "_vite-preload-helper-B7qeedMF.js",
48
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js"
49
+ ],
50
+ "dynamicImports": [
51
+ "virtual:mf-localSharedImportMap:__mfe_internal__ConfigCustomAssistant__mf_owner__1",
52
+ "virtual:mf-exposes:__mfe_internal__ConfigCustomAssistant__customComponents_js"
53
+ ]
54
+ },
55
+ "_virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js-BTUQTbYo.js": {
56
+ "file": "assets/virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js-BTUQTbYo.js",
57
+ "name": "virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js",
58
+ "imports": [
59
+ "_vite-preload-helper-B7qeedMF.js"
60
+ ],
61
+ "dynamicImports": [
62
+ "src/Components.tsx"
63
+ ]
64
+ },
65
+ "_vite-preload-helper-B7qeedMF.js": {
66
+ "file": "assets/vite-preload-helper-B7qeedMF.js",
67
+ "name": "vite-preload-helper"
68
+ },
69
+ "index.html": {
70
+ "file": "assets/index-B8wW0kQx.js",
71
+ "name": "index",
72
+ "src": "index.html",
73
+ "isEntry": true,
74
+ "imports": [
75
+ "_virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js-BTUQTbYo.js",
76
+ "_virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js-CQa59yVi.js"
77
+ ]
78
+ },
79
+ "node_modules/react-qr-code/lib/index.mjs": {
80
+ "file": "assets/lib-DpE8sc4h.js",
81
+ "name": "lib",
82
+ "src": "node_modules/react-qr-code/lib/index.mjs",
83
+ "isDynamicEntry": true,
84
+ "imports": [
85
+ "_rolldown-runtime-C0FnF6B9.js",
86
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js",
87
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js"
88
+ ]
89
+ },
90
+ "src/Components.tsx": {
91
+ "file": "assets/Components-DcnuVFM6.js",
92
+ "name": "Components",
93
+ "src": "src/Components.tsx",
94
+ "isEntry": true,
95
+ "imports": [
96
+ "_rolldown-runtime-C0FnF6B9.js",
97
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js",
98
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js",
99
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js"
100
+ ]
101
+ },
102
+ "virtual:mf-REMOTE_ENTRY_ID:__mfe_internal__ConfigCustomAssistant__customComponents_js": {
103
+ "file": "customComponents.js",
104
+ "name": "remoteEntry",
105
+ "src": "virtual:mf-REMOTE_ENTRY_ID:__mfe_internal__ConfigCustomAssistant__customComponents_js",
106
+ "imports": [
107
+ "_virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomAssistant__customComponents_js-CQa59yVi.js"
108
+ ]
109
+ },
110
+ "virtual:mf-REMOTE_ENTRY_SSR_ID:__mfe_internal__ConfigCustomAssistant__customComponents_js": {
111
+ "file": "customComponents.ssr.js",
112
+ "name": "ssrRemoteEntry",
113
+ "src": "virtual:mf-REMOTE_ENTRY_SSR_ID:__mfe_internal__ConfigCustomAssistant__customComponents_js",
114
+ "imports": [
115
+ "_vite-preload-helper-B7qeedMF.js"
116
+ ],
117
+ "dynamicImports": [
118
+ "virtual:mf-exposes-ssr:__mfe_internal__ConfigCustomAssistant__customComponents_js"
119
+ ]
120
+ },
121
+ "virtual:mf-exposes-ssr:__mfe_internal__ConfigCustomAssistant__customComponents_js": {
122
+ "file": "assets/virtual_mf-exposes-ssr___mfe_internal__ConfigCustomAssistant__customComponents_js-9g2Fj8tk.js",
123
+ "name": "virtual_mf-exposes-ssr___mfe_internal__ConfigCustomAssistant__customComponents_js",
124
+ "src": "virtual:mf-exposes-ssr:__mfe_internal__ConfigCustomAssistant__customComponents_js",
125
+ "isDynamicEntry": true,
126
+ "imports": [
127
+ "_vite-preload-helper-B7qeedMF.js"
128
+ ],
129
+ "dynamicImports": [
130
+ "src/Components.tsx"
131
+ ]
132
+ },
133
+ "virtual:mf-exposes:__mfe_internal__ConfigCustomAssistant__customComponents_js": {
134
+ "file": "assets/virtualExposes-DOTO22UK.js",
135
+ "name": "virtualExposes",
136
+ "src": "virtual:mf-exposes:__mfe_internal__ConfigCustomAssistant__customComponents_js",
137
+ "imports": [
138
+ "_virtual_mf-exposes___mfe_internal__ConfigCustomAssistant__customComponents_js-BTUQTbYo.js"
139
+ ]
140
+ },
141
+ "virtual:mf-localSharedImportMap:__mfe_internal__ConfigCustomAssistant__mf_owner__1": {
142
+ "file": "assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomAssistant__mf_owner__1-DogEjv3U.js",
143
+ "name": "_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomAssistant__mf_owner__1",
144
+ "src": "virtual:mf-localSharedImportMap:__mfe_internal__ConfigCustomAssistant__mf_owner__1",
145
+ "isDynamicEntry": true,
146
+ "imports": [
147
+ "_vite-preload-helper-B7qeedMF.js",
148
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js"
149
+ ],
150
+ "dynamicImports": [
151
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js",
152
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js",
153
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js",
154
+ "__virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js"
155
+ ]
156
+ },
157
+ "virtual:mf:__mfe_internal__ConfigCustomAssistant__mf_owner__1__H_A_I__hostAutoInit__H_A_I__.js": {
158
+ "file": "assets/hostInit-DKMI-sLp.js",
159
+ "name": "hostInit",
160
+ "src": "virtual:mf:__mfe_internal__ConfigCustomAssistant__mf_owner__1__H_A_I__hostAutoInit__H_A_I__.js",
161
+ "imports": [
162
+ "_vite-preload-helper-B7qeedMF.js"
163
+ ],
164
+ "dynamicImports": [
165
+ "virtual:mf-REMOTE_ENTRY_ID:__mfe_internal__ConfigCustomAssistant__customComponents_js",
166
+ "virtual:mf-localSharedImportMap:__mfe_internal__ConfigCustomAssistant__mf_owner__1"
167
+ ]
168
+ }
169
+ }
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-C0FnF6B9.js";import{t}from"./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js";import{B as n,_ as r}from"./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js";import{$t as i,At as a,Bn as o,Bt as s,Cn as c,Gt as l,I as ee,Jt as te,Kt as u,Mn as d,O as ne,On as f,Pt as re,R as ie,Tt as ae,Ur as p,Ut as oe,W as se,Wr as m,Xt as h,Yt as ce,_t as le,an as g,d as _,dn as v,k as ue,l as de,ln as fe,nn as y,qt as b,rn as x,sn as pe,u as me,un as S,wr as C}from"./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js";var w=e({custom_assistant_Announcement:()=>k,custom_assistant_Host:()=>O,custom_assistant_Satellite:()=>E,custom_assistant_Satellites:()=>T,custom_assistant_Speak:()=>he,custom_assistant_Status:()=>D,custom_assistant_auto:()=>ge,custom_assistant_device:()=>_e,custom_assistant_filter:()=>ve,custom_assistant_hint:()=>ye,custom_assistant_llm_downloading:()=>z,custom_assistant_llm_error:()=>H,custom_assistant_llm_idle:()=>L,custom_assistant_llm_installing:()=>R,custom_assistant_llm_loading:()=>B,custom_assistant_llm_ready:()=>V,custom_assistant_offline:()=>j,custom_assistant_online:()=>A,custom_assistant_read:()=>be,custom_assistant_room:()=>xe,custom_assistant_sat_idle:()=>M,custom_assistant_sat_listening:()=>N,custom_assistant_sat_offline:()=>I,custom_assistant_sat_processing:()=>P,custom_assistant_sat_speaking:()=>F,custom_assistant_type:()=>`Typ`,custom_assistant_write:()=>Se,default:()=>Ce}),T=`Satelliten`,E=`Satellit`,D=`Status`,O=`Host`,k=`Ansage`,A=`online`,j=`offline`,M=`inaktiv`,N=`hört zu`,P=`verarbeitet`,F=`spricht`,I=`offline`,L=`inaktiv`,R=`Engine wird installiert …`,z=`Modell wird geladen …`,B=`lädt …`,V=`bereit`,H=`Fehler`,he=`Sprechen`,ge=`automatisch`,_e=`Gerät`,ve=`Filter`,ye=`Deaktivieren Sie die Leseberechtigung, um ein Gerät vor dem Assistenten auszublenden, oder die Schreibberechtigung, um es schreibgeschützt zu halten (z. B. bei Sperren). Geräte sind standardmäßig vollständig zugelassen.`,be=`Lesen`,xe=`Zimmer`,Se=`Schreiben`,Ce={"custom_assistant_Clear chat":`Chat leeren`,"custom_assistant_Device cache cleared.":`Gerätecache geleert.`,"custom_assistant_Hide disabled":`Deaktivierte ausblenden`,"custom_assistant_Listening…":`Höre zu …`,"custom_assistant_Local model":`Lokales Modell`,custom_assistant_Satellites:T,custom_assistant_Satellite:E,custom_assistant_Status:D,custom_assistant_Host:O,"custom_assistant_Last seen":`Zuletzt gesehen`,custom_assistant_Announcement:k,"custom_assistant_Send announcement":`Ansage senden`,"custom_assistant_Speak on all satellites":`Auf allen Satelliten ansagen`,"custom_assistant_No satellites registered yet.":`Noch keine Satelliten registriert.`,custom_assistant_online:A,custom_assistant_offline:j,custom_assistant_sat_idle:M,custom_assistant_sat_listening:N,custom_assistant_sat_processing:P,custom_assistant_sat_speaking:F,custom_assistant_sat_offline:I,custom_assistant_llm_idle:L,"custom_assistant_llm_not installed":`nicht installiert`,custom_assistant_llm_installing:R,custom_assistant_llm_downloading:z,custom_assistant_llm_loading:B,custom_assistant_llm_ready:V,custom_assistant_llm_error:H,"custom_assistant_Name language: %s":`Namens-Sprache: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Es wurden keine Geräte erkannt. Weisen Sie Räumen und Funktionen in ioBroker Zustände zu.`,"custom_assistant_No messages yet. Type a question below.":`Noch keine Nachrichten. Geben Sie unten eine Frage ein.`,"custom_assistant_Per-device permissions":`Gerätespezifische Berechtigungen`,"custom_assistant_Play answer (backend TTS)":`Antwort abspielen (Backend-TTS)`,"custom_assistant_Read answers aloud":`Antworten vorlesen`,"custom_assistant_Refresh device cache":`Gerätecache aktualisieren`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Speichern Sie die Konfiguration (die Instanz startet neu), bevor Sie chatten.`,custom_assistant_Speak:he,"custom_assistant_Start the assistant instance to chat.":`Starten Sie die Assistenteninstanz, um zu chatten.`,"custom_assistant_Start the assistant instance to load the device list.":`Starten Sie die Assistenteninstanz, um die Geräteliste zu laden.`,"custom_assistant_Stop listening":`Zuhören beenden`,"custom_assistant_Stop reading answers aloud":`Vorlesen beenden`,"custom_assistant_Test chat":`Test-Chat`,"custom_assistant_Thinking…":`Denkt nach …`,"custom_assistant_Translate all missing (%s)":`Alle fehlenden übersetzen (%s)`,"custom_assistant_Translate name into %s":`Namen nach %s übersetzen`,"custom_assistant_Type a message…":`Nachricht eingeben …`,custom_assistant_auto:ge,"custom_assistant_change it on the Voice tab":`im Voice-Tab umschalten`,custom_assistant_device:_e,custom_assistant_filter:ve,custom_assistant_hint:ye,"custom_assistant_no name in %s (showing %s)":`Kein Name in "%s" — angezeigt: "%s"`,custom_assistant_read:be,custom_assistant_room:xe,custom_assistant_type:`Typ`,custom_assistant_write:Se},U=e({custom_assistant_Announcement:()=>Oe,custom_assistant_Host:()=>De,custom_assistant_Satellite:()=>Te,custom_assistant_Satellites:()=>we,custom_assistant_Speak:()=>He,custom_assistant_Status:()=>Ee,custom_assistant_auto:()=>Ue,custom_assistant_device:()=>We,custom_assistant_filter:()=>Ge,custom_assistant_hint:()=>Ke,custom_assistant_llm_downloading:()=>Re,custom_assistant_llm_error:()=>Ve,custom_assistant_llm_idle:()=>Ie,custom_assistant_llm_installing:()=>Le,custom_assistant_llm_loading:()=>ze,custom_assistant_llm_ready:()=>Be,custom_assistant_offline:()=>Ae,custom_assistant_online:()=>ke,custom_assistant_read:()=>qe,custom_assistant_room:()=>Je,custom_assistant_sat_idle:()=>je,custom_assistant_sat_listening:()=>Me,custom_assistant_sat_offline:()=>Fe,custom_assistant_sat_processing:()=>Ne,custom_assistant_sat_speaking:()=>Pe,custom_assistant_type:()=>Ye,custom_assistant_write:()=>Xe,default:()=>Ze}),we=`Satellites`,Te=`Satellite`,Ee=`Status`,De=`Host`,Oe=`Announcement`,ke=`online`,Ae=`offline`,je=`idle`,Me=`listening`,Ne=`processing`,Pe=`speaking`,Fe=`offline`,Ie=`idle`,Le=`installing engine…`,Re=`downloading model…`,ze=`loading…`,Be=`ready`,Ve=`error`,He=`Speak`,Ue=`auto`,We=`Device`,Ge=`Filter`,Ke=`Uncheck read to hide a device from the assistant, or uncheck write to keep it read-only (e.g. locks). Devices default to fully allowed.`,qe=`Read`,Je=`Room`,Ye=`Type`,Xe=`Write`,Ze={"custom_assistant_Clear chat":`Clear chat`,"custom_assistant_Device cache cleared.":`Device cache cleared.`,"custom_assistant_Hide disabled":`Hide disabled`,"custom_assistant_Listening…":`Listening…`,"custom_assistant_Local model":`Local model`,custom_assistant_Satellites:we,custom_assistant_Satellite:Te,custom_assistant_Status:Ee,custom_assistant_Host:De,"custom_assistant_Last seen":`Last seen`,custom_assistant_Announcement:Oe,"custom_assistant_Send announcement":`Send announcement`,"custom_assistant_Speak on all satellites":`Speak on all satellites`,"custom_assistant_No satellites registered yet.":`No satellites registered yet.`,custom_assistant_online:ke,custom_assistant_offline:Ae,custom_assistant_sat_idle:je,custom_assistant_sat_listening:Me,custom_assistant_sat_processing:Ne,custom_assistant_sat_speaking:Pe,custom_assistant_sat_offline:Fe,custom_assistant_llm_idle:Ie,"custom_assistant_llm_not installed":`not installed`,custom_assistant_llm_installing:Le,custom_assistant_llm_downloading:Re,custom_assistant_llm_loading:ze,custom_assistant_llm_ready:Be,custom_assistant_llm_error:Ve,"custom_assistant_Name language: %s":`Name language: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`No devices detected. Assign states to rooms and functions in ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`No messages yet. Type a question below.`,"custom_assistant_Per-device permissions":`Per-device permissions`,"custom_assistant_Play answer (backend TTS)":`Play answer (backend TTS)`,"custom_assistant_Read answers aloud":`Read answers aloud`,"custom_assistant_Refresh device cache":`Refresh device cache`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Save the configuration (the instance will restart) before chatting.`,custom_assistant_Speak:He,"custom_assistant_Start the assistant instance to chat.":`Start the assistant instance to chat.`,"custom_assistant_Start the assistant instance to load the device list.":`Start the assistant instance to load the device list.`,"custom_assistant_Stop listening":`Stop listening`,"custom_assistant_Stop reading answers aloud":`Stop reading answers aloud`,"custom_assistant_Test chat":`Test chat`,"custom_assistant_Thinking…":`Thinking…`,"custom_assistant_Translate all missing (%s)":`Translate all missing (%s)`,"custom_assistant_Translate name into %s":`Translate name into %s`,"custom_assistant_Type a message…":`Type a message…`,custom_assistant_auto:Ue,"custom_assistant_change it on the Voice tab":`change it on the Voice tab`,custom_assistant_device:We,custom_assistant_filter:Ge,custom_assistant_hint:Ke,"custom_assistant_no name in %s (showing %s)":`No name in "%s" — showing "%s"`,custom_assistant_read:qe,custom_assistant_room:Je,custom_assistant_type:Ye,custom_assistant_write:Xe},W=e({custom_assistant_Speak:()=>Qe,custom_assistant_auto:()=>$e,custom_assistant_device:()=>et,custom_assistant_filter:()=>tt,custom_assistant_hint:()=>nt,custom_assistant_read:()=>rt,custom_assistant_room:()=>it,custom_assistant_type:()=>at,custom_assistant_write:()=>ot,default:()=>st}),Qe=`Hablar`,$e=`auto`,et=`Dispositivo`,tt=`Filtrar`,nt=`Desactive la opción de lectura para ocultar un dispositivo al asistente, o desactive la opción de escritura para mantenerlo en modo de solo lectura (por ejemplo, candados). Los dispositivos vienen configurados por defecto con acceso completo.`,rt=`Leer`,it=`Habitación`,at=`Tipo`,ot=`Escribir`,st={"custom_assistant_Clear chat":`Chat claro`,"custom_assistant_Device cache cleared.":`Se ha borrado la caché del dispositivo.`,"custom_assistant_Hide disabled":`Ocultar deshabilitado`,"custom_assistant_Listening…":`Escuchando…`,"custom_assistant_Name language: %s":`Idioma del nombre: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`No se detectaron dispositivos. Asigne estados a las salas y funciones en ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Aún no hay mensajes. Escribe tu pregunta a continuación.`,"custom_assistant_Per-device permissions":`Permisos por dispositivo`,"custom_assistant_Play answer (backend TTS)":`Reproducir respuesta (TTS de backend)`,"custom_assistant_Read answers aloud":`Lee las respuestas en voz alta.`,"custom_assistant_Refresh device cache":`Actualizar la caché del dispositivo`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Guarda la configuración (la instancia se reiniciará) antes de chatear.`,custom_assistant_Speak:Qe,"custom_assistant_Start the assistant instance to chat.":`Inicia la instancia del asistente para chatear.`,"custom_assistant_Start the assistant instance to load the device list.":`Inicie la instancia del asistente para cargar la lista de dispositivos.`,"custom_assistant_Stop listening":`Deja de escuchar`,"custom_assistant_Stop reading answers aloud":`Deja de leer las respuestas en voz alta.`,"custom_assistant_Test chat":`Chat de prueba`,"custom_assistant_Thinking…":`Pensamiento…`,"custom_assistant_Translate all missing (%s)":`Traducir todos los (%s) faltantes`,"custom_assistant_Translate name into %s":`Traducir nombre a %s`,"custom_assistant_Type a message…":`Escribe un mensaje…`,custom_assistant_auto:$e,"custom_assistant_change it on the Voice tab":`Cámbialo en la pestaña Voz.`,custom_assistant_device:et,custom_assistant_filter:tt,custom_assistant_hint:nt,"custom_assistant_no name in %s (showing %s)":`No se encontró ningún nombre en "%s" — se muestra "%s"`,custom_assistant_read:rt,custom_assistant_room:it,custom_assistant_type:at,custom_assistant_write:ot},G=e({custom_assistant_Speak:()=>ct,custom_assistant_auto:()=>lt,custom_assistant_device:()=>ut,custom_assistant_filter:()=>dt,custom_assistant_hint:()=>ft,custom_assistant_read:()=>pt,custom_assistant_room:()=>mt,custom_assistant_type:()=>ht,custom_assistant_write:()=>gt,default:()=>_t}),ct=`Parler`,lt=`auto`,ut=`Appareil`,dt=`Filtre`,ft=`Décochez l'option «\xA0Lecture\xA0» pour masquer un périphérique à l'assistant, ou décochez l'option «\xA0Écriture\xA0» pour le rendre accessible en lecture seule (par exemple, les verrous). Par défaut, tous les périphériques sont autorisés.`,pt=`Lire`,mt=`Chambre`,ht=`Taper`,gt=`Écrire`,_t={"custom_assistant_Clear chat":`Discussion claire`,"custom_assistant_Device cache cleared.":`Cache du périphérique effacé.`,"custom_assistant_Hide disabled":`Masquer les fonctions désactivées`,"custom_assistant_Listening…":`Écoute…`,"custom_assistant_Name language: %s":`Langue du nom\xA0: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Aucun appareil détecté. Attribuez des états aux salles et aux fonctions dans ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Aucun message pour l'instant. Posez votre question ci-dessous.`,"custom_assistant_Per-device permissions":`Autorisations par appareil`,"custom_assistant_Play answer (backend TTS)":`Réponse de lecture (TTS backend)`,"custom_assistant_Read answers aloud":`Lisez les réponses à voix haute`,"custom_assistant_Refresh device cache":`Actualiser le cache de l'appareil`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Enregistrez la configuration (l'instance redémarrera) avant de discuter.`,custom_assistant_Speak:ct,"custom_assistant_Start the assistant instance to chat.":`Démarrez l'instance de l'assistant pour discuter.`,"custom_assistant_Start the assistant instance to load the device list.":`Démarrez l'instance de l'assistant pour charger la liste des périphériques.`,"custom_assistant_Stop listening":`Arrêtez d'écouter`,"custom_assistant_Stop reading answers aloud":`Arrêtez de lire les réponses à voix haute`,"custom_assistant_Test chat":`Chat de test`,"custom_assistant_Thinking…":`Pensée…`,"custom_assistant_Translate all missing (%s)":`Traduire tout ce qui est manquant (%s)`,"custom_assistant_Translate name into %s":`Traduire le nom en %s`,"custom_assistant_Type a message…":`Saisissez un message…`,custom_assistant_auto:lt,"custom_assistant_change it on the Voice tab":`modifiez-le dans l'onglet Voix`,custom_assistant_device:ut,custom_assistant_filter:dt,custom_assistant_hint:ft,"custom_assistant_no name in %s (showing %s)":`Aucun nom dans « %s » — affichage de « %s »`,custom_assistant_read:pt,custom_assistant_room:mt,custom_assistant_type:ht,custom_assistant_write:gt},K=e({custom_assistant_Speak:()=>vt,custom_assistant_auto:()=>yt,custom_assistant_device:()=>bt,custom_assistant_filter:()=>xt,custom_assistant_hint:()=>St,custom_assistant_read:()=>Ct,custom_assistant_room:()=>wt,custom_assistant_type:()=>Tt,custom_assistant_write:()=>Et,default:()=>Dt}),vt=`Parlare`,yt=`auto`,bt=`Dispositivo`,xt=`Filtro`,St=`Deseleziona "Lettura" per nascondere un dispositivo all'assistente, oppure deseleziona "Scrittura" per mantenerlo in sola lettura (ad esempio, per bloccare le serrature). Per impostazione predefinita, i dispositivi sono completamente accessibili.`,Ct=`Leggere`,wt=`Camera`,Tt=`Tipo`,Et=`Scrivere`,Dt={"custom_assistant_Clear chat":`Chat chiara`,"custom_assistant_Device cache cleared.":`Cache del dispositivo svuotata.`,"custom_assistant_Hide disabled":`Nascondi disabilitato`,"custom_assistant_Listening…":`Ascolto…`,"custom_assistant_Name language: %s":`Lingua del nome: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Nessun dispositivo rilevato. Assegna stati a stanze e funzioni in ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Nessun messaggio ancora. Scrivi una domanda qui sotto.`,"custom_assistant_Per-device permissions":`Autorizzazioni per dispositivo`,"custom_assistant_Play answer (backend TTS)":`Riproduci la risposta (TST di backend)`,"custom_assistant_Read answers aloud":`Leggi le risposte ad alta voce`,"custom_assistant_Refresh device cache":`Aggiorna la cache del dispositivo`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Salva la configurazione (l'istanza si riavvierà) prima di iniziare la chat.`,custom_assistant_Speak:vt,"custom_assistant_Start the assistant instance to chat.":`Avvia l'assistente per chattare.`,"custom_assistant_Start the assistant instance to load the device list.":`Avvia l'istanza dell'assistente per caricare l'elenco dei dispositivi.`,"custom_assistant_Stop listening":`Smetti di ascoltare`,"custom_assistant_Stop reading answers aloud":`Smetti di leggere le risposte ad alta voce`,"custom_assistant_Test chat":`Chat di prova`,"custom_assistant_Thinking…":`Pensiero…`,"custom_assistant_Translate all missing (%s)":`Traduci tutto ciò che manca (%s)`,"custom_assistant_Translate name into %s":`Traduci il nome in %s`,"custom_assistant_Type a message…":`Digita un messaggio…`,custom_assistant_auto:yt,"custom_assistant_change it on the Voice tab":`modificalo nella scheda Voce`,custom_assistant_device:bt,custom_assistant_filter:xt,custom_assistant_hint:St,"custom_assistant_no name in %s (showing %s)":`Nessun nome in "%s" — visualizzazione di "%s"`,custom_assistant_read:Ct,custom_assistant_room:wt,custom_assistant_type:Tt,custom_assistant_write:Et},q=e({custom_assistant_Speak:()=>Ot,custom_assistant_auto:()=>kt,custom_assistant_device:()=>At,custom_assistant_filter:()=>jt,custom_assistant_hint:()=>Mt,custom_assistant_read:()=>Nt,custom_assistant_room:()=>Pt,custom_assistant_type:()=>Ft,custom_assistant_write:()=>It,default:()=>Lt}),Ot=`Spreken`,kt=`auto`,At=`Apparaat`,jt=`Filter`,Mt=`Schakel de optie 'Lezen' uit om een apparaat voor de assistent te verbergen, of schakel de optie 'Schrijven' uit om het apparaat alleen-lezen te houden (bijv. sloten). Apparaten zijn standaard volledig toegestaan.`,Nt=`Lezen`,Pt=`Kamer`,Ft=`Type`,It=`Schrijven`,Lt={"custom_assistant_Clear chat":`Duidelijke chat`,"custom_assistant_Device cache cleared.":`Apparaatcache gewist.`,"custom_assistant_Hide disabled":`Verberg uitgeschakeld`,"custom_assistant_Listening…":`Luisteren…`,"custom_assistant_Name language: %s":`Naamtaal: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Geen apparaten gedetecteerd. Wijs statussen toe aan kamers en functies in ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Nog geen berichten. Typ hieronder een vraag.`,"custom_assistant_Per-device permissions":`Machtigingen per apparaat`,"custom_assistant_Play answer (backend TTS)":`Speel antwoord (backend TTS)`,"custom_assistant_Read answers aloud":`Lees de antwoorden hardop voor.`,"custom_assistant_Refresh device cache":`Vernieuw de apparaatcache.`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Sla de configuratie op (het apparaat zal opnieuw opstarten) voordat je gaat chatten.`,custom_assistant_Speak:Ot,"custom_assistant_Start the assistant instance to chat.":`Start de assistent-instantie om te chatten.`,"custom_assistant_Start the assistant instance to load the device list.":`Start de assistent-instantie om de lijst met apparaten te laden.`,"custom_assistant_Stop listening":`Stop met luisteren`,"custom_assistant_Stop reading answers aloud":`Stop met het hardop voorlezen van antwoorden.`,"custom_assistant_Test chat":`Testchat`,"custom_assistant_Thinking…":`Aan het nadenken…`,"custom_assistant_Translate all missing (%s)":`Vertaal alle ontbrekende (%) tekens`,"custom_assistant_Translate name into %s":`Vertaal de naam naar %s`,"custom_assistant_Type a message…":`Typ een bericht…`,custom_assistant_auto:kt,"custom_assistant_change it on the Voice tab":`Wijzig dit op het tabblad 'Stem'.`,custom_assistant_device:At,custom_assistant_filter:jt,custom_assistant_hint:Mt,"custom_assistant_no name in %s (showing %s)":`Geen naam in "%s" — "%s" wordt weergegeven`,custom_assistant_read:Nt,custom_assistant_room:Pt,custom_assistant_type:Ft,custom_assistant_write:It},J=e({custom_assistant_Speak:()=>Rt,custom_assistant_auto:()=>zt,custom_assistant_device:()=>Bt,custom_assistant_filter:()=>Vt,custom_assistant_hint:()=>Ht,custom_assistant_read:()=>Ut,custom_assistant_room:()=>Wt,custom_assistant_type:()=>`Typ`,custom_assistant_write:()=>Gt,default:()=>Kt}),Rt=`Mówić`,zt=`automatyczny`,Bt=`Urządzenie`,Vt=`Filtr`,Ht=`Odznacz opcję „Odczyt”, aby ukryć urządzenie przed asystentem, lub odznacz opcję „Zapis”, aby zachować je tylko do odczytu (np. blokady). Domyślnie urządzenia mają pełne uprawnienia.`,Ut=`Czytać`,Wt=`Pokój`,Gt=`Pisać`,Kt={"custom_assistant_Clear chat":`Wyczyść czat`,"custom_assistant_Device cache cleared.":`Pamięć podręczna urządzenia została wyczyszczona.`,"custom_assistant_Hide disabled":`Ukryj wyłączone`,"custom_assistant_Listening…":`Słuchający…`,"custom_assistant_Name language: %s":`Język nazwy: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Nie wykryto urządzeń. Przypisz stany do pomieszczeń i funkcji w ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Brak wiadomości. Wpisz pytanie poniżej.`,"custom_assistant_Per-device permissions":`Uprawnienia na urządzenie`,"custom_assistant_Play answer (backend TTS)":`Odtwórz odpowiedź (TTS w tle)`,"custom_assistant_Read answers aloud":`Przeczytaj odpowiedzi na głos`,"custom_assistant_Refresh device cache":`Odśwież pamięć podręczną urządzenia`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Przed rozpoczęciem czatu zapisz konfigurację (instancja zostanie uruchomiona ponownie).`,custom_assistant_Speak:Rt,"custom_assistant_Start the assistant instance to chat.":`Uruchom asystenta, aby rozpocząć rozmowę.`,"custom_assistant_Start the assistant instance to load the device list.":`Uruchom instancję asystenta, aby załadować listę urządzeń.`,"custom_assistant_Stop listening":`Przestań słuchać`,"custom_assistant_Stop reading answers aloud":`Przestań czytać odpowiedzi na głos`,"custom_assistant_Test chat":`Czat testowy`,"custom_assistant_Thinking…":`Myślący…`,"custom_assistant_Translate all missing (%s)":`Przetłumacz wszystkie brakujące (%s)`,"custom_assistant_Translate name into %s":`Przetłumacz nazwę na %s`,"custom_assistant_Type a message…":`Wpisz wiadomość…`,custom_assistant_auto:zt,"custom_assistant_change it on the Voice tab":`zmień to na karcie Głos`,custom_assistant_device:Bt,custom_assistant_filter:Vt,custom_assistant_hint:Ht,"custom_assistant_no name in %s (showing %s)":`Brak nazwy w "%s" — wyświetlanie "%s"`,custom_assistant_read:Ut,custom_assistant_room:Wt,custom_assistant_type:`Typ`,custom_assistant_write:Gt},Y=e({custom_assistant_Speak:()=>qt,custom_assistant_auto:()=>Jt,custom_assistant_device:()=>Yt,custom_assistant_filter:()=>Xt,custom_assistant_hint:()=>Zt,custom_assistant_read:()=>`Ler`,custom_assistant_room:()=>Qt,custom_assistant_type:()=>$t,custom_assistant_write:()=>en,default:()=>tn}),qt=`Falar`,Jt=`auto`,Yt=`Dispositivo`,Xt=`Filtro`,Zt=`Desmarque a opção "Ler" para ocultar um dispositivo do assistente ou desmarque a opção "Gravar" para mantê-lo somente leitura (por exemplo, fechaduras). Os dispositivos são configurados por padrão para permitir totalmente o acesso.`,Qt=`Sala`,$t=`Tipo`,en=`Escrever`,tn={"custom_assistant_Clear chat":`Chat limpo`,"custom_assistant_Device cache cleared.":`Cache do dispositivo limpo.`,"custom_assistant_Hide disabled":`Ocultar desativado`,"custom_assistant_Listening…":`Audição…`,"custom_assistant_Name language: %s":`Idioma do nome: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Nenhum dispositivo detectado. Atribua estados a salas e funções no ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Ainda não há mensagens. Digite sua pergunta abaixo.`,"custom_assistant_Per-device permissions":`Permissões por dispositivo`,"custom_assistant_Play answer (backend TTS)":`Reproduzir resposta (TTS em segundo plano)`,"custom_assistant_Read answers aloud":`Leia as respostas em voz alta.`,"custom_assistant_Refresh device cache":`Atualizar cache do dispositivo`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Salve a configuração (a instância será reiniciada) antes de iniciar o chat.`,custom_assistant_Speak:qt,"custom_assistant_Start the assistant instance to chat.":`Inicie a instância do assistente para conversar.`,"custom_assistant_Start the assistant instance to load the device list.":`Inicie a instância do assistente para carregar a lista de dispositivos.`,"custom_assistant_Stop listening":`Pare de ouvir`,"custom_assistant_Stop reading answers aloud":`Pare de ler as respostas em voz alta.`,"custom_assistant_Test chat":`Chat de teste`,"custom_assistant_Thinking…":`Pensamento…`,"custom_assistant_Translate all missing (%s)":`Traduzir todos os (%s) ausentes`,"custom_assistant_Translate name into %s":`Traduzir nome para %s`,"custom_assistant_Type a message…":`Digite uma mensagem…`,custom_assistant_auto:Jt,"custom_assistant_change it on the Voice tab":`Altere isso na guia Voz.`,custom_assistant_device:Yt,custom_assistant_filter:Xt,custom_assistant_hint:Zt,"custom_assistant_no name in %s (showing %s)":`Nenhum nome em "%s" — exibindo "%s"`,custom_assistant_read:`Ler`,custom_assistant_room:Qt,custom_assistant_type:$t,custom_assistant_write:en},X=e({custom_assistant_Speak:()=>nn,custom_assistant_auto:()=>rn,custom_assistant_device:()=>an,custom_assistant_filter:()=>on,custom_assistant_hint:()=>sn,custom_assistant_read:()=>cn,custom_assistant_room:()=>ln,custom_assistant_type:()=>un,custom_assistant_write:()=>dn,default:()=>fn}),nn=`Говорить`,rn=`авто`,an=`Устройство`,on=`Фильтр`,sn=`Снимите флажок «Чтение», чтобы скрыть устройство от голосового помощника, или снимите флажок «Запись», чтобы оставить его только для чтения (например, блокировка). По умолчанию устройствам разрешен полный доступ.`,cn=`Читать`,ln=`Комната`,un=`Тип`,dn=`Писать`,fn={"custom_assistant_Clear chat":`Четкий чат`,"custom_assistant_Device cache cleared.":`Кэш устройства очищен.`,"custom_assistant_Hide disabled":`Скрыть отключено`,"custom_assistant_Listening…":`Слушаю…`,"custom_assistant_Name language: %s":`Название языка: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Устройства не обнаружены. Назначьте состояния комнатам и функциям в ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Сообщений пока нет. Задайте вопрос ниже.`,"custom_assistant_Per-device permissions":`Разрешения для каждого устройства`,"custom_assistant_Play answer (backend TTS)":`Воспроизвести ответ (синтезатор речи на стороне сервера)`,"custom_assistant_Read answers aloud":`Прочитайте ответы вслух.`,"custom_assistant_Refresh device cache":`Обновить кэш устройства`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Сохраните конфигурацию (при этом экземпляр перезапустится) перед началом чата.`,custom_assistant_Speak:nn,"custom_assistant_Start the assistant instance to chat.":`Запустите экземпляр ассистента для начала чата.`,"custom_assistant_Start the assistant instance to load the device list.":`Запустите экземпляр помощника, чтобы загрузить список устройств.`,"custom_assistant_Stop listening":`Прекратите слушать`,"custom_assistant_Stop reading answers aloud":`Прекратите зачитывать ответы вслух.`,"custom_assistant_Test chat":`Тестовый чат`,"custom_assistant_Thinking…":`Размышления…`,"custom_assistant_Translate all missing (%s)":`Переведите все отсутствующие (%s)`,"custom_assistant_Translate name into %s":`Переведите имя в %s`,"custom_assistant_Type a message…":`Введите сообщение…`,custom_assistant_auto:rn,"custom_assistant_change it on the Voice tab":`Измените это на вкладке «Голос».`,custom_assistant_device:an,custom_assistant_filter:on,custom_assistant_hint:sn,"custom_assistant_no name in %s (showing %s)":`Имя отсутствует в "%s" — отображается "%s"`,custom_assistant_read:cn,custom_assistant_room:ln,custom_assistant_type:un,custom_assistant_write:dn},Z=e({custom_assistant_Speak:()=>pn,custom_assistant_auto:()=>mn,custom_assistant_device:()=>hn,custom_assistant_filter:()=>gn,custom_assistant_hint:()=>_n,custom_assistant_read:()=>vn,custom_assistant_room:()=>yn,custom_assistant_type:()=>bn,custom_assistant_write:()=>xn,default:()=>Sn}),pn=`Говоріть`,mn=`авто`,hn=`Пристрій`,gn=`Фільтр`,_n=`Зніміть позначку «Читання», щоб приховати пристрій від помічника, або «Запис», щоб залишити його в режимі лише для читання (наприклад, блокування). За замовчуванням пристрої повністю дозволені.`,vn=`Читати`,yn=`Кімната`,bn=`Тип`,xn=`Написати`,Sn={"custom_assistant_Clear chat":`Очистити чат`,"custom_assistant_Device cache cleared.":`Кеш пристрою очищено.`,"custom_assistant_Hide disabled":`Приховати вимкнено`,"custom_assistant_Listening…":`Слухання…`,"custom_assistant_Name language: %s":`Мова назви: %s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`Пристроїв не виявлено. Призначте стани кімнатам та функціям в ioBroker.`,"custom_assistant_No messages yet. Type a question below.":`Поки що немає повідомлень. Введіть запитання нижче.`,"custom_assistant_Per-device permissions":`Дозволи для кожного пристрою`,"custom_assistant_Play answer (backend TTS)":`Відтворити відповідь (бекенд TTS)`,"custom_assistant_Read answers aloud":`Прочитайте відповіді вголос`,"custom_assistant_Refresh device cache":`Оновити кеш пристрою`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`Збережіть конфігурацію (екземпляр перезавантажиться) перед спілкуванням у чаті.`,custom_assistant_Speak:pn,"custom_assistant_Start the assistant instance to chat.":`Запустіть екземпляр помічника для спілкування в чаті.`,"custom_assistant_Start the assistant instance to load the device list.":`Запустіть екземпляр помічника, щоб завантажити список пристроїв.`,"custom_assistant_Stop listening":`Перестань слухати`,"custom_assistant_Stop reading answers aloud":`Перестаньте читати відповіді вголос`,"custom_assistant_Test chat":`Тестовий чат`,"custom_assistant_Thinking…":`Мислення…`,"custom_assistant_Translate all missing (%s)":`Перекласти все, що відсутні (%s)`,"custom_assistant_Translate name into %s":`Перекладіть назву мовою %s`,"custom_assistant_Type a message…":`Введіть повідомлення…`,custom_assistant_auto:mn,"custom_assistant_change it on the Voice tab":`змінити це на вкладці «Голос»`,custom_assistant_device:hn,custom_assistant_filter:gn,custom_assistant_hint:_n,"custom_assistant_no name in %s (showing %s)":`Немає імені в "%s" — відображається "%s"`,custom_assistant_read:vn,custom_assistant_room:yn,custom_assistant_type:bn,custom_assistant_write:xn},Q=e({custom_assistant_Speak:()=>Cn,custom_assistant_auto:()=>wn,custom_assistant_device:()=>Tn,custom_assistant_filter:()=>En,custom_assistant_hint:()=>Dn,custom_assistant_read:()=>`读`,custom_assistant_room:()=>On,custom_assistant_type:()=>kn,custom_assistant_write:()=>`写`,default:()=>An}),Cn=`说话`,wn=`汽车`,Tn=`设备`,En=`筛选`,Dn=`取消勾选“读取”选项可将设备对语音助手隐藏,取消勾选“写入”选项可将其设置为只读(例如,锁定设备)。设备默认设置为完全允许访问。`,On=`房间`,kn=`类型`,An={"custom_assistant_Clear chat":`清晰聊天`,"custom_assistant_Device cache cleared.":`设备缓存已清除。`,"custom_assistant_Hide disabled":`隐藏已禁用`,"custom_assistant_Listening…":`正在听……`,"custom_assistant_Name language: %s":`名称语言:%s`,"custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.":`未检测到设备。请在ioBroker中为房间和功能分配状态。`,"custom_assistant_No messages yet. Type a question below.":`暂无消息。请在下方输入问题。`,"custom_assistant_Per-device permissions":`每个设备的权限`,"custom_assistant_Play answer (backend TTS)":`播放答案(后端 TTS)`,"custom_assistant_Read answers aloud":`大声朗读答案`,"custom_assistant_Refresh device cache":`刷新设备缓存`,"custom_assistant_Save the configuration (the instance will restart) before chatting.":`聊天前请保存配置(实例将重启)。`,custom_assistant_Speak:Cn,"custom_assistant_Start the assistant instance to chat.":`启动助手实例进行聊天。`,"custom_assistant_Start the assistant instance to load the device list.":`启动助手实例以加载设备列表。`,"custom_assistant_Stop listening":`别听了`,"custom_assistant_Stop reading answers aloud":`停止大声朗读答案`,"custom_assistant_Test chat":`测试聊天`,"custom_assistant_Thinking…":`思维…`,"custom_assistant_Translate all missing (%s)":`翻译所有缺失值(%s)`,"custom_assistant_Translate name into %s":`将名称翻译成 %s`,"custom_assistant_Type a message…":`输入消息…`,custom_assistant_auto:wn,"custom_assistant_change it on the Voice tab":`在“语音”选项卡上更改。`,custom_assistant_device:Tn,custom_assistant_filter:En,custom_assistant_hint:Dn,"custom_assistant_no name in %s (showing %s)":`“%s”中没有名称——显示“%s”`,custom_assistant_read:`读`,custom_assistant_room:On,custom_assistant_type:kn,custom_assistant_write:`写`};n(),me();var jn={},Mn=Object.assign({"./i18n/de.json":w,"./i18n/en.json":U,"./i18n/es.json":W,"./i18n/fr.json":G,"./i18n/it.json":K,"./i18n/nl.json":q,"./i18n/pl.json":J,"./i18n/pt.json":Y,"./i18n/ru.json":X,"./i18n/uk.json":Z,"./i18n/zh-cn.json":Q});for(let[e,t]of Object.entries(Mn)){var Nn;let n=((Nn=e.split(`/`).pop())==null?void 0:Nn.replace(`.json`,``))||`en`;jn[n]=t.default}_.extendTranslations(jn);var Pn=new Set([`temperature`,`humidity`,`illuminance`,`motion`,`door`,`window`,`windowTilt`,`fireAlarm`,`floodAlarm`,`camera`,`weatherCurrent`,`weatherForecast`,`warning`,`location`,`info`,`chart`,`image`,`instance`]);function Fn(e){return e===`lock`?{read:!0,write:!1}:{read:!0,write:!0}}var In=[{value:`en`,label:`English`},{value:`de`,label:`Deutsch`},{value:`ru`,label:`Русский`},{value:`pt`,label:`Português`},{value:`nl`,label:`Nederlands`},{value:`fr`,label:`Français`},{value:`it`,label:`Italiano`},{value:`es`,label:`Español`},{value:`pl`,label:`Polski`},{value:`uk`,label:`Українська`},{value:`zh-cn`,label:`简体中文`}],Ln=class extends t{constructor(e){super(e),C(this,`aliveSubId`,``),C(this,`onAliveChange`,(e,t)=>{let n=!!(t!=null&&t.val);n!==this.state.alive&&this.setState({alive:n,loading:n},()=>{n&&this.loadDevices()})}),this.state={...this.state,devices:[],loading:!0,alive:!1,filter:``,edits:{},savingKey:``,translatingKeys:{},rowStatus:{},hideDisabled:!1}}rowColor(e){switch(this.state.rowStatus[e]){case`dirty`:return`rgba(128,128,128,0.20)`;case`saving`:return`rgba(244,67,54,0.20)`;case`saved`:return`rgba(76,175,80,0.28)`;default:return}}setRowStatus(e,t){this.setState(n=>{let r={...n.rowStatus};return t?r[e]=t:delete r[e],{rowStatus:r}})}get instanceId(){let e=this.props.oContext;return`${e.adapterName}.${e.instance}`}get editLang(){return String(this.props.data.voiceLanguage||``)||_.getLanguage()}componentDidUpdate(e){String(e.data.voiceLanguage||``)!==String(this.props.data.voiceLanguage||``)&&Object.keys(this.state.edits).length&&this.setState({edits:{}})}async componentDidMount(){super.componentDidMount(),this.aliveSubId=`system.adapter.${this.instanceId}.alive`;let e=!1;try{let t=await this.props.oContext.socket.getState(this.aliveSubId);e=!!(t!=null&&t.val)}catch{e=!1}this.setState({alive:e},()=>void this.loadDevices()),this.props.oContext.socket.subscribeState(this.aliveSubId,this.onAliveChange)}componentWillUnmount(){var e;this.aliveSubId&&this.props.oContext.socket.unsubscribeState(this.aliveSubId,this.onAliveChange),(e=super.componentWillUnmount)==null||e.call(this)}async loadDevices(e=4){if(!this.state.alive){this.setState({loading:!1});return}let t=[];try{let e=await this.props.oContext.socket.sendTo(this.instanceId,`getDevices`,{language:_.getLanguage()});t=(Array.isArray(e)?e:[]).filter(e=>e.type!==`button`)}catch{t=[]}if(!t.length&&e>0){setTimeout(()=>{this.state.alive&&this.loadDevices(e-1)},1200);return}this.setState({devices:t,edits:{},loading:!1})}nameFor(e){let t=this.editLang,n=e.smartName;if(typeof n==`string`&&n)return{value:n,exact:!0,from:``};if(n&&typeof n==`object`){if(n[t])return{value:n[t],exact:!0,from:t};let e=n.en?`en`:Object.keys(n)[0];if(e&&n[e])return{value:n[e],exact:!1,from:e}}return{value:e.autoName||e.name||``,exact:!1,from:`auto`}}fieldValue(e){return this.state.edits[e.key]??this.nameFor(e).value}onNameChange(e,t){let n=this.state.devices.find(t=>t.key===e),r=n?this.nameFor(n).value:``;this.setState(n=>{let i={...n.rowStatus};return t===r?i[e]===`dirty`&&delete i[e]:i[e]=`dirty`,{edits:{...n.edits,[e]:t},rowStatus:i}})}flashSaved(e){this.setRowStatus(e,`saved`),setTimeout(()=>{this.state.rowStatus[e]===`saved`&&this.setRowStatus(e,null)},2e3)}applyLocalName(e,t,n){this.setState(r=>({devices:r.devices.map(r=>{if(r.key!==e)return r;let i=r.smartName&&typeof r.smartName==`object`?{...r.smartName}:typeof r.smartName==`string`&&r.smartName?{en:r.smartName}:{};return n?i[t]=n:delete i[t],{...r,smartName:i}}),edits:(()=>{let t={...r.edits};return delete t[e],t})()}))}async saveName(e){let t=this.state.edits[e.key];if(t===void 0||t===this.nameFor(e).value)return;let n=this.editLang;this.setState({savingKey:e.key}),this.setRowStatus(e.key,`saving`);try{await this.props.oContext.socket.sendTo(this.instanceId,`setDeviceName`,{stateId:e.key,name:t,language:n}),this.applyLocalName(e.key,n,t.trim()),this.flashSaved(e.key)}catch{this.setRowStatus(e.key,`dirty`)}this.setState({savingKey:``})}async translateName(e){let t=this.nameFor(e).value,n=e.key;if(!t||this.state.translatingKeys[n])return;let r=this.editLang;this.setState(e=>({translatingKeys:{...e.translatingKeys,[n]:!0}})),this.setRowStatus(n,`saving`);try{var i;let e=await this.props.oContext.socket.sendTo(this.instanceId,`translateName`,{text:t,targetLang:r}),a=e==null||(i=e.translation)==null?void 0:i.trim();a?(await this.props.oContext.socket.sendTo(this.instanceId,`setDeviceName`,{stateId:n,name:a,language:r}),this.applyLocalName(n,r,a),this.flashSaved(n)):this.setRowStatus(n,null)}catch{this.setRowStatus(n,null)}this.setState(e=>{let t={...e.translatingKeys};return delete t[n],{translatingKeys:t}})}async translateAllMissing(){let e=this.state.devices.filter(e=>!this.nameFor(e).exact&&!this.state.translatingKeys[e.key]);await Promise.all(e.map(e=>this.translateName(e)))}getAcl(e){var t;return((t=this.props.data.deviceAcl)==null?void 0:t[e.key])||Fn(e.type)}setAcl(e,t){let n=JSON.parse(JSON.stringify(this.props.data));n.deviceAcl=n.deviceAcl||{};let r=Fn(e.type),i={...n.deviceAcl[e.key]||r,...t};i.read===r.read&&i.write===r.write?delete n.deviceAcl[e.key]:n.deviceAcl[e.key]=i,this.props.onChange(n)}renderItem(){var e;if(this.state.loading)return p(d,{});if(!this.state.alive)return p(x,{sx:{p:2},color:`warning.main`,children:_.t(`custom_assistant_Start the assistant instance to load the device list.`)});if(!this.state.devices.length)return p(x,{sx:{p:2},children:_.t(`custom_assistant_No devices detected. Assign states to rooms and functions in ioBroker.`)});let t=this.state.filter.trim().toLowerCase(),n=t?this.state.devices.filter(e=>`${e.name} ${e.type} ${e.room}`.toLowerCase().includes(t)):this.state.devices;this.state.hideDisabled&&(n=n.filter(e=>this.getAcl(e).read));let r=this.props.oContext.themeType===`dark`;return m(g,{sx:{width:`100%`},children:[p(x,{variant:`h6`,sx:{mt:1},children:_.t(`custom_assistant_Per-device permissions`)}),p(x,{variant:`body2`,sx:{mb:1},color:`text.secondary`,children:_.t(`custom_assistant_hint`)}),m(g,{sx:{display:`flex`,alignItems:`center`,gap:1,mb:1,flexWrap:`wrap`},children:[p(S,{size:`small`,color:`primary`,variant:`outlined`,label:_.t(`custom_assistant_Name language: %s`,((e=In.find(e=>e.value===this.editLang))==null?void 0:e.label)||this.editLang)}),p(x,{variant:`caption`,color:`text.secondary`,children:_.t(`custom_assistant_change it on the Voice tab`)}),(()=>{let e=this.state.devices.filter(e=>!this.nameFor(e).exact).length,t=Object.keys(this.state.translatingKeys).length>0;return p(pe,{size:`small`,variant:`outlined`,startIcon:t?p(v,{size:14}):p(s,{}),disabled:!e||t,onClick:()=>void this.translateAllMissing(),children:_.t(`custom_assistant_Translate all missing (%s)`,e)})})(),p(g,{sx:{flex:1}}),p(c,{control:p(oe,{size:`small`,checked:this.state.hideDisabled,onChange:e=>this.setState({hideDisabled:e.target.checked})}),label:_.t(`custom_assistant_Hide disabled`)}),p(i,{variant:`standard`,size:`small`,label:`Filter`,value:this.state.filter,onChange:e=>this.setState({filter:e.target.value}),sx:{width:320}})]}),p(te,{component:o,sx:{width:`100%`},children:m(l,{size:`small`,children:[p(ce,{children:m(h,{sx:{background:r?`#333`:`#DDD`},children:[p(b,{children:_.t(`custom_assistant_device`)}),p(b,{children:_.t(`custom_assistant_type`)}),p(b,{children:_.t(`custom_assistant_room`)}),p(b,{align:`center`,children:_.t(`custom_assistant_read`)}),p(b,{align:`center`,children:_.t(`custom_assistant_write`)})]})}),p(u,{children:n.map(e=>{let t=this.getAcl(e),n=e.writableStateIds.length>0&&!Pn.has(e.type),r=!t.read;return m(h,{sx:{background:this.rowColor(e.key),opacity:r?.5:1,transition:`background-color 0.4s`},children:[m(b,{children:[(()=>{let t=this.nameFor(e),n=!!this.state.translatingKeys[e.key],r=this.state.savingKey===e.key||n;return m(g,{sx:{display:`flex`,alignItems:`flex-start`,gap:.5},children:[p(i,{variant:`standard`,size:`small`,fullWidth:!0,value:this.fieldValue(e),disabled:r,error:!t.exact&&!this.state.edits[e.key],helperText:!t.exact&&!this.state.edits[e.key]?_.t(`custom_assistant_no name in %s (showing %s)`,this.editLang,t.from===`auto`?_.t(`custom_assistant_auto`):t.from):` `,onChange:t=>this.onNameChange(e.key,t.target.value),onBlur:()=>void this.saveName(e),onKeyDown:e=>{e.key===`Enter`&&e.target.blur()},slotProps:{input:{endAdornment:this.state.savingKey===e.key?p(v,{size:14}):null}}}),p(y,{title:_.t(`custom_assistant_Translate name into %s`,this.editLang),children:p(`span`,{children:p(f,{size:`small`,disabled:r,onClick:()=>void this.translateName(e),children:n?p(v,{size:16}):p(s,{fontSize:`small`})})})})]})})(),e.stateIds.length?p(x,{variant:`caption`,component:`div`,sx:{wordBreak:`break-all`,fontStyle:`italic`,opacity:.7,fontSize:`smaller`},children:e.stateIds.join(`, `)}):null]}),p(b,{children:m(g,{sx:{display:`flex`,alignItems:`center`,gap:.75},children:[p(de,{type:e.type,style:{width:20,height:20}}),p(`span`,{children:_.t(`type-${e.type}`)})]})}),p(b,{children:e.room&&e.room!==`No room`?e.room:`-`}),p(b,{align:`center`,children:p(fe,{checked:t.read,onChange:()=>this.setAcl(e,{read:!t.read})})}),p(b,{align:`center`,children:p(fe,{checked:t.write&&n,disabled:!n,onChange:()=>this.setAcl(e,{write:!t.write})})})]},e.key)})})]})})]})}};n();var Rn={},zn=Object.assign({"./i18n/de.json":w,"./i18n/en.json":U,"./i18n/es.json":W,"./i18n/fr.json":G,"./i18n/it.json":K,"./i18n/nl.json":q,"./i18n/pl.json":J,"./i18n/pt.json":Y,"./i18n/ru.json":X,"./i18n/uk.json":Z,"./i18n/zh-cn.json":Q});for(let[e,t]of Object.entries(zn)){var Bn;let n=((Bn=e.split(`/`).pop())==null?void 0:Bn.replace(`.json`,``))||`en`;Rn[n]=t.default}_.extendTranslations(Rn);var Vn=class extends t{constructor(e){super(e),C(this,`scrollRef`,r.createRef()),C(this,`aliveSubId`,``),C(this,`recognition`,null),C(this,`onAliveChange`,(e,t)=>{let n=!!(t!=null&&t.val);this.setState({alive:n}),n&&this.checkTtsAvailable()}),C(this,`onKeyDown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),this.send())}),this.state={...this.state,messages:[],input:``,sending:!1,alive:!1,listening:!1,speak:!1,ttsPlayingTs:0,ttsAvailable:!1}}async checkTtsAvailable(){try{let e=await this.props.oContext.socket.sendTo(this.instanceId,`ttsAvailable`,{});this.setState({ttsAvailable:!!(e!=null&&e.available)})}catch{this.setState({ttsAvailable:!1})}}get speechSupported(){let e=window;return(!!e.SpeechRecognition||!!e.webkitSpeechRecognition)&&window.isSecureContext}get ttsSupported(){return typeof window<`u`&&`speechSynthesis`in window}speechLang(){return{de:`de-DE`,en:`en-US`,ru:`ru-RU`,pt:`pt-PT`,nl:`nl-NL`,fr:`fr-FR`,it:`it-IT`,es:`es-ES`,pl:`pl-PL`,uk:`uk-UA`,"zh-cn":`zh-CN`}[_.getLanguage()]||`en-US`}get instanceId(){let e=this.props.oContext;return`${e.adapterName}.${e.instance}`}async componentDidMount(){super.componentDidMount(),this.aliveSubId=`system.adapter.${this.instanceId}.alive`;let e=!1;try{let t=await this.props.oContext.socket.getState(this.aliveSubId);e=!!(t!=null&&t.val)}catch{e=!1}this.setState({alive:e}),e&&this.checkTtsAvailable(),this.props.oContext.socket.subscribeState(this.aliveSubId,this.onAliveChange)}componentWillUnmount(){var e;this.aliveSubId&&this.props.oContext.socket.unsubscribeState(this.aliveSubId,this.onAliveChange);try{var t;(t=this.recognition)==null||t.stop()}catch{}this.ttsSupported&&window.speechSynthesis.cancel(),(e=super.componentWillUnmount)==null||e.call(this)}toggleListening(){if(this.state.listening){var e;(e=this.recognition)==null||e.stop();return}let t=window,n=t.SpeechRecognition||t.webkitSpeechRecognition;if(!n)return;let r=new n;r.lang=this.speechLang(),r.interimResults=!1,r.continuous=!1,r.onresult=e=>{var t;let n=((t=e.results)==null||(t=t[0])==null||(t=t[0])==null?void 0:t.transcript)||``;n&&this.setState({input:n},()=>void this.send())},r.onerror=()=>this.setState({listening:!1}),r.onend=()=>this.setState({listening:!1}),this.recognition=r,this.setState({listening:!0});try{r.start()}catch{this.setState({listening:!1})}}speak(e){if(!this.ttsSupported||!e)return;window.speechSynthesis.cancel();let t=new SpeechSynthesisUtterance(e);t.lang=this.speechLang(),window.speechSynthesis.speak(t)}async playViaBackend(e,t){if(!(!this.ready||!t)){this.setState({ttsPlayingTs:e});try{let e=await this.props.oContext.socket.sendTo(this.instanceId,`tts`,{text:t});if(e!=null&&e.audio){let t=new Audio(`data:${e.mime||`audio/wav`};base64,${e.audio}`);t.onended=()=>this.setState({ttsPlayingTs:0}),t.onerror=()=>this.setState({ttsPlayingTs:0}),await t.play()}else this.setState({ttsPlayingTs:0})}catch{this.setState({ttsPlayingTs:0})}}}scrollToBottom(){setTimeout(()=>{let e=this.scrollRef.current;e&&(e.scrollTop=e.scrollHeight)},0)}get ready(){return this.state.alive&&!this.props.changed}async send(){let e=this.state.input.trim();if(!e||this.state.sending||!this.ready)return;let t={role:`user`,text:e,ts:Date.now()};this.setState(e=>({messages:[...e.messages,t],input:``,sending:!0})),this.scrollToBottom();let n;try{let t=await this.props.oContext.socket.sendTo(this.instanceId,`ask`,{text:e});n=(t==null?void 0:t.error)===void 0?{role:`assistant`,text:(t==null?void 0:t.answer)??``,ts:Date.now()}:{role:`error`,text:t.error,ts:Date.now()}}catch(e){n={role:`error`,text:e.message,ts:Date.now()}}this.setState(e=>({messages:[...e.messages,n],sending:!1})),this.scrollToBottom(),this.state.speak&&n.role===`assistant`&&this.speak(n.text)}async refreshCache(){if(this.ready)try{await this.props.oContext.socket.sendTo(this.instanceId,`clearCache`,{}),this.setState(e=>({messages:[...e.messages,{role:`info`,text:_.t(`custom_assistant_Device cache cleared.`),ts:Date.now()}]})),this.scrollToBottom()}catch{}}renderMessage(e,t){let n=this.props.oContext.themeType===`dark`;if(e.role===`info`)return p(x,{variant:`caption`,component:`div`,sx:{textAlign:`center`,opacity:.6,my:1,fontStyle:`italic`},children:e.text},t);let r=e.role===`user`,i=e.role===`error`,a;a=r?n?`#1e88e5`:`#2196f3`:i?n?`#5d1f1f`:`#f8d7da`:n?`#3a3a3a`:`#eceff1`;let s=r?`#fff`:i?n?`#ffb4b4`:`#842029`:n?`#eee`:`#111`,c=new Date(e.ts).toLocaleTimeString();return p(g,{sx:{display:`flex`,justifyContent:r?`flex-end`:`flex-start`,mb:1},children:m(o,{elevation:1,sx:{px:1.5,py:1,maxWidth:`75%`,background:a,color:s,borderRadius:2,whiteSpace:`pre-wrap`,wordBreak:`break-word`},children:[p(x,{variant:`body2`,component:`div`,children:e.text}),m(g,{sx:{display:`flex`,alignItems:`center`,justifyContent:`flex-end`,gap:.5},children:[e.role===`assistant`&&this.state.ttsAvailable?p(y,{title:_.t(`custom_assistant_Play answer (backend TTS)`),children:p(`span`,{children:p(f,{size:`small`,disabled:!this.ready||this.state.ttsPlayingTs===e.ts,onClick:()=>void this.playViaBackend(e.ts,e.text),sx:{p:.25,color:`inherit`,opacity:.7},children:this.state.ttsPlayingTs===e.ts?p(v,{size:12}):p(ae,{sx:{fontSize:`0.9rem`}})})})}):null,p(x,{variant:`caption`,component:`div`,sx:{opacity:.6,fontSize:`0.65rem`},children:c})]})]})},t)}renderItem(){let e=this.props.oContext.themeType===`dark`,{alive:t,messages:n,sending:r,input:o,listening:s,speak:c}=this.state,l=this.ready;return m(g,{sx:{width:`100%`,display:`flex`,flexDirection:`column`,height:`calc(100vh - 300px)`},children:[m(g,{sx:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,mb:1},children:[p(x,{variant:`h6`,children:_.t(`custom_assistant_Test chat`)}),m(g,{children:[this.ttsSupported?p(y,{title:_.t(c?`custom_assistant_Stop reading answers aloud`:`custom_assistant_Read answers aloud`),children:p(f,{size:`small`,color:c?`primary`:`default`,onClick:()=>{c&&window.speechSynthesis.cancel(),this.setState({speak:!c})},children:p(c?ue:ne,{})})}):null,p(y,{title:_.t(`custom_assistant_Refresh device cache`),children:p(`span`,{children:p(f,{size:`small`,disabled:!l,onClick:()=>void this.refreshCache(),children:p(a,{})})})}),p(y,{title:_.t(`custom_assistant_Clear chat`),children:p(`span`,{children:p(f,{size:`small`,disabled:!n.length,onClick:()=>this.setState({messages:[]}),children:p(se,{})})})})]})]}),l?null:p(x,{sx:{p:2},color:`warning.main`,children:t?_.t(`custom_assistant_Save the configuration (the instance will restart) before chatting.`):_.t(`custom_assistant_Start the assistant instance to chat.`)}),m(g,{ref:this.scrollRef,sx:{flex:1,overflowY:`auto`,p:1,border:`1px solid ${e?`#444`:`#ccc`}`,borderRadius:1,background:e?`#1e1e1e`:`#fafafa`,mb:1},children:[n.length?n.map((e,t)=>this.renderMessage(e,t)):p(x,{sx:{p:2,textAlign:`center`,opacity:.6},variant:`body2`,children:_.t(`custom_assistant_No messages yet. Type a question below.`)}),r?m(g,{sx:{display:`flex`,alignItems:`center`,gap:1,p:1,opacity:.7},children:[p(v,{size:16}),p(x,{variant:`body2`,children:_.t(`custom_assistant_Thinking…`)})]}):null]}),m(g,{sx:{display:`flex`,alignItems:`flex-end`,gap:1},children:[this.speechSupported?p(y,{title:_.t(s?`custom_assistant_Stop listening`:`custom_assistant_Speak`),children:p(`span`,{children:p(f,{color:s?`error`:`primary`,disabled:!l||r,onClick:()=>this.toggleListening(),children:p(le,{})})})}):null,p(i,{fullWidth:!0,multiline:!0,maxRows:4,size:`small`,variant:`outlined`,placeholder:_.t(s?`custom_assistant_Listening…`:`custom_assistant_Type a message…`),value:o,disabled:!l||r,onChange:e=>this.setState({input:e.target.value}),onKeyDown:this.onKeyDown}),p(f,{color:`primary`,disabled:!l||r||!o.trim(),onClick:()=>void this.send(),children:p(re,{})})]})]})}};n();var Hn={},Un=Object.assign({"./i18n/de.json":w,"./i18n/en.json":U,"./i18n/es.json":W,"./i18n/fr.json":G,"./i18n/it.json":K,"./i18n/nl.json":q,"./i18n/pl.json":J,"./i18n/pt.json":Y,"./i18n/ru.json":X,"./i18n/uk.json":Z,"./i18n/zh-cn.json":Q});for(let[e,t]of Object.entries(Un)){var Wn;let n=((Wn=e.split(`/`).pop())==null?void 0:Wn.replace(`.json`,``))||`en`;Hn[n]=t.default}_.extendTranslations(Hn);var Gn={ready:`success`,error:`error`,installing:`info`,downloading:`info`,loading:`info`},Kn=class extends t{constructor(e){super(e),C(this,`statusId`,``),C(this,`progressId`,``),C(this,`onStatus`,(e,t)=>{this.setState({status:(t==null?void 0:t.val)||`idle`})}),C(this,`onProgress`,(e,t)=>{this.setState({progress:Number(t==null?void 0:t.val)||0})}),this.state={...this.state,status:`idle`,progress:0}}get instanceId(){let e=this.props.oContext;return`${e.adapterName}.${e.instance}`}async componentDidMount(){super.componentDidMount(),this.statusId=`${this.instanceId}.localLlm.status`,this.progressId=`${this.instanceId}.localLlm.progress`;let e=this.props.oContext.socket;try{let t=await e.getState(this.statusId),n=await e.getState(this.progressId);this.setState({status:(t==null?void 0:t.val)||`idle`,progress:Number(n==null?void 0:n.val)||0})}catch{}e.subscribeState(this.statusId,this.onStatus),e.subscribeState(this.progressId,this.onProgress)}componentWillUnmount(){var e;let t=this.props.oContext.socket;this.statusId&&(t.unsubscribeState(this.statusId,this.onStatus),t.unsubscribeState(this.progressId,this.onProgress)),(e=super.componentWillUnmount)==null||e.call(this)}renderItem(){let{status:e,progress:t}=this.state,n=e===`installing`||e===`downloading`||e===`loading`,r=e===`downloading`;return m(g,{sx:{width:`100%`,mt:.5,mb:1},children:[m(g,{sx:{display:`flex`,alignItems:`center`,gap:1,mb:.5},children:[m(x,{variant:`body2`,children:[_.t(`custom_assistant_Local model`),`:`]}),p(S,{size:`small`,color:Gn[e]||`default`,variant:`outlined`,label:_.t(`custom_assistant_llm_${e}`)}),r?m(x,{variant:`body2`,children:[Math.round(t),`%`]}):null]}),n?p(d,{variant:r?`determinate`:`indeterminate`,value:r?t:void 0}):null]})}};n();var qn={},Jn=Object.assign({"./i18n/de.json":w,"./i18n/en.json":U,"./i18n/es.json":W,"./i18n/fr.json":G,"./i18n/it.json":K,"./i18n/nl.json":q,"./i18n/pl.json":J,"./i18n/pt.json":Y,"./i18n/ru.json":X,"./i18n/uk.json":Z,"./i18n/zh-cn.json":Q});for(let[e,t]of Object.entries(Jn)){var Yn;let n=((Yn=e.split(`/`).pop())==null?void 0:Yn.replace(`.json`,``))||`en`;qn[n]=t.default}_.extendTranslations(qn);var Xn={idle:`default`,listening:`info`,processing:`warning`,speaking:`success`,offline:`error`},$=`__all__`,Zn={DeviceAclComponent:Ln,ChatComponent:Vn,LocalLlmProgress:Kn,SatellitesComponent:class extends t{constructor(e){super(e),C(this,`pattern`,``),C(this,`onState`,(e,t)=>{this.setState(n=>{let r={...n.sats},i=this.parse(e);return i&&r[i.satId]&&(r[i.satId]={...r[i.satId]}),this.applyToMap(r,e,t),{sats:r}})}),this.state={...this.state,sats:{},speak:{}}}get instanceId(){let e=this.props.oContext;return`${e.adapterName}.${e.instance}`}async componentDidMount(){super.componentDidMount(),this.pattern=`${this.instanceId}.satellites.*`;try{let e=await this.props.oContext.socket.getForeignStates(this.pattern),t={};for(let[n,r]of Object.entries(e||{}))this.applyToMap(t,n,r);this.setState({sats:t})}catch{}this.props.oContext.socket.subscribeState(this.pattern,this.onState)}componentWillUnmount(){var e;this.pattern&&this.props.oContext.socket.unsubscribeState(this.pattern,this.onState),(e=super.componentWillUnmount)==null||e.call(this)}parse(e){let t=`${this.instanceId}.satellites.`;if(!e.startsWith(t))return null;let n=e.slice(t.length),r=n.indexOf(`.`);return r<0?null:{satId:n.slice(0,r),prop:n.slice(r+1)}}applyToMap(e,t,n){let r=this.parse(t);if(!r)return;let i=e[r.satId]||{status:`idle`,room:``,host:``,alive:!1,lastSeen:0};r.prop===`status`?i.status=String((n==null?void 0:n.val)??`idle`):r.prop===`room`?i.room=String((n==null?void 0:n.val)??``):r.prop===`host`?i.host=String((n==null?void 0:n.val)??``):r.prop===`alive`?i.alive=!!(n!=null&&n.val):r.prop===`lastSeen`&&(i.lastSeen=Number(n==null?void 0:n.val)||0),e[r.satId]=i}announce(e){let t=(this.state.speak[e]||``).trim();if(!t)return;let n=e===$?`${this.instanceId}.tts.text`:`${this.instanceId}.satellites.${e}.tts`;this.props.oContext.socket.setState(n,{val:t,ack:!1}).catch(()=>{}),this.setState(t=>({speak:{...t.speak,[e]:``}}))}ago(e){if(!e)return`—`;let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t} s`:t<3600?`${Math.round(t/60)} min`:t<86400?`${Math.round(t/3600)} h`:`${Math.round(t/86400)} d`}renderComposer(e,t){let n=this.state.speak[e]||``;return m(g,{sx:{display:`flex`,alignItems:`center`,gap:.5},children:[p(i,{size:`small`,variant:`outlined`,placeholder:t,value:n,onChange:t=>this.setState(n=>({speak:{...n.speak,[e]:t.target.value}})),onKeyDown:t=>{t.key===`Enter`&&(t.preventDefault(),this.announce(e))},sx:{minWidth:180}}),p(y,{title:_.t(`custom_assistant_Send announcement`),children:p(`span`,{children:p(f,{size:`small`,color:`primary`,disabled:!n.trim(),onClick:()=>this.announce(e),children:p(ee,{})})})})]})}renderItem(){let e=Object.keys(this.state.sats).sort();return m(g,{sx:{width:`100%`},children:[m(g,{sx:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,mb:1},children:[p(x,{variant:`h6`,children:_.t(`custom_assistant_Satellites`)}),e.length?this.renderComposer($,_.t(`custom_assistant_Speak on all satellites`)):null]}),e.length?m(l,{size:`small`,sx:{"& td, & th":{px:1}},children:[p(ce,{children:m(h,{children:[p(b,{}),p(b,{children:_.t(`custom_assistant_Satellite`)}),p(b,{children:_.t(`custom_assistant_room`)}),p(b,{children:_.t(`custom_assistant_Host`)}),p(b,{children:_.t(`custom_assistant_Status`)}),p(b,{children:_.t(`custom_assistant_Last seen`)}),p(b,{children:_.t(`custom_assistant_Announcement`)})]})}),p(u,{children:e.map(e=>{let t=this.state.sats[e];return m(h,{children:[p(b,{sx:{width:24},children:p(y,{title:t.alive?_.t(`custom_assistant_online`):_.t(`custom_assistant_offline`),children:p(ie,{sx:{fontSize:`0.8rem`,color:t.alive?`success.main`:`error.main`}})})}),p(b,{children:e}),p(b,{children:t.room||`—`}),p(b,{children:t.host||`—`}),p(b,{children:p(S,{size:`small`,variant:`outlined`,color:Xn[t.status]||`default`,label:_.t(`custom_assistant_sat_${t.status}`)})}),p(b,{children:p(y,{title:t.lastSeen?new Date(t.lastSeen).toLocaleString():``,children:p(`span`,{children:this.ago(t.lastSeen)})})}),p(b,{children:this.renderComposer(e,_.t(`custom_assistant_Type a message…`))})]},e)})})]}):p(x,{sx:{p:2,opacity:.7},variant:`body2`,children:_.t(`custom_assistant_No satellites registered yet.`)})]})}}};export{Zn as default};
@@ -0,0 +1 @@
1
+ import{t as e}from"./vite-preload-helper-B7qeedMF.js";var t={react:async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js`).then(e=>(e.H(),e.V)),[],import.meta.url),"react/jsx-runtime":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js`).then(e=>e.Gr),[],import.meta.url),"react-dom":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js`).then(e=>e.pr),[],import.meta.url),"@emotion/react":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-Dw5TkU1t.js`).then(e=>e.s),[],import.meta.url),"@emotion/styled":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-BEFjTs9S.js`).then(e=>e.n),[],import.meta.url),"@mui/material":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js`).then(e=>e.Gn),[],import.meta.url),"@mui/icons-material":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js`).then(e=>e.Vt),[],import.meta.url),"@iobroker/gui-components":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C4r3udVz.js`).then(e=>e.b),[],import.meta.url),"@iobroker/json-config":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__ConfigCustomAssistant__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DlOBHPL0.js`).then(e=>e.n),[],import.meta.url)},n={react:{name:`react`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n.react.loaded=!0;let{react:e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"react/jsx-runtime":{name:`react/jsx-runtime`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`react/jsx-runtime`].loaded=!0;let{"react/jsx-runtime":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"react-dom":{name:`react-dom`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`react-dom`].loaded=!0;let{"react-dom":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@emotion/react":{name:`@emotion/react`,version:`11.14.0`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`@emotion/react`].loaded=!0;let{"@emotion/react":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@emotion/styled":{name:`@emotion/styled`,version:`11.14.1`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`@emotion/styled`].loaded=!0;let{"@emotion/styled":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@mui/material":{name:`@mui/material`,version:`9.2.0`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`@mui/material`].loaded=!0;let{"@mui/material":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@mui/icons-material":{name:`@mui/icons-material`,version:`9.2.0`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`@mui/icons-material`].loaded=!0;let{"@mui/icons-material":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@iobroker/gui-components":{name:`@iobroker/gui-components`,version:`10.0.12`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`@iobroker/gui-components`].loaded=!0;let{"@iobroker/gui-components":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@iobroker/json-config":{name:`@iobroker/json-config`,version:`9.0.16`,scope:[`default`],loaded:!1,eager:!1,from:`ConfigCustomAssistant`,canLiveRebind:!0,async get(){n[`@iobroker/json-config`].loaded=!0;let{"@iobroker/json-config":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}}},r=[];export{r as usedRemotes,n as usedShared};