iobroker.al-ko 0.2.2 → 0.2.4

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
@@ -54,7 +54,31 @@ Es handelt sich um ein Community-Projekt, und AL-KO bietet **keinen Support** da
54
54
 
55
55
  ## Changelog
56
56
 
57
- ## Changelog
57
+ ### 0.2.4 (2025-10-23)
58
+
59
+ **Deutsch:**
60
+ - Metadaten-Anpassungen für korrekte Anzeige im ioBroker Admin und auf npm
61
+ - Der Autor wird jetzt korrekt angezeigt, und das Adapter-Icon erscheint im Admin
62
+ - Keine funktionalen Änderungen am Code
63
+
64
+ **English:**
65
+ - Metadata adjustments for correct display in ioBroker Admin and npm
66
+ - Author information and adapter icon are now shown correctly
67
+ - No functional changes to the code
68
+
69
+ ### 0.2.3 (2025-10-22)
70
+
71
+ **Deutsch:**
72
+ - WebSocket-Stabilität deutlich verbessert:
73
+ - Heartbeat (Ping/Pong) alle **120 Sekunden** mit **30 Sekunden** Timeout
74
+ - Bei fehlendem Pong oder Fehlern wird die Verbindung **aktiv beendet**, damit ein sauberer **Reconnect** erfolgt
75
+ - Entfernt: „Silence-Watchdog“, damit es in längeren Ruhephasen (z. B. nachts) **keine unnötigen Reconnects** gibt
76
+
77
+ **English:**
78
+ - Improved WebSocket stability:
79
+ - Heartbeat (ping/pong) every **120 seconds** with **30 seconds** timeout
80
+ - If pong is missing or errors occur, the socket is **terminated** to trigger a clean **reconnect**
81
+ - Removed the **silence watchdog** to avoid unnecessary reconnects during long idle periods (e.g., at night)
58
82
 
59
83
 
60
84
  ### 0.2.2 (2025-10-20)
package/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "al-ko",
4
- "version": "0.2.2",
4
+ "version": "0.2.4",
5
5
  "tier": 3,
6
6
  "titleLang": {
7
7
  "en": "AL-KO",
@@ -33,6 +33,32 @@
33
33
  "Hubert Zechner <hubertiob@posteo.at>"
34
34
  ],
