iobroker.sun2000 2.3.4 → 2.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/LICENSE +1 -1
- package/README.md +13 -1
- package/io-package.json +29 -29
- package/lib/alarms.js +91 -0
- package/lib/controls/inverter_service_queue.js +2 -0
- package/lib/drivers/driver_base.js +4 -2
- package/lib/drivers/driver_emma.js +21 -3
- package/lib/drivers/driver_inverter.js +241 -18
- package/lib/modbus/modbus_connect.js +24 -10
- package/lib/register.js +9 -4
- package/main.js +38 -42
- package/package.json +4 -6
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025 bolliy <stephan@mante.info>
|
|
3
|
+
Copyright (c) 2025-2026 bolliy <stephan@mante.info>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -65,6 +65,18 @@ browse in the [wiki](https://github.com/bolliy/ioBroker.sun2000/wiki)
|
|
|
65
65
|
Placeholder for the next version (at the beginning of the line):
|
|
66
66
|
### **WORK IN PROGRESS**
|
|
67
67
|
-->
|
|
68
|
+
### 2.3.6 (2026-01-29)
|
|
69
|
+
* dependency and configuration updates
|
|
70
|
+
* new state `inverter.x.derived.alarmsJSON` : json array with intverter alarms (id, name, level) [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)
|
|
71
|
+
* add ChargeDischargePower for Battery units [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)
|
|
72
|
+
* add minimum and maximum temperature for battery packs [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)
|
|
73
|
+
|
|
74
|
+
### 2.3.5 (2025-11-17)
|
|
75
|
+
* dependency and configuration updates
|
|
76
|
+
* Battery status check was suspended in inverter control [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)
|
|
77
|
+
* Emma: dynamic detection of sun2000 inverters and integration of devices such as sun2000
|
|
78
|
+
* allow Modbus ID 0 when using the sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/218)
|
|
79
|
+
|
|
68
80
|
### 2.3.4 (2025-11-01)
|
|
69
81
|
* dependency and configuration updates
|
|
70
82
|
* new state `collected.dailyExternalYield` Riemann sum of `collected.externalPower`
|
|
@@ -319,7 +331,7 @@ initial release
|
|
|
319
331
|
## License
|
|
320
332
|
MIT License
|
|
321
333
|
|
|
322
|
-
Copyright (c) 2025 bolliy <stephan@mante.info>
|
|
334
|
+
Copyright (c) 2025-2026 bolliy <stephan@mante.info>
|
|
323
335
|
|
|
324
336
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
325
337
|
of this software and associated documentation files (the "Software"), to deal
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "sun2000",
|
|
4
|
-
"version": "2.3.
|
|
4
|
+
"version": "2.3.6",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.3.6": {
|
|
7
|
+
"en": "dependency and configuration updates\nnew state `inverter.x.derived.alarmsJSON` : json array with intverter alarms (id, name, level) [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)\nadd ChargeDischargePower for Battery units [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\nadd minimum and maximum temperature for battery packs [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
8
|
+
"de": "abhängigkeits- und konfigurationsupdates\nneuer Zustand `inverter.x.derived.alarmsJSON`: json array with intverter alarms (id, name, level) [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)\nadd ChargeDischargePower for Battery Units [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\nmindest- und Höchsttemperatur für Akkupacks [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
9
|
+
"ru": "обновления зависимостей и конфигурации\njson array with intverter alarms (id, name, level) [#226] (https://github.com/bolliy/ioBroker.sun2000/issues/226)\nдобавить ChargeDischargePower для батарейных блоков [#234] (https://github.com/bolliy/ioBroker.sun2000/issues/234)\nдобавить минимальную и максимальную температуру для аккумуляторных батарей [#236] (https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
10
|
+
"pt": "atualizações de dependência e configuração\nnovo estado `inverter.x.derived.alarmsJSON` : json array com alarmes de inversor (id, name, level) [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)\nadicionar ChargeDischargePower for Battery units [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\nadicionar temperatura mínima e máxima para pacotes de bateria [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
11
|
+
"nl": "afhankelijkheid en configuratie-updates\nnieuwe staat \nchargeDischargePower for Battery units [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\nminimum- en maximumtemperatuur toevoegen voor batterijpakketten [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
12
|
+
"fr": "mises à jour de la dépendance et de la configuration\nnouvel état `inverter.x.derived.alarmsJSON` : tableau json avec alarmes d'intverter (id, nom, niveau) [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)\najouter ChargeDischargePower pour les unités de batterie [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\najouter la température minimale et maximale pour les batteries [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
13
|
+
"it": "aggiornamenti di dipendenza e configurazione\nnuovo stato `inverter.x.derived.alarmsJSON` : json array con allarme intverter (id, nome, livello) [#226](https://github.com/bolliy/ioBroker.sun2000/problems/226)\naggiungi ChargeDischargePower per batterie [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\naggiungere la temperatura minima e massima per le batterie [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
14
|
+
"es": "actualizaciones de dependencia y configuración\nnuevo estado `inverter.x.derived.alarmsJSON` : json array with intverter alarms (id, name, level) [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)\nañadir ChargeDischargePower for Battery units [#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\nañadir la temperatura mínima y máxima para los paquetes de baterías [#236](https://github.com/bolliy/ioBroker.sun2000/issues/236)",
|
|
15
|
+
"pl": "aktualizacje zależności i konfiguracji\nnowość \"inverter.x.derived.alarmsJSON\": tablica json z alarmami intverter (id, name, level) [# 226] (https: / / github.com / bolliy / ioBroker.sun2000 / issues / 226)\ndata umieszczenia w wykazie\ndodać minimalną i maksymalną temperaturę dla baterii [# 236] (https: / / github.com / bolliy / ioBroker.sun2000 / issues / 236)",
|
|
16
|
+
"uk": "оновлення залежності та конфігурації\nновий стан `inverter.x.derived.alarmsJSON` : json array with intverter тривоги (id, назва, рівень) [#226](https://github.com/bolliy/ioBroker.sun2000/products/226)\nadd ChargeDischargePower для батарей [#234](https://github.com/bolliy/ioBroker.sun2000/products/234)\nдодайте мінімальну і максимальну температуру для акумуляторних пакетів [#236](https://github.com/bolliy/ioBroker.sun2000/products/236)",
|
|
17
|
+
"zh-cn": "依赖和配置更新\nnew state `inverter.x. inducted.alarmsJSON ' : json 数组带内置式警报器(id, name, level) [# 226] (https://github.com/bolliy/ioBroker.sun2000/issues/226) (中文(简体) )\n添加电池单位充电放电器[#234](https://github.com/bolliy/ioBroker.sun2000/issues/234)\n增加电池包的最低和最高温度[第236号](https://github.com/bolliy/ioBroker.sun2000/issues/236)"
|
|
18
|
+
},
|
|
19
|
+
"2.3.5": {
|
|
20
|
+
"en": "dependency and configuration updates\nBattery status check was suspended in inverter control [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\nEmma: dynamic detection of sun2000 inverters and integration of devices such as sun2000\nallow Modbus ID 0 when using the sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
21
|
+
"de": "abhängigkeits- und konfigurationsupdates\nDie Batteriestatusprüfung wurde in der Wechselrichtersteuerung [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220) ausgesetzt\nEmma: dynamische Erkennung von Wechselrichtern von Sun2000 und Integration von Geräten wie sun2000\nerlauben Sie Modbus ID 0 bei Verwendung des sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
22
|
+
"ru": "обновления зависимостей и конфигурации\nПроверка состояния батареи была приостановлена в инверторном управлении [#220] (https://github.com/bolliy/ioBroker.sun2000/issues/220)\nЭмма: динамическое обнаружение инверторов Sun2000 и интеграция таких устройств, как Sun2000\nразрешить Modbus ID 0 при использовании sDongle [#218] (https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
23
|
+
"pt": "atualizações de dependência e configuração\nA verificação do estado da bateria foi suspensa no controle do inversor [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\nEmma: detecção dinâmica de inversores sun2000 e integração de dispositivos como sun2000\npermitir Modbus ID 0 ao usar o sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
24
|
+
"nl": "afhankelijkheid en configuratie-updates\nDe controle van de status van de batterij werd opgeschort bij controle van de inverter [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\nEmma: dynamische detectie van zonne2000 omvormers en integratie van apparaten zoals sun2000\nmodbus ID 0 toestaan bij gebruik van sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
25
|
+
"fr": "mises à jour de la dépendance et de la configuration\nLe contrôle de l'état de la batterie a été suspendu dans le contrôle de l'onduleur [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\nEmma : détection dynamique des onduleurs Sun2000 et intégration de dispositifs tels que Sun2000\npermettre Modbus ID 0 lors de l'utilisation de sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
26
|
+
"it": "aggiornamenti di dipendenza e configurazione\nIl controllo dello stato della batteria è stato sospeso nel controllo dell'inverter [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\nEmma: rilevazione dinamica degli inverter Sun2000 e integrazione di dispositivi come sun2000\nconsentire Modbus ID 0 quando si utilizza lo sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
27
|
+
"es": "actualizaciones de dependencia y configuración\nSe suspendió el control del estado de la batería [#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\nEmma: detección dinámica de inversores de sol2000 e integración de dispositivos como el sol2000\npermitir Modbus ID 0 al utilizar el sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
28
|
+
"pl": "aktualizacje zależności i konfiguracji\nKontrola stanu baterii została zawieszona w kontrolach inwertera [# 220] (https: / / github.com / bolliy / ioBroker.sun2000 / issues / 220)\nEmma: dynamiczna detekcja inwerterów sun2000 i integracja urządzeń takich jak sun2000\nw przypadku stosowania sDongle [# 218] (https: / / github.com / bolliy / ioBroker.sun2000 / issues / 118)",
|
|
29
|
+
"uk": "оновлення залежності та конфігурації\nПеревірка стану акумулятора була припинена в інверторному режимі [#220] (https://github.com/bolliy/ioBroker.sun2000/issues/220)\nЕмма: динамічне виявлення інверторів сонця2000 та інтеграції пристроїв, таких як сонце2000\nдозволити Modbus ID 0 при використанні sDongle [#218](https://github.com/bolliy/ioBroker.sun2000/issues/118)",
|
|
30
|
+
"zh-cn": "依赖和配置更新\n在反转控制中暂停了电池状态检查[#220](https://github.com/bolliy/ioBroker.sun2000/issues/220)\n艾玛:对太阳2000反转器的动态检测和太阳2000等设备的集成\n允许在使用 sDongle [# 218] 时使用 Modbus ID (https:// github.com/ bolliy/ioBroker.sun2000/issues/118) "
|
|
31
|
+
},
|
|
6
32
|
"2.3.4": {
|
|
7
33
|
"en": "dependency and configuration updates\nnew state `collected.dailyExternalYield` Riemann sum of `collected.externalPower`",
|
|
8
34
|
"de": "abhängigkeits- und konfigurationsupdates\nneuer Zustand `collect.dailyExternalYield` Riemann Summe von `collected.externalPower `",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "nowa wersja dla migratów npm do zaufanej publikacji",
|
|
68
94
|
"uk": "новий реліз для npm migrats для Trusted Publishing",
|
|
69
95
|
"zh-cn": "npm 的新版本迁移到信任出版"
|
|
70
|
-
},
|
|
71
|
-
"2.2.1-alpha.0": {
|
|
72
|
-
"en": "inverter control: add same state for startup and shutdown an inverter [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\nfix: Device status name has been corrected [#202](https://github.com/bolliy/ioBroker.sun2000/pull/202)\nadd undocumented device status `Shutdown: End of the ESS discharge process` \nemma control: new state ` emma.control.battery.ESSControlMode`. You can now configure EMMA with TOU-mode (Time of Use) to charge the battery from grid. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nif an Emma is installed, some control states of the inverter are deactivated (read only). Mainly for the grid settings.\ndeprecated control states have been removed.\na workaround for issue [#582](https://github.com/yaacov/node-modbus-serial/issues/582) of node-modbus-serial has been implemented.",
|
|
73
|
-
"de": "inverter-Steuerung: Fügen Sie den gleichen Zustand für Start und Abschaltung eines Inverters [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199) hinzu\nbehoben: Gerätestatusname wurde korrigiert [#202](https://github.com/bolliy/ioBroker.sun2000/pull/202)\n`Shutdown: Ende des ESS-Entladungsvorgangs`\nemma control: new state ` emma.control.battery.ESSControlMode`. Sie können nun EMMA mit TOU-Modus (Time of Use) konfigurieren, um den Akku aus dem Netz zu laden. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nwenn eine Emma installiert ist, werden einige Steuerzustände des Wechselrichters deaktiviert (nur lesen). Hauptsächlich für die Netzeinstellungen.\ndeprekierte steuerzustände wurden entfernt.\nein workaround für ausgabe [#582](https://github.com/yaacov/node-modbus-serial/issues/582) von node-modbus-serial wurde implementiert.",
|
|
74
|
-
"ru": "инверторное управление: добавьте то же состояние для запуска и отключения инвертора [#199] (https://github.com/bolliy/ioBroker.sun2000/issues/199)\nисправление: имя статуса устройства было исправлено [#202] (https://github.com/bolliy/ioBroker.sun2000/pull/202)\nдобавить незарегистрированный статус устройства «Shutdown: End of the ESS discharge process»\nemma control: emma.control.battery.ESSControlMode. Теперь вы можете настроить EMMA с режимом TOU (Время использования) для зарядки батареи из сетки. [#200] (https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nесли установлена Эмма, некоторые контрольные состояния инвертора деактивируются (только чтение). В основном для настроек сетки.\nустаревшие контрольные штаты были удалены.\nбыл реализован обходной путь для выпуска [#582] (https://github.com/yaacov/node-modbus-serial/issues/582) node-modbus-serial.",
|
|
75
|
-
"pt": "controle do inversor: adicione o mesmo estado para iniciar e desligar um inversor [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\ncorreção: o nome do estado do dispositivo foi corrigido [#202] (https://github.com/bolliy/ioBroker.sun2000/pull/202)\nadicionar status do dispositivo não documentado `Shutdown: Fim do processo de descarga do ESS'\nemma control: novo estado `emma.control.battery.ESSControlMode`. Agora você pode configurar o EMMA com o modo TOU (Time of Use) para carregar a bateria da grade. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nse uma Emma estiver instalada, alguns estados de controle do inversor são desativados (apenas lidos). Principalmente para as configurações da grade.\nos estados de controlo desactualizados foram removidos.\numa solução alternativa para o problema [#582](https://github.com/yaacov/node-modbus-serial/issues/582) do nó-modbus-serial foi implementada.",
|
|
76
|
-
"nl": "inverter control: voeg dezelfde status toe voor het opstarten en afsluiten van een inverter [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\nfix: De status van het apparaat is gecorrigeerd [#202](https://github.com/bolliy/ioBroker.sun2000/pull/202)\nstatus van niet-gedocumenteerd apparaat toevoegen: Afsluiten: Einde van het ESS-ontladingsproces\nemma control: nieuwe staat U kunt nu EMMA configureren met de TOU-modus (Time of Use) om de batterij op te laden van het net. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nals een Emma is geïnstalleerd, worden sommige controletoestanden van de omvormer gedeactiveerd (alleen lezen). Vooral voor de rasterinstellingen.\nverouderde controlestaten zijn verwijderd.\ner is een oplossing gevonden voor nummer [#582](https://github.com/yaacov/node-modbus-serial/issues/582) van node-modbus-serial.",
|
|
77
|
-
"fr": "contrôle de l'onduleur: ajouter le même état pour le démarrage et l'arrêt d'un onduleur [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\ncorrection : le nom de l'état du périphérique a été corrigé [#202](https://github.com/bolliy/ioBroker.sun2000/pull/202)\najouter l'état de l'appareil sans papiers `Shutdown: Fin du processus de décharge ESS'\ncontrôle emma: nouvel état ` emma.control.battery.ESSControlMode`. Vous pouvez maintenant configurer EMMA en mode TOU (Time of Use) pour charger la batterie à partir de la grille. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nsi une Emma est installée, certains états de contrôle de l'onduleur sont désactivés (lisez seulement). Principalement pour les paramètres de la grille.\nles états de contrôle dépréciés ont été supprimés.\nune solution de rechange pour l'émission [#582](https://github.com/yaacov/node-modbus-serial/issues/582) de nœud-modbus-serial a été mise en œuvre.",
|
|
78
|
-
"it": "controllo inverter: aggiungere lo stesso stato per l'avvio e l'arresto di un inverter [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\nfix: Il nome dello stato del dispositivo è stato corretto [#202](https://github.com/bolliy/ioBroker.sun2000/pull/202)\naggiungere lo stato del dispositivo non documentato `Shutdown: Fine del processo di scarico ESS`\ncontrollo emma: nuovo stato ` emma.control.battery.ESSControlMode`. È ora possibile configurare EMMA con TOU-mode (Time of Use) per caricare la batteria dalla rete. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nse viene installata una Emma, alcuni stati di controllo dell'inverter sono disattivati (leggi solo). Principalmente per le impostazioni della griglia.\nstati di controllo deprecati sono stati rimossi.\nè stato implementato un workaround per il numero [#582](https://github.com/yaacov/node-modbus-serial/issues/582) di node-modbus-serial.",
|
|
79
|
-
"es": "control inverter: añadir el mismo estado para iniciar y cerrar un inverter [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\nfijado: Se ha corregido el nombre del estado de los dispositivos [#202](https://github.com/bolliy/ioBroker.sun2000/pull/202)\nañadir estado de dispositivo no documentado `Shutdown: Final del proceso de descarga ESS`\nemma control: nuevo estado ` emma.control.battery.ESSControlMode`. Ahora puede configurar EMMA con TOU-mode (Time of Use) para cargar la batería de la red. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nsi se instala una Emma, se desactivan algunos estados de control del inversor (sólo lectura). Principalmente para la configuración de la red.\nestados de control deprecatados han sido eliminados.\na workaround for issue [#582](https://github.com/yaacov/node-modbus-serial/issues/582) of node-modbus-serial has been implemented.",
|
|
80
|
-
"pl": "inverter control: add same state for startup and shutdown an inverter [# 199] (https: / / github.com / bolliy / ioBroker.sun2000 / issues / 199)\nfix: Nazwa statusu urządzenia została poprawiona [# 202] (https: / / github.com / bolliy / ioBroker.sun2000 / pull / 202)\ndodać nieudokumentowany status urządzenia \"Wyłączenie: koniec procesu rozładowania ESS\"\nemma control: New state 'emma.control.battery.ESSControlMode'. Można teraz skonfigurować EMMA z TOU- mode (Time of Use), aby naładować baterię z siatki. [# 200] (https: / / github.com / bolliy / ioBroker.sun2000 / discussions / 200)\njeśli zainstalowana jest Emma, niektóre stany sterujące inwertera są wyłączone (tylko do odczytu). Głównie dla ustawień siatki.\nusunięto zdepregatowane stany kontrolne.\na workaround for issue [# 582] (https: / / github.com / yaacov / node- modbus- serial / issues / 582) of node- modbus- serial został wdrożony.",
|
|
81
|
-
"uk": "контроль інвертора: додати однаковий стан для запуску та відключення інвертора [#199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\nвиправлено: Назва стану пристрою було виправлено [#202] (https://github.com/bolliy/ioBroker.sun2000/pull/202)\nдодати недокументований статус пристрою `Пошук: кінець процесу розряду ESS\nемма управління: новий стан ` emma.control.battery.ESSControlMode`. Ви можете налаштувати EMMA з TOU-mode (Time of Use) для зарядки акумулятора з сітки. [#200](https://github.com/bolliy/ioBroker.sun2000/discussions/200)\nякщо встановлений Емма, деактивуються деякі стани управління інвертором (прочитати тільки). В основному для налаштування сітки.\nвилучені стани керування.\n[#582](https://github.com/yaacov/node-modbus-serial/issues/582) вузла-modbus-serial.",
|
|
82
|
-
"zh-cn": "反转器控制:为启动和关闭添加相同状态的反转器[199](https://github.com/bolliy/ioBroker.sun2000/issues/199)\n固定: 设备状态名称已更正 [# 202] (https://github.com/bolliy/ioBroker.sun2000/pul/202)\n添加无文件设备状态“关闭:ESS放电过程结束”\nemma控制:新状态`emma.control.battery.ESS Control Mode'. 您现在可以用 TOU- mode( 使用时间) 配置 EMMA 从电网中充电 。 [# 200] (https://github.com/bolliy/ioBroker.sun2000/discussions/200)\n如果安装了Emma,反转器的某些控制状态就会失效(只读). 主要用于网格设置.\n贬值的控制状态已被取消.\n已落实了节点-modbus-serial[#582](https://github.com/yaacov/node-modbus-serial/issues/582)的工作."
|
|
83
|
-
},
|
|
84
|
-
"2.2.0": {
|
|
85
|
-
"en": "dependency and configuration updates\nnew state `meter.derived.signConventionForPowerFeed-in` sign of meter.activePower that is currently being fed into the power grid\nnew state `meter.derived.feed-inPower` electric power that is supplied to a grid (\"fed in\")",
|
|
86
|
-
"de": "abhängigkeits- und konfigurationsupdates\nneuer Zustand `meter.derived.signConventionForPowerFeed-in` Zeichen von meter.active Strom, der derzeit in das Stromnetz eingespeist wird\nneue Zustand `meter.derived.feed-inPower` elektrische Leistung, die einem Netz zugeführt wird (\"fed in\")",
|
|
87
|
-
"ru": "обновления зависимостей и конфигурации\nновый государственный знак «meter.derived.signConventionForPowerFeed-in» Мощность, которая в настоящее время подается в электросеть\nэлектрическая мощность нового состояния «meter.derived.feed-inPower», которая подается в сеть («питается в»)",
|
|
88
|
-
"pt": "atualizações de dependência e configuração\nnovo estado `meter.derived.signConventionForPowerFeed-in` sinal do medidor.active Energia que está sendo alimentada na rede de energia\nnovo estado `meter.derived.feed-inPower` energia elétrica que é fornecida a uma grade (\"feed in\")",
|
|
89
|
-
"nl": "afhankelijkheid en configuratie-updates\nnieuwe staat Energie die momenteel wordt gevoed in het elektriciteitsnet\nnieuwe toestand ",
|
|
90
|
-
"fr": "mises à jour de la dépendance et de la configuration\nnouvel état `meter.derived.signConventionForPowerFeed-in` signe de meter.active Puissance qui est actuellement introduite dans le réseau électrique\nnouvel état `meter.derived.feed-inPower` électricité qui est fourni à un réseau (\"feed in\")",
|
|
91
|
-
"it": "aggiornamenti di dipendenza e configurazione\nnuovo stato `meter.derived.signConventionForPowerFeed-in` segno di metro.active Potenza che sta attualmente alimentando nella rete elettrica\nnuovo stato `meter.derived.feed-inPower` potere elettrico che viene fornito a una griglia (\"fed in\")",
|
|
92
|
-
"es": "actualizaciones de dependencia y configuración\nnuevo estado `meter.derived.signConventionForPowerFeed-in` signo de medidor.active Potencia que actualmente está siendo alimentada en la red eléctrica\nnuevo estado `meter.derived.feed-inPower` energía eléctrica que se suministra a una red (\"fed in\")",
|
|
93
|
-
"pl": "aktualizacje zależności i konfiguracji\nnowy stan 'meter.derived.signConventionForPowerFeed- in' znak meter.active Energia zasilana obecnie do sieci energetycznej\nnowy stan 'meter.derived.feed-inPower' energia elektryczna, która jest dostarczana do sieci (\"karmiona w\")",
|
|
94
|
-
"uk": "оновлення залежності та конфігурації\nновий стан `meter.derived.signConventionForPowerFeed-in` знак лічильника.active Потужність, яка в даний час вдається в електромережу\nновий стан `meter.derived.feed-inPower` електрична потужність, яка подається в сітку (\"fed in\")",
|
|
95
|
-
"zh-cn": "依赖和配置更新\n新的状态“ 公尺” 。 生成。 签署 Convention ForPowerFeed- in' sign of meter. 活动 目前输入电网的电力\n新状态“ met. entered. feed-inpower” 供电给电网(“ feeded in”)"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -233,14 +233,14 @@
|
|
|
233
233
|
"native": {
|
|
234
234
|
"address": "",
|
|
235
235
|
"port": 502,
|
|
236
|
-
"modbusIds": "
|
|
236
|
+
"modbusIds": "",
|
|
237
237
|
"updateInterval": 20,
|
|
238
238
|
"sd_active": false,
|
|
239
239
|
"sDongleId": "100",
|
|
240
240
|
"timeout": 10000,
|
|
241
241
|
"delay": 0,
|
|
242
242
|
"connectDelay": 5000,
|
|
243
|
-
"autoAdjust":
|
|
243
|
+
"autoAdjust": false,
|
|
244
244
|
"ms_active": false,
|
|
245
245
|
"ms_address": "0.0.0.0",
|
|
246
246
|
"ms_port": 502,
|
package/lib/alarms.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const alarmLevel = {
|
|
2
|
+
Major: 'major',
|
|
3
|
+
Minor: 'minor',
|
|
4
|
+
Warning: 'warning',
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const inverterAlarms1 = new Map()
|
|
8
|
+
.set('0', { id: 2001, name: 'High String Input Voltage', level: alarmLevel.Major })
|
|
9
|
+
.set('1', { id: 2002, name: 'DC Arc Fault', level: alarmLevel.Major })
|
|
10
|
+
.set('2', { id: 2011, name: 'String Reverse Connection', level: alarmLevel.Major })
|
|
11
|
+
.set('3', { id: 2012, name: 'String Current Backfeed', level: alarmLevel.Warning })
|
|
12
|
+
.set('4', { id: 2913, name: 'Abnormal String Power', level: alarmLevel.Warning })
|
|
13
|
+
.set('5', { id: 2021, name: 'AFCI Self-Check Fail', level: alarmLevel.Major })
|
|
14
|
+
.set('6', { id: 2031, name: 'Phase Wire Short-Circuited to PE', level: alarmLevel.Major })
|
|
15
|
+
.set('7', { id: 2032, name: 'Grid Loss', level: alarmLevel.Major })
|
|
16
|
+
.set('8', { id: 2033, name: 'Grid Undervoltage', level: alarmLevel.Major })
|
|
17
|
+
.set('9', { id: 2034, name: 'Grid Overvoltage', level: alarmLevel.Major })
|
|
18
|
+
.set('10', { id: 2035, name: 'Grid Volt. Imbalance', level: alarmLevel.Major })
|
|
19
|
+
.set('11', { id: 2036, name: 'Grid Overfrequency', level: alarmLevel.Major })
|
|
20
|
+
.set('12', { id: 2037, name: 'Grid Underfrequency', level: alarmLevel.Major })
|
|
21
|
+
.set('13', { id: 2038, name: 'Unstable Grid Frequency', level: alarmLevel.Major })
|
|
22
|
+
.set('14', { id: 2039, name: 'Output Overcurrent', level: alarmLevel.Major })
|
|
23
|
+
.set('15', { id: 2040, name: 'Output DC Component Overhigh', level: alarmLevel.Major });
|
|
24
|
+
|
|
25
|
+
const inverterAlarms2 = new Map()
|
|
26
|
+
.set('0', { id: 2051, name: 'Abnormal Residual Current', level: alarmLevel.Major })
|
|
27
|
+
.set('1', { id: 2061, name: 'Abnormal Grounding', level: alarmLevel.Major })
|
|
28
|
+
.set('2', { id: 2062, name: 'Low Insulation Resistance', level: alarmLevel.Major })
|
|
29
|
+
.set('3', { id: 2063, name: 'Overtemperature', level: alarmLevel.Minor })
|
|
30
|
+
.set('4', { id: 2064, name: 'Device Fault', level: alarmLevel.Major })
|
|
31
|
+
.set('5', { id: 2065, name: 'Upgrade Failed or Version Mismatch', level: alarmLevel.Minor })
|
|
32
|
+
.set('6', { id: 2066, name: 'License Expired', level: alarmLevel.Warning })
|
|
33
|
+
.set('7', { id: 61440, name: 'Faulty Monitoring Unit', level: alarmLevel.Minor })
|
|
34
|
+
.set('8', { id: 2067, name: 'Faulty Power Collector', level: alarmLevel.Major })
|
|
35
|
+
.set('9', { id: 2068, name: 'Battery abnormal', level: alarmLevel.Minor })
|
|
36
|
+
.set('10', { id: 2070, name: 'Active Islanding', level: alarmLevel.Major })
|
|
37
|
+
.set('11', { id: 2071, name: 'Passive Islanding', level: alarmLevel.Major })
|
|
38
|
+
.set('12', { id: 2072, name: 'Transient AC Overvoltage', level: alarmLevel.Major })
|
|
39
|
+
.set('13', { id: 2075, name: 'Peripheral port short circuit', level: alarmLevel.Warning })
|
|
40
|
+
.set('14', { id: 2077, name: 'Churn output overload', level: alarmLevel.Major })
|
|
41
|
+
.set('15', { id: 2080, name: 'Abnormal PV module configuration', level: alarmLevel.Major });
|
|
42
|
+
|
|
43
|
+
const inverterAlarms3 = new Map()
|
|
44
|
+
.set('0', { id: 2081, name: 'Optimizer fault', level: alarmLevel.Warning })
|
|
45
|
+
.set('1', { id: 2085, name: 'Built-in PID operation abnormal', level: alarmLevel.Minor })
|
|
46
|
+
.set('2', { id: 2014, name: 'High input string voltage to ground', level: alarmLevel.Major })
|
|
47
|
+
.set('3', { id: 2086, name: 'External Fan Abnormal', level: alarmLevel.Major })
|
|
48
|
+
.set('4', { id: 2069, name: 'Battery Reverse Connection', level: alarmLevel.Major })
|
|
49
|
+
.set('5', { id: 2082, name: 'On-grid /Off-grid controller abnormal', level: alarmLevel.Major })
|
|
50
|
+
.set('6', { id: 2015, name: 'PV String Loss', level: alarmLevel.Warning })
|
|
51
|
+
.set('7', { id: 2087, name: 'Internal Fan Abnormal', level: alarmLevel.Major })
|
|
52
|
+
.set('8', { id: 2088, name: 'DC Protection Unit Abnormal', level: alarmLevel.Major })
|
|
53
|
+
.set('9', { id: 2089, name: 'EL Unit Abnormal', level: alarmLevel.Minor })
|
|
54
|
+
.set('10', { id: 2090, name: 'Active Adjustment Instruction Abnormal', level: alarmLevel.Major })
|
|
55
|
+
.set('11', { id: 2091, name: 'Reactive Adjustment Instruction Abnormal', level: alarmLevel.Major })
|
|
56
|
+
.set('12', { id: 2092, name: 'CT Wiring Abnormal', level: alarmLevel.Major })
|
|
57
|
+
.set('13', { id: 2003, name: 'DC Arc Fault(ADMC Alarm to be clear manually)', level: alarmLevel.Major })
|
|
58
|
+
.set('14', { id: 2093, name: 'DC Switch Abnormal', level: alarmLevel.Minor })
|
|
59
|
+
.set('15', { id: 2094, name: 'Allowable discharge capacity of the battery is low', level: alarmLevel.Warning });
|
|
60
|
+
|
|
61
|
+
function textsFromBitfield(alarmString, lot) {
|
|
62
|
+
const result = [];
|
|
63
|
+
for (const [i, char] of Object.entries(alarmString)) {
|
|
64
|
+
if (char === '1') {
|
|
65
|
+
const alarmText = lot.get(i);
|
|
66
|
+
if (alarmText) {
|
|
67
|
+
result.push(alarmText);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getAlarmInfo(alarmCode, alarmNo) {
|
|
75
|
+
if (alarmCode !== null) {
|
|
76
|
+
const alarmString = (alarmCode >>> 0).toString(2).padStart(16, '0');
|
|
77
|
+
switch (alarmNo) {
|
|
78
|
+
case 1:
|
|
79
|
+
return textsFromBitfield(alarmString, inverterAlarms1);
|
|
80
|
+
case 2:
|
|
81
|
+
return textsFromBitfield(alarmString, inverterAlarms2);
|
|
82
|
+
case 3:
|
|
83
|
+
return textsFromBitfield(alarmString, inverterAlarms3);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
getAlarmInfo,
|
|
91
|
+
};
|
|
@@ -750,6 +750,7 @@ class ServiceQueueMap {
|
|
|
750
750
|
this._eventMap.delete(event.id); //forget the event
|
|
751
751
|
continue;
|
|
752
752
|
}
|
|
753
|
+
/*
|
|
753
754
|
const BatStatus = this.inverterInfo.instance.stateCache.get(`${this.inverterInfo.path}.battery.runningStatus`)?.value ?? -1;
|
|
754
755
|
if (BatStatus !== 2 && BatStatus !== 1 && BatStatus !== -1) {
|
|
755
756
|
this.log.warn(
|
|
@@ -758,6 +759,7 @@ class ServiceQueueMap {
|
|
|
758
759
|
this._eventMap.delete(event.id); //forget the event
|
|
759
760
|
continue;
|
|
760
761
|
}
|
|
762
|
+
*/
|
|
761
763
|
}
|
|
762
764
|
if (service.state.type === 'number') {
|
|
763
765
|
if (!this.isNumber(event)) {
|
|
@@ -154,6 +154,10 @@ class DriverBase {
|
|
|
154
154
|
}
|
|
155
155
|
if (reg.states) {
|
|
156
156
|
for (const field of reg.states) {
|
|
157
|
+
//typeof field.register.checkIfActive === 'function'
|
|
158
|
+
if (field.checkIfActive && !field.checkIfActive()) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
157
161
|
const state = field.state;
|
|
158
162
|
if (field.store !== storeType.never && !state.initState) {
|
|
159
163
|
await this.state.initState(path, state);
|
|
@@ -162,11 +166,9 @@ class DriverBase {
|
|
|
162
166
|
if (field.register) {
|
|
163
167
|
let value = this._fromArray(data, reg.address, field);
|
|
164
168
|
if (value !== null) {
|
|
165
|
-
//v0.8.x
|
|
166
169
|
if (field.register.type) {
|
|
167
170
|
value = this._checkValidValueRange(value, field.register);
|
|
168
171
|
}
|
|
169
|
-
|
|
170
172
|
if (field.register.gain) {
|
|
171
173
|
value /= field.register.gain;
|
|
172
174
|
}
|
|
@@ -570,7 +570,7 @@ class Emma extends DriverBase {
|
|
|
570
570
|
this.log.debug('### PostHook for Emma - identify Subdevices charger');
|
|
571
571
|
this.identifySubdevices('charger', this.modbusId)
|
|
572
572
|
.then(ret => {
|
|
573
|
-
this.log.debug(`### PostHook identification for
|
|
573
|
+
this.log.debug(`### PostHook identification for Emma chargers - ret: ${JSON.stringify(ret)}`);
|
|
574
574
|
for (const [i, charger] of ret.entries()) {
|
|
575
575
|
const device = {
|
|
576
576
|
index: i,
|
|
@@ -586,10 +586,28 @@ class Emma extends DriverBase {
|
|
|
586
586
|
this.log.warn(`PostHook for identification EmmaChargers - err: ${err}`);
|
|
587
587
|
});
|
|
588
588
|
this.identifySubdevices('sun2000', this.modbusId)
|
|
589
|
-
.then(ret => {
|
|
589
|
+
.then(async ret => {
|
|
590
590
|
this.log.debug(`### PostHook indentification for Inverter Sun2000 - ret: ${JSON.stringify(ret)}`);
|
|
591
|
-
|
|
591
|
+
//check if inverter sun2000 already exists
|
|
592
|
+
const inverterExist = this.adapter.devices.findIndex(x => x.driverClass === driverClasses.inverter);
|
|
593
|
+
for (const [i, inverter] of ret.entries()) {
|
|
592
594
|
this.log.info(`${this._name} identify subdevice an inverter sun2000: OID=${inverter.obj_id}, modbus id: ${inverter.slave_id}`);
|
|
595
|
+
//unless inverters are configured, add them
|
|
596
|
+
if (inverterExist === -1) {
|
|
597
|
+
const device = {
|
|
598
|
+
index: i,
|
|
599
|
+
duration: 5000,
|
|
600
|
+
modbusId: inverter.slave_id,
|
|
601
|
+
driverClass: driverClasses.inverter,
|
|
602
|
+
meter: false,
|
|
603
|
+
};
|
|
604
|
+
this.adapter.devices.push(device);
|
|
605
|
+
await this.adapter.initDevicePath(device);
|
|
606
|
+
this.log.info(`Inverter sun2000 with modbus id ${inverter.slave_id} added.`);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
if (inverterExist === -1) {
|
|
610
|
+
await this.adapter.adjustInverval();
|
|
593
611
|
}
|
|
594
612
|
})
|
|
595
613
|
.catch(err => {
|
|
@@ -4,6 +4,7 @@ const { deviceType, driverClasses, storeType, getDeviceStatusInfo, batteryStatus
|
|
|
4
4
|
const { RiemannSum, isSunshine } = require(`${__dirname}/../tools.js`);
|
|
5
5
|
const DriverBase = require(`${__dirname}/driver_base.js`);
|
|
6
6
|
const ServiceQueueMap = require(`${__dirname}/../controls/inverter_service_queue.js`);
|
|
7
|
+
const { getAlarmInfo } = require(`${__dirname}/../alarms.js`);
|
|
7
8
|
|
|
8
9
|
class InverterInfo extends DriverBase {
|
|
9
10
|
constructor(stateInstance, device) {
|
|
@@ -88,10 +89,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
88
89
|
driverClass: driverClasses.inverter,
|
|
89
90
|
...options,
|
|
90
91
|
});
|
|
91
|
-
//TestMode
|
|
92
|
-
//this._testMode = this.adapter.settings.address === '192.168.2.54';
|
|
93
|
-
this._testMode = false;
|
|
94
|
-
this.log.debug(`### TestMode (#60) ${this._testMode} ${this.adapter.settings.address}`);
|
|
92
|
+
this._testMode = false; //TestMode
|
|
95
93
|
|
|
96
94
|
this.solarSum = new RiemannSum();
|
|
97
95
|
this.adapter.getState(`${this.deviceInfo.path}.derived.dailySolarYield`, (err, state) => {
|
|
@@ -157,7 +155,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
157
155
|
|
|
158
156
|
this.log.debug('### TEST MODE - PostHook for InverterSun2000 ####');
|
|
159
157
|
this.identifySubdevices('sun2000', this.modbusId)
|
|
160
|
-
.then(ret => {
|
|
158
|
+
.then(async ret => {
|
|
161
159
|
this.log.debug(`### PostHook for InverterSun2000 - ret: ${JSON.stringify(ret)}`);
|
|
162
160
|
for (const [i, inverter] of ret.entries()) {
|
|
163
161
|
this.log.info(`${this._name} identifies an inverter sun2000: OID=${inverter.obj_id}, modbus id: ${inverter.slave_id}`);
|
|
@@ -168,8 +166,9 @@ class InverterSun2000 extends DriverBase {
|
|
|
168
166
|
driverClass: driverClasses.emmaCharger,
|
|
169
167
|
};
|
|
170
168
|
this.adapter.devices.push(device);
|
|
171
|
-
this.adapter.initDevicePath(device);
|
|
169
|
+
await this.adapter.initDevicePath(device);
|
|
172
170
|
}
|
|
171
|
+
await this.adapter.adjustInverval();
|
|
173
172
|
})
|
|
174
173
|
.catch(err => {
|
|
175
174
|
this.log.warn(`### PostHook for InverterSun2000 - err: ${err}`);
|
|
@@ -212,7 +211,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
212
211
|
{
|
|
213
212
|
state: {
|
|
214
213
|
id: 'battery.chargeDischargePower',
|
|
215
|
-
name: 'Charge/
|
|
214
|
+
name: 'Charge/discharge power',
|
|
216
215
|
desc: 'reg:37765, len:2 (>0 charging, <0 discharging)',
|
|
217
216
|
type: 'number',
|
|
218
217
|
unit: 'kW',
|
|
@@ -355,6 +354,93 @@ class InverterSun2000 extends DriverBase {
|
|
|
355
354
|
}
|
|
356
355
|
},
|
|
357
356
|
},
|
|
357
|
+
{
|
|
358
|
+
//NEU!!
|
|
359
|
+
address: 38452,
|
|
360
|
+
length: 6,
|
|
361
|
+
info: 'battery Pack max/min Temperature of unit 1',
|
|
362
|
+
refresh: dataRefreshRate.low,
|
|
363
|
+
type: deviceType.battery,
|
|
364
|
+
states: [
|
|
365
|
+
{
|
|
366
|
+
state: {
|
|
367
|
+
id: 'battery.unit.1.batteryPack.1.maximumTemperature',
|
|
368
|
+
name: 'Max. temperature',
|
|
369
|
+
type: 'number',
|
|
370
|
+
unit: '°C',
|
|
371
|
+
role: 'value.temperature',
|
|
372
|
+
desc: 'reg:38452, len:1',
|
|
373
|
+
},
|
|
374
|
+
register: { reg: 38452, type: dataType.int16, gain: 10 },
|
|
375
|
+
checkIfActive: () => this._batteryExists(1, 1),
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
state: {
|
|
379
|
+
id: 'battery.unit.1.batteryPack.1.minimumTemperature',
|
|
380
|
+
name: 'Min. temperature',
|
|
381
|
+
type: 'number',
|
|
382
|
+
unit: '°C',
|
|
383
|
+
role: 'value.temperature',
|
|
384
|
+
desc: 'reg:38453, len:1',
|
|
385
|
+
},
|
|
386
|
+
register: { reg: 38453, type: dataType.int16, gain: 10 },
|
|
387
|
+
checkIfActive: () => this._batteryExists(1, 1),
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
// 38454
|
|
391
|
+
state: {
|
|
392
|
+
id: 'battery.unit.1.batteryPack.2.maximumTemperature',
|
|
393
|
+
name: 'Max. temperature',
|
|
394
|
+
type: 'number',
|
|
395
|
+
unit: '°C',
|
|
396
|
+
role: 'value.temperature',
|
|
397
|
+
desc: 'reg:38454, len:1',
|
|
398
|
+
},
|
|
399
|
+
register: { reg: 38454, type: dataType.int16, gain: 10 },
|
|
400
|
+
checkIfActive: () => this._batteryExists(1, 2),
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
// 38455
|
|
404
|
+
state: {
|
|
405
|
+
id: 'battery.unit.1.batteryPack.2.minimumTemperature',
|
|
406
|
+
name: 'Min. temperature',
|
|
407
|
+
type: 'number',
|
|
408
|
+
unit: '°C',
|
|
409
|
+
role: 'value.temperature',
|
|
410
|
+
desc: 'reg:38455, len:1',
|
|
411
|
+
},
|
|
412
|
+
register: { reg: 38455, type: dataType.int16, gain: 10 },
|
|
413
|
+
checkIfActive: () => this._batteryExists(1, 2),
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
// 38456
|
|
417
|
+
state: {
|
|
418
|
+
id: 'battery.unit.1.batteryPack.3.maximumTemperature',
|
|
419
|
+
name: 'Max. temperature',
|
|
420
|
+
type: 'number',
|
|
421
|
+
unit: '°C',
|
|
422
|
+
role: 'value.temperature',
|
|
423
|
+
desc: 'reg:38456, len:1',
|
|
424
|
+
},
|
|
425
|
+
register: { reg: 38456, type: dataType.int16, gain: 10 },
|
|
426
|
+
checkIfActive: () => this._batteryExists(1, 3),
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
// 38457
|
|
430
|
+
state: {
|
|
431
|
+
id: 'battery.unit.1.batteryPack.3.minimumTemperature',
|
|
432
|
+
name: 'Min. temperature',
|
|
433
|
+
type: 'number',
|
|
434
|
+
unit: '°C',
|
|
435
|
+
role: 'value.temperature',
|
|
436
|
+
desc: 'reg:38457, len:1',
|
|
437
|
+
},
|
|
438
|
+
register: { reg: 38457, type: dataType.int16, gain: 10 },
|
|
439
|
+
checkIfActive: () => this._batteryExists(1, 3),
|
|
440
|
+
},
|
|
441
|
+
],
|
|
442
|
+
checkIfActive: () => this._batteryExists(1),
|
|
443
|
+
},
|
|
358
444
|
{
|
|
359
445
|
address: 38229,
|
|
360
446
|
length: 13,
|
|
@@ -494,7 +580,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
494
580
|
{
|
|
495
581
|
state: {
|
|
496
582
|
id: 'battery.unit.1.batteryPack.1.chargeDischargePower',
|
|
497
|
-
name: 'Charge/
|
|
583
|
+
name: 'Charge/discharge power',
|
|
498
584
|
desc: 'reg:38233, len:2 (>0 charging, <0 discharging)',
|
|
499
585
|
type: 'number',
|
|
500
586
|
unit: 'kW',
|
|
@@ -526,7 +612,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
526
612
|
{
|
|
527
613
|
state: {
|
|
528
614
|
id: 'battery.unit.1.batteryPack.2.chargeDischargePower',
|
|
529
|
-
name: 'Charge/
|
|
615
|
+
name: 'Charge/discharge power',
|
|
530
616
|
desc: 'reg:38275, len:2 (>0 charging, <0 discharging)',
|
|
531
617
|
type: 'number',
|
|
532
618
|
unit: 'kW',
|
|
@@ -558,7 +644,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
558
644
|
{
|
|
559
645
|
state: {
|
|
560
646
|
id: 'battery.unit.1.batteryPack.3.chargeDischargePower',
|
|
561
|
-
name: 'Charge/
|
|
647
|
+
name: 'Charge/discharge power',
|
|
562
648
|
desc: 'reg:38317, len:2 (>0 charging, <0 discharging)',
|
|
563
649
|
type: 'number',
|
|
564
650
|
unit: 'kW',
|
|
@@ -580,12 +666,35 @@ class InverterSun2000 extends DriverBase {
|
|
|
580
666
|
],
|
|
581
667
|
checkIfActive: () => this._batteryExists(1, 3),
|
|
582
668
|
},
|
|
583
|
-
|
|
669
|
+
/*
|
|
670
|
+
//TESTS FOR BATTERY UNIT 2
|
|
671
|
+
{
|
|
672
|
+
address: 37001,
|
|
673
|
+
length: 2,
|
|
674
|
+
info: 'battery Unit1 chargeDischargePower',
|
|
675
|
+
refresh: dataRefreshRate.high,
|
|
676
|
+
type: deviceType.battery,
|
|
677
|
+
states: [
|
|
678
|
+
{
|
|
679
|
+
state: {
|
|
680
|
+
id: 'battery.unit.1.chargeDischargePower2',
|
|
681
|
+
name: 'Charge/discharge power',
|
|
682
|
+
type: 'number',
|
|
683
|
+
unit: 'W',
|
|
684
|
+
role: 'value.power',
|
|
685
|
+
desc: 'reg:37001, len:2 (>0 charging, <0 discharging)',
|
|
686
|
+
},
|
|
687
|
+
register: { reg: 37001, type: dataType.int32 },
|
|
688
|
+
},
|
|
689
|
+
],
|
|
690
|
+
checkIfActive: () => this._batteryExists(1),
|
|
691
|
+
},
|
|
692
|
+
*/
|
|
584
693
|
{
|
|
585
694
|
address: 37000,
|
|
586
695
|
length: 23,
|
|
587
696
|
info: 'battery Unit1 information',
|
|
588
|
-
refresh: dataRefreshRate.
|
|
697
|
+
refresh: dataRefreshRate.high,
|
|
589
698
|
type: deviceType.battery,
|
|
590
699
|
states: [
|
|
591
700
|
{
|
|
@@ -598,7 +707,17 @@ class InverterSun2000 extends DriverBase {
|
|
|
598
707
|
desc: 'reg:37000, len:1',
|
|
599
708
|
},
|
|
600
709
|
register: { reg: 37000, type: dataType.uint16 },
|
|
601
|
-
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
state: {
|
|
713
|
+
id: 'battery.unit.1.chargeDischargePower',
|
|
714
|
+
name: 'Charge/discharge power',
|
|
715
|
+
type: 'number',
|
|
716
|
+
unit: 'W',
|
|
717
|
+
role: 'value.power',
|
|
718
|
+
desc: 'reg:37001, len:2 (>0 charging, <0 discharging)',
|
|
719
|
+
},
|
|
720
|
+
register: { reg: 37001, type: dataType.int32 },
|
|
602
721
|
},
|
|
603
722
|
{
|
|
604
723
|
state: {
|
|
@@ -770,7 +889,6 @@ class InverterSun2000 extends DriverBase {
|
|
|
770
889
|
},
|
|
771
890
|
},
|
|
772
891
|
{
|
|
773
|
-
//for NRGKick
|
|
774
892
|
address: 47000,
|
|
775
893
|
length: 1,
|
|
776
894
|
info: 'battery unit1 (static)',
|
|
@@ -933,7 +1051,20 @@ class InverterSun2000 extends DriverBase {
|
|
|
933
1051
|
state: { id: 'alarm3', name: 'Alarm 3', type: 'number', unit: '', role: 'value', desc: 'reg:32010, len:1' },
|
|
934
1052
|
register: { reg: 32010, type: dataType.uint16 },
|
|
935
1053
|
},
|
|
1054
|
+
{
|
|
1055
|
+
state: { id: 'derived.alarmJSON', name: 'alarms as json string', type: 'string', unit: '', role: 'value' },
|
|
1056
|
+
},
|
|
936
1057
|
],
|
|
1058
|
+
postHook: path => {
|
|
1059
|
+
//const alarm1Info = getAlarmInfo(128, 1);
|
|
1060
|
+
const alarm1Info = getAlarmInfo(this.stateCache.get(`${path}alarm1`)?.value, 1);
|
|
1061
|
+
const alarm2Info = getAlarmInfo(this.stateCache.get(`${path}alarm2`)?.value, 2);
|
|
1062
|
+
const alarm3Info = getAlarmInfo(this.stateCache.get(`${path}alarm3`)?.value, 3);
|
|
1063
|
+
const alarmInfos = alarm1Info.concat(alarm2Info, alarm3Info);
|
|
1064
|
+
|
|
1065
|
+
this.adapter.log.silly(`Inverter alarms '${alarmInfos}'`);
|
|
1066
|
+
this.stateCache.set(`${path}derived.alarmJSON`, JSON.stringify(alarmInfos), { type: 'string' });
|
|
1067
|
+
},
|
|
937
1068
|
},
|
|
938
1069
|
{
|
|
939
1070
|
address: 32016,
|
|
@@ -1520,7 +1651,7 @@ class InverterSun2000 extends DriverBase {
|
|
|
1520
1651
|
//let inputYield = this.stateCache.get(`${path}dailyEnergyYield`)?.value ?? 0 * 0.97 + charge - disCharge;
|
|
1521
1652
|
const activeEnergy = this.stateCache.get(`${path}derived.dailyActiveEnergy`)?.value ?? 0;
|
|
1522
1653
|
//let inYield = activeEnergy + (charge - disCharge) * 0.97; //efficiency loss of battery 3%
|
|
1523
|
-
let inYield = activeEnergy +
|
|
1654
|
+
let inYield = activeEnergy + charge * 0.97 - disCharge * 1.03; //efficiency loss of battery 3%
|
|
1524
1655
|
if (inYield < 0) {
|
|
1525
1656
|
inYield = 0;
|
|
1526
1657
|
}
|
|
@@ -1792,11 +1923,94 @@ class InverterSun2000_M1 extends InverterSun2000 {
|
|
|
1792
1923
|
}
|
|
1793
1924
|
},
|
|
1794
1925
|
},
|
|
1926
|
+
{
|
|
1927
|
+
//NEU!!
|
|
1928
|
+
address: 38458,
|
|
1929
|
+
length: 6,
|
|
1930
|
+
info: 'battery Packs max/min Temperature of unit 2',
|
|
1931
|
+
refresh: dataRefreshRate.low,
|
|
1932
|
+
type: deviceType.battery,
|
|
1933
|
+
states: [
|
|
1934
|
+
{
|
|
1935
|
+
state: {
|
|
1936
|
+
id: 'battery.unit.2.batteryPack.1.maximumTemperature',
|
|
1937
|
+
name: 'Max. temperature',
|
|
1938
|
+
type: 'number',
|
|
1939
|
+
unit: '°C',
|
|
1940
|
+
role: 'value.temperature',
|
|
1941
|
+
desc: 'reg:38458, len:1',
|
|
1942
|
+
},
|
|
1943
|
+
register: { reg: 38458, type: dataType.int16, gain: 10 },
|
|
1944
|
+
checkIfActive: () => this._batteryExists(2, 1),
|
|
1945
|
+
},
|
|
1946
|
+
{
|
|
1947
|
+
state: {
|
|
1948
|
+
id: 'battery.unit.2.batteryPack.1.minimumTemperature',
|
|
1949
|
+
name: 'Min. temperature',
|
|
1950
|
+
type: 'number',
|
|
1951
|
+
unit: '°C',
|
|
1952
|
+
role: 'value.temperature',
|
|
1953
|
+
desc: 'reg:38459, len:1',
|
|
1954
|
+
},
|
|
1955
|
+
register: { reg: 38459, type: dataType.int16, gain: 10 },
|
|
1956
|
+
checkIfActive: () => this._batteryExists(2, 1),
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
state: {
|
|
1960
|
+
id: 'battery.unit.2.batteryPack.2.maximumTemperature',
|
|
1961
|
+
name: 'Max. temperature',
|
|
1962
|
+
type: 'number',
|
|
1963
|
+
unit: '°C',
|
|
1964
|
+
role: 'value.temperature',
|
|
1965
|
+
desc: 'reg:38460, len:1',
|
|
1966
|
+
},
|
|
1967
|
+
register: { reg: 38460, type: dataType.int16, gain: 10 },
|
|
1968
|
+
checkIfActive: () => this._batteryExists(2, 2),
|
|
1969
|
+
},
|
|
1970
|
+
{
|
|
1971
|
+
state: {
|
|
1972
|
+
id: 'battery.unit.2.batteryPack.2.minimumTemperature',
|
|
1973
|
+
name: 'Min. temperature',
|
|
1974
|
+
type: 'number',
|
|
1975
|
+
unit: '°C',
|
|
1976
|
+
role: 'value.temperature',
|
|
1977
|
+
desc: 'reg:38461, len:1',
|
|
1978
|
+
},
|
|
1979
|
+
register: { reg: 38461, type: dataType.int16, gain: 10 },
|
|
1980
|
+
checkIfActive: () => this._batteryExists(2, 2),
|
|
1981
|
+
},
|
|
1982
|
+
{
|
|
1983
|
+
state: {
|
|
1984
|
+
id: 'battery.unit.2.batteryPack.3.maximumTemperature',
|
|
1985
|
+
name: 'Max. temperature',
|
|
1986
|
+
type: 'number',
|
|
1987
|
+
unit: '°C',
|
|
1988
|
+
role: 'value.temperature',
|
|
1989
|
+
desc: 'reg:38462, len:1',
|
|
1990
|
+
},
|
|
1991
|
+
register: { reg: 38462, type: dataType.int16, gain: 10 },
|
|
1992
|
+
checkIfActive: () => this._batteryExists(2, 3),
|
|
1993
|
+
},
|
|
1994
|
+
{
|
|
1995
|
+
state: {
|
|
1996
|
+
id: 'battery.unit.2.batteryPack.3.minimumTemperature',
|
|
1997
|
+
name: 'Min. temperature',
|
|
1998
|
+
type: 'number',
|
|
1999
|
+
unit: '°C',
|
|
2000
|
+
role: 'value.temperature',
|
|
2001
|
+
desc: 'reg:38463, len:1',
|
|
2002
|
+
},
|
|
2003
|
+
register: { reg: 38463, type: dataType.int16, gain: 10 },
|
|
2004
|
+
checkIfActive: () => this._batteryExists(2, 3),
|
|
2005
|
+
},
|
|
2006
|
+
],
|
|
2007
|
+
checkIfActive: () => this._batteryExists(2),
|
|
2008
|
+
},
|
|
1795
2009
|
{
|
|
1796
2010
|
address: 37738,
|
|
1797
2011
|
length: 15,
|
|
1798
2012
|
info: 'battery unit2 information',
|
|
1799
|
-
refresh: dataRefreshRate.
|
|
2013
|
+
refresh: dataRefreshRate.high,
|
|
1800
2014
|
type: deviceType.battery,
|
|
1801
2015
|
states: [
|
|
1802
2016
|
{
|
|
@@ -1820,7 +2034,17 @@ class InverterSun2000_M1 extends InverterSun2000 {
|
|
|
1820
2034
|
desc: 'reg:37741, len:1',
|
|
1821
2035
|
},
|
|
1822
2036
|
register: { reg: 37741, type: dataType.uint16 },
|
|
1823
|
-
|
|
2037
|
+
},
|
|
2038
|
+
{
|
|
2039
|
+
state: {
|
|
2040
|
+
id: 'battery.unit.2.chargeDischargePower',
|
|
2041
|
+
name: 'Charge/discharge power',
|
|
2042
|
+
type: 'number',
|
|
2043
|
+
unit: 'W',
|
|
2044
|
+
role: 'value.power',
|
|
2045
|
+
desc: 'reg:37743, len:2 (>0 charging, <0 discharging)',
|
|
2046
|
+
},
|
|
2047
|
+
register: { reg: 37743, type: dataType.int32 },
|
|
1824
2048
|
},
|
|
1825
2049
|
{
|
|
1826
2050
|
state: {
|
|
@@ -1851,7 +2075,6 @@ class InverterSun2000_M1 extends InverterSun2000 {
|
|
|
1851
2075
|
],
|
|
1852
2076
|
checkIfActive: () => this._batteryExists(2),
|
|
1853
2077
|
},
|
|
1854
|
-
//--V0.12
|
|
1855
2078
|
{
|
|
1856
2079
|
address: 38355,
|
|
1857
2080
|
length: 13,
|
|
@@ -97,11 +97,17 @@ class ModbusConnect extends DeviceInterface {
|
|
|
97
97
|
close() {
|
|
98
98
|
return new Promise(resolve => {
|
|
99
99
|
if (this.client) {
|
|
100
|
-
|
|
100
|
+
try {
|
|
101
|
+
this.client.close(() => {
|
|
102
|
+
resolve({});
|
|
103
|
+
});
|
|
104
|
+
//workaround for issue https://github.com/yaacov/node-modbus-serial/issues/582 with node-modbus-serial
|
|
101
105
|
resolve({});
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
} catch (err) {
|
|
107
|
+
this.log.warn(`Could not close Modbus connection: ${err.message}`);
|
|
108
|
+
resolve({});
|
|
109
|
+
//reject();
|
|
110
|
+
}
|
|
105
111
|
} else {
|
|
106
112
|
resolve({});
|
|
107
113
|
}
|
|
@@ -112,9 +118,15 @@ class ModbusConnect extends DeviceInterface {
|
|
|
112
118
|
_destroy() {
|
|
113
119
|
return new Promise(resolve => {
|
|
114
120
|
if (this.client) {
|
|
115
|
-
|
|
121
|
+
try {
|
|
122
|
+
this.client.destroy(() => {
|
|
123
|
+
resolve({});
|
|
124
|
+
});
|
|
125
|
+
} catch (err) {
|
|
126
|
+
this.log.warn(`Could not destroy Modbus connection: ${err.message}`);
|
|
116
127
|
resolve({});
|
|
117
|
-
|
|
128
|
+
//reject();
|
|
129
|
+
}
|
|
118
130
|
} else {
|
|
119
131
|
resolve({});
|
|
120
132
|
}
|
|
@@ -140,18 +152,20 @@ class ModbusConnect extends DeviceInterface {
|
|
|
140
152
|
if (err.modbusCode === undefined) {
|
|
141
153
|
this._adjustDelay(err, false);
|
|
142
154
|
await this.close();
|
|
143
|
-
//await this._destroy();
|
|
144
|
-
//await this.closing();
|
|
145
155
|
await this._create();
|
|
146
156
|
if (err.errno === 'ECONNREFUSED') {
|
|
157
|
+
this.log.warn('Connection Refused!');
|
|
158
|
+
this.log.warn(
|
|
159
|
+
'Either the Modbus TCP service is not enabled, the wrong IP address or port is being used, or a firewall is blocking the connection.',
|
|
160
|
+
);
|
|
161
|
+
} else if (err.errno === 'ECONNRESET') {
|
|
162
|
+
this.log.warn('Connection Reset!');
|
|
147
163
|
this.log.warn('Has another device interrupted the modbus connection?');
|
|
148
164
|
this.log.warn('Consider that only 1 client is allowed to connect to modbus at the same time!');
|
|
149
165
|
}
|
|
150
166
|
} else {
|
|
151
167
|
if (err.modbusCode === 0) {
|
|
152
168
|
await this.close();
|
|
153
|
-
//await this._destroy();
|
|
154
|
-
//await this.closing();
|
|
155
169
|
this._adjustDelay(err, false);
|
|
156
170
|
await this._create();
|
|
157
171
|
}
|
package/lib/register.js
CHANGED
|
@@ -75,6 +75,7 @@ class Registers {
|
|
|
75
75
|
let inPowerEff = 0;
|
|
76
76
|
let chargeDischarge = 0;
|
|
77
77
|
let ratedPower = 0;
|
|
78
|
+
let maxDischargingPower = 0;
|
|
78
79
|
|
|
79
80
|
function calcUsableSurplus() {
|
|
80
81
|
let surplusPower = 0;
|
|
@@ -109,11 +110,14 @@ class Registers {
|
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
usableSurplusPower = surplusPower;
|
|
112
|
-
|
|
113
|
+
// Using battery power to calculate usable surplus power
|
|
113
114
|
if (bufferSoc > 0) {
|
|
114
115
|
if (soc > minSoc && soc >= bufferSoc + threshold) {
|
|
115
116
|
this.bufferOn = true;
|
|
116
|
-
|
|
117
|
+
let bufferPower = this.adapter.control.get('usableSurplus.bufferPower')?.value ?? 0;
|
|
118
|
+
if (bufferPower > maxDischargingPower) {
|
|
119
|
+
bufferPower = maxDischargingPower;
|
|
120
|
+
}
|
|
117
121
|
usableSurplusPower += bufferPower / 1000;
|
|
118
122
|
} else {
|
|
119
123
|
this.bufferOn = false;
|
|
@@ -130,8 +134,8 @@ class Registers {
|
|
|
130
134
|
usableSurplusPower = ratedPower;
|
|
131
135
|
}
|
|
132
136
|
if (!allowNegativeValue) {
|
|
133
|
-
if (surplusPower < 0.
|
|
134
|
-
if (usableSurplusPower < 0.
|
|
137
|
+
if (surplusPower < 0.01) surplusPower = 0;
|
|
138
|
+
if (usableSurplusPower < 0.01) usableSurplusPower = 0;
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
this.adapter.log.debug(
|
|
@@ -150,6 +154,7 @@ class Registers {
|
|
|
150
154
|
inPowerEff += this.stateCache.get(`${inverter.path}.derived.inputPowerWithEfficiencyLoss`)?.value ?? 0;
|
|
151
155
|
chargeDischarge += this.stateCache.get(`${inverter.path}.battery.chargeDischargePower`)?.value ?? 0;
|
|
152
156
|
ratedPower += this.stateCache.get(`${inverter.path}.info.ratedPower`)?.value ?? 0;
|
|
157
|
+
maxDischargingPower += this.stateCache.get(`${inverter.path}.battery.maximumDischargingPower`)?.value ?? 0;
|
|
153
158
|
}
|
|
154
159
|
|
|
155
160
|
const feedinPower = this.stateCache.get('meter.derived.feed-inPower')?.value ?? 0;
|
package/main.js
CHANGED
|
@@ -103,15 +103,7 @@ class Sun2000 extends utils.Adapter {
|
|
|
103
103
|
},
|
|
104
104
|
native: {},
|
|
105
105
|
});
|
|
106
|
-
|
|
107
|
-
await this.extendObject(path+'.battery', {
|
|
108
|
-
type: 'channel',
|
|
109
|
-
common: {
|
|
110
|
-
name: 'channel battery'
|
|
111
|
-
},
|
|
112
|
-
native: {}
|
|
113
|
-
});
|
|
114
|
-
*/
|
|
106
|
+
|
|
115
107
|
await this.extendObject(`${path}.string`, {
|
|
116
108
|
type: 'channel',
|
|
117
109
|
common: {
|
|
@@ -325,17 +317,16 @@ class Sun2000 extends utils.Adapter {
|
|
|
325
317
|
if (this.settings.modbusAdjust) {
|
|
326
318
|
this.settings.highInterval = 10000 * this.settings.modbusIds.length;
|
|
327
319
|
} else {
|
|
320
|
+
this.settings.highInterval = this.config.updateInterval * 1000; //ms
|
|
328
321
|
let minInterval = this.settings.modbusIds.length * this.settings.modbusDelay * 2.5; //len*5*delay/2
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
} else {
|
|
333
|
-
for (const device of this.devices) {
|
|
334
|
-
if (device.duration) {
|
|
335
|
-
minInterval += device.duration;
|
|
336
|
-
}
|
|
322
|
+
for (const device of this.devices) {
|
|
323
|
+
if (device.duration) {
|
|
324
|
+
minInterval += device.duration;
|
|
337
325
|
}
|
|
338
326
|
}
|
|
327
|
+
if (minInterval < 5000) {
|
|
328
|
+
minInterval = 5000;
|
|
329
|
+
}
|
|
339
330
|
if (minInterval > this.settings.highInterval) {
|
|
340
331
|
this.settings.highInterval = Math.round(minInterval);
|
|
341
332
|
}
|
|
@@ -348,8 +339,8 @@ class Sun2000 extends utils.Adapter {
|
|
|
348
339
|
const newHighInterval = Math.round(this.settings.highInterval / 1000);
|
|
349
340
|
if (!this.settings.modbusAdjust) {
|
|
350
341
|
if (this.config.updateInterval < newHighInterval) {
|
|
351
|
-
this.logger.
|
|
352
|
-
this.logger.warn('Please check your configuration!');
|
|
342
|
+
this.logger.info(`The interval is too small. The value has been changed on ${newHighInterval} sec.`);
|
|
343
|
+
//this.logger.warn('Please check your configuration!');
|
|
353
344
|
}
|
|
354
345
|
}
|
|
355
346
|
await this.setState('info.modbusUpdateInterval', { val: newHighInterval, ack: true });
|
|
@@ -386,14 +377,13 @@ class Sun2000 extends utils.Adapter {
|
|
|
386
377
|
this.settings.modbusDelay = this.config.delay; //ms
|
|
387
378
|
this.settings.modbusConnectDelay = this.config.connectDelay; //ms
|
|
388
379
|
this.settings.modbusAdjust = this.config.autoAdjust;
|
|
389
|
-
this.
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
*/
|
|
380
|
+
if (this.config.modbusIds !== '') {
|
|
381
|
+
this.settings.modbusIds = this.config.modbusIds.split(',').map(n => {
|
|
382
|
+
return Number(n);
|
|
383
|
+
});
|
|
384
|
+
} else {
|
|
385
|
+
this.settings.modbusIds = [];
|
|
386
|
+
}
|
|
397
387
|
//SmartDongle
|
|
398
388
|
this.settings.sd.active = this.config.sd_active;
|
|
399
389
|
// eslint-disable-next-line no-constant-binary-expression
|
|
@@ -401,7 +391,7 @@ class Sun2000 extends utils.Adapter {
|
|
|
401
391
|
if (this.settings.sd.sDongleId < 0 || this.settings.sd.sDongleId >= 255) {
|
|
402
392
|
this.settings.sd.active = false;
|
|
403
393
|
}
|
|
404
|
-
this.settings.highInterval = this.config.updateInterval * 1000; //ms
|
|
394
|
+
//this.settings.highInterval = this.config.updateInterval * 1000; //ms
|
|
405
395
|
//Modbus-Proxy
|
|
406
396
|
this.settings.ms.address = this.config.ms_address;
|
|
407
397
|
this.settings.ms.port = this.config.ms_port;
|
|
@@ -419,27 +409,34 @@ class Sun2000 extends utils.Adapter {
|
|
|
419
409
|
if (this.settings.modbusAdjust) {
|
|
420
410
|
await this.setState('info.JSONhealth', { val: '{message: "Adjust modbus settings"}', ack: true });
|
|
421
411
|
} else {
|
|
422
|
-
await this.setState('info.JSONhealth', { val: '{message : "Information is collected"}', ack: true });
|
|
412
|
+
await this.setState('info.JSONhealth', { val: '{message : "Information is collected..."}', ack: true });
|
|
413
|
+
}
|
|
414
|
+
//validate modbus Ids
|
|
415
|
+
if (this.settings.modbusIds.length > 5) {
|
|
416
|
+
this.adapterDisable(`*** Adapter deactivated, Only a maximum of 5 inverters are allowed! ***`);
|
|
417
|
+
return;
|
|
423
418
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
this.adapterDisable(`*** Adapter deactivated, inverter modbus Ids is invalid! ***`);
|
|
419
|
+
if (this.settings.integration !== 2 && this.settings.modbusIds.length === 0) {
|
|
420
|
+
this.adapterDisable(`*** Adapter deactivated, inverter Modbus IDs must be entered! ***`);
|
|
427
421
|
return;
|
|
428
422
|
}
|
|
429
423
|
//ES6 use a for (const [index, item] of array.entries()) of loop
|
|
430
424
|
for (const [i, id] of this.settings.modbusIds.entries()) {
|
|
431
425
|
//Inverter
|
|
432
|
-
if (id
|
|
426
|
+
if (id >= 250) {
|
|
433
427
|
this.adapterDisable(`*** Adapter deactivated, inverter modbus Id ${id} is not permitted! ***`);
|
|
434
428
|
return;
|
|
435
429
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
430
|
+
//inverter modbus id 0 does not exist with emma
|
|
431
|
+
if (this.settings.integration !== 2 || id > 0) {
|
|
432
|
+
this.devices.push({
|
|
433
|
+
index: i,
|
|
434
|
+
duration: 5000,
|
|
435
|
+
modbusId: id,
|
|
436
|
+
driverClass: driverClasses.inverter,
|
|
437
|
+
meter: i == 0 && this.settings.integration === 0,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
443
440
|
}
|
|
444
441
|
|
|
445
442
|
//SDongle
|
|
@@ -471,7 +468,7 @@ class Sun2000 extends utils.Adapter {
|
|
|
471
468
|
}
|
|
472
469
|
}
|
|
473
470
|
|
|
474
|
-
//EMMA
|
|
471
|
+
//EMMA
|
|
475
472
|
if (this.settings.integration === 2) {
|
|
476
473
|
this.devices.push({
|
|
477
474
|
index: 0,
|
|
@@ -542,7 +539,6 @@ class Sun2000 extends utils.Adapter {
|
|
|
542
539
|
const sinceLastUpdate = new Date().getTime() - this.lastTimeUpdated; //ms
|
|
543
540
|
this.logger.debug(`### Watchdog: time since last update ${sinceLastUpdate / 1000} sec`);
|
|
544
541
|
const lastIsConnected = this.isConnected;
|
|
545
|
-
//this.isConnected = this.lastStateUpdatedHigh > 0 && sinceLastUpdate < this.settings.highInterval*3;
|
|
546
542
|
this.isConnected = this.lastStateUpdatedHigh > 0 || this.lastStateUpdatedLow > 0;
|
|
547
543
|
|
|
548
544
|
if (this.isConnected !== lastIsConnected) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.sun2000",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"description": "sun2000",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bolliy",
|
|
@@ -37,13 +37,11 @@
|
|
|
37
37
|
"@alcalzone/release-script-plugin-iobroker": "^4.0.0",
|
|
38
38
|
"@alcalzone/release-script-plugin-license": "^4.0.0",
|
|
39
39
|
"@alcalzone/release-script-plugin-manual-review": "^4.0.0",
|
|
40
|
-
"@eslint/eslintrc": "^3.3.1",
|
|
41
|
-
"@eslint/js": "^9.39.0",
|
|
42
40
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
43
41
|
"@iobroker/eslint-config": "^2.2.0",
|
|
44
|
-
"@iobroker/testing": "^5.
|
|
45
|
-
"@tsconfig/node20": "^20.1.
|
|
46
|
-
"@types/node": "^
|
|
42
|
+
"@iobroker/testing": "^5.2.2",
|
|
43
|
+
"@tsconfig/node20": "^20.1.8",
|
|
44
|
+
"@types/node": "^25.0.10",
|
|
47
45
|
"globals": "^16.5.0",
|
|
48
46
|
"typescript": "~5.9.3"
|
|
49
47
|
},
|