iobroker.fakeroku 1.8.2 → 1.10.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.
Files changed (42) hide show
  1. package/README.md +27 -23
  2. package/admin/i18n/de.json +15 -13
  3. package/admin/i18n/en.json +15 -13
  4. package/admin/i18n/es.json +15 -13
  5. package/admin/i18n/fr.json +15 -13
  6. package/admin/i18n/it.json +15 -13
  7. package/admin/i18n/nl.json +15 -13
  8. package/admin/i18n/pl.json +15 -13
  9. package/admin/i18n/pt.json +15 -13
  10. package/admin/i18n/ru.json +15 -13
  11. package/admin/i18n/uk.json +15 -13
  12. package/admin/i18n/zh-cn.json +15 -13
  13. package/build/command-handler.js +1 -2
  14. package/build/command-handler.js.map +2 -2
  15. package/build/device-management.js +9 -0
  16. package/build/device-management.js.map +2 -2
  17. package/build/discovery/ssdp-responder.js.map +1 -1
  18. package/build/ecp/device-info.js +2 -19
  19. package/build/ecp/device-info.js.map +2 -2
  20. package/build/ecp/ecp-command.js.map +1 -1
  21. package/build/ecp/ecp-http-server.js +1 -9
  22. package/build/ecp/ecp-http-server.js.map +2 -2
  23. package/build/ecp/state-model.js +0 -1
  24. package/build/ecp/state-model.js.map +2 -2
  25. package/build/lib/constants.js +7 -1
  26. package/build/lib/constants.js.map +2 -2
  27. package/build/lib/detect-ip.js +7 -71
  28. package/build/lib/detect-ip.js.map +2 -2
  29. package/build/lib/device-config.js +1 -0
  30. package/build/lib/device-config.js.map +2 -2
  31. package/build/lib/i18n.js +2 -7
  32. package/build/lib/i18n.js.map +2 -2
  33. package/build/lib/network-address.js +85 -0
  34. package/build/lib/network-address.js.map +7 -0
  35. package/build/lib/object-cleanup.js +3 -2
  36. package/build/lib/object-cleanup.js.map +2 -2
  37. package/build/main.js +347 -271
  38. package/build/main.js.map +2 -2
  39. package/io-package.json +152 -38
  40. package/package.json +3 -3
  41. package/build/lib/lan-guard.js +0 -43
  42. package/build/lib/lan-guard.js.map +0 -7
package/README.md CHANGED
@@ -9,14 +9,12 @@
9
9
  > [!IMPORTANT]
10
10
  > This adapter cannot be installed from github
11
11
 
