iobroker.sun2000 0.17.1 → 0.18.1
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 +12 -4
- package/admin/i18n/de/translations.json +3 -3
- package/admin/i18n/en/translations.json +1 -1
- package/io-package.json +27 -27
- package/lib/controls/service_queue.js +32 -13
- package/lib/drivers/driver_inverter.js +6 -1
- package/lib/modbus/modbus_server.js +19 -1
- package/main.js +1 -1
- package/package.json +9 -9
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2025 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
|
@@ -21,7 +21,7 @@ Sentry reporting is used starting with js-controller 3.0.
|
|
|
21
21
|
|
|
22
22
|
## sun2000 adapter for ioBroker
|
|
23
23
|
|
|
24
|
-
Read and write register data from Huawei SUN2000 inverter and LUNA2000 battery using Modbus TCP. Third-party devices can
|
|
24
|
+
Read and write register data from Huawei SUN2000 inverter and LUNA2000 battery using Modbus TCP. Third-party devices can access via the modbus proxy. Even a Huawei SmartLogger or an Huawei Emma can be integrated.
|
|
25
25
|
|
|
26
26
|
[Huawei product information](https://solar.huawei.com/en/professionals/all-products?residential-smart-pv)
|
|
27
27
|
|
|
@@ -57,14 +57,22 @@ browse in the [wiki](https://github.com/bolliy/ioBroker.sun2000/wiki)
|
|
|
57
57
|
* [`Export Control`](https://github.com/bolliy/ioBroker.sun2000/wiki/Begrenzung-Netzeinspeisung-(Export-Control)): The excess PV energy is fed into the power grid, but not all countries allow users to sell electricity. Some countries have introduced regulations to restrict the sale of electricity to the grid.
|
|
58
58
|
* [`modbus-proxy`](https://github.com/bolliy/ioBroker.sun2000/wiki/Modbus-Proxy): Third party device such as wallbox, energy manager etc. can receive data even if the modbus interface of inverter is already in use. In addition you can mirror the sun2000 data to another IoBroker instance.
|
|
59
59
|
* Huawei [`SmartLogger`](https://github.com/bolliy/ioBroker.sun2000/wiki/SmartLogger) integration: Monitors and manages the PV power system. The adapter saves the collected data in the same way as it does when read out the inverter directly.
|
|
60
|
-
* Huawei [`Emma`]() integration: The Modbus access, network connectivity (WiFi and Ethernet) and the DDSU/DTSU-666H smart meter functions are integrated in one unit - the use of the Sdongle becomes redundant. In addition Huawei EV chargers and load shedding/control (via selected Shelly devices) are supported and "intelligent" controlled.
|
|
60
|
+
* Huawei [`Emma`](https://github.com/bolliy/ioBroker.sun2000/wiki/Emma) integration: The Modbus access, network connectivity (WiFi and Ethernet) and the DDSU/DTSU-666H smart meter functions are integrated in one unit - the use of the Sdongle becomes redundant. In addition Huawei EV chargers and load shedding/control (via selected Shelly devices) are supported and "intelligent" controlled.
|
|
61
61
|
|
|
62
62
|
## Changelog
|
|
63
|
-
|
|
64
63
|
<!--
|
|
65
64
|
Placeholder for the next version (at the beginning of the line):
|
|
66
65
|
### **WORK IN PROGRESS**
|
|
67
66
|
-->
|
|
67
|
+
### 0.18.1 (2025-01-08)
|
|
68
|
+
* dependency and configuration updates
|
|
69
|
+
* control: if the battery is not running, events related to the battery are discarded
|
|
70
|
+
* modbus-proxy: adjusted advanced logging
|
|
71
|
+
|
|
72
|
+
### 0.18.0 (2024-12-11)
|
|
73
|
+
* dependency and configuration updates
|
|
74
|
+
* modbus-proxy: the modbus ID 250 is mapped to ID 0
|
|
75
|
+
|
|
68
76
|
### 0.17.1 (2024-11-21)
|
|
69
77
|
* during the device status "Standby: detecting irradiation" (0x0002) register data is now also read from the inverter
|
|
70
78
|
* The reading order of the battery data has been adjusted
|
|
@@ -221,7 +229,7 @@ initial release
|
|
|
221
229
|
## License
|
|
222
230
|
MIT License
|
|
223
231
|
|
|
224
|
-
Copyright (c)
|
|
232
|
+
Copyright (c) 2025 bolliy <stephan@mante.info>
|
|
225
233
|
|
|
226
234
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
227
235
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"donateTxt": "Wenn
|
|
2
|
+
"donateTxt": "Wenn Ihnen dieser Adapter gefällt, denken Sie bitte über eine Spende nach, um meine Arbeit zu unterstützen.",
|
|
3
3
|
"address": "Geräte-IP-Adresse",
|
|
4
4
|
"port": "Modbus TCP-Port",
|
|
5
5
|
"Modbus inverter IDs": "Modbus-Wechselrichter-IDs",
|
|
6
6
|
"Update interval (sec)": "Aktualisierungsintervall [Sek.]",
|
|
7
7
|
"The device ip address": "Die IP-Adresse des Geräts",
|
|
8
8
|
"The modbus TCP port": "Der Modbus-TCP-Port",
|
|
9
|
-
"The modbus inverter IDs, separated with character ,": "
|
|
9
|
+
"The modbus inverter IDs, separated with character ,": "Wechselrichter-IDs, der Master muss zuerst eingegeben werden, getrennt durch ,",
|
|
10
10
|
"Update interval to update the values from the inverters": "Aktualisierungsintervall zur Aktualisierung der Werte von den Wechselrichtern",
|
|
11
11
|
"modbus connection timeout": "Zeitüberschreitung der Modbus-Verbindung",
|
|
12
12
|
"delay between modbus requests": "Verzögerung zwischen Modbus-Anfragen",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"If want to listen only at localhost use 127.0.0.1": "Wenn Sie nur auf localhost zuhören möchten, verwenden Sie 127.0.0.1",
|
|
19
19
|
"ms.port": "Modbus-Proxy-TCP-Port",
|
|
20
20
|
"The Modbus-proxy TCP port": "Der Modbus-Proxy-TCP-Port",
|
|
21
|
-
"The SDongle modbus ID": "Die SDongle-Modbus-ID
|
|
21
|
+
"The SDongle modbus ID": "Die SDongle-Modbus-ID – normalerweise 100",
|
|
22
22
|
"ms.log": "Erweiterte Protokollierung",
|
|
23
23
|
"Advanced logging": "Erweiterte Protokollierung von Modbus-Transaktionen",
|
|
24
24
|
"sl.meterId": "Modbus-ID des SmartLogger-Messgeräts",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"Update interval (sec)": "Update interval [sec]",
|
|
7
7
|
"The device ip address": "The device ip address",
|
|
8
8
|
"The modbus TCP port" : "The modbus TCP port",
|
|
9
|
-
"The modbus inverter IDs, separated with character ," : "
|
|
9
|
+
"The modbus inverter IDs, separated with character ," : "Inverter IDs, the master must be entered first, separated by ,",
|
|
10
10
|
"Update interval to update the values from the inverters" : "Update interval to update the values from the inverters",
|
|
11
11
|
"modbus connection timeout" : "modbus connection timeout",
|
|
12
12
|
"delay between modbus requests" : "delay between modbus requests",
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "sun2000",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.18.1",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.18.1": {
|
|
7
|
+
"en": "dependency and configuration updates\ncontrol: if the battery is not running, events related to the battery are discarded\nmodbus-proxy: adjusted advanced logging",
|
|
8
|
+
"de": "abhängigkeits- und konfigurationsupdates\nsteuerung: wenn die batterie nicht läuft, werden ereignisse im zusammenhang mit der batterie verworfen\nmodbus-proxy: angepasste erweiterte protokollierung",
|
|
9
|
+
"ru": "обновления зависимости и конфигурации\nуправление: если батарея не работает, события, связанные с батареей, отбрасываются\nmodbus-proxy: скорректированные передовые лесозаготовки",
|
|
10
|
+
"pt": "atualizações de dependência e configuração\ncontrole: se a bateria não estiver funcionando, os eventos relacionados à bateria são descartados\nmodbus-proxy: log avançado ajustado",
|
|
11
|
+
"nl": "afhankelijkheid en configuratie-updates\ncontrole: als de batterij niet draait, worden gebeurtenissen in verband met de batterij weggegooid\nmodbus-proxy: aangepaste geavanceerde logging",
|
|
12
|
+
"fr": "mises à jour de la dépendance et de la configuration\ncontrôle: si la batterie ne fonctionne pas, les événements liés à la batterie sont jetés\nmodbus-proxy: enregistrement avancé ajusté",
|
|
13
|
+
"it": "aggiornamenti di dipendenza e configurazione\ncontrollo: se la batteria non è in esecuzione, gli eventi relativi alla batteria vengono scartati\nmodbus-proxy: registrazione avanzata regolata",
|
|
14
|
+
"es": "actualizaciones de dependencia y configuración\ncontrol: si la batería no funciona, los eventos relacionados con la batería son descartados\nmodbus-proxy: registro avanzado ajustado",
|
|
15
|
+
"pl": "aktualizacje zależności i konfiguracji\nsterowanie: jeśli akumulator nie jest uruchomiony, zdarzenia związane z akumulatorem są odrzucane\nmodbus- proxy: dostosowane zaawansowane logowanie",
|
|
16
|
+
"uk": "оновлення залежності та конфігурації\nконтроль: якщо акумулятор не працює, події, пов'язані з акумулятором, відкидаються\nmodbus-proxy: регульований розширений журналювання",
|
|
17
|
+
"zh-cn": "依赖和配置更新\n控件: 如果电池没有运行, 与电池相关的事件会被丢弃\nmodbus-代用:经过调整的高级记录"
|
|
18
|
+
},
|
|
19
|
+
"0.18.0": {
|
|
20
|
+
"en": "dependency and configuration updates\nmodbus-proxy: the modbus ID 250 is mapped to ID 0",
|
|
21
|
+
"de": "abhängigkeits- und konfigurationsupdates\nmodbus-proxy: die modbus ID 250 wird auf ID 0 abgebildet",
|
|
22
|
+
"ru": "обновления зависимости и конфигурации\nmodbus-proxy: modbus ID 250 отображается на ID 0",
|
|
23
|
+
"pt": "atualizações de dependência e configuração\nmodbus-proxy: o modbus ID 250 é mapeado para ID 0",
|
|
24
|
+
"nl": "afhankelijkheid en configuratie-updates\nmodbus-proxy: de modbus ID 250 is toegewezen aan ID 0",
|
|
25
|
+
"fr": "mises à jour de la dépendance et de la configuration\nmodbus-proxy: le modbus ID 250 est mapé à ID 0",
|
|
26
|
+
"it": "aggiornamenti di dipendenza e configurazione\nmodbus-proxy: il modbus ID 250 è mappato su ID 0",
|
|
27
|
+
"es": "actualizaciones de dependencia y configuración\nmodbus-proxy: el modbus ID 250 se asigna al ID 0",
|
|
28
|
+
"pl": "aktualizacje zależności i konfiguracji\nmodbus- proxy: modbus ID 250 jest odwzorowany na ID 0",
|
|
29
|
+
"uk": "оновлення залежності та конфігурації\nmodbus-proxy: modbus ID 250 is mapped to ID 0",
|
|
30
|
+
"zh-cn": "依赖和配置更新\nmodbus-代用:modbus ID 250被映射到ID 0"
|
|
31
|
+
},
|
|
6
32
|
"0.17.1": {
|
|
7
33
|
"en": "during the device status \"Standby: detecting irradiation\" (0x0002) register data is now also read from the inverter\nThe reading order of the battery data has been adjusted",
|
|
8
34
|
"de": "während des Gerätestatus \"Standby: Detektion von Bestrahlung\" (0x0002) werden nun auch Registerdaten aus dem Wechselrichter gelesen\nDie Lesereihenfolge der Batteriedaten wurde angepasst",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "Dane SDongle nie zostały zapisane jako stany obiektu\nustawić ustawienia adaptera",
|
|
68
94
|
"uk": "Дані SDongle не були написані як об'єкти\nналаштування адаптера",
|
|
69
95
|
"zh-cn": "SDongle 数据没有作为对象状态写入\n调整适配器设置"
|
|
70
|
-
},
|
|
71
|
-
"0.15.0": {
|
|
72
|
-
"en": "dependency and configuration updates\ndisplay a clearly legible table bar #121\nmodbus-proxy write data also to the read cache #119",
|
|
73
|
-
"de": "abhängigkeits- und konfigurationsupdates\neine deutlich lesbare tischleiste #121 anzeigen\nmodbus-proxy schreibdaten auch zum lesespeicher #119",
|
|
74
|
-
"ru": "обновления зависимости и конфигурации\n#121\nmodbus-proxy пишут данные также кэшу #119",
|
|
75
|
-
"pt": "atualizações de dependência e configuração\nexibir uma barra de mesa claramente legível #121\nmodbus-proxy escrever dados também para o cache de leitura #119",
|
|
76
|
-
"nl": "afhankelijkheid en configuratie-updates\neen duidelijk leesbare tafelbalk #121 tonen\nmodbus-proxy schrijf gegevens ook naar de leescache #119",
|
|
77
|
-
"fr": "mises à jour de la dépendance et de la configuration\nafficher une barre de table clairement lisible #121\nmodbus-proxy écrire les données aussi au cache lecture #119",
|
|
78
|
-
"it": "aggiornamenti di dipendenza e configurazione\nvisualizza una barra da tavolo chiaramente leggibile #121\nmodbus-proxy scrivere i dati anche alla cache di lettura #119",
|
|
79
|
-
"es": "actualizaciones de dependencia y configuración\nmostrar una barra de mesa claramente legible #121\nmodbus-proxy escribe datos también al caché de lectura #119",
|
|
80
|
-
"pl": "aktualizacje zależności i konfiguracji\nwyświetla czytelny pasek tabeli # 121\nmodbus- proxy write data also to the read cache # 119",
|
|
81
|
-
"uk": "оновлення залежності та конфігурації\nдисплей чітко нижня білизна #121\nmodbus-proxy пише дані також для читання кеш #119",
|
|
82
|
-
"zh-cn": "依赖和配置更新\n显示清晰可见的表栏 # 121\nmodbus- 代理写入数据到读缓存 # 119"
|
|
83
|
-
},
|
|
84
|
-
"0.14.0": {
|
|
85
|
-
"en": "adjust for Responsive Design #121\nlock on asynchronous modbus code\nwriting data via the modbus-proxy #119\nread additional register data of Huawei Emma",
|
|
86
|
-
"de": "anpassung für Responsive Design #121\nasynchrone modbus-code blockieren\nschreiben von daten über die modbus-proxy #119\nweitere Registrierungsdaten von Huawei Emma lesen",
|
|
87
|
-
"ru": "#121\nзамок на асинхронном коде modbus\nзаписи данных через modbus-proxy #119\nпрочитать дополнительные данные реестра Huawei Эмма",
|
|
88
|
-
"pt": "ajustar para Design responsivo #121\nbloqueio no código modbus assíncrono\nescrever dados através do modbus-proxy #119\nleia dados de registro adicionais de Huawei Emma",
|
|
89
|
-
"nl": "aanpassen voor Responsive Design #121\nvergrendelen op asynchrone modbus-code\nschrijven van gegevens via de modbus-proxy #119\nlees extra registergegevens van Huawei Emma",
|
|
90
|
-
"fr": "ajuster pour Responsive Design #121\nverrouillage du code modbus asynchrone\nécrire des données via le modbus-proxy #119\nlire les données supplémentaires du registre de Huawei Emma",
|
|
91
|
-
"it": "regolazione per Responsive Design #121\nblocco su codice modbus asincrono\ndati di scrittura tramite il modbus-proxy #119\nleggere ulteriori dati di registro di Huawei Emma",
|
|
92
|
-
"es": "ajuste para el diseño responsable #121\nbloqueo en código modbus asincrónico\nescribir datos a través del modbus-proxy #119\nleer más datos de registro de Huawei Emma",
|
|
93
|
-
"pl": "dostosowanie do projektu Responsive Design # 121\nblokada asynchronicznego kodu modbusa\nzapisywanie danych za pośrednictwem modbus- proxy # 119\nprzeczytaj dodatkowe dane rejestru Huawei Emma",
|
|
94
|
-
"uk": "регульований для відповідального дизайну #121\nблокування на коді asynchronous modbus\nнаписання даних через modbus-proxy #119\nчитати додаткові реєстраційні дані Huawei Emma",
|
|
95
|
-
"zh-cn": "适应设计 # 121\n锁定同步调制解码\n通过modbus- 代理 119 写入数据\n读取 Huawei Emma 的额外注册数据"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -139,12 +139,6 @@ class ServiceQueueMap {
|
|
|
139
139
|
return await this._writeRegisters(47249,dataType.numToArray(event.value,dataType.uint32));
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
|
-
/*
|
|
143
|
-
{
|
|
144
|
-
state: { id: 'battery.targetSOC ', name: 'Target SOC', type: 'number', unit: '%', role: 'level', desc: 'reg: 47101 , len: 1'},
|
|
145
|
-
type : deviceType.gridPowerControl
|
|
146
|
-
},
|
|
147
|
-
*/
|
|
148
142
|
{
|
|
149
143
|
state: { id: 'battery.targetSOC', name: 'Target SOC', type: 'number', unit: '%', role: 'level', desc: 'reg: 47101 , len: 1'},
|
|
150
144
|
type : deviceType.battery,
|
|
@@ -242,7 +236,7 @@ class ServiceQueueMap {
|
|
|
242
236
|
if (this.inverterInfo.instance) {
|
|
243
237
|
for (const item of this.serviceFields) {
|
|
244
238
|
//no battery - no controls
|
|
245
|
-
if (item.type == deviceType.battery && this.inverterInfo.instance.numberBatteryUnits() === 0) continue;
|
|
239
|
+
//if (item.type == deviceType.battery && this.inverterInfo.instance.numberBatteryUnits() === 0) continue;
|
|
246
240
|
if (item.type == deviceType.meter && !this.inverterInfo?.meter) continue;
|
|
247
241
|
if (item.type == deviceType.gridPowerControl && !this.inverterInfo?.meter) continue;
|
|
248
242
|
if (item?.state) {
|
|
@@ -259,7 +253,7 @@ class ServiceQueueMap {
|
|
|
259
253
|
this.set(entry.state.id,state);
|
|
260
254
|
}
|
|
261
255
|
}
|
|
262
|
-
|
|
256
|
+
//upgrade
|
|
263
257
|
const tSOC = await this.adapter.getState(this.inverterInfo.path+'.control.battery.targetSOC ');
|
|
264
258
|
if (tSOC) {
|
|
265
259
|
await this.adapter.delObject(this.inverterInfo.path+'.control.battery.targetSOC ',{ recursive: false });
|
|
@@ -286,10 +280,14 @@ class ServiceQueueMap {
|
|
|
286
280
|
tCDP[3] = 383 - Working mode settings - self-consumption (discharge)
|
|
287
281
|
*/
|
|
288
282
|
const tCDP = [1,0,1440,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
|
289
|
-
if (await this._writeRegisters(47255,tCDP)) this.
|
|
283
|
+
if (await this._writeRegisters(47255,tCDP)) this.log.info('Control: The default TOU setting are transferred');
|
|
290
284
|
}
|
|
291
285
|
}
|
|
292
286
|
}
|
|
287
|
+
|
|
288
|
+
if (this._initialized) {
|
|
289
|
+
this.log.info('Control: Service queue initialized');
|
|
290
|
+
}
|
|
293
291
|
}
|
|
294
292
|
|
|
295
293
|
get(id) {
|
|
@@ -316,8 +314,12 @@ class ServiceQueueMap {
|
|
|
316
314
|
return this._map.values();
|
|
317
315
|
}
|
|
318
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Processes the events in the eventMap. For each event, it calls the associated function in the serviceMap.
|
|
319
|
+
* @param {ModbusClient} modbusClient - The modbus client to use for writing the states.
|
|
320
|
+
*/
|
|
319
321
|
async process(modbusClient) {
|
|
320
|
-
if (!this.inverterInfo.instance.modbusAllowed) return;
|
|
322
|
+
//if (!this.inverterInfo.instance.modbusAllowed) return;
|
|
321
323
|
this._modbusClient = modbusClient;
|
|
322
324
|
|
|
323
325
|
if (this._initialized) {
|
|
@@ -326,8 +328,24 @@ class ServiceQueueMap {
|
|
|
326
328
|
if (event.ack) continue; //allready done
|
|
327
329
|
const service = this._serviceMap.get(event.id);
|
|
328
330
|
if(!service.errorCount) service.errorCount = 0;
|
|
329
|
-
|
|
330
331
|
if (event.value !== null && service.fn) {
|
|
332
|
+
//check if battery is present and running
|
|
333
|
+
if (service.type == deviceType.battery) {
|
|
334
|
+
if (this.inverterInfo.instance.numberBatteryUnits() === 0) {
|
|
335
|
+
this.log.warn(`Control: Event is discarded because no battery has been detected. `);
|
|
336
|
+
if (!this.adapter.isReady) {
|
|
337
|
+
this.log.warn('Control: The Adapter is not ready! Please check the value in the state sun2000.x.info.JSONhealth and the Log output.');
|
|
338
|
+
}
|
|
339
|
+
this._eventMap.delete(event.id); //forget the event
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
const BatStatus = this.inverterInfo.instance.stateCache.get(this.inverterInfo.path+'.battery.runningStatus')?.value;
|
|
343
|
+
if (BatStatus !== 'RUNNING' && BatStatus !== 'STANDBY' && BatStatus !== '') {
|
|
344
|
+
this.log.warn(`Control: Event is discarded because battery is not running. State: ${this.inverterInfo.path}.battery.runningStatus = ${BatStatus}. `);
|
|
345
|
+
this._eventMap.delete(event.id); //forget the event
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
331
349
|
count ++;
|
|
332
350
|
if (await service.fn(event)) {
|
|
333
351
|
service.errorCount = 0;
|
|
@@ -347,10 +365,11 @@ class ServiceQueueMap {
|
|
|
347
365
|
}
|
|
348
366
|
}
|
|
349
367
|
}
|
|
350
|
-
if (count > 1) break; //max 2
|
|
368
|
+
if (count > 1) break; //max 2 Events
|
|
351
369
|
}
|
|
352
370
|
}
|
|
353
|
-
if (!this._initialized && this.adapter.isReady) await this._init();
|
|
371
|
+
//if (!this._initialized && this.adapter.isReady) await this._init();
|
|
372
|
+
if (!this._initialized && this.adapter.isConnected) await this._init();
|
|
354
373
|
}
|
|
355
374
|
|
|
356
375
|
async _writeRegisters(address,data) {
|
|
@@ -969,9 +969,14 @@ class InverterSun2000 extends DriverBase{
|
|
|
969
969
|
}
|
|
970
970
|
}
|
|
971
971
|
|
|
972
|
-
|
|
972
|
+
/**
|
|
973
|
+
* #overload#
|
|
974
|
+
* Get the number of battery units.
|
|
975
|
+
* @returns {number} The number of battery units
|
|
976
|
+
*/
|
|
973
977
|
numberBatteryUnits() {
|
|
974
978
|
let units = 0;
|
|
979
|
+
//Check if the first battery unit exists
|
|
975
980
|
const state1 = this.stateCache.get(`${this.deviceInfo.path}.battery.unit.1.SN`);
|
|
976
981
|
if (state1 && state1.value) units = 1;
|
|
977
982
|
const state2 = this.stateCache.get(`${this.deviceInfo.path}.battery.unit.2.SN`);
|
|
@@ -114,6 +114,10 @@ class ModbusServer {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Close the Modbus-proxy server.
|
|
119
|
+
* @returns {Promise<void>}
|
|
120
|
+
*/
|
|
117
121
|
close() {
|
|
118
122
|
return new Promise((resolve) => {
|
|
119
123
|
this._isConnected = false;
|
|
@@ -128,9 +132,15 @@ class ModbusServer {
|
|
|
128
132
|
});
|
|
129
133
|
}
|
|
130
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Finds the device instance (like InverterInfo) for a given modbus unitId.
|
|
137
|
+
* @param {number} unitId the modbus unitId
|
|
138
|
+
* @returns {InverterInfo|undefined} the device instance or undefined
|
|
139
|
+
*/
|
|
131
140
|
getDeviceInstance(unitId) {
|
|
132
141
|
for (const device of this.adapter.devices) {
|
|
133
142
|
if (device.instance) {
|
|
143
|
+
if (unitId === 250 && device.instance?.modbusId === 0) return device.instance;
|
|
134
144
|
if (device.instance?.modbusId === unitId) return device.instance;
|
|
135
145
|
}
|
|
136
146
|
}
|
|
@@ -143,6 +153,10 @@ class ModbusServer {
|
|
|
143
153
|
if (device) {
|
|
144
154
|
//this.adapter.log.debug('Device Info '+JSON.stringify(device?.info));
|
|
145
155
|
const values = device.getHoldingRegisters(startAddr,length);
|
|
156
|
+
if (this.adapter.settings.ms.log) {
|
|
157
|
+
this.log.info('Modbus-proxy: read data from id/address/data ' + unitId + '/' + startAddr +'/'+ values);
|
|
158
|
+
}
|
|
159
|
+
|
|
146
160
|
if (!this.adapter.isConnected) {
|
|
147
161
|
//this._addInfoStat('#WaitForConnected',startAddr, length, unitId);
|
|
148
162
|
await this.wait(500);
|
|
@@ -170,8 +184,12 @@ class ModbusServer {
|
|
|
170
184
|
}
|
|
171
185
|
|
|
172
186
|
async _handleSetReg(fnName,address, data, unitId, callback) {
|
|
173
|
-
|
|
187
|
+
if (this.adapter.settings.ms.log) {
|
|
188
|
+
this.log.info('Modbus-proxy: Try to write data to id/address ' + unitId + '/' + address +'/'+ data);
|
|
189
|
+
} else {
|
|
174
190
|
this.log.debug('Modbus-proxy: Try to write data to id/address ' + unitId + '/' + address +'/'+ data);
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
175
193
|
const device = this.getDeviceInstance(unitId);
|
|
176
194
|
if (!device) {
|
|
177
195
|
await this.wait(500);
|
package/main.js
CHANGED
|
@@ -279,7 +279,7 @@ class Sun2000 extends utils.Adapter {
|
|
|
279
279
|
this.settings.highInterval = 10000*this.settings.modbusIds.length;
|
|
280
280
|
} else {
|
|
281
281
|
let minInterval = this.settings.modbusIds.length*this.settings.modbusDelay*2.5; //len*5*delay/2
|
|
282
|
-
if (this.settings.integration > 0) { //SmartLogger
|
|
282
|
+
if (this.settings.integration > 0) { //SmartLogger, Emma
|
|
283
283
|
minInterval += 5000;
|
|
284
284
|
} else {
|
|
285
285
|
for (const device of this.devices) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.sun2000",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "sun2000",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bolliy",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node": ">= 18.18.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@iobroker/adapter-core": "^3.2.
|
|
30
|
+
"@iobroker/adapter-core": "^3.2.3",
|
|
31
31
|
"modbus-serial": "^8.0.17",
|
|
32
32
|
"suncalc2": "^1.8.1",
|
|
33
33
|
"tcp-port-used": "^1.0.2"
|
|
@@ -37,27 +37,27 @@
|
|
|
37
37
|
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
|
|
38
38
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
39
39
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
40
|
-
"@eslint/eslintrc": "^3.
|
|
40
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
41
41
|
"@eslint/js": "^9.14.0",
|
|
42
42
|
"@iobroker/adapter-dev": "^1.3.0",
|
|
43
43
|
"@iobroker/testing": "^5.0.0",
|
|
44
44
|
"@tsconfig/node16": "^16.1.3",
|
|
45
45
|
"@types/chai": "^4.3.20",
|
|
46
46
|
"@types/chai-as-promised": "^7.1.8",
|
|
47
|
-
"@types/mocha": "^10.0.
|
|
48
|
-
"@types/node": "^22.
|
|
47
|
+
"@types/mocha": "^10.0.10",
|
|
48
|
+
"@types/node": "^22.10.5",
|
|
49
49
|
"@types/proxyquire": "^1.3.31",
|
|
50
50
|
"@types/sinon": "^17.0.3",
|
|
51
51
|
"@types/sinon-chai": "^3.2.12",
|
|
52
52
|
"chai": "^4.5.0",
|
|
53
53
|
"chai-as-promised": "^7.1.2",
|
|
54
|
-
"eslint": "^9.
|
|
55
|
-
"globals": "^15.
|
|
56
|
-
"mocha": "^
|
|
54
|
+
"eslint": "^9.17.0",
|
|
55
|
+
"globals": "^15.14.0",
|
|
56
|
+
"mocha": "^11.0.1",
|
|
57
57
|
"proxyquire": "^2.1.3",
|
|
58
58
|
"sinon": "^19.0.2",
|
|
59
59
|
"sinon-chai": "^3.7.0",
|
|
60
|
-
"typescript": "~5.
|
|
60
|
+
"typescript": "~5.7.2"
|
|
61
61
|
},
|
|
62
62
|
"main": "main.js",
|
|
63
63
|
"files": [
|