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 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",
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": "1",
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": true,
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 Emmachargers - ret: ${JSON.stringify(ret)}`);
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
- for (const [, inverter] of ret.entries()) {
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/Discharge power',
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/Discharge power',
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/Discharge power',
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/Discharge power',
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.low,
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
- //mapper: value => Promise.resolve(batteryStatus[value]),
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 + (charge - disCharge); //efficiency loss of battery 3%
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.low,
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
- //mapper: value => Promise.resolve(batteryStatus[value]),
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
- this.client.close(() => {
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
- //workaround for issue https://github.com/yaacov/node-modbus-serial/issues/582 with node-modbus-serial
104
- resolve({});
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
- this.client.destroy(() => {
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
- const bufferPower = this.adapter.control.get('usableSurplus.bufferPower')?.value ?? 0;
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.1) surplusPower = 0;
134
- if (usableSurplusPower < 0.1) 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
- if (this.settings.integration > 0) {
330
- //SmartLogger, Emma
331
- minInterval += 5000;
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.warn(`The interval is too small. The value has been changed on ${newHighInterval} sec.`);
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.settings.modbusIds = this.config.modbusIds.split(',').map(n => {
390
- return Number(n);
391
- });
392
- /*
393
- this.settings.chargerIds = this.config.chargerIds.split(',').map(n => {
394
- return Number(n);
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
- //future: if (this.settings.integration !== 2 && (this.settings.modbusIds.length === 0 || this.settings.modbusIds.length > 5)) {
425
- if (this.settings.modbusIds.length === 0 || this.settings.modbusIds.length > 5) {
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 < 1 || id >= 250) {
426
+ if (id >= 250) {
433
427
  this.adapterDisable(`*** Adapter deactivated, inverter modbus Id ${id} is not permitted! ***`);
434
428
  return;
435
429
  }
436
- this.devices.push({
437
- index: i,
438
- duration: 5000,
439
- modbusId: id,
440
- driverClass: driverClasses.inverter,
441
- meter: i == 0 && this.settings.integration === 0,
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 with TestMode
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.4",
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.1.1",
45
- "@tsconfig/node20": "^20.1.6",
46
- "@types/node": "^24.9.2",
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
  },