iobroker.al-ko 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -53,13 +53,19 @@ Do **not** contact AL-KO customer service regarding this project.
53
53
 
54
54
  ## Changelog
55
55
 
56
- ### 0.3.4 (2026-03-20)
56
+ ### 0.3.6
57
+ - Fixed invalid state roles (`value.number` removed, correct usage of `value` and `level`)
58
+ - Fixed whitelist handling for writable states
59
+ - Improved object structure according to review feedback
60
+
61
+ ### 0.3.5 (2026-03-26)
62
+
63
+ - Enable npm trusted publishing
64
+ - Fix GitHub Actions workflow warnings
57
65
 
58
- - Fix responsive layout in jsonConfig (xs/sm/md/lg/xl)
59
- - Remove example i18n entries (option1/option2)
60
66
 
61
67
  ➡ Full changelog here:
62
- [CHANGELOG.md](./CHANGELOG.md)
68
+ [CHANGELOG_OLD.md](./CHANGELOG_OLD.md)
63
69
 
64
70
  ---
65
71
 
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Adaptereinstellungen für al-ko"
2
+ "clientId": "Client-ID",
3
+ "clientSecret": "Client-Secret",
4
+ "password": "Passwort",
5
+ "username": "Benutzername",
6
+ "username_placeholder": "Geben Sie den Benutzernamen Ihres AL-KO-Kontos ein",
7
+ "wsDebug": "Aktivieren Sie die WebSocket-Nachrichtenprotokollierung"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Adapter settings for al-ko"
3
- }
2
+ "username": "Username",
3
+ "username_placeholder": "Enter your AL-KO account username",
4
+ "password": "Password",
5
+ "clientId": "Client ID",
6
+ "clientSecret": "Client Secret",
7
+ "wsDebug": "Enable WebSocket message logging"
8
+ }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Ajustes del adaptador para al-ko"
2
+ "clientId": "ID de cliente",
3
+ "clientSecret": "Secreto del cliente",
4
+ "password": "Contraseña",
5
+ "username": "Nombre de usuario",
6
+ "username_placeholder": "Ingrese el nombre de usuario de su cuenta AL-KO",
7
+ "wsDebug": "Habilitar el registro de mensajes de WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Paramètres d'adaptateur pour al-ko"
2
+ "clientId": "Identifiant client",
3
+ "clientSecret": "Secret client",
4
+ "password": "Mot de passe",
5
+ "username": "Nom d'utilisateur",
6
+ "username_placeholder": "Entrez le nom d'utilisateur de votre compte AL-KO",
7
+ "wsDebug": "Activer la journalisation des messages WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Impostazioni dell'adattatore per al-ko"
2
+ "clientId": "ID cliente",
3
+ "clientSecret": "Segreto del cliente",
4
+ "password": "Password",
5
+ "username": "Nome utente",
6
+ "username_placeholder": "Inserisci il nome utente del tuo account AL-KO",
7
+ "wsDebug": "Abilita la registrazione dei messaggi WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Adapterinstellingen voor al-ko"
2
+ "clientId": "Klant-ID",
3
+ "clientSecret": "Klantgeheim",
4
+ "password": "Wachtwoord",
5
+ "username": "Gebruikersnaam",
6
+ "username_placeholder": "Vul de gebruikersnaam van uw AL-KO-account in",
7
+ "wsDebug": "Schakel WebSocket-berichtregistratie in"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Ustawienia adaptera dla al-ko"
2
+ "clientId": "Identyfikator klienta",
3
+ "clientSecret": "Sekret Klienta",
4
+ "password": "Hasło",
5
+ "username": "Nazwa użytkownika",
6
+ "username_placeholder": "Wprowadź nazwę użytkownika swojego konta AL-KO",
7
+ "wsDebug": "Włącz rejestrowanie komunikatów WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Configurações do adaptador para al-ko"
2
+ "clientId": "ID do cliente",
3
+ "clientSecret": "Segredo do cliente",
4
+ "password": "Senha",
5
+ "username": "Nome de usuário",
6
+ "username_placeholder": "Digite o nome de usuário da sua conta AL-KO",
7
+ "wsDebug": "Habilitar registro de mensagens WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Настройки адаптера для al-ko"
2
+ "clientId": "Идентификатор клиента",
3
+ "clientSecret": "Секрет клиента",
4
+ "password": "Пароль",
5
+ "username": "Имя пользователя",
6
+ "username_placeholder": "Введите имя пользователя вашей учетной записи AL-KO",
7
+ "wsDebug": "Включить ведение журнала сообщений WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "Налаштування адаптера для al-ko"
2
+ "clientId": "ID клієнта",
3
+ "clientSecret": "Секрет клієнта",
4
+ "password": "Пароль",
5
+ "username": "Ім'я користувача",
6
+ "username_placeholder": "Введіть ім’я користувача облікового запису AL-KO",
7
+ "wsDebug": "Увімкнути журнал повідомлень WebSocket"
3
8
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "al-ko adapter settings": "al-ko的适配器设置"
2
+ "clientId": "客户ID",
3
+ "clientSecret": "客户秘密",
4
+ "password": "密码",
5
+ "username": "用户名",
6
+ "username_placeholder": "输入您的 AL-KO 帐户用户名",
7
+ "wsDebug": "启用 WebSocket 消息日志记录"
3
8
  }