35
35
  "news": {
36
+ "0.2.4": {
37
+ "en": "Metadata adjustments for correct npm/Admin display (author, icon). No functional changes.",
38
+ "de": "Metadaten-Anpassungen für korrekte npm-/Admin-Anzeige (Autor, Icon). Keine funktionalen Änderungen.",
39
+ "ru": "Корректировка метаданных для правильного отображения npm/Admin (автор, значок). Без функциональных изменений.",
40
+ "pt": "Ajustes de metadados para exibição correta no npm/Admin (autor, ícone). Sem alterações funcionais.",
41
+ "nl": "Metadata-aanpassingen voor juiste npm/Admin-weergave (auteur, pictogram). Geen functionele wijzigingen.",
42
+ "fr": "Ajustements des métadonnées pour un affichage correct dans npm/Admin (auteur, icône). Aucune modification fonctionnelle.",
43
+ "it": "Regolazioni dei metadati per la corretta visualizzazione su npm/Admin (autore, icona). Nessuna modifica funzionale.",
44
+ "es": "Ajustes de metadatos para una visualización correcta en npm/Admin (autor, icono). Sin cambios funcionales.",
45
+ "pl": "Dostosowanie metadanych do prawidłowego wyświetlania w npm/Admin (autor, ikona). Bez zmian funkcjonalnych.",
46
+ "uk": "Коригування метаданих для правильного відображення в npm/Admin (автор, іконка). Без функціональних змін.",
47
+ "zh-cn": "为确保在 npm/Admin 中正确显示(作者、图标)调整了元数据。无功能更改。"
48
+ },
49
+ "0.2.3": {
50
+ "en": "Improved WebSocket stability: Added heartbeat (ping/pong) every 120 seconds with 30 seconds timeout. If no pong or an error occurs, the socket is closed and reconnected automatically. Removed the silence watchdog to avoid unnecessary reconnects during long idle phases (e.g., at night).",
51
+ "de": "WebSocket-Stabilität verbessert: Heartbeat (Ping/Pong) alle 120 Sekunden mit 30 Sekunden Timeout hinzugefügt. Bei fehlendem Pong oder Fehlern wird die Verbindung geschlossen und automatisch neu verbunden. Der Silence-Watchdog wurde entfernt, um unnötige Reconnects während längerer Ruhephasen (z. B. nachts) zu vermeiden.",
52
+ "ru": "Улучшена стабильность WebSocket: добавлен Heartbeat (ping/pong) каждые 120 секунд с тайм-аутом 30 секунд. При отсутствии pong или ошибках соединение закрывается и автоматически восстанавливается. Удалён watchdog тишины, чтобы избежать ненужных переподключений во время долгих периодов бездействия (например, ночью).",
53
+ "pt": "Melhorada a estabilidade do WebSocket: Adicionado heartbeat (ping/pong) a cada 120 segundos com tempo limite de 30 segundos. Se não houver pong ou ocorrer um erro, o socket é fechado e reconectado automaticamente. Removido o watchdog de silêncio para evitar reconexões desnecessárias durante longos períodos de inatividade (por exemplo, à noite).",
54
+ "nl": "Verbeterde WebSocket-stabiliteit: Heartbeat (ping/pong) toegevoegd elke 120 seconden met een timeout van 30 seconden. Als er geen pong of een fout optreedt, wordt de socket gesloten en automatisch opnieuw verbonden. De stilte-watchdog is verwijderd om onnodige reconnects tijdens langere inactieve periodes (bijv. 's nachts) te voorkomen.",
55
+ "fr": "Stabilité WebSocket améliorée : ajout d'un heartbeat (ping/pong) toutes les 120 secondes avec un délai d'attente de 30 secondes. En cas d'absence de pong ou d'erreur, la connexion est fermée et reconnectée automatiquement. Le watchdog de silence a été supprimé afin d'éviter des reconnexions inutiles lors de longues périodes d'inactivité (par exemple, la nuit).",
56
+ "it": "Migliorata la stabilità del WebSocket: aggiunto heartbeat (ping/pong) ogni 120 secondi con timeout di 30 secondi. Se manca il pong o si verifica un errore, la connessione viene chiusa e riconnessa automaticamente. Rimosso il watchdog del silenzio per evitare riconnessioni inutili durante lunghi periodi di inattività (ad esempio, di notte).",
57
+ "es": "Mejorada la estabilidad del WebSocket: se añadió un heartbeat (ping/pong) cada 120 segundos con un tiempo de espera de 30 segundos. Si no hay pong o ocurre un error, el socket se cierra y se reconecta automáticamente. Se eliminó el watchdog de silencio para evitar reconexiones innecesarias durante largos períodos de inactividad (por ejemplo, por la noche).",
58
+ "pl": "Poprawiona stabilność WebSocket: dodano heartbeat (ping/pong) co 120 sekund z limitem czasu 30 sekund. W przypadku braku pong lub błędu połączenie jest zamykane i automatycznie ponownie nawiązywane. Usunięto watchdog ciszy, aby uniknąć niepotrzebnych ponownych połączeń podczas długich okresów bezczynności (np. w nocy).",
59
+ "uk": "Покращено стабільність WebSocket: додано heartbeat (ping/pong) кожні 120 секунд із тайм-аутом 30 секунд. Якщо pong не надходить або виникає помилка, з'єднання закривається та автоматично відновлюється. Видалено watchdog тиші, щоб уникнути непотрібних повторних підключень під час тривалих періодів бездіяльності (наприклад, уночі).",
60
+ "zh-cn": "改进了 WebSocket 稳定性:每 120 秒添加一次心跳 (ping/pong),超时 30 秒。如果没有收到 pong 或发生错误,连接将关闭并自动重新连接。移除了静默监视程序,以避免在长时间空闲期间(例如夜间)不必要的重新连接。"
61
+ },
36
62
  "0.2.2": {
37
63
  "en": "Prepared for the first npm release. Synchronized versions between io-package.json and package.json. Added npm metadata and publication configuration. Minor internal adjustments for improved compatibility.",
38
64
  "de": "Für die erste npm-Veröffentlichung vorbereitet. Versionen zwischen io-package.json und package.json synchronisiert. npm-Metadaten und Veröffentlichungskonfiguration hinzugefügt. Kleine interne Anpassungen zur verbesserten Kompatibilität.",
@@ -45,60 +71,8 @@
45
71
  "pl": "Przygotowano do pierwszego wydania npm. Zsynchronizowano wersje między io-package.json i package.json. Dodano metadane npm i konfigurację publikacji. Drobne poprawki wewnętrzne dla lepszej kompatybilności.",
46
72
  "uk": "Підготовлено до першого випуску npm. Синхронізовано версії між io-package.json і package.json. Додано метадані npm та конфігурацію публікації. Невеликі внутрішні покращення для кращої сумісності.",
47
73
  "zh-cn": "为首次 npm 发布做好准备。同步 io-package.json 与 package.json 之间的版本。添加了 npm 元数据和发布配置。进行了少量内部改进以提高兼容性。"
48
- },
49
- "0.2.1": {
50
- "en": "Added option in Admin UI to enable or disable WebSocket message logging (wsDebug). This allows toggling incoming WebSocket message logs directly in the adapter configuration. Minor internal improvements.",
51
- "de": "Neue Option in der Admin-UI zum Aktivieren oder Deaktivieren des WebSocket-Nachrichten-Loggings (wsDebug). Das Logging eingehender WebSocket-Nachrichten kann nun direkt in der Adapter-Konfiguration gesteuert werden. Kleine interne Verbesserungen.",
52
- "ru": "Добавлена опция в интерфейсе администратора для включения или отключения логирования сообщений WebSocket (wsDebug). Теперь можно управлять логированием входящих сообщений WebSocket прямо в настройках адаптера. Незначительные внутренние улучшения.",
53
- "pt": "Adicionada opção na interface de administração para ativar ou desativar o registro de mensagens WebSocket (wsDebug). Agora é possível alternar o registro de mensagens diretamente na configuração do adaptador. Pequenas melhorias internas.",
54
- "nl": "Optie toegevoegd in de Admin UI om het loggen van WebSocket-berichten in of uit te schakelen (wsDebug). Hiermee kun je inkomende berichten direct in de adapterconfiguratie beheren. Kleine interne verbeteringen.",
55
- "fr": "Ajout d'une option dans l'interface d'administration pour activer ou désactiver la journalisation des messages WebSocket (wsDebug). Permet de basculer l'enregistrement des messages directement depuis la configuration de l'adaptateur. Améliorations internes mineures.",
56
- "it": "Aggiunta un'opzione nell'interfaccia di amministrazione per abilitare o disabilitare il logging dei messaggi WebSocket (wsDebug). Ora è possibile gestire i log direttamente nella configurazione dell'adattatore. Piccoli miglioramenti interni.",
57
- "es": "Se agregó una opción en la interfaz de administración para habilitar o deshabilitar el registro de mensajes WebSocket (wsDebug). Ahora se puede activar o desactivar directamente desde la configuración del adaptador. Pequeñas mejoras internas.",
58
- "pl": "Dodano opcję w interfejsie administratora do włączania lub wyłączania logowania wiadomości WebSocket (wsDebug). Można teraz sterować logowaniem bezpośrednio w konfiguracji adaptera. Drobne ulepszenia wewnętrzne.",
59
- "uk": "Додано опцію в інтерфейсі адміністратора для ввімкнення або вимкнення журналювання повідомлень WebSocket (wsDebug). Тепер можна керувати логуванням безпосередньо в налаштуваннях адаптера. Незначні внутрішні покращення.",
60
- "zh-cn": "在管理界面中添加了启用或禁用 WebSocket 消息日志记录 (wsDebug) 的选项。现在可以在适配器配置中直接切换日志记录。进行了少量内部改进。"
61
- },
62
- "0.2.0": {
63
- "en": "Migrated to ESLint 9 (Flat-Config) and updated development dependencies",
64
- "de": "Migration auf ESLint 9 (Flat-Config) und Aktualisierung der Entwicklungsabhängigkeiten",
65
- "ru": "Переход на ESLint 9 (Flat-Config) и обновлены зависимости для разработки",
66
- "pt": "Migrado para ESLint 9 (Flat-Config) e dependências de desenvolvimento atualizadas",
67
- "nl": "Gemigreerd naar ESLint 9 (Flat-Config) en ontwikkelafhankelijkheden bijgewerkt",
68
- "fr": "Migration vers ESLint 9 (Flat-Config) et mise à jour des dépendances de développement",
69
- "it": "Migrazione a ESLint 9 (Flat-Config) e aggiornate le dipendenze di sviluppo",
70
- "es": "Migrado a ESLint 9 (Flat-Config) y actualizadas las dependencias de desarrollo",
71
- "pl": "Migracja do ESLint 9 (Flat-Config) i aktualizacja zależności deweloperskich",
72
- "uk": "Міграція на ESLint 9 (Flat-Config) та оновлено залежності розробки",
73
- "zh-cn": "迁移到 ESLint 9(Flat-Config)并更新开发依赖项"
74
- },
75
- "0.1.2": {
76
- "en": "Improved admin UI config and fixed adapter-check issues",
77
- "de": "Verbesserte Admin-UI-Konfiguration und behobene Adapter-Check-Fehler",
78
- "ru": "Улучшена конфигурация админ-интерфейса и исправлены ошибки adapter-check",
79
- "pt": "Configuração da interface de administração melhorada e problemas do adapter-check corrigidos",
80
- "nl": "Verbeterde admin UI-configuratie en adapter-checkproblemen opgelost",
81
- "fr": "Configuration de l'interface d'administration améliorée et correction des problèmes d'adapter-check",
82
- "it": "Configurazione dell'interfaccia di amministrazione migliorata e risolti i problemi di adapter-check",
83
- "es": "Configuración de la interfaz de administración mejorada y problemas de verificación del adaptador corregidos",
84
- "pl": "Ulepszona konfiguracja interfejsu administratora i naprawione błędy adapter-check",
85
- "uk": "Покращена конфігурація інтерфейсу адміністратора та виправлені помилки adapter-check",
86
- "zh-cn": "改进了管理界面配置并修复了适配器检查问题"
87
- },
88
- "0.1.1": {
89
- "en": "Initial release",
90
- "de": "Erste Version",
91
- "ru": "Первая версия",
92
- "pt": "Versão inicial",
93
- "nl": "Eerste versie",
94
- "fr": "Première version",
95
- "it": "Prima versione",
96
- "es": "Primera versión",
97
- "pl": "Pierwsza wersja",
98
- "uk": "Перша версія",
99
- "zh-cn": "初始版本"
100
74
  }
101
- },
75
+ },
102
76
  "keywords": [
103
77
  "al-ko",
104
78
  "Robolinho",
@@ -110,7 +84,6 @@
110
84
  "adminUI": {
111
85
  "config": "json"
112
86
  },
113
- "license": "MIT",
114
87
  "licenseInformation": {
115
88
  "type": "free",
116
89
  "license": "MIT",
package/main.js CHANGED
@@ -31,7 +31,9 @@ class AlKoAdapter extends utils.Adapter {
31
31
  this.adapterSetStates = new Set();
32
32
  this.pendingPushes = new Set();
33
33
  this.webSockets = {}; // offene WebSocket-Verbindungen pro Gerät
34
- this.reconnectTimeouts = {}; // hier speichern wir alle offenen Reconnect-Timeouts
34
+ this.reconnectTimeouts = {}; // offene Reconnect-Timeouts
35
+ this.pingIntervals = {}; // Ping-Intervalle pro Gerät
36
+ this.pongTimeouts = {}; // Timeout-Überwachung nach Ping
35
37
 
36
38
  this._stopRequested = false;
37
39
 
@@ -97,6 +99,7 @@ class AlKoAdapter extends utils.Adapter {
97
99
 
98
100
  this.log.info("✅ Login erfolgreich");
99
101
  }
102
+
100
103
  async refreshAuth() {
101
104
  if (!this.refreshToken || Date.now() >= this.tokenExpiresAt - 60000) {
102
105
  this.log.info("🔄 Erneuere Access-Token…");
@@ -206,8 +209,32 @@ class AlKoAdapter extends utils.Adapter {
206
209
  const url = `wss://socket.al-ko.com/v1?Authorization=${this.accessToken}&thingName=${deviceId}`;
207
210
  const ws = new WebSocket(url);
208
211
 
212
+ ws.isAlive = true;
213
+
209
214
  ws.on("open", () => {
210
215
  this.log.info(`🔗 WebSocket verbunden für Gerät: ${deviceId}`);
216
+
217
+ // PING-Mechanismus (alle 120 Sekunden)
218
+ this.pingIntervals[deviceId] = setInterval(() => {
219
+ if (ws.readyState === WebSocket.OPEN) {
220
+ ws.ping();
221
+ ws.isAlive = false;
222
+
223
+ this.pongTimeouts[deviceId] = setTimeout(() => {
224
+ if (!ws.isAlive) {
225
+ this.log.warn(
226
+ `💤 Keine Pong-Antwort von ${deviceId} → Verbindung wird beendet`,
227
+ );
228
+ ws.terminate();
229
+ }
230
+ }, 30_000); // 30 Sekunden Zeit für Pong
231
+ }
232
+ }, 120_000); // 120 Sekunden Ping-Intervall
233
+ });
234
+
235
+ ws.on("pong", () => {
236
+ ws.isAlive = true;
237
+ clearTimeout(this.pongTimeouts[deviceId]);
211
238
  });
212
239
 
213
240
  ws.on("message", async (msg) => {
@@ -242,7 +269,8 @@ class AlKoAdapter extends utils.Adapter {
242
269
  this.log.warn(
243
270
  `⚠️ WebSocket geschlossen für ${deviceId}, erneuter Versuch in 10s`,
244
271
  );
245
- // Timeout merken, damit wir ihn im onUnload wieder aufräumen können
272
+ clearInterval(this.pingIntervals[deviceId]);
273
+ clearTimeout(this.pongTimeouts[deviceId]);
246
274
  this.reconnectTimeouts[deviceId] = setTimeout(
247
275
  () => this.connectWebSocket(deviceId),
248
276
  10000,
@@ -251,6 +279,10 @@ class AlKoAdapter extends utils.Adapter {
251
279
 
252
280
  ws.on("error", (err) => {
253
281
  this.log.error(`❌ WebSocket-Fehler (${deviceId}): ${err.message}`);
282
+ // Falls kein 'close' folgt, aktiv terminieren, damit Reconnect greift
283
+ try {
284
+ ws.terminate();
285
+ } catch {}
254
286
  });
255
287
 
256
288
  this.webSockets[deviceId] = ws;
@@ -565,22 +597,29 @@ class AlKoAdapter extends utils.Adapter {
565
597
  clearInterval(this.tokenInterval);
566
598
  }
567
599
 
568
- // offene Reconnect-Timeouts aufräumen
569
600
  for (const t of Object.values(this.reconnectTimeouts)) {
570
601
  try {
571
602
  clearTimeout(t);
572
- } catch {
573
- // intentionally empty
574
- }
603
+ } catch {}
604
+ }
605
+
606
+ for (const t of Object.values(this.pingIntervals)) {
607
+ try {
608
+ clearInterval(t);
609
+ } catch {}
610
+ }
611
+
612
+ for (const t of Object.values(this.pongTimeouts)) {
613
+ try {
614
+ clearTimeout(t);
615
+ } catch {}
575
616
  }
576
617
 
577
618
  // offene WebSockets schließen
578
619
  for (const ws of Object.values(this.webSockets)) {
579
620
  try {
580
621
  ws.close();
581
- } catch {
582
- // intentionally empty
583
- }
622
+ } catch {}
584
623
  }
585
624
 
586
625
  this.log.info("Adapter gestoppt.");
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "iobroker.al-ko",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Adapter for communication with Al-Ko garden tools",
5
- "author": {
6
- "name": "Hubertiob",
7
- "email": "hubertiob@posteo.at"
8
- },
5
+ "author": "Hubert Zechner <hubertiob@posteo.at>",
9
6
  "contributors": [
10
7
  {
11
8
  "name": "AL-KO"
@@ -23,7 +20,7 @@
23
20
  ],
24
21
  "repository": {
25
22
  "type": "git",
26
- "url": "https://github.com/zechnerhubert/ioBroker.al-ko.git"
23
+ "url": "git+https://github.com/zechnerhubert/ioBroker.al-ko.git"
27
24
  },
28
25
  "bugs": {
29
26
  "url": "https://github.com/zechnerhubert/ioBroker.al-ko/issues"
@@ -44,15 +41,15 @@
44
41
  "README.md"
45
42
  ],
46
43
  "scripts": {
47
- "test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
48
- "test:package": "mocha test/package --exit",
49
- "test:integration": "mocha test/integration --exit",
50
- "test": "npm run test:js && npm run test:package",
51
- "check": "tsc --noEmit -p tsconfig.check.json",
52
- "lint": "eslint main.js lib/ --ext .js",
53
- "lint:fix": "eslint main.js lib/ --ext .js --fix",
54
- "translate": "translate-adapter",
55
- "release": "release-script"
44
+ "test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
45
+ "test:package": "mocha test/package --exit",
46
+ "test:integration": "mocha test/integration --exit",
47
+ "test": "npm run test:js && npm run test:package",
48
+ "check": "tsc --noEmit -p tsconfig.check.json",
49
+ "lint": "eslint main.js lib/ admin/jsonConfig.json --ext .js,.json",
50
+ "lint:fix": "eslint main.js lib/ admin/jsonConfig.json --ext .js,.json --fix",
51
+ "translate": "translate-adapter",
52
+ "release": "release-script"
56
53
  },
57
54
  "dependencies": {
58
55
  "@iobroker/adapter-core": "^3.3.2",
@@ -60,35 +57,35 @@
60
57
  "ws": "^8.18.0"
61
58
  },
62
59
  "devDependencies": {
63
- "@alcalzone/release-script": "^3.8.0",
64
- "@alcalzone/release-script-plugin-iobroker": "^3.7.2",
65
- "@alcalzone/release-script-plugin-license": "^3.7.0",
66
- "@alcalzone/release-script-plugin-manual-review": "^3.7.0",
67
- "@iobroker/adapter-dev": "^1.5.0",
68
- "@iobroker/testing": "^5.1.1",
69
- "@tsconfig/node20": "^20.1.6",
70
- "@types/chai": "^4.3.20",
71
- "@types/chai-as-promised": "^7.1.8",
72
- "@types/mocha": "^10.0.10",
73
- "@types/node": "^24.6.1",
74
- "@types/proxyquire": "^1.3.31",
75
- "@types/sinon": "^17.0.4",
76
- "@types/sinon-chai": "^4.0.0",
77
- "@eslint/js": "^9.14.0",
78
- "@iobroker/eslint-config": "^1.5.0",
79
- "chai": "^4.5.0",
80
- "chai-as-promised": "^7.1.2",
81
- "eslint": "^9.14.0",
82
- "mocha": "^11.7.2",
83
- "prettier": "^3.3.3",
84
- "proxyquire": "^2.1.3",
85
- "sinon": "^21.0.0",
86
- "sinon-chai": "^4.0.1",
87
- "typescript": "~5.0.4",
88
- "typescript-eslint": "^8.8.0"
89
- },
90
- "publishConfig": {
91
- "access": "public"
92
- },
60
+ "@alcalzone/release-script": "^3.8.0",
61
+ "@alcalzone/release-script-plugin-iobroker": "^3.7.2",
62
+ "@alcalzone/release-script-plugin-license": "^3.7.0",
63
+ "@alcalzone/release-script-plugin-manual-review": "^3.7.0",
64
+ "@iobroker/adapter-dev": "^1.5.0",
65
+ "@iobroker/testing": "^5.1.1",
66
+ "@tsconfig/node20": "^20.1.6",
67
+ "@types/chai": "^4.3.20",
68
+ "@types/chai-as-promised": "^7.1.8",
69
+ "@types/mocha": "^10.0.10",
70
+ "@types/node": "^24.6.1",
71
+ "@types/proxyquire": "^1.3.31",
72
+ "@types/sinon": "^17.0.4",
73
+ "@types/sinon-chai": "^4.0.0",
74
+ "@eslint/js": "^9.14.0",
75
+ "@iobroker/eslint-config": "^1.5.0",
76
+ "chai": "^4.5.0",
77
+ "chai-as-promised": "^7.1.2",
78
+ "eslint": "^9.14.0",
79
+ "mocha": "^11.7.2",
80
+ "prettier": "^3.3.3",
81
+ "proxyquire": "^2.1.3",
82
+ "sinon": "^21.0.0",
83
+ "sinon-chai": "^4.0.1",
84
+ "typescript": "~5.0.4",
85
+ "typescript-eslint": "^8.8.0"
86
+ },
87
+ "publishConfig": {
88
+ "access": "public"
89
+ },
93
90
  "readmeFilename": "README.md"
94
91
  }