12
- Emulates one or more **[Roku](https://www.roku.com/) devices** on your LAN so that ECP/SSDP remotes and
13
- controllers — a Logitech Harmony Hub, a Sofabaton X1/X2, Home Assistant's Roku integration,
14
- openHAB — can trigger events in ioBroker. It is the **input** counterpart to the Logitech
12
+ Emulates one or more **[Roku](https://www.roku.com/) devices** on your LAN so that a Logitech Harmony Hub or
13
+ a Sofabaton X1/X2 can trigger events in ioBroker. It is the **input** counterpart to the Logitech
15
14
  Harmony adapter: a button on the remote becomes a datapoint in ioBroker.
16
15
 
17
- Besides the key presses it answers the queries these controllers make before and while
18
- they use a Roku — device info, app list, active app, media player, TV channels, app icons —
19
- so they accept the emulated device instead of giving up on it.
16
+ Besides the key presses it answers what these remotes read when they pair — device info,
17
+ app list, app icons.
20
18
 
21
19
  > **The official Roku mobile app is not supported.** It drives Rokus over Roku's
22
20
  > proprietary, undocumented ECP-2 WebSocket channel, which this emulator does not
@@ -76,19 +74,23 @@ At instance level:
76
74
 
77
75
  | Datapoint | Type | Meaning |
78
76
  |---|---|---|
79
- | `info.connection` | boolean, read-only | `true` only while **every** configured Roku is actually listening. If one of them cannot start — usually because its port is already taken — the log names the device and the port, and the adapter retries that device every minute until it comes up. |
77
+ | `info.connection` | boolean, read-only | `true` only while everything runs: **every** configured Roku listens, discovery answers, and the chosen address exists. Anything less shows the instance yellow; the log names the cause once, and the adapter retries a Roku or discovery that is down every minute. |
78
+ | `info.devicesTotal` | number, read-only | How many emulated Rokus are configured. |
79
+ | `info.devicesOnline` | number, read-only | How many of them listen right now. |
80
+ | `info.devicesAllOnline` | boolean, read-only | `true` while every configured Roku listens; `false` while none is configured. |
80
81
 
81
82
  For every emulated Roku (`fakeroku.0.<name>`):
82
83
 
83
84
  | Datapoint | Type | Meaning |
84
85
  |---|---|---|
86
+ | `.info.online` | boolean, read-only | `true` while this Roku listens on its port. The device shows a green or grey symbol in the object tree, its card in the device manager online or offline. |
87
+ | `.info.error` | string, read-only | Why this Roku does not run, e.g. `port 8061 is already in use (another program or another instance holds it)`; empty while it runs, `Unknown` while the adapter is off or starting. The card shows it as a warning. |
85
88
  | `.command` | string, read-only | The last command as plain text (`Home`, `Lit_a`, `launch:12`, `search:news`). One datapoint for everything — no object-per-character sprawl. |
86
- | `.commandType` | string, read-only | `keypress` / `keydown` / `keyup` / `launch` / `install` / `input` / `search`. |
87
89
  | `.keys.<Key>` | boolean, read-only | One state per remote key the device type exposes — a *Player* has the 16 navigation/playback keys, a *TV* adds Volume\*, PowerOn/PowerOff/Power, Sleep, Channel\*, Tuner/HDMI/AV inputs — all created up front. A keypress pulses it `true` for a moment; keydown/keyup hold it. Key names are read in any case (`home` is `Home`). |
88
90
 
89
91
  Free keyboard input (`Lit_x`) and app launches show up in `.command` only — they do
90
92
  not get their own objects. An app button of a remote that sends app launches (a
91
- Sofabaton, Home Assistant) arrives as `launch:<id>`; a Harmony Hub did not send its app
93
+ Sofabaton) arrives as `launch:<id>`; a Harmony Hub did not send its app
92
94
  buttons to the emulated Roku.
93
95
 
94
96
  > Note: the Roku remote sends the **same** `Play` command for play and pause, so
@@ -103,6 +105,22 @@ becomes `true` — or watch `.command` for the last button as text.
103
105
  Placeholder for the next version (at the beginning of the line):
104
106
  ### **WORK IN PROGRESS**
105
107
  -->
108
+ ### 1.10.0 (2026-10-03)
109
+
110
+ - (krobipd) New: every emulated Roku shows whether it runs and, if not, why — a green or grey symbol in the object tree, online or offline on its card with the reason.
111
+ - (krobipd) New: three datapoints count the emulated Rokus — how many are configured, how many run, and whether all of them run.
112
+ - (krobipd) Fixed: the connection datapoint's description says what green means — every Roku listening, discovery answering and the chosen address present.
113
+
114
+ ### 1.9.0 (2026-10-03)
115
+
116
+ - (krobipd) Changed: the emulated Roku answers only what a Harmony or Sofabaton reads — Home Assistant and openHAB can no longer set it up.
117
+ - (krobipd) Changed: the instance shows green only while every Roku and discovery run, and yellow otherwise.
118
+ - (krobipd) Changed: a Roku whose server stopped while running and a discovery that failed start again within a minute instead of waiting for a restart.
119
+ - (krobipd) Changed: with no Roku configured or none running, the instance stays up so the device manager works, and asks you to add a Roku.
120
+ - (krobipd) Changed: a chosen address that is missing on the host no longer leaves the Rokus off — they listen on all addresses until you choose another.
121
+ - (krobipd) Changed: requests from the ioBroker host itself or from self-assigned addresses outside the host's networks are refused.
122
+ - (krobipd) Changed: the datapoint with the kind of the last command is gone — the last command itself still arrives as before; existing installations drop it on the next start.
123
+
106
124
  ### 1.8.2 (2026-10-02)
107
125
 
108
126
  - (krobipd) Changed: a new instance starts switched off — check the settings, then switch it on.
@@ -129,20 +147,6 @@ becomes `true` — or watch `.command` for the last button as text.
129
147
  - (krobipd) New: the TV profile adds the PowerOn, Power, Sleep and InputTuner keys and announces itself the way real Roku TVs do.
130
148
  - (krobipd) New: every new emulated Roku gets its own network identity instead of one every installation with the same name would share.
131
149
 
132
- ### 1.7.1 (2026-09-16) — stable
133
-
134
- - (krobipd) Changed: the instance restarts once after this update to clear a setting left behind by an older version; nothing else changes for you.
135
-
136
- ### 1.7.0 (2026-09-16)
137
-
138
- - (krobipd) Fixed: button datapoints keep their value and their room and function assignment when the adapter starts.
139
- - (krobipd) Fixed: after an emulated Roku drops out, its port is free again instead of staying blocked until ioBroker restarts.
140
- - (krobipd) Fixed: stopping the instance no longer leaves it reported as connected.
141
- - (krobipd) Fixed: a key you hold right after a short press stays pressed instead of being released early.
142
- - (krobipd) Fixed: the device dialog now also refuses a name that would collide with an existing device in the object tree.
143
- - (krobipd) Improved: after the host gets a new IP address, remotes find the emulated Rokus again without restarting the instance.
144
- - (krobipd) Changed: the network interface setting moved to the standard settings key (bind); the instance restarts once after this update.
145
-
146
150
  [Older changelogs can be found there](CHANGELOG_OLD.md)
147
151
 
148
152
  ## History
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Name",
8
8
  "devicePort": "ECP-Port",
9
9
  "portLabel": "Port",
10
- "devicePortHint": "Der ECP-Port, auf dem dieser Roku antwortet. Jeder emulierte Roku braucht seinen eigenen Port. Harmony und Sofabaton lesen den Port aus der Erkennung; Home Assistant und Homey nutzen immer 8060 — gib 8060 dem Roku, den sie steuern sollen.",
10
+ "devicePortHint": "Der ECP-Port, auf dem dieser Roku antwortet. Jeder emulierte Roku braucht seinen eigenen Port. Harmony und Sofabaton lesen den Port aus der Erkennung.",
11
11
  "deviceTypeLabel": "Typ",
12
12
  "deviceTypePlayer": "Player (Streaming-Box)",
13
13
  "deviceTypeTv": "TV (mit Lautstärke, Ein/Aus, Kanal, Eingang)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Adapter-Informationen",
29
29
  "connectionStatus": "Verbindungsstatus",
30
- "connectionStatusDesc": "Nur wahr, solange jeder konfigurierte emulierte Roku tatsächlich lauscht.",
30
+ "connectionStatusDesc": "Nur wahr, solange alles läuft: jeder konfigurierte emulierte Roku lauscht, die Erkennung antwortet und die gewählte Adresse existiert.",
31
31
  "stateLastCommand": "Letzter Befehl",
32
32
  "stateLastCommandDesc": "Der zuletzt empfangene Befehl dieses emulierten Roku als Klartext.",
33
- "stateLastCommandType": "Art des letzten Befehls",
34
- "stateLastCommandTypeDesc": "Um welche Art Befehl es sich handelte: Tastendruck, Taste gehalten oder losgelassen, App-Start oder -Installation, Texteingabe oder Suche.",
35
- "commandType_none": "Noch kein Befehl",
36
- "commandType_keypress": "Tastendruck",
37
- "commandType_keydown": "Taste gehalten",
38
- "commandType_keyup": "Taste losgelassen",
39
- "commandType_launch": "App-Start",
40
- "commandType_install": "App-Installation",
41
- "commandType_input": "Texteingabe",
42
- "commandType_search": "Suche",
43
33
  "channelKeys": "Fernbedienungstasten",
44
- "channelKeysDesc": "Ein Datenpunkt je Taste, die dieses Gerät anbietet; ein Tastendruck setzt ihn kurz auf wahr."
34
+ "channelKeysDesc": "Ein Datenpunkt je Taste, die dieses Gerät anbietet; ein Tastendruck setzt ihn kurz auf wahr.",
35
+ "channelDeviceInfo": "Status",
36
+ "channelDeviceInfoDesc": "Ob dieser emulierte Roku läuft und, falls nicht, warum.",
37
+ "stateOnline": "Online",
38
+ "stateOnlineDesc": "Wahr, solange dieser emulierte Roku auf seinem ECP-Port lauscht.",
39
+ "stateError": "Fehler",
40
+ "stateErrorDesc": "Warum dieser emulierte Roku nicht läuft; leer, solange er läuft, Unknown, solange der Adapter aus ist oder startet.",
41
+ "devicesTotal": "Emulierte Rokus",
42
+ "devicesTotalDesc": "Wie viele emulierte Rokus eingerichtet sind.",
43
+ "devicesOnline": "Emulierte Rokus online",
44
+ "devicesOnlineDesc": "Wie viele emulierte Rokus gerade lauschen.",
45
+ "devicesAllOnline": "Alle emulierten Rokus online",
46
+ "devicesAllOnlineDesc": "Wahr, solange jeder eingerichtete emulierte Roku lauscht; falsch, solange keiner eingerichtet ist."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Name",
8
8
  "devicePort": "ECP port",
9
9
  "portLabel": "Port",
10
- "devicePortHint": "The ECP port this Roku answers on. Each emulated Roku needs its own port. Harmony and Sofabaton read the port from the discovery; Home Assistant and Homey always use 8060 — give 8060 to the Roku they should control.",
10
+ "devicePortHint": "The ECP port this Roku answers on. Each emulated Roku needs its own port. Harmony and Sofabaton read the port from the discovery.",
11
11
  "deviceTypeLabel": "Type",
12
12
  "deviceTypePlayer": "Player (streaming box)",
13
13
  "deviceTypeTv": "TV (adds volume, power, channel, input)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Adapter information",
29
29
  "connectionStatus": "Connection status",
30
- "connectionStatusDesc": "True only while every configured emulated Roku is actually listening.",
30
+ "connectionStatusDesc": "True only while everything runs: every configured emulated Roku listens, discovery answers and the chosen address exists.",
31
31
  "stateLastCommand": "Last command",
32
32
  "stateLastCommandDesc": "The most recent command this emulated Roku received, as plain text.",
33
- "stateLastCommandType": "Last command type",
34
- "stateLastCommandTypeDesc": "What kind of command it was: a key press, a key held or released, an app launch or install, a text input or a search.",
35
- "commandType_none": "No command yet",
36
- "commandType_keypress": "Key press",
37
- "commandType_keydown": "Key held",
38
- "commandType_keyup": "Key released",
39
- "commandType_launch": "App launch",
40
- "commandType_install": "App install",
41
- "commandType_input": "Text input",
42
- "commandType_search": "Search",
43
33
  "channelKeys": "Remote keys",
44
- "channelKeysDesc": "One state per remote key this device offers; a key press pulses it briefly."
34
+ "channelKeysDesc": "One state per remote key this device offers; a key press pulses it briefly.",
35
+ "channelDeviceInfo": "Status",
36
+ "channelDeviceInfoDesc": "Whether this emulated Roku runs and, if not, why.",
37
+ "stateOnline": "Online",
38
+ "stateOnlineDesc": "True while this emulated Roku listens on its ECP port.",
39
+ "stateError": "Error",
40
+ "stateErrorDesc": "Why this emulated Roku does not run; empty while it runs, Unknown while the adapter is off or starting.",
41
+ "devicesTotal": "Emulated Rokus",
42
+ "devicesTotalDesc": "How many emulated Rokus are configured.",
43
+ "devicesOnline": "Emulated Rokus online",
44
+ "devicesOnlineDesc": "How many emulated Rokus listen right now.",
45
+ "devicesAllOnline": "All emulated Rokus online",
46
+ "devicesAllOnlineDesc": "True while every configured emulated Roku listens; false while none is configured."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Nombre",
8
8
  "devicePort": "Puerto ECP",
9
9
  "portLabel": "Puerto",
10
- "devicePortHint": "El puerto ECP en el que responde este Roku. Cada Roku emulado necesita su propio puerto. Harmony y Sofabaton leen el puerto del descubrimiento; Home Assistant y Homey usan siempre el 8060: asigna el 8060 al Roku que deben controlar.",
10
+ "devicePortHint": "El puerto ECP en el que responde este Roku. Cada Roku emulado necesita su propio puerto. Harmony y Sofabaton leen el puerto del descubrimiento.",
11
11
  "deviceTypeLabel": "Tipo",
12
12
  "deviceTypePlayer": "Reproductor (dispositivo de streaming)",
13
13
  "deviceTypeTv": "TV (con volumen, encendido, canal, entrada)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Información del adaptador",
29
29
  "connectionStatus": "Estado de conexión",
30
- "connectionStatusDesc": "Verdadero solo mientras cada Roku emulado configurado esté realmente a la escucha.",
30
+ "connectionStatusDesc": "Verdadero solo mientras todo funciona: cada Roku emulado configurado escucha, la detección responde y la dirección elegida existe.",
31
31
  "stateLastCommand": "Último comando",
32
32
  "stateLastCommandDesc": "El comando más reciente que recibió este Roku emulado, como texto simple.",
33
- "stateLastCommandType": "Tipo del último comando",
34
- "stateLastCommandTypeDesc": "Qué tipo de comando fue: pulsar una tecla, mantenerla o soltarla, iniciar o instalar una aplicación, introducir texto o buscar.",
35
- "commandType_none": "Aún sin comando",
36
- "commandType_keypress": "Pulsación de tecla",
37
- "commandType_keydown": "Tecla mantenida",
38
- "commandType_keyup": "Tecla soltada",
39
- "commandType_launch": "Inicio de app",
40
- "commandType_install": "Instalación de app",
41
- "commandType_input": "Entrada de texto",
42
- "commandType_search": "Búsqueda",
43
33
  "channelKeys": "Teclas del mando",
44
- "channelKeysDesc": "Un estado por cada tecla que ofrece este dispositivo; una pulsación lo pone brevemente en verdadero."
34
+ "channelKeysDesc": "Un estado por cada tecla que ofrece este dispositivo; una pulsación lo pone brevemente en verdadero.",
35
+ "channelDeviceInfo": "Estado",
36
+ "channelDeviceInfoDesc": "Si este Roku emulado funciona y, si no, por qué.",
37
+ "stateOnline": "En línea",
38
+ "stateOnlineDesc": "Verdadero mientras este Roku emulado escucha en su puerto ECP.",
39
+ "stateError": "Error",
40
+ "stateErrorDesc": "Por qué este Roku emulado no funciona; vacío mientras funciona, Unknown mientras el adaptador está apagado o arrancando.",
41
+ "devicesTotal": "Rokus emulados",
42
+ "devicesTotalDesc": "Cuántos Rokus emulados están configurados.",
43
+ "devicesOnline": "Rokus emulados en línea",
44
+ "devicesOnlineDesc": "Cuántos Rokus emulados escuchan ahora mismo.",
45
+ "devicesAllOnline": "Todos los Rokus emulados en línea",
46
+ "devicesAllOnlineDesc": "Verdadero mientras cada Roku emulado configurado escucha; falso mientras no hay ninguno configurado."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Nom",
8
8
  "devicePort": "Port ECP",
9
9
  "portLabel": "Port",
10
- "devicePortHint": "Le port ECP sur lequel ce Roku répond. Chaque Roku émulé a besoin de son propre port. Harmony et Sofabaton lisent le port dans la découverte ; Home Assistant et Homey utilisent toujours 8060 — attribuez 8060 au Roku qu'ils doivent piloter.",
10
+ "devicePortHint": "Le port ECP sur lequel ce Roku répond. Chaque Roku émulé a besoin de son propre port. Harmony et Sofabaton lisent le port dans la découverte.",
11
11
  "deviceTypeLabel": "Type",
12
12
  "deviceTypePlayer": "Player (box de streaming)",
13
13
  "deviceTypeTv": "TV (avec volume, marche/arrêt, chaîne, entrée)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Informations sur l'adaptateur",
29
29
  "connectionStatus": "État de la connexion",
30
- "connectionStatusDesc": "Vrai uniquement tant que chaque Roku émulé configuré est réellement à l'écoute.",
30
+ "connectionStatusDesc": "Vrai uniquement tant que tout fonctionne : chaque Roku émulé configuré écoute, la découverte répond et l'adresse choisie existe.",
31
31
  "stateLastCommand": "Dernière commande",
32
32
  "stateLastCommandDesc": "La commande la plus récente reçue par ce Roku émulé, en texte brut.",
33
- "stateLastCommandType": "Type de la dernière commande",
34
- "stateLastCommandTypeDesc": "De quel type de commande il s'agissait : appui sur une touche, touche maintenue ou relâchée, lancement ou installation d'une application, saisie de texte ou recherche.",
35
- "commandType_none": "Aucune commande pour l'instant",
36
- "commandType_keypress": "Appui sur une touche",
37
- "commandType_keydown": "Touche maintenue",
38
- "commandType_keyup": "Touche relâchée",
39
- "commandType_launch": "Lancement d'appli",
40
- "commandType_install": "Installation d'appli",
41
- "commandType_input": "Saisie de texte",
42
- "commandType_search": "Recherche",
43
33
  "channelKeys": "Touches de la télécommande",
44
- "channelKeysDesc": "Un état par touche proposée par cet appareil ; un appui le met brièvement à vrai."
34
+ "channelKeysDesc": "Un état par touche proposée par cet appareil ; un appui le met brièvement à vrai.",
35
+ "channelDeviceInfo": "État",
36
+ "channelDeviceInfoDesc": "Si ce Roku émulé fonctionne et, sinon, pourquoi.",
37
+ "stateOnline": "En ligne",
38
+ "stateOnlineDesc": "Vrai tant que ce Roku émulé écoute sur son port ECP.",
39
+ "stateError": "Erreur",
40
+ "stateErrorDesc": "Pourquoi ce Roku émulé ne fonctionne pas ; vide tant qu'il fonctionne, Unknown tant que l'adaptateur est arrêté ou démarre.",
41
+ "devicesTotal": "Rokus émulés",
42
+ "devicesTotalDesc": "Combien de Rokus émulés sont configurés.",
43
+ "devicesOnline": "Rokus émulés en ligne",
44
+ "devicesOnlineDesc": "Combien de Rokus émulés écoutent en ce moment.",
45
+ "devicesAllOnline": "Tous les Rokus émulés en ligne",
46
+ "devicesAllOnlineDesc": "Vrai tant que chaque Roku émulé configuré écoute ; faux tant qu'aucun n'est configuré."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Nome",
8
8
  "devicePort": "Porta ECP",
9
9
  "portLabel": "Porta",
10
- "devicePortHint": "La porta ECP su cui risponde questo Roku. Ogni Roku emulato ha bisogno della propria porta. Harmony e Sofabaton leggono la porta dal rilevamento; Home Assistant e Homey usano sempre la 8060 — assegna la 8060 al Roku che devono controllare.",
10
+ "devicePortHint": "La porta ECP su cui risponde questo Roku. Ogni Roku emulato ha bisogno della propria porta. Harmony e Sofabaton leggono la porta dal rilevamento.",
11
11
  "deviceTypeLabel": "Tipo",
12
12
  "deviceTypePlayer": "Player (box di streaming)",
13
13
  "deviceTypeTv": "TV (con volume, accensione, canale, ingresso)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Informazioni sull'adattatore",
29
29
  "connectionStatus": "Stato connessione",
30
- "connectionStatusDesc": "Vero solo finché ogni Roku emulato configurato è effettivamente in ascolto.",
30
+ "connectionStatusDesc": "Vero solo finché tutto funziona: ogni Roku emulato configurato è in ascolto, il rilevamento risponde e l'indirizzo scelto esiste.",
31
31
  "stateLastCommand": "Ultimo comando",
32
32
  "stateLastCommandDesc": "Il comando più recente ricevuto da questo Roku emulato, come testo semplice.",
33
- "stateLastCommandType": "Tipo dell'ultimo comando",
34
- "stateLastCommandTypeDesc": "Di che tipo di comando si trattava: pressione di un tasto, tasto tenuto premuto o rilasciato, avvio o installazione di un'app, immissione di testo o ricerca.",
35
- "commandType_none": "Ancora nessun comando",
36
- "commandType_keypress": "Pressione tasto",
37
- "commandType_keydown": "Tasto tenuto premuto",
38
- "commandType_keyup": "Tasto rilasciato",
39
- "commandType_launch": "Avvio app",
40
- "commandType_install": "Installazione app",
41
- "commandType_input": "Inserimento testo",
42
- "commandType_search": "Ricerca",
43
33
  "channelKeys": "Tasti del telecomando",
44
- "channelKeysDesc": "Uno stato per ogni tasto offerto da questo dispositivo; una pressione lo porta brevemente a vero."
34
+ "channelKeysDesc": "Uno stato per ogni tasto offerto da questo dispositivo; una pressione lo porta brevemente a vero.",
35
+ "channelDeviceInfo": "Stato",
36
+ "channelDeviceInfoDesc": "Se questo Roku emulato è in funzione e, in caso contrario, perché.",
37
+ "stateOnline": "Online",
38
+ "stateOnlineDesc": "Vero finché questo Roku emulato è in ascolto sulla sua porta ECP.",
39
+ "stateError": "Errore",
40
+ "stateErrorDesc": "Perché questo Roku emulato non è in funzione; vuoto finché funziona, Unknown finché l'adattatore è spento o si avvia.",
41
+ "devicesTotal": "Roku emulati",
42
+ "devicesTotalDesc": "Quanti Roku emulati sono configurati.",
43
+ "devicesOnline": "Roku emulati online",
44
+ "devicesOnlineDesc": "Quanti Roku emulati sono in ascolto in questo momento.",
45
+ "devicesAllOnline": "Tutti i Roku emulati online",
46
+ "devicesAllOnlineDesc": "Vero finché ogni Roku emulato configurato è in ascolto; falso finché nessuno è configurato."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Naam",
8
8
  "devicePort": "ECP-poort",
9
9
  "portLabel": "Poort",
10
- "devicePortHint": "De ECP-poort waarop deze Roku antwoordt. Elke geëmuleerde Roku heeft een eigen poort nodig. Harmony en Sofabaton lezen de poort uit de detectie; Home Assistant en Homey gebruiken altijd 8060 — geef 8060 aan de Roku die zij moeten bedienen.",
10
+ "devicePortHint": "De ECP-poort waarop deze Roku antwoordt. Elke geëmuleerde Roku heeft een eigen poort nodig. Harmony en Sofabaton lezen de poort uit de detectie.",
11
11
  "deviceTypeLabel": "Type",
12
12
  "deviceTypePlayer": "Player (streaming-box)",
13
13
  "deviceTypeTv": "TV (met volume, aan/uit, kanaal, ingang)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Adapterinformatie",
29
29
  "connectionStatus": "Verbindingsstatus",
30
- "connectionStatusDesc": "Alleen waar zolang elke geconfigureerde geëmuleerde Roku daadwerkelijk luistert.",
30
+ "connectionStatusDesc": "Alleen waar zolang alles draait: elke geconfigureerde geëmuleerde Roku luistert, de detectie antwoordt en het gekozen adres bestaat.",
31
31
  "stateLastCommand": "Laatste opdracht",
32
32
  "stateLastCommandDesc": "De meest recente opdracht die deze geëmuleerde Roku ontving, als platte tekst.",
33
- "stateLastCommandType": "Type laatste opdracht",
34
- "stateLastCommandTypeDesc": "Wat voor soort opdracht het was: een toetsdruk, een toets ingedrukt of losgelaten, een app starten of installeren, tekstinvoer of zoeken.",
35
- "commandType_none": "Nog geen opdracht",
36
- "commandType_keypress": "Toetsdruk",
37
- "commandType_keydown": "Toets vastgehouden",
38
- "commandType_keyup": "Toets losgelaten",
39
- "commandType_launch": "App starten",
40
- "commandType_install": "App installeren",
41
- "commandType_input": "Tekstinvoer",
42
- "commandType_search": "Zoeken",
43
33
  "channelKeys": "Afstandsbedieningstoetsen",
44
- "channelKeysDesc": "Eén status per toets die dit apparaat biedt; een toetsdruk zet hem kort op waar."
34
+ "channelKeysDesc": "Eén status per toets die dit apparaat biedt; een toetsdruk zet hem kort op waar.",
35
+ "channelDeviceInfo": "Status",
36
+ "channelDeviceInfoDesc": "Of deze geëmuleerde Roku draait en, zo niet, waarom.",
37
+ "stateOnline": "Online",
38
+ "stateOnlineDesc": "Waar zolang deze geëmuleerde Roku op zijn ECP-poort luistert.",
39
+ "stateError": "Fout",
40
+ "stateErrorDesc": "Waarom deze geëmuleerde Roku niet draait; leeg zolang hij draait, Unknown zolang de adapter uit staat of start.",
41
+ "devicesTotal": "Geëmuleerde Roku's",
42
+ "devicesTotalDesc": "Hoeveel geëmuleerde Roku's er zijn ingesteld.",
43
+ "devicesOnline": "Geëmuleerde Roku's online",
44
+ "devicesOnlineDesc": "Hoeveel geëmuleerde Roku's op dit moment luisteren.",
45
+ "devicesAllOnline": "Alle geëmuleerde Roku's online",
46
+ "devicesAllOnlineDesc": "Waar zolang elke ingestelde geëmuleerde Roku luistert; onwaar zolang er geen is ingesteld."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Nazwa",
8
8
  "devicePort": "Port ECP",
9
9
  "portLabel": "Port",
10
- "devicePortHint": "Port ECP, na którym odpowiada ten Roku. Każdy emulowany Roku potrzebuje własnego portu. Harmony i Sofabaton odczytują port z wykrywania; Home Assistant i Homey zawsze używają 8060 — nadaj 8060 temu Roku, którym mają sterować.",
10
+ "devicePortHint": "Port ECP, na którym odpowiada ten Roku. Każdy emulowany Roku potrzebuje własnego portu. Harmony i Sofabaton odczytują port z wykrywania.",
11
11
  "deviceTypeLabel": "Typ",
12
12
  "deviceTypePlayer": "Player (przystawka)",
13
13
  "deviceTypeTv": "TV (z głośnością, zasilaniem, kanałem, wejściem)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Informacje o adapterze",
29
29
  "connectionStatus": "Stan połączenia",
30
- "connectionStatusDesc": "Prawda tylko wtedy, gdy każdy skonfigurowany emulowany Roku faktycznie nasłuchuje.",
30
+ "connectionStatusDesc": "Prawda tylko wtedy, gdy wszystko działa: każdy skonfigurowany emulowany Roku nasłuchuje, wykrywanie odpowiada, a wybrany adres istnieje.",
31
31
  "stateLastCommand": "Ostatnie polecenie",
32
32
  "stateLastCommandDesc": "Najnowsze polecenie odebrane przez ten emulowany Roku, jako zwykły tekst.",
33
- "stateLastCommandType": "Typ ostatniego polecenia",
34
- "stateLastCommandTypeDesc": "Jakiego rodzaju było to polecenie: naciśnięcie klawisza, przytrzymanie lub zwolnienie, uruchomienie lub instalacja aplikacji, wpisanie tekstu albo wyszukiwanie.",
35
- "commandType_none": "Jeszcze brak polecenia",
36
- "commandType_keypress": "Naciśnięcie klawisza",
37
- "commandType_keydown": "Klawisz przytrzymany",
38
- "commandType_keyup": "Klawisz zwolniony",
39
- "commandType_launch": "Uruchomienie aplikacji",
40
- "commandType_install": "Instalacja aplikacji",
41
- "commandType_input": "Wprowadzanie tekstu",
42
- "commandType_search": "Wyszukiwanie",
43
33
  "channelKeys": "Klawisze pilota",
44
- "channelKeysDesc": "Jeden stan na każdy klawisz oferowany przez to urządzenie; naciśnięcie ustawia go na krótko na wartość true."
34
+ "channelKeysDesc": "Jeden stan na każdy klawisz oferowany przez to urządzenie; naciśnięcie ustawia go na krótko na wartość true.",
35
+ "channelDeviceInfo": "Stan",
36
+ "channelDeviceInfoDesc": "Czy ten emulowany Roku działa, a jeśli nie, to dlaczego.",
37
+ "stateOnline": "Online",
38
+ "stateOnlineDesc": "Prawda, dopóki ten emulowany Roku nasłuchuje na swoim porcie ECP.",
39
+ "stateError": "Błąd",
40
+ "stateErrorDesc": "Dlaczego ten emulowany Roku nie działa; puste, gdy działa, Unknown, gdy adapter jest wyłączony lub się uruchamia.",
41
+ "devicesTotal": "Emulowane Roku",
42
+ "devicesTotalDesc": "Ile emulowanych Roku jest skonfigurowanych.",
43
+ "devicesOnline": "Emulowane Roku online",
44
+ "devicesOnlineDesc": "Ile emulowanych Roku nasłuchuje w tej chwili.",
45
+ "devicesAllOnline": "Wszystkie emulowane Roku online",
46
+ "devicesAllOnlineDesc": "Prawda, dopóki nasłuchuje każdy skonfigurowany emulowany Roku; fałsz, dopóki żaden nie jest skonfigurowany."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Nome",
8
8
  "devicePort": "Porta ECP",
9
9
  "portLabel": "Porta",
10
- "devicePortHint": "A porta ECP em que este Roku responde. Cada Roku emulado precisa da sua própria porta. O Harmony e o Sofabaton leem a porta na descoberta; o Home Assistant e o Homey usam sempre a 8060 — atribua a 8060 ao Roku que devem controlar.",
10
+ "devicePortHint": "A porta ECP em que este Roku responde. Cada Roku emulado precisa da sua própria porta. O Harmony e o Sofabaton leem a porta na descoberta.",
11
11
  "deviceTypeLabel": "Tipo",
12
12
  "deviceTypePlayer": "Player (box de streaming)",
13
13
  "deviceTypeTv": "TV (com volume, ligar/desligar, canal, entrada)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Informação do adaptador",
29
29
  "connectionStatus": "Estado da ligação",
30
- "connectionStatusDesc": "Verdadeiro apenas enquanto todos os Roku emulados configurados estiverem realmente à escuta.",
30
+ "connectionStatusDesc": "Verdadeiro apenas enquanto tudo funciona: cada Roku emulado configurado está à escuta, a descoberta responde e o endereço escolhido existe.",
31
31
  "stateLastCommand": "Último comando",
32
32
  "stateLastCommandDesc": "O comando mais recente recebido por este Roku emulado, em texto simples.",
33
- "stateLastCommandType": "Tipo do último comando",
34
- "stateLastCommandTypeDesc": "Que tipo de comando foi: pressionar uma tecla, manter ou soltar, iniciar ou instalar uma aplicação, introduzir texto ou pesquisar.",
35
- "commandType_none": "Ainda sem comando",
36
- "commandType_keypress": "Toque de tecla",
37
- "commandType_keydown": "Tecla mantida",
38
- "commandType_keyup": "Tecla solta",
39
- "commandType_launch": "Abrir aplicação",
40
- "commandType_install": "Instalar aplicação",
41
- "commandType_input": "Entrada de texto",
42
- "commandType_search": "Pesquisa",
43
33
  "channelKeys": "Teclas do comando",
44
- "channelKeysDesc": "Um estado por cada tecla que este dispositivo oferece; uma pressão coloca-o brevemente a verdadeiro."
34
+ "channelKeysDesc": "Um estado por cada tecla que este dispositivo oferece; uma pressão coloca-o brevemente a verdadeiro.",
35
+ "channelDeviceInfo": "Estado",
36
+ "channelDeviceInfoDesc": "Se este Roku emulado está a funcionar e, se não, porquê.",
37
+ "stateOnline": "Online",
38
+ "stateOnlineDesc": "Verdadeiro enquanto este Roku emulado está à escuta na sua porta ECP.",
39
+ "stateError": "Erro",
40
+ "stateErrorDesc": "Porque é que este Roku emulado não funciona; vazio enquanto funciona, Unknown enquanto o adaptador está desligado ou a arrancar.",
41
+ "devicesTotal": "Rokus emulados",
42
+ "devicesTotalDesc": "Quantos Rokus emulados estão configurados.",
43
+ "devicesOnline": "Rokus emulados online",
44
+ "devicesOnlineDesc": "Quantos Rokus emulados estão à escuta neste momento.",
45
+ "devicesAllOnline": "Todos os Rokus emulados online",
46
+ "devicesAllOnlineDesc": "Verdadeiro enquanto cada Roku emulado configurado está à escuta; falso enquanto nenhum está configurado."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Имя",
8
8
  "devicePort": "Порт ECP",
9
9
  "portLabel": "Порт",
10
- "devicePortHint": "Порт ECP, на котором отвечает этот Roku. Каждому эмулированному Roku нужен свой порт. Harmony и Sofabaton берут порт из обнаружения; Home Assistant и Homey всегда используют 8060 — назначьте 8060 тому Roku, которым они должны управлять.",
10
+ "devicePortHint": "Порт ECP, на котором отвечает этот Roku. Каждому эмулированному Roku нужен свой порт. Harmony и Sofabaton берут порт из обнаружения.",
11
11
  "deviceTypeLabel": "Тип",
12
12
  "deviceTypePlayer": "Проигрыватель (приставка)",
13
13
  "deviceTypeTv": "ТВ (с громкостью, питанием, каналом, входом)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Информация об адаптере",
29
29
  "connectionStatus": "Статус подключения",
30
- "connectionStatusDesc": "Истина только пока каждый настроенный эмулированный Roku действительно слушает.",
30
+ "connectionStatusDesc": "Истина только пока всё работает: каждый настроенный эмулированный Roku слушает, обнаружение отвечает и выбранный адрес существует.",
31
31
  "stateLastCommand": "Последняя команда",
32
32
  "stateLastCommandDesc": "Последняя команда, полученная этим эмулированным Roku, в виде текста.",
33
- "stateLastCommandType": "Тип последней команды",
34
- "stateLastCommandTypeDesc": "Какого рода была команда: нажатие кнопки, удержание или отпускание, запуск или установка приложения, ввод текста или поиск.",
35
- "commandType_none": "Команд ещё не было",
36
- "commandType_keypress": "Нажатие клавиши",
37
- "commandType_keydown": "Клавиша удерживается",
38
- "commandType_keyup": "Клавиша отпущена",
39
- "commandType_launch": "Запуск приложения",
40
- "commandType_install": "Установка приложения",
41
- "commandType_input": "Ввод текста",
42
- "commandType_search": "Поиск",
43
33
  "channelKeys": "Кнопки пульта",
44
- "channelKeysDesc": "По одному состоянию на каждую кнопку пульта этого устройства; нажатие кратко переводит его в истину."
34
+ "channelKeysDesc": "По одному состоянию на каждую кнопку пульта этого устройства; нажатие кратко переводит его в истину.",
35
+ "channelDeviceInfo": "Состояние",
36
+ "channelDeviceInfoDesc": "Работает ли этот эмулированный Roku и, если нет, почему.",
37
+ "stateOnline": "В сети",
38
+ "stateOnlineDesc": "Истина, пока этот эмулированный Roku слушает свой порт ECP.",
39
+ "stateError": "Ошибка",
40
+ "stateErrorDesc": "Почему этот эмулированный Roku не работает; пусто, пока он работает, Unknown, пока адаптер выключен или запускается.",
41
+ "devicesTotal": "Эмулированные Roku",
42
+ "devicesTotalDesc": "Сколько эмулированных Roku настроено.",
43
+ "devicesOnline": "Эмулированные Roku в сети",
44
+ "devicesOnlineDesc": "Сколько эмулированных Roku сейчас слушают.",
45
+ "devicesAllOnline": "Все эмулированные Roku в сети",
46
+ "devicesAllOnlineDesc": "Истина, пока слушает каждый настроенный эмулированный Roku; ложь, пока ни один не настроен."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "Назва",
8
8
  "devicePort": "Порт ECP",
9
9
  "portLabel": "Порт",
10
- "devicePortHint": "Порт ECP, на якому відповідає цей Roku. Кожному емульованому Roku потрібен власний порт. Harmony і Sofabaton беруть порт із виявлення; Home Assistant і Homey завжди використовують 8060 — призначте 8060 тому Roku, яким вони мають керувати.",
10
+ "devicePortHint": "Порт ECP, на якому відповідає цей Roku. Кожному емульованому Roku потрібен власний порт. Harmony і Sofabaton беруть порт із виявлення.",
11
11
  "deviceTypeLabel": "Тип",
12
12
  "deviceTypePlayer": "Програвач (приставка)",
13
13
  "deviceTypeTv": "ТБ (з гучністю, живленням, каналом, входом)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "Інформація про адаптер",
29
29
  "connectionStatus": "Стан з'єднання",
30
- "connectionStatusDesc": "Істина лише поки кожен налаштований емульований Roku справді слухає.",
30
+ "connectionStatusDesc": "Істина лише поки все працює: кожен налаштований емульований Roku слухає, виявлення відповідає і вибрана адреса існує.",
31
31
  "stateLastCommand": "Остання команда",
32
32
  "stateLastCommandDesc": "Найновіша команда, яку отримав цей емульований Roku, у вигляді тексту.",
33
- "stateLastCommandType": "Тип останньої команди",
34
- "stateLastCommandTypeDesc": "Якого роду була команда: натискання кнопки, утримання чи відпускання, запуск або встановлення застосунку, введення тексту чи пошук.",
35
- "commandType_none": "Команд ще не було",
36
- "commandType_keypress": "Натискання клавіші",
37
- "commandType_keydown": "Клавіша утримується",
38
- "commandType_keyup": "Клавішу відпущено",
39
- "commandType_launch": "Запуск застосунку",
40
- "commandType_install": "Встановлення застосунку",
41
- "commandType_input": "Введення тексту",
42
- "commandType_search": "Пошук",
43
33
  "channelKeys": "Кнопки пульта",
44
- "channelKeysDesc": "По одному стану на кожну кнопку, яку пропонує цей пристрій; натискання ненадовго переводить його в істину."
34
+ "channelKeysDesc": "По одному стану на кожну кнопку, яку пропонує цей пристрій; натискання ненадовго переводить його в істину.",
35
+ "channelDeviceInfo": "Стан",
36
+ "channelDeviceInfoDesc": "Чи працює цей емульований Roku і, якщо ні, чому.",
37
+ "stateOnline": "У мережі",
38
+ "stateOnlineDesc": "Істина, поки цей емульований Roku слухає свій порт ECP.",
39
+ "stateError": "Помилка",
40
+ "stateErrorDesc": "Чому цей емульований Roku не працює; порожньо, поки він працює, Unknown, поки адаптер вимкнений або запускається.",
41
+ "devicesTotal": "Емульовані Roku",
42
+ "devicesTotalDesc": "Скільки емульованих Roku налаштовано.",
43
+ "devicesOnline": "Емульовані Roku у мережі",
44
+ "devicesOnlineDesc": "Скільки емульованих Roku зараз слухають.",
45
+ "devicesAllOnline": "Усі емульовані Roku у мережі",
46
+ "devicesAllOnlineDesc": "Істина, поки слухає кожен налаштований емульований Roku; хибність, поки жоден не налаштований."
45
47
  }