@@ -1,23 +1,11 @@
1
1
  {
2
2
  "type": "panel",
3
- "label": {
4
- "en": "General",
5
- "de": "Allgemein",
6
- "ru": "Общие",
7
- "pt": "Geral",
8
- "nl": "Algemeen",
9
- "fr": "Général",
10
- "it": "Generale",
11
- "es": "General",
12
- "pl": "Ogólne",
13
- "uk": "Загальні",
14
- "zh-cn": "常规"
15
- },
3
+ "i18n": true,
16
4
  "items": {
17
5
  "username": {
18
6
  "type": "text",
19
- "label": { "en": "Username", "de": "Benutzername" },
20
- "placeholder": "Enter your AL-KO account username",
7
+ "label": "username",
8
+ "placeholder": "username_placeholder",
21
9
  "xs": 12,
22
10
  "sm": 6,
23
11
  "md": 6,
@@ -26,7 +14,7 @@
26
14
  },
27
15
  "password": {
28
16
  "type": "password",
29
- "label": { "en": "Password", "de": "Passwort" },
17
+ "label": "password",
30
18
  "xs": 12,
31
19
  "sm": 6,
32
20
  "md": 6,
@@ -35,7 +23,7 @@
35
23
  },
36
24
  "clientId": {
37
25
  "type": "text",
38
- "label": { "en": "Client ID", "de": "Client-ID" },
26
+ "label": "clientId",
39
27
  "xs": 12,
40
28
  "sm": 6,
41
29
  "md": 6,
@@ -44,7 +32,7 @@
44
32
  },
45
33
  "clientSecret": {
46
34
  "type": "password",
47
- "label": { "en": "Client Secret", "de": "Client-Secret" },
35
+ "label": "clientSecret",
48
36
  "xs": 12,
49
37
  "sm": 6,
50
38
  "md": 6,
@@ -53,10 +41,7 @@
53
41
  },
54
42
  "wsDebug": {
55
43
  "type": "checkbox",
56
- "label": {
57
- "en": "Enable WebSocket message logging",
58
- "de": "WebSocket-Nachrichten protokollieren"
59
- },
44
+ "label": "wsDebug",
60
45
  "default": false,
61
46
  "xs": 12,
62
47
  "sm": 6,
package/docs/de/README.md CHANGED
@@ -48,6 +48,17 @@ AL-KO bietet **keinen offiziellen Support** hierfür.
48
48
 
49
49
  ## Änderungen (Auszug)
50
50
 
51
+ ### 0.3.6 (2026-04-26)
52
+
53
+ - Ungültige State-Rollen korrigiert (`value.number` entfernt, korrekte Verwendung von `value` und `level`)
54
+ - Whitelist für schreibbare States korrigiert
55
+ - Objektstruktur gemäß Review-Anforderungen verbessert
56
+
57
+ ### 0.3.5 (2026-03-26)
58
+
59
+ - npm Trusted Publishing aktiviert
60
+ - GitHub Actions Workflow-Warnungen behoben
61
+
51
62
  ### 0.3.4 (2026-03-20)
52
63
 
53
64
  - Responsives Layout in der jsonConfig korrigiert (xs/sm/md/lg/xl)
@@ -69,7 +80,7 @@ AL-KO bietet **keinen offiziellen Support** hierfür.
69
80
  - Logging für WebSocket-Close-Code und Reason ergänzt
70
81
 
71
82
  Alle Änderungen siehe vollständigen Changelog:
72
- ➡ [CHANGELOG.md](../../CHANGELOG.md)
83
+ ➡ [CHANGELOG_OLD.md](../../CHANGELOG_OLD.md)
73
84
 
74
85
  Wesentliche Neuerungen:
75
86
 
package/docs/en/README.md CHANGED
@@ -48,13 +48,18 @@ It is a **community-developed project**.
48
48
 
49
49
  ## Changes (Summary)
50
50
 
51
- ### 0.3.4 (2026-03-20)
51
+ ### 0.3.6 (2026-04-26)
52
+ - Fixed invalid state roles (`value.number` removed, correct usage of `value` and `level`)
53
+ - Fixed whitelist handling for writable states
54
+ - Improved object structure according to review feedback
52
55
 
53
- - Fix responsive layout in jsonConfig (xs/sm/md/lg/xl)
54
- - Remove example i18n entries (option1/option2)
56
+ ### 0.3.5 (2026-03-26)
57
+
58
+ - Enable npm trusted publishing
59
+ - Fix GitHub Actions workflow warnings
55
60
 
56
61
  See full changelog here:
57
- ➡ [CHANGELOG.md](../../CHANGELOG.md)
62
+ ➡ [CHANGELOG_OLD.md](../../CHANGELOG_OLD.md)
58
63
 
59
64
  Key updates:
60
65
 
package/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "al-ko",
4
- "version": "0.3.4",
4
+ "version": "0.3.6",
5
5
  "tier": 3,
6
6
  "titleLang": {
7
7
  "en": "AL-KO",
@@ -29,8 +29,10 @@
29
29
  "uk": "Адаптер для газонокосарок AL-KO Robolinho",
30
30
  "zh-cn": "AL-KO Robolinho 割草机适配器"
31
31
  },
32
- "authors": ["Hubert Zechner <hubertiob@posteo.at>"],
33
- "licenseInformation": {
32
+ "authors": [
33
+ "Hubert Zechner <hubertiob@posteo.at>"
34
+ ],
35
+ "licenseInformation": {
34
36
  "type": "free",
35
37
  "license": "MIT",
36
38
  "link": "https://opensource.org/licenses/MIT"
@@ -40,28 +42,66 @@
40
42
  "de": "docs/de/README.md"
41
43
  },
42
44
  "news": {
45
+ "0.3.6": {
46
+ "en": "Fix state roles (remove invalid value.number, align value/level), correct whitelist handling for writable states, and finalize object structure according to review feedback",
47
+ "de": "State-Rollen korrigiert (value.number entfernt, value/level angepasst), Whitelist für schreibbare States korrigiert und Objektstruktur gemäß Review-Anforderungen finalisiert",
48
+ "ru": "Исправлены роли состояний (удалён value.number, выровнены value/level), исправлена whitelist для записываемых состояний и завершена структура объектов согласно требованиям ревью",
49
+ "pt": "Corrigidas as roles dos estados (removido value.number, ajustado value/level), corrigida a whitelist para estados graváveis e finalizada a estrutura de objetos conforme revisão",
50
+ "nl": "State-rollen gecorrigeerd (value.number verwijderd, value/level aangepast), whitelist voor schrijfbare states gecorrigeerd en objectstructuur volgens review afgerond",
51
+ "fr": "Correction des rôles d’état (suppression de value.number, ajustement value/level), correction de la whitelist des états modifiables et finalisation de la structure d’objets selon la revue",
52
+ "it": "Corretti i ruoli degli stati (rimosso value.number, allineati value/level), corretta la whitelist per stati scrivibili e finalizzata la struttura degli oggetti secondo la revisione",
53
+ "es": "Corregidos los roles de estado (eliminado value.number, ajustado value/level), corregida la whitelist para estados escribibles y finalizada la estructura de objetos según la revisión",
54
+ "pl": "Poprawiono role stanów (usunięto value.number, dostosowano value/level), poprawiono whitelistę dla zapisywalnych stanów i zakończono strukturę obiektów zgodnie z uwagami",
55
+ "uk": "Виправлено ролі станів (видалено value.number, узгоджено value/level), виправлено whitelist для записуваних станів та завершено структуру об'єктів відповідно до зауважень",
56
+ "zh-cn": "修复状态角色(移除 value.number,调整为 value/level),修复可写状态白名单,并根据审查意见完善对象结构"
57
+ },
58
+ "0.3.5": {
59
+ "en": "Enable npm trusted publishing and fix workflow warnings",
60
+ "de": "npm Trusted Publishing aktiviert und Workflow-Warnungen behoben",
61
+ "ru": "Включена публикация npm через Trusted Publishing и исправлены предупреждения workflow",
62
+ "pt": "Ativado o Trusted Publishing do npm e corrigidos avisos do workflow",
63
+ "nl": "npm Trusted Publishing ingeschakeld en workflow-waarschuwingen opgelost",
64
+ "fr": "Activation du Trusted Publishing npm et correction des avertissements du workflow",
65
+ "it": "Abilitato il Trusted Publishing npm e corretti gli avvisi del workflow",
66
+ "es": "Habilitado Trusted Publishing de npm y corregidas advertencias del workflow",
67
+ "pl": "Włączono Trusted Publishing npm i poprawiono ostrzeżenia workflow",
68
+ "uk": "Увімкнено Trusted Publishing npm та виправлено попередження workflow",
69
+ "zh-cn": "启用 npm Trusted Publishing 并修复工作流警告"
70
+ },
43
71
  "0.3.4": {
44
72
  "en": "Fix jsonConfig responsive layout and remove example i18n entries",
45
- "de": "jsonConfig responsive Layout korrigiert und Beispiel-i18n-Einträge entfernt"
73
+ "de": "jsonConfig responsive Layout korrigiert und Beispiel-i18n-Einträge entfernt",
74
+ "ru": "Исправлено адаптивное отображение jsonConfig и удалены примерные записи i18n",
75
+ "pt": "Corrigido o layout responsivo do jsonConfig e removidas entradas de exemplo i18n",
76
+ "nl": "Responsieve layout van jsonConfig gecorrigeerd en voorbeeld i18n-items verwijderd",
77
+ "fr": "Correction de la mise en page responsive de jsonConfig et suppression des entrées i18n d'exemple",
78
+ "it": "Corretto il layout responsive di jsonConfig e rimosse le voci i18n di esempio",
79
+ "es": "Corregido el diseño responsivo de jsonConfig y eliminadas las entradas i18n de ejemplo",
80
+ "pl": "Poprawiono responsywny układ jsonConfig i usunięto przykładowe wpisy i18n",
81
+ "uk": "Виправлено адаптивний макет jsonConfig та видалено приклади i18n",
82
+ "zh-cn": "修复了 jsonConfig 的响应式布局并删除了示例 i18n 条目"
46
83
  },
47
84
  "0.3.3": {
48
85
  "en": "Improved WebSocket handling and message processing, updated repository workflows, and updated development dependencies.",
49
- "de": "WebSocket-Handling und Nachrichtenverarbeitung verbessert, Repository-Workflows aktualisiert und Entwicklungsabhängigkeiten aktualisiert."
50
- },
51
- "0.3.2": {
52
- "en": "Improved WebSocket reconnect handling, prevented reconnect loops on intentional closes, and improved API error logging for push requests.",
53
- "de": "WebSocket-Reconnect-Verhalten verbessert, Reconnect-Schleifen bei absichtlich geschlossenen Verbindungen verhindert und API-Fehlerlogging für Push-Requests verbessert."
54
- },
55
- "0.3.1": {
56
- "en": "Documentation improvements, corrected license information and updated development dependencies. No functional changes.",
57
- "de": "Dokumentation verbessert, Lizenzangaben korrigiert und Entwicklungsabhängigkeiten aktualisiert. Keine funktionalen Änderungen."
58
- },
59
- "0.3.0": {
60
- "en": "Major maintenance release. Updated ESLint 9, Prettier 3, TypeScript tooling and development dependencies. Improved adapter structure and CI pipeline. No functional changes.",
61
- "de": "Größeres Wartungsrelease. Aktualisierung von ESLint 9, Prettier 3, TypeScript-Tooling und Entwicklungsabhängigkeiten. Verbesserte Adapterstruktur und CI-Pipeline. Keine funktionalen Änderungen."
86
+ "de": "WebSocket-Handling und Nachrichtenverarbeitung verbessert, Repository-Workflows aktualisiert und Entwicklungsabhängigkeiten aktualisiert.",
87
+ "ru": "Улучшена обработка WebSocket и сообщений, обновлены workflow репозитория и зависимости разработки",
88
+ "pt": "Melhorado o tratamento de WebSocket e processamento de mensagens, workflows do repositório atualizados e dependências de desenvolvimento atualizadas",
89
+ "nl": "WebSocket-afhandeling en berichtverwerking verbeterd, repository-workflows en ontwikkelingsafhankelijkheden bijgewerkt",
90
+ "fr": "Amélioration de la gestion WebSocket et du traitement des messages, mise à jour des workflows du dépôt et des dépendances de développement",
91
+ "it": "Migliorata la gestione WebSocket e l'elaborazione dei messaggi, aggiornati i workflow del repository e le dipendenze di sviluppo",
92
+ "es": "Mejorado el manejo de WebSocket y el procesamiento de mensajes, actualizados los workflows del repositorio y las dependencias de desarrollo",
93
+ "pl": "Ulepszono obsługę WebSocket i przetwarzanie wiadomości, zaktualizowano workflow repozytorium i zależności deweloperskie",
94
+ "uk": "Покращено обробку WebSocket і повідомлень, оновлено workflow репозиторію та залежності розробки",
95
+ "zh-cn": "改进了 WebSocket 处理和消息处理,更新了仓库工作流和开发依赖"
62
96
  }
63
97
  },
64
- "keywords": ["al-ko", "Robolinho", "mower", "garden", "smart-garden"],
98
+ "keywords": [
99
+ "al-ko",
100
+ "Robolinho",
101
+ "mower",
102
+ "garden",
103
+ "smart-garden"
104
+ ],
65
105
  "extIcon": "https://raw.githubusercontent.com/zechnerhubert/ioBroker.al-ko/master/admin/al-ko-128.png",
66
106
  "adminUI": {
67
107
  "config": "json"
@@ -92,8 +132,14 @@
92
132
  "clientSecret": "",
93
133
  "wsDebug": false
94
134
  },
95
- "protectedNative": ["password", "clientSecret"],
96
- "encryptedNative": ["password", "clientSecret"],
135
+ "protectedNative": [
136
+ "password",
137
+ "clientSecret"
138
+ ],
139
+ "encryptedNative": [
140
+ "password",
141
+ "clientSecret"
142
+ ],
97
143
  "objects": [],
98
144
  "instanceObjects": []
99
145
  }
package/main.js CHANGED
@@ -46,6 +46,142 @@ class AlKoAdapter extends utils.Adapter {
46
46
  this.on("stateChange", this.onStateChange.bind(this));
47
47
  }
48
48
 
49
+ getType(value) {
50
+ if (value === null || value === undefined) {
51
+ return "mixed";
52
+ }
53
+ if (typeof value === "number") {
54
+ return "number";
55
+ }
56
+ if (typeof value === "boolean") {
57
+ return "boolean";
58
+ }
59
+ if (typeof value === "string") {
60
+ return "string";
61
+ }
62
+ return "mixed";
63
+ }
64
+
65
+ getRole(key, value, write) {
66
+ const k = key.toLowerCase();
67
+
68
+ // BOOLEAN
69
+ if (typeof value === "boolean") {
70
+ if (write) {
71
+ return "switch";
72
+ }
73
+ if (k.includes("connected")) {
74
+ return "indicator.reachable";
75
+ }
76
+ if (k.includes("rain")) {
77
+ return "indicator";
78
+ }
79
+ if (k.includes("error")) {
80
+ return "indicator";
81
+ }
82
+ return "indicator";
83
+ }
84
+
85
+ // BATTERY
86
+ if (k.includes("battery")) {
87
+ if (k.includes("level")) {
88
+ return "level.battery";
89
+ }
90
+ return "value.number";
91
+ }
92
+
93
+ // TEMPERATURE
94
+ if (k.includes("temp")) {
95
+ return "value.temperature";
96
+ }
97
+
98
+ // VOLTAGE
99
+ if (k.includes("voltage")) {
100
+ return "value.voltage";
101
+ }
102
+
103
+ // CURRENT
104
+ if (k.includes("current")) {
105
+ return "value.current";
106
+ }
107
+
108
+ // TIME / DURATION
109
+ if (k.includes("duration")) {
110
+ return "value.duration";
111
+ }
112
+ if (k.includes("hour") || k.includes("minute")) {
113
+ return "level";
114
+ }
115
+
116
+ // SIGNAL
117
+ if (k.includes("rssi") || k.includes("signal")) {
118
+ return "value.number";
119
+ }
120
+
121
+ // GENERIC NUMBER
122
+ if (typeof value === "number") {
123
+ return write ? "level" : "value";
124
+ }
125
+
126
+ // STRING
127
+ if (typeof value === "string") {
128
+ return "text";
129
+ }
130
+
131
+ return "state";
132
+ }
133
+
134
+ getUnit(key, value, relPath = "") {
135
+ //KEINE Unit für boolean / indicator
136
+ if (typeof value === "boolean") {
137
+ return undefined;
138
+ }
139
+ const path = relPath.toLowerCase();
140
+
141
+ if (path.endsWith("batterylevel")) {
142
+ return "%";
143
+ }
144
+
145
+ return undefined;
146
+ }
147
+
148
+ async ensureObjectTree(id) {
149
+ const parts = id.split(".");
150
+
151
+ // Device sicherstellen
152
+ const deviceId = `${parts[0]}.${parts[1]}.${parts[2]}`;
153
+
154
+ const deviceObj = await this.getObjectAsync(deviceId);
155
+ if (!deviceObj) {
156
+ await this.setObjectAsync(deviceId, {
157
+ type: "device",
158
+ common: {
159
+ name: parts[2],
160
+ role: "device",
161
+ },
162
+ native: {},
163
+ });
164
+ }
165
+
166
+ let path = deviceId;
167
+
168
+ for (let i = 3; i < parts.length - 1; i++) {
169
+ path += `.${parts[i]}`;
170
+
171
+ const obj = await this.getObjectAsync(path);
172
+ if (!obj) {
173
+ await this.setObjectAsync(path, {
174
+ type: "channel",
175
+ common: {
176
+ name: parts[i],
177
+ role: "channel",
178
+ },
179
+ native: {},
180
+ });
181
+ }
182
+ }
183
+ }
184
+
49
185
  // ---------------- ID Sanitizer ----------------
50
186
  sanitizeId(id) {
51
187
  return id
@@ -213,7 +349,7 @@ class AlKoAdapter extends utils.Adapter {
213
349
  stateData.state.reported || stateData.state;
214
350
 
215
351
  await this.createStatesRecursive(
216
- `${this.namespace}.${deviceId}.state`,
352
+ `${this.namespace}.${deviceId}`,
217
353
  this.deviceStates[deviceId],
218
354
  "",
219
355
  );
@@ -444,7 +580,7 @@ class AlKoAdapter extends utils.Adapter {
444
580
  );
445
581
 
446
582
  await this.createStatesRecursive(
447
- `${this.namespace}.${deviceId}.state`,
583
+ `${this.namespace}.${deviceId}`,
448
584
  this.deviceStates[deviceId],
449
585
  "",
450
586
  );
@@ -586,48 +722,48 @@ class AlKoAdapter extends utils.Adapter {
586
722
  return whitelist.includes(relPath);
587
723
  }
588
724
  // ---------------- Role Mapping ----------------
589
- mapRole(relPath, type) {
590
- if (!relPath) {
591
- return "state";
592
- }
593
-
594
- const lower = relPath.toLowerCase();
595
-
596
- if (lower.endsWith("starthour") || lower.endsWith("hour")) {
597
- return "value.hour";
598
- }
599
- if (lower.endsWith("startminute") || lower.endsWith("minute")) {
600
- return "value.minute";
601
- }
602
-
603
- if (type === "boolean") {
604
- if (
605
- lower.includes("mode") ||
606
- lower.includes("enabled") ||
607
- lower.includes("manualmowing")
608
- ) {
609
- return "switch";
610
- }
611
- return "indicator";
612
- }
613
-
614
- if (lower.includes("operationstate") || lower.includes("state")) {
615
- return "indicator.status";
616
- }
617
-
618
- if (type === "number") {
619
- if (lower.includes("battery")) {
620
- return "value.battery";
621
- }
622
- return "value";
623
- }
624
-
625
- if (type === "string") {
626
- return "text";
627
- }
628
-
629
- return "state";
630
- }
725
+ // mapRole(relPath, type) {
726
+ // if (!relPath) {
727
+ // return "state";
728
+ // }
729
+ //
730
+ // const lower = relPath.toLowerCase();
731
+ //
732
+ // if (lower.endsWith("starthour") || lower.endsWith("hour")) {
733
+ // return "value.hour";
734
+ // }
735
+ // if (lower.endsWith("startminute") || lower.endsWith("minute")) {
736
+ // return "value.minute";
737
+ // }
738
+ //
739
+ // if (type === "boolean") {
740
+ // if (
741
+ // lower.includes("mode") ||
742
+ // lower.includes("enabled") ||
743
+ // lower.includes("manualmowing")
744
+ // ) {
745
+ // return "switch";
746
+ // }
747
+ // return "indicator";
748
+ // }
749
+ //
750
+ // if (lower.includes("operationstate") || lower.includes("state")) {
751
+ // return "indicator.status";
752
+ // }
753
+ //
754
+ // if (type === "number") {
755
+ // if (lower.includes("battery")) {
756
+ // return "value.battery";
757
+ // }
758
+ // return "value";
759
+ // }
760
+ //
761
+ // if (type === "string") {
762
+ // return "text";
763
+ // }
764
+ //
765
+ // return "state";
766
+ //}
631
767
 
632
768
  // ---------------- Safe setState wrapper ----------------
633
769
  async setStateIfChanged(
@@ -637,23 +773,38 @@ class AlKoAdapter extends utils.Adapter {
637
773
  write = false,
638
774
  relPath = null,
639
775
  ) {
640
- let type;
641
- if (typeof value === "boolean") {
642
- type = "boolean";
643
- } else if (typeof value === "number") {
644
- type = "number";
645
- } else {
646
- type = "string";
647
- }
648
-
649
776
  id = this.sanitizeId(id);
650
777
 
778
+ const type = this.getType(value);
779
+ const key = relPath?.split(".").pop() || id.split(".").pop();
780
+ const role = this.getRole(key, value, write);
781
+ const unit = this.getUnit(key, value, relPath);
782
+
783
+ await this.ensureObjectTree(id);
784
+
651
785
  await this.setObjectNotExistsAsync(id, {
652
786
  type: "state",
653
- common: { type, role: this.mapRole(relPath, type), read: true, write },
787
+ common: {
788
+ name: key,
789
+ type,
790
+ role,
791
+ unit,
792
+ read: true,
793
+ write,
794
+ },
654
795
  native: {},
655
796
  });
656
797
 
798
+ await this.extendObjectAsync(id, {
799
+ common: {
800
+ role,
801
+ type,
802
+ unit,
803
+ read: true,
804
+ write,
805
+ },
806
+ });
807
+
657
808
  const prev = this.lastStateValues[id];
658
809
  if (prev !== value) {
659
810
  this.lastStateValues[id] = value;
@@ -673,6 +824,12 @@ class AlKoAdapter extends utils.Adapter {
673
824
  if (!state || this._stopRequested) {
674
825
  return;
675
826
  }
827
+
828
+ // FIX: ack handling
829
+ if (state.ack) {
830
+ return;
831
+ }
832
+
676
833
  if (this.adapterSetStates.has(id)) {
677
834
  return;
678
835
  }
@@ -693,7 +850,7 @@ class AlKoAdapter extends utils.Adapter {
693
850
 
694
851
  const parts = id.split(".");
695
852
  const deviceId = parts[2];
696
- const relPathArr = parts.slice(4);
853
+ const relPathArr = parts.slice(3);
697
854
 
698
855
  this.pendingPushes.add(id);
699
856
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.al-ko",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Adapter for communication with AL-KO smart garden devices (Robolinho, mowing windows, operationState, etc.)",
5
5
  "author": {
6
6
  "name": "Hubert Zechner",
@@ -64,11 +64,9 @@
64
64
  "@iobroker/eslint-config": "^2.2.0",
65
65
  "@iobroker/testing": "^5.2.2",
66
66
  "@tsconfig/node20": "^20.1.8",
67
- "@types/node": "^25.5.0",
68
- "@typescript-eslint/eslint-plugin": "^8.57.1",
69
- "@typescript-eslint/parser": "^8.57.0",
70
- "prettier": "^3.8.1",
71
- "proxyquire": "^2.1.3"
67
+ "@types/node": "^25.6.0",
68
+ "@typescript-eslint/eslint-plugin": "^8.58.2",
69
+ "@typescript-eslint/parser": "^8.58.2"
72
70
  },
73
71
  "readmeFilename": "README.md"
74
72
  }
package/whitelist.json CHANGED
@@ -1,4 +1,5 @@
1
1
  [
2
+ "entryPoints.0",
2
3
  "entryPoints.1",
3
4
  "entryPoints.2",
4
5
  "entryPoints.3",
@@ -128,5 +129,6 @@
128
129
  "operationState",
129
130
  "rainDelay",
130
131
  "rainSensitivity",
131
- "rainSensor"
132
+ "rainSensor",
133
+ "resetBladesService"
132
134
  ]