@@ -7,7 +7,7 @@
7
7
  "deviceName": "名称",
8
8
  "devicePort": "ECP 端口",
9
9
  "portLabel": "端口",
10
- "devicePortHint": "此 Roku 响应的 ECP 端口。每个模拟 Roku 都需要自己的端口。Harmony 和 Sofabaton 从发现信息中读取端口;Home Assistant 和 Homey 始终使用 8060——请把 8060 分配给它们要控制的 Roku。",
10
+ "devicePortHint": "此 Roku 响应的 ECP 端口。每个模拟 Roku 都需要自己的端口。Harmony 和 Sofabaton 从发现信息中读取端口。",
11
11
  "deviceTypeLabel": "类型",
12
12
  "deviceTypePlayer": "播放器(流媒体盒子)",
13
13
  "deviceTypeTv": "电视(带音量、电源、频道、输入)",
@@ -27,19 +27,21 @@
27
27
  "donatePaypal": "PayPal",
28
28
  "channelInfo": "适配器信息",
29
29
  "connectionStatus": "连接状态",
30
- "connectionStatusDesc": "仅当每个已配置的模拟 Roku 都在监听时才为真。",
30
+ "connectionStatusDesc": "仅当一切正常运行时才为真:每个已配置的模拟 Roku 都在监听、发现服务有应答且所选地址存在。",
31
31
  "stateLastCommand": "最后一条命令",
32
32
  "stateLastCommandDesc": "该模拟 Roku 最近收到的命令,以纯文本表示。",
33
- "stateLastCommandType": "最后一条命令的类型",
34
- "stateLastCommandTypeDesc": "命令的种类:按键、按住或松开按键、启动或安装应用、输入文本或搜索。",
35
- "commandType_none": "尚无命令",
36
- "commandType_keypress": "按键",
37
- "commandType_keydown": "按住按键",
38
- "commandType_keyup": "松开按键",
39
- "commandType_launch": "启动应用",
40
- "commandType_install": "安装应用",
41
- "commandType_input": "文本输入",
42
- "commandType_search": "搜索",
43
33
  "channelKeys": "遥控器按键",
44
- "channelKeysDesc": "该设备提供的每个遥控器按键各有一个状态;按下时会短暂置为真。"
34
+ "channelKeysDesc": "该设备提供的每个遥控器按键各有一个状态;按下时会短暂置为真。",
35
+ "channelDeviceInfo": "状态",
36
+ "channelDeviceInfoDesc": "此模拟 Roku 是否在运行,如未运行则说明原因。",
37
+ "stateOnline": "在线",
38
+ "stateOnlineDesc": "此模拟 Roku 在其 ECP 端口上监听时为真。",
39
+ "stateError": "错误",
40
+ "stateErrorDesc": "此模拟 Roku 未运行的原因;运行时为空,适配器关闭或启动时为 Unknown。",
41
+ "devicesTotal": "模拟 Roku 数量",
42
+ "devicesTotalDesc": "已配置的模拟 Roku 数量。",
43
+ "devicesOnline": "在线的模拟 Roku",
44
+ "devicesOnlineDesc": "当前正在监听的模拟 Roku 数量。",
45
+ "devicesAllOnline": "所有模拟 Roku 均在线",
46
+ "devicesAllOnlineDesc": "每个已配置的模拟 Roku 都在监听时为真;未配置任何 Roku 时为假。"
45
47
  }
@@ -46,7 +46,7 @@ class CommandHandler {
46
46
  gates = /* @__PURE__ */ new Map();
47
47
  rateWarnings = new import_log_throttle.LogThrottle(RATE_WARN_INTERVAL_MS);
48
48
  /**
49
- * Apply a received ECP command to the device's states: record it in `command` / `commandType`, and pulse or hold
49
+ * Apply a received ECP command to the device's states: record it in `command`, and pulse or hold
50
50
  * the standard key if the device carries it. The server logs only what this accepted, so the rate gate covers the
51
51
  * log as well as the states database.
52
52
  *
@@ -63,7 +63,6 @@ class CommandHandler {
63
63
  return false;
64
64
  }
65
65
  this.host.writeState(`${device.id}.command`, write.command);
66
- this.host.writeState(`${device.id}.commandType`, write.commandType);
67
66
  if (write.pulseKey && device.keys.has(write.pulseKey)) {
68
67
  this.pulse(`${device.id}.keys.${write.pulseKey}`);
69
68
  } else if (write.holdKey && device.keys.has(write.holdKey.key)) {