iobroker.sun2000 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,6 +44,7 @@ browse in the [wiki](https://github.com/bolliy/ioBroker.sun2000/wiki)
44
44
  * HUAWEI Luna2000 Battery
45
45
  * HUAWEI Smart Power Sensor DTSU666-H or DDSU666-H
46
46
  * HUAWEI Smart Logger / min. Softwareversion: V300R023C10SPC311
47
+ * HUAWEI EMMA / min. Softwareversion: V100R024C00SPC101
47
48
 
48
49
  ## Feature list
49
50
 
@@ -56,7 +57,7 @@ browse in the [wiki](https://github.com/bolliy/ioBroker.sun2000/wiki)
56
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.
57
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.
58
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.
59
- * Huawei [`Emma`]()
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
61
 
61
62
  ## Changelog
62
63
 
@@ -64,10 +65,21 @@ browse in the [wiki](https://github.com/bolliy/ioBroker.sun2000/wiki)
64
65
  Placeholder for the next version (at the beginning of the line):
65
66
  ### **WORK IN PROGRESS**
66
67
  -->
68
+ ### 0.15.0 (2024-10-24)
69
+ * dependency and configuration updates
70
+ * display a clearly legible table bar #121
71
+ * modbus-proxy write data also to the read cache #119
72
+
73
+ ### 0.14.0 (2024-10-20)
74
+ * adjust for Responsive Design #121
75
+ * lock on asynchronous modbus code
76
+ * writing data ​​via the modbus-proxy #119
77
+ * read additional register data of Huawei Emma
78
+
67
79
  ### 0.13.0 (2024-10-11)
68
80
  * improve Modbus reconnection #116
69
81
  * configuration update
70
- * simple Integration of Huawei Emma (Huawei Energy Management Assistant) #63
82
+ * initial Integration of Huawei Emma (Huawei Energy Management Assistant) #63
71
83
 
72
84
  ### 0.12.1 (2024-09-29)
73
85
  * no warning from check the valid number during standby: "no irradiation"
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "i18n": true,
3
3
  "type": "tabs",
4
+ "tabsStyle": {
5
+ "width": "calc(100% - 100px)"
6
+ },
4
7
  "items": {
5
8
  "mainTab": {
6
9
  "type": "panel",
@@ -15,7 +18,12 @@
15
18
  "label": "label",
16
19
  "href" : "https://www.paypal.com/donate/?hosted_button_id=ZTX3VP9LZBDCG",
17
20
  "src" : "paypal-button.png",
18
- "newLine": true
21
+ "newLine": true,
22
+ "xs": 8,
23
+ "sm": 10,
24
+ "md": 2,
25
+ "lg": 2,
26
+ "xl": 2
19
27
  },
20
28
  "mainHdr1": {
21
29
  "newLine": true,
@@ -26,9 +34,13 @@
26
34
  "integration": {
27
35
  "type": "select",
28
36
  "label": "Huawei Device Integration",
29
- "options":[{"label": "Only Inverter(s)", "value":0}, {"label": "SmartLogger (monitors and manages PV and energy storage systems)", "value":1},{"label": "EMMA (Huawei Energy Management Assistant)", "value":2}],
37
+ "options":[{"label": "SDongle (communication expansion module)", "value":0}, {"label": "SmartLogger (monitors and manages PV and energy storage systems)", "value":1},{"label": "EMMA (Huawei Energy Management Assistant)", "value":2}],
38
+ "newLine": true,
39
+ "xs": 12,
40
+ "sm": 12,
41
+ "md": 6,
30
42
  "lg": 4,
31
- "newLine": true
43
+ "xl": 4
32
44
  },
33
45
  "mainHdr2": {
34
46
  "newLine": true,
@@ -40,10 +52,12 @@
40
52
  "type": "text",
41
53
  "label": "address",
42
54
  "tooltip": "The device ip address",
55
+ "newLine": true,
56
+ "xs": 12,
43
57
  "sm": 12,
44
- "md": 8,
45
- "lg": 2,
46
- "newLine": true
58
+ "md": 6,
59
+ "lg": 4,
60
+ "xl": 4
47
61
  },
48
62
  "port": {
49
63
  "type": "number",
@@ -52,17 +66,24 @@
52
66
  "max" : 655565,
53
67
  "default": 502,
54
68
  "newLine": true,
55
- "tooltip": "The modbus TCP port"
69
+ "tooltip": "The modbus TCP port",
70
+ "xs": 12,
71
+ "sm": 12,
72
+ "md": 6,
73
+ "lg": 4,
74
+ "xl": 4
56
75
  },
57
76
  "modbusIds": {
58
77
  "type": "text",
59
78
  "label": "Modbus inverter IDs",
60
- "sm": 12,
61
- "md": 8,
62
- "lg": 2,
63
79
  "default": "1",
64
80
  "newLine": true,
65
- "tooltip": "The modbus inverter IDs, separated with character ,"
81
+ "tooltip": "The modbus inverter IDs, separated with character ,",
82
+ "xs": 12,
83
+ "sm": 12,
84
+ "md": 6,
85
+ "lg": 4,
86
+ "xl": 4
66
87
  },
67
88
  "updateInterval": {
68
89
  "type": "number",
@@ -71,7 +92,12 @@
71
92
  "max" : 120,
72
93
  "default": 20,
73
94
  "newLine": true,
74
- "tooltip": "Update interval to update the values from the inverters"
95
+ "tooltip": "Update interval to update the values from the devices",
96
+ "xs": 12,
97
+ "sm": 12,
98
+ "md": 6,
99
+ "lg": 4,
100
+ "xl": 4
75
101
  }
76
102
  }
77
103
  },
@@ -94,13 +120,22 @@
94
120
  "type": "checkbox",
95
121
  "label": "sd.active",
96
122
  "newLine": true,
97
- "tooltip": "SDongle active"
123
+ "tooltip": "SDongle active",
124
+ "xs": 12,
125
+ "sm": 12,
126
+ "md": 6,
127
+ "lg": 4,
128
+ "xl": 4
98
129
  },
99
130
  "sDongleId": {
100
131
  "type": "text",
101
132
  "label": "SDongleA modbus ID",
102
- "lg": 2,
103
- "newLine": true
133
+ "newLine": true,
134
+ "xs": 12,
135
+ "sm": 12,
136
+ "md": 6,
137
+ "lg": 4,
138
+ "xl": 4
104
139
  },
105
140
  "mainHdr2": {
106
141
  "newLine": true,
@@ -111,9 +146,13 @@
111
146
  "sl_meterId": {
112
147
  "type": "text",
113
148
  "label": "sl.meterId",
114
- "lg": 2,
115
149
  "newLine": true,
116
- "tooltip": "The Meter modbus ID"
150
+ "tooltip": "The Meter modbus ID",
151
+ "xs": 12,
152
+ "sm": 12,
153
+ "md": 6,
154
+ "lg": 4,
155
+ "xl": 4
117
156
  },
118
157
  "mainHdr3": {
119
158
  "newLine": true,
@@ -147,32 +186,45 @@
147
186
  "type": "checkbox",
148
187
  "label": "ms.aktive",
149
188
  "newLine": true,
150
- "tooltip": "Modbus-proxy via TCP for read-only is active"
189
+ "tooltip": "Modbus-proxy via TCP is active",
190
+ "xs": 12,
191
+ "sm": 12,
192
+ "md": 6,
193
+ "lg": 4,
194
+ "xl": 4
151
195
  },
152
196
  "ms_address": {
153
197
  "type": "text",
154
198
  "label": "ms.address",
155
199
  "newLine": true,
156
200
  "tooltip": "If want to listen only at localhost use 127.0.0.1",
201
+ "xs": 12,
157
202
  "sm": 12,
158
- "md": 8,
159
- "lg": 2
203
+ "md": 6,
204
+ "lg": 4,
205
+ "xl": 4
160
206
  },
161
207
  "ms_port": {
162
208
  "type": "port",
163
209
  "label": "ms.port",
164
- "sm":3,
165
- "md":3,
166
- "lg":2,
167
- "xs":3,
168
210
  "newLine": true,
169
- "tooltip" : "The Modbus-proxy TCP port"
211
+ "tooltip" : "The Modbus-proxy TCP port",
212
+ "xs": 12,
213
+ "sm": 12,
214
+ "md": 6,
215
+ "lg": 4,
216
+ "xl": 4
170
217
  },
171
218
  "ms_log": {
172
219
  "type": "checkbox",
173
220
  "label": "ms.log",
174
221
  "newLine": true,
175
- "tooltip": "Advanced logging"
222
+ "tooltip": "Advanced logging",
223
+ "xs": 12,
224
+ "sm": 12,
225
+ "md": 6,
226
+ "lg": 4,
227
+ "xl": 4
176
228
  }
177
229
  }
178
230
  },
@@ -188,14 +240,19 @@
188
240
  },
189
241
  "chipsTxt1": {
190
242
  "type": "staticText",
191
- "text": "This control is set in the opject path sun2000.0.inverter.x.control.battery",
243
+ "text": "This control is set in the opject path `sun2000.0.inverter.x.control.battery`",
192
244
  "newLine": true
193
245
  },
194
246
  "cb_tou": {
195
247
  "type": "checkbox",
196
248
  "label": "Create default TOU setting",
197
249
  "newLine": true,
198
- "help": "The default TOU settings is interesting for the force battery charging from the grid function, which is required for variable energy prices."
250
+ "help": "The `default TOU settings` is interesting for the `force battery charging from the grid` function, which is required for variable energy prices.",
251
+ "xs": 12,
252
+ "sm": 12,
253
+ "md": 6,
254
+ "lg": 4,
255
+ "xl": 4
199
256
  },
200
257
  "staticLink1": {
201
258
  "type": "staticLink",
@@ -203,7 +260,12 @@
203
260
  "href": "https://github.com/bolliy/ioBroker.sun2000/wiki/Battery-control",
204
261
  "button": true,
205
262
  "icon": "info",
206
- "newLine": true
263
+ "newLine": true,
264
+ "xs": 12,
265
+ "sm": 12,
266
+ "md": 6,
267
+ "lg": 3,
268
+ "xl": 3
207
269
  },
208
270
  "mainHdr2": {
209
271
  "newLine": true,
@@ -213,7 +275,7 @@
213
275
  },
214
276
  "chipsTxt2": {
215
277
  "type": "staticText",
216
- "text": "This control is set in the opject path sun2000.0.inverter.x.control.battery",
278
+ "text": "This control is set in the opject path `sun2000.0.inverter.x.control.battery`",
217
279
  "newLine": true
218
280
  },
219
281
  "staticLink2": {
@@ -222,7 +284,12 @@
222
284
  "href": "https://github.com/bolliy/ioBroker.sun2000/wiki/Erzwungenes-Laden-und-Entladen-der-Batterie-(Force-charge-discharge-battery)",
223
285
  "button": true,
224
286
  "icon": "info",
225
- "newLine": true
287
+ "newLine": true,
288
+ "xs": 12,
289
+ "sm": 12,
290
+ "md": 6,
291
+ "lg": 3,
292
+ "xl": 3
226
293
  },
227
294
  "mainHdr3": {
228
295
  "newLine": true,
@@ -232,7 +299,7 @@
232
299
  },
233
300
  "chipsTxt3": {
234
301
  "type": "staticText",
235
- "text": "This control is set in the opject path sun2000.0.inverter.0.control.grid",
302
+ "text": "This control is set in the opject path `sun2000.0.inverter.0.control.grid`",
236
303
  "newLine": true
237
304
  },
238
305
  "staticLink3": {
@@ -241,7 +308,12 @@
241
308
  "href": "https://github.com/bolliy/ioBroker.sun2000/wiki/Begrenzung-Netzeinspeisung-(Export-Control)",
242
309
  "button": true,
243
310
  "icon": "info",
244
- "newLine": true
311
+ "newLine": true,
312
+ "xs": 12,
313
+ "sm": 12,
314
+ "md": 6,
315
+ "lg": 3,
316
+ "xl": 3
245
317
  }
246
318
  }
247
319
  },
@@ -259,13 +331,23 @@
259
331
  "type": "checkbox",
260
332
  "label": "battery units",
261
333
  "newLine": true,
262
- "help": "This register data is stored in the opject path sun2000.x.inverter.x.battery.unit"
334
+ "help": "This register data is stored in the opject path `sun2000.x.inverter.x.battery.unit`",
335
+ "xs": 12,
336
+ "sm": 12,
337
+ "md": 6,
338
+ "lg": 4,
339
+ "xl": 4
263
340
  },
264
341
  "ds_bp": {
265
342
  "type": "checkbox",
266
343
  "label": "battery packs",
267
344
  "newLine": true,
268
- "help": "This register data is stored in the opject path sun2000.x.inverter.x.battery.unit.x.pack"
345
+ "help": "This register data is stored in the opject path `sun2000.x.inverter.x.battery.unit.x.pack`",
346
+ "xs": 12,
347
+ "sm": 12,
348
+ "md": 6,
349
+ "lg": 4,
350
+ "xl": 4
269
351
  }
270
352
  }
271
353
  },
@@ -285,7 +367,12 @@
285
367
  "min" : 5000,
286
368
  "max" : 30000,
287
369
  "newLine": true,
288
- "tooltip": "modbus connection timeout"
370
+ "tooltip": "Modbus connection timeout",
371
+ "xs": 12,
372
+ "sm": 12,
373
+ "md": 6,
374
+ "lg": 4,
375
+ "xl": 4
289
376
  },
290
377
  "delay": {
291
378
  "type": "number",
@@ -293,7 +380,12 @@
293
380
  "min" : 0,
294
381
  "max" : 6000,
295
382
  "newLine": true,
296
- "tooltip": "delay between modbus requests"
383
+ "tooltip": "Delay between modbus requests",
384
+ "xs": 12,
385
+ "sm": 12,
386
+ "md": 6,
387
+ "lg": 4,
388
+ "xl": 4
297
389
  },
298
390
  "connectDelay": {
299
391
  "type": "number",
@@ -301,13 +393,23 @@
301
393
  "min" : 2000,
302
394
  "max" : 10000,
303
395
  "newLine": true,
304
- "tooltip": "delay after modbus connected"
396
+ "tooltip": "Delay after modbus connected",
397
+ "xs": 12,
398
+ "sm": 12,
399
+ "md": 6,
400
+ "lg": 4,
401
+ "xl": 4
305
402
  },
306
403
  "autoAdjust": {
307
404
  "type": "checkbox",
308
405
  "label": "auto-adjust",
309
406
  "newLine": true,
310
- "tooltip": "automatic adjustment of the modbus settings"
407
+ "tooltip": "Automatic adjustment of the modbus settings",
408
+ "xs": 12,
409
+ "sm": 12,
410
+ "md": 6,
411
+ "lg": 4,
412
+ "xl": 4
311
413
  }
312
414
  }
313
415
  },
@@ -332,7 +434,12 @@
332
434
  "href": "https://github.com/bolliy/ioBroker.sun2000/wiki/Hilfe-(support)",
333
435
  "icon": "info",
334
436
  "button": true,
335
- "newLine": true
437
+ "newLine": true,
438
+ "xs": 12,
439
+ "sm": 12,
440
+ "md": 6,
441
+ "lg": 3,
442
+ "xl": 3
336
443
  }
337
444
  }
338
445
  }
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "sun2000",
4
- "version": "0.13.0",
4
+ "version": "0.15.0",
5
5
  "news": {
6
+ "0.15.0": {
7
+ "en": "dependency and configuration updates\ndisplay a clearly legible table bar #121\nmodbus-proxy write data also to the read cache #119",
8
+ "de": "abhängigkeits- und konfigurationsupdates\neine deutlich lesbare tischleiste #121 anzeigen\nmodbus-proxy schreibdaten auch zum lesespeicher #119",
9
+ "ru": "обновления зависимости и конфигурации\n#121\nmodbus-proxy пишут данные также кэшу #119",
10
+ "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",
11
+ "nl": "afhankelijkheid en configuratie-updates\neen duidelijk leesbare tafelbalk #121 tonen\nmodbus-proxy schrijf gegevens ook naar de leescache #119",
12
+ "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",
13
+ "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",
14
+ "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",
15
+ "pl": "aktualizacje zależności i konfiguracji\nwyświetla czytelny pasek tabeli # 121\nmodbus- proxy write data also to the read cache # 119",
16
+ "uk": "оновлення залежності та конфігурації\nдисплей чітко нижня білизна #121\nmodbus-proxy пише дані також для читання кеш #119",
17
+ "zh-cn": "依赖和配置更新\n显示清晰可见的表栏 # 121\nmodbus- 代理写入数据到读缓存 # 119"
18
+ },
19
+ "0.14.0": {
20
+ "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",
21
+ "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",
22
+ "ru": "#121\nзамок на асинхронном коде modbus\nзаписи данных через modbus-proxy #119\nпрочитать дополнительные данные реестра Huawei Эмма",
23
+ "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",
24
+ "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",
25
+ "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",
26
+ "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",
27
+ "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",
28
+ "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",
29
+ "uk": "регульований для відповідального дизайну #121\nблокування на коді asynchronous modbus\nнаписання даних через modbus-proxy #119\nчитати додаткові реєстраційні дані Huawei Emma",
30
+ "zh-cn": "适应设计 # 121\n锁定同步调制解码\n通过modbus- 代理 119 写入数据\n读取 Huawei Emma 的额外注册数据"
31
+ },
6
32
  "0.13.0": {
7
33
  "en": "improve Modbus reconnection #116\nconfiguration update\nsimple Integration of Huawei Emma (Huawei Energy Management Assistant) #63",
8
34
  "de": "modbus-Reconnection #116 verbessern\nkonfigurationsupdate\neinfache Integration von Huawei Emma (Huawei Energy Management Assistant) #63",
@@ -67,32 +93,6 @@
67
93
  "pl": "aktualizacje zależności i konfiguracji\ndostosować role w ścieżce sterowania\nKontrola baterii: dodać zasilanie awaryjne SOC # 84\nfix: błędna nazwa stanu 'control.battery.ActivitSOC' z przepustnicą",
68
94
  "uk": "оновлення залежності та конфігурації\nрегулювання ролі в шляху управління\nКонтроль акумулятора: додаємо резервну потужність SOC #84\nвиправити: неправильне ім'я держави `control.battery.targetSOC` з причепом",
69
95
  "zh-cn": "依赖和配置更新\n调整控制路径中的角色\n电池控制: 添加备份功率 SOC #84\n修补:错误的州名`control.battery.targetSOC ' ,带有后端空间"
70
- },
71
- "0.9.0": {
72
- "en": "dependency and configuration updates\nmodbus device remains active in standby on the inverter M2,M3",
73
- "de": "abhängigkeits- und konfigurationsupdates\nmodbus-Gerät bleibt im Standby am Wechselrichter M2,M3 aktiv",
74
- "ru": "обновления зависимости и конфигурации\nmodbus device остается активным в режиме ожидания на инверторе M2,M3",
75
- "pt": "atualizações de dependência e configuração\ndispositivo modbus permanece ativo em espera no inversor M2, M3",
76
- "nl": "afhankelijkheid en configuratie-updates\nmodbus apparaat blijft actief in stand-by op de omvormer M2,M3",
77
- "fr": "mises à jour de la dépendance et de la configuration\nmodbus reste actif en veille sur l'onduleur M2,M3",
78
- "it": "aggiornamenti di dipendenza e configurazione\ndispositivo modbus rimane attivo in standby sull'inverter M2,M3",
79
- "es": "actualizaciones de dependencia y configuración\ndispositivo modbus permanece activo en espera en el inversor M2,M3",
80
- "pl": "aktualizacje zależności i konfiguracji\nurządzenie modbus pozostaje aktywne w gotowości na falowniku M2, M3",
81
- "uk": "оновлення залежності та конфігурації\nмотузковий пристрій залишається активним в автономному режимі на інверторі M2,M3",
82
- "zh-cn": "依赖和配置更新\nmodbus设备仍然在反转器M2,M3上处于待机状态"
83
- },
84
- "0.8.0": {
85
- "en": "Check numerical values for plausibility #75\nrealization the \"limit the power fed to grid\" (Export control)\nrealization the \"forcible Charge or Discharge Power\"\nIf the error 'ECONNRESET' appear, the modbus proxy should not terminate",
86
- "de": "Zahlenwerte für Plausibilität prüfen #75\nrealisierung der \"begrenzt die Stromzufuhr zum Netz\" (Exportsteuerung)\nrealisierung der \"forcible Charge or Discharge Power\"\nWenn der Fehler 'ECONNRESET' angezeigt wird, sollte der Modbus-Proxy nicht enden",
87
- "ru": "Проверьте численные значения правдоподобности #75\nреализация «ограничения мощности, подаваемой в сетку» (Export control)\nреализация «сильной зарядки или выдающейся силы»\nЕсли появляется ошибка \"ECONNRESET\", то прокси-модуль не должен прекращать",
88
- "pt": "Verificar valores numéricos para plausibilidade #75\nrealização do \"limite o poder alimentado à grade\" (controle de exportação)\nrealização do \"poder de carga ou descarga forcível\"\nSe o erro 'ECONNRESET' aparecer, o proxy modbus não deve terminar",
89
- "nl": "Numerieke waarden controleren op plausibiliteit #75\nrealisatie van de \"limit the power feed to grid\" (Export control)\nrealisatie van de \"forcible charge or discharge power\"\nAls de fout 'ECONNRESET' verschijnt, moet de modbus-proxy niet worden beëindigd",
90
- "fr": "Vérifier les valeurs numériques pour la plausibilité #75\nréalisation de la \"limite de la puissance alimentée au réseau\" (contrôle des exportations)\nréalisation de la \"puissance de charge ou de décharge forcée\"\nSi l'erreur 'ECONNESET' apparaît, le proxy modbus ne doit pas se terminer",
91
- "it": "Controlla i valori numerici per la plausibilità #75\nrealizzazione del \"limite la potenza alimentata alla griglia\" (Controllo dell'esportazione)\nrealizzazione del \"Forcible Charge or Discharge Power\"\nSe viene visualizzato l'errore 'ECONNRESET', il proxy modbus non deve terminare",
92
- "es": "Compruebe los valores numéricos para la plausibilidad #75\nrealización del \"limitar el poder alimentado a la red\" (Control de exportación)\nrealización del \"poder de carga forzosa o descarga\"\nSi aparece el error 'ECONNRESET', el modbus proxy no debe terminar",
93
- "pl": "Sprawdź wartości numeryczne pod względem wiarygodności # 75\nrealizacja \"ograniczenie mocy zasilanej do siatki\" (Kontrola eksportu)\nrealizacja \"mocy ładowania lub wyładowania\"\nJeśli pojawi się błąd 'ECONNRESET', proxy modbusa nie powinny kończyć",
94
- "uk": "Перевірити чисельні значення для плати #75\nреалізація \"випуску потужності, що надходить до сітки\"\nреалізація \"потужного заряду або розряду\"\nЯкщо з'явиться помилка «ЕКОНРЕСЕТ», то модбус не повинен припинити",
95
- "zh-cn": "请检查archive-date=中的日期值 (帮助) 75\n实现“将供电限制在网格上”(出口管制)\n实现“强制充电或放电”\n如果错误“ ECONRESET” 出现, modbus 代理不应该终止"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -260,7 +260,6 @@ class ServiceQueueMap {
260
260
  }
261
261
  }
262
262
 
263
- //Update --
264
263
  const tSOC = await this.adapter.getState(this.inverterInfo.path+'.control.battery.targetSOC ');
265
264
  if (tSOC) {
266
265
  await this.adapter.delObject(this.inverterInfo.path+'.control.battery.targetSOC ',{ recursive: false });
@@ -269,7 +268,6 @@ class ServiceQueueMap {
269
268
  if (tSOC.ack === false) this.set('battery.targetSOC',tSOC);
270
269
  }
271
270
  }
272
- //Update ++
273
271
 
274
272
  this.adapter.subscribeStates(this.inverterInfo.path+'.control*');
275
273
  this._initialized = true;
@@ -357,7 +355,7 @@ class ServiceQueueMap {
357
355
 
358
356
  async _writeRegisters(address,data) {
359
357
  try {
360
- this.log.debug('Try to write data to id/address ' + this._modbusClient.id + '/' + address+'/'+data.length);
358
+ this.log.debug('Try to write data to id/address/length ' + this._modbusClient.id + '/' + address+'/'+data.length);
361
359
  await this._modbusClient.writeRegisters(address,data);
362
360
  this.inverterInfo.instance.addHoldingRegisters(address,data);
363
361
  return true;
@@ -368,7 +366,7 @@ class ServiceQueueMap {
368
366
 
369
367
  async _readHoldingRegisters(address,length) {
370
368
  try {
371
- this.log.debug('Try to read data to id/address ' + this._modbusClient.id + '/' + address+'/'+length);
369
+ this.log.debug('Try to read data to id/address/length ' + this._modbusClient.id + '/' + address+'/'+length);
372
370
  const data = await this._modbusClient.readHoldingRegisters(address,length);
373
371
  return data;
374
372
  } catch (err) {
@@ -60,12 +60,184 @@ class Emma extends DriverBase{
60
60
  },
61
61
  {
62
62
  address : 30302,
63
- length : 4,
63
+ length : 50,
64
64
  info : 'Emma sampled data',
65
65
  refresh : dataRefreshRate.low,
66
66
  states: [{
67
- state: {id: 'emma.inverterTotalAbsorbedEnergy', name: 'Inverter total absorbed energy', type: 'number', unit: 'kWh', role: 'value', desc: 'reg:30302, len:4'},
67
+ state: {id: 'emma.inverterTotalAbsorbedEnergy', name: 'Inverter total absorbed energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30302, len:4'},
68
68
  register: {reg: 30302, type: dataType.uint64, gain: 100}
69
+ },
70
+ {
71
+ state: {id: 'emma.energyChargedToday', name: 'Energy charged today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30306, len:2'},
72
+ register: {reg: 30306, type: dataType.uint32, gain: 100}
73
+ },
74
+ {
75
+ state: {id: 'emma.totalChargedEnergy', name: 'Total charged energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30308, len:4'},
76
+ register: {reg: 30308, type: dataType.uint64, gain: 100}
77
+ },
78
+ {
79
+ state: {id: 'emma.energyDischargedToday', name: 'nergy discharged today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30312, len:2'},
80
+ register: {reg: 30312, type: dataType.uint32, gain: 100}
81
+ },
82
+ {
83
+ state: {id: 'emma.TotalDischargedEnergy', name: 'Total discharged energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30314, len:4'},
84
+ register: {reg: 30314, type: dataType.uint64, gain: 100}
85
+ },
86
+ {
87
+ state: {id: 'emma.ESSchargeableEnergy', name: 'ESS chargeable energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30318, len:2'},
88
+ register: {reg: 30318, type: dataType.uint32, gain: 1000}
89
+ },
90
+ {
91
+ state: {id: 'emma.ESSdischargeableEnergy', name: 'ESS dischargeable energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30320, len:2'},
92
+ register: {reg: 30320, type: dataType.uint32, gain: 1000}
93
+ },
94
+ {
95
+ state: {id: 'emma.ratedESScapacity', name: 'Rated ESS capacity', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30322, len:2'},
96
+ register: {reg: 30322, type: dataType.uint32, gain: 1000}
97
+ },
98
+ {
99
+ state: {id: 'emma.consumptionToday', name: 'Consumption today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30324, len:2'},
100
+ register: {reg: 30324, type: dataType.uint32, gain: 100}
101
+ },
102
+ {
103
+ state: {id: 'emma.totalEnergyConsumption', name: 'Total energy consumption', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30326, len:4'},
104
+ register: {reg: 30326, type: dataType.uint64, gain: 100}
105
+ },
106
+ {
107
+ state: {id: 'emma.feed-inToGridToday', name: 'Feed-in to grid today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30330, len:2'},
108
+ register: {reg: 30330, type: dataType.uint32, gain: 100}
109
+ },
110
+ {
111
+ state: {id: 'emma.totalFeed-inToGrid', name: 'Total feed-in to grid', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30332, len:4'},
112
+ register: {reg: 30332, type: dataType.uint64, gain: 100}
113
+ },
114
+ {
115
+ state: {id: 'emma.supplyFromGridToday', name: 'Supply from grid today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30336, len:2'},
116
+ register: {reg: 30336, type: dataType.uint32, gain: 100}
117
+ },
118
+ {
119
+ state: {id: 'emma.totalSupplyFromGrid', name: 'Total supply from grid', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30338, len:4'},
120
+ register: {reg: 30338, type: dataType.uint64, gain: 100}
121
+ },
122
+ {
123
+ state: {id: 'emma.inverterEnergyYieldToday', name: 'Inverter energy yield today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30342, len:2'},
124
+ register: {reg: 30342, type: dataType.uint32, gain: 100}
125
+ },
126
+ {
127
+ state: {id: 'emma.inverterTotalEnergyYield', name: 'Inverter total energy yieldy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30344, len:2'},
128
+ register: {reg: 30344, type: dataType.uint32, gain: 100}
129
+ },
130
+ {
131
+ state: {id: 'emma.PVyieldToday', name: 'PV yield today', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30346, len:2'},
132
+ register: {reg: 30346, type: dataType.uint32, gain: 100}
133
+ },
134
+ {
135
+ state: {id: 'emma.totalPVenergyYield', name: 'Total PV energy yield', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30348, len:4'},
136
+ register: {reg: 30348, type: dataType.uint64, gain: 100}
137
+ }]
138
+ },
139
+ {
140
+ address : 30354,
141
+ length : 12,
142
+ info : 'Emma sampled data 2',
143
+ refresh : dataRefreshRate.high,
144
+ states: [{
145
+ state: {id: 'emma.PVoutputPower', name: 'PV output power', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:30354, len:2'},
146
+ register: {reg: 30354, type: dataType.uint32, gain: 1000}
147
+ },
148
+ {
149
+ state: {id: 'emma.loadPower', name: 'Load power', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:30356, len:2'},
150
+ register: {reg: 30356, type: dataType.uint32, gain: 1000}
151
+ },
152
+ {
153
+ state: {id: 'emma.feed-inPower', name: 'Feed-in Power', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:30358, len:2'},
154
+ register: {reg: 30358, type: dataType.int32, gain: 1000}
155
+ },
156
+ {
157
+ state: {id: 'emma.batteryChargeDischargePower', name: 'Battery charge/discharge power', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:30360, len:2'},
158
+ register: {reg: 30360, type: dataType.int32, gain: 1000}
159
+ },
160
+ {
161
+ state: {id: 'emma.inverterRatedPower', name: 'Battery charge/discharge power', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:30362, len:2'},
162
+ register: {reg: 30362, type: dataType.uint32, gain: 1000}
163
+ },
164
+ {
165
+ state: {id: 'emma.Inverter active power', name: 'Inverter active power', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:30364, len:2'},
166
+ register: {reg: 30364, type: dataType.int32, gain: 1000}
167
+ }]
168
+ },
169
+ {
170
+ address : 30368,
171
+ length : 6,
172
+ info : 'Emma sampled data 3',
173
+ refresh : dataRefreshRate.low,
174
+ states: [{
175
+ state: {id: 'emma.SOC', name: 'SOC', type: 'number', unit: '%', role: 'value.battery', desc: 'reg:30368, len:1'},
176
+ register: {reg: 30368, type: dataType.uint16, gain: 100}
177
+ },
178
+ {
179
+ state: {id: 'emma.ESSchargeableCapacity', name: 'ESS chargeable capacity', type: 'number', unit: 'kWh', role: 'value.power.capacity', desc: 'reg:30369, len:2'},
180
+ register: {reg: 30369, type: dataType.uint32, gain: 1000}
181
+ },
182
+ {
183
+ state: {id: 'emma.ESSdischargeableCapacity', name: 'ESS dischargeable capacity', type: 'number', unit: 'kWh', role: 'value.power.capacity', desc: 'reg:30371, len:2'},
184
+ register: {reg: 30371, type: dataType.uint32, gain: 1000}
185
+ },
186
+ {
187
+ state: {id: 'emma.BackupPowerSOC', name: 'Backup power SOC', type: 'number', unit: '%', role: 'value.battery', desc: 'reg:30373, len:1'},
188
+ register: {reg: 30373, type: dataType.uint16, gain: 100}
189
+ }]
190
+ },
191
+ {
192
+ address : 30380,
193
+ length : 18,
194
+ info : 'Emma sampled data 4',
195
+ refresh : dataRefreshRate.low,
196
+ states: [{
197
+ state: {id: 'emma.yieldThisMonth', name: 'Yield this month', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30380, len:2'},
198
+ register: {reg: 30380, type: dataType.uint32, gain: 100}
199
+ },
200
+ {
201
+ state: {id: 'emma.monthlyEnergyConsumption', name: 'Monthly energy consumption', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30382, len:2'},
202
+ register: {reg: 30382, type: dataType.uint32, gain: 100}
203
+ },
204
+ {
205
+ state: {id: 'emma.monthlyFeed-inToGrid', name: 'Monthly feed-in to grid', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30384, len:2'},
206
+ register: {reg: 30384, type: dataType.uint32, gain: 100}
207
+ },
208
+ {
209
+ state: {id: 'emma.yieldThisYear', name: 'Yield this year', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30386, len:2'},
210
+ register: {reg: 30386, type: dataType.uint32, gain: 100}
211
+ },
212
+ {
213
+ state: {id: 'emma.annualEnergyConsumption', name: 'Annual energy consumption', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30388, len:2'},
214
+ register: {reg: 30388, type: dataType.uint32, gain: 100}
215
+ },
216
+ {
217
+ state: {id: 'emma.yearlyFeed-inToGrid', name: 'Yearly feed-in to grid', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30390, len:2'},
218
+ register: {reg: 30390, type: dataType.uint32, gain: 100}
219
+ },
220
+ {
221
+ state: {id: 'emma.monthlySupplyFromGrid', name: 'Monthly supply from grid', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30394, len:2'},
222
+ register: {reg: 30394, type: dataType.uint32, gain: 100}
223
+ },
224
+ {
225
+ state: {id: 'emma.yearlySupplyFromGrid', name: 'Yearly supply from grid', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30396, len:2'},
226
+ register: {reg: 30396, type: dataType.uint32, gain: 100}
227
+ }]
228
+ },
229
+ {
230
+ address : 30407,
231
+ length : 4,
232
+ info : 'Emma sampled data 5',
233
+ refresh : dataRefreshRate.low,
234
+ states: [{
235
+ state: {id: 'emma.energyChargedThisMonth', name: 'Energy charged this month', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30407, len:2'},
236
+ register: {reg: 30407, type: dataType.uint32, gain: 100}
237
+ },
238
+ {
239
+ state: {id: 'emma.energyDischargedThisMonth', name: 'Energy discharged this month', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:30409, len:2'},
240
+ register: {reg: 30409, type: dataType.uint32, gain: 100}
69
241
  }]
70
242
  },
71
243
  {
@@ -172,196 +344,5 @@ class Emma extends DriverBase{
172
344
 
173
345
  }
174
346
 
175
- class EmmaMeter extends DriverBase{
176
- constructor(stateInstance,inverter,options) {
177
- super(stateInstance,inverter,
178
- {
179
- name: 'emmaMeter',
180
- driverClass : driverClasses.emmaMeter,
181
- ...options,
182
- });
183
- this._testMode = false;
184
- //this._testMode = (this._modbusId == 1);
185
-
186
- //https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/stateroles.md
187
- const newFields = [
188
- {
189
- address : 32260,
190
- length : 105,
191
- info : 'Emma external smart meter info',
192
- refresh : dataRefreshRate.high,
193
- type : deviceType.meter,
194
- states: [
195
- {
196
- state: {id: 'meter.voltageL1', name: 'Phase 1 voltage', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:32260, len:2'},
197
- register: {reg: 32260, type: dataType.uint32, gain: 100}
198
- },
199
- {
200
- state: {id: 'meter.voltageL2', name: 'Phase 2 voltage', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:32262, len:2'},
201
- register: {reg: 32262, type: dataType.uint32, gain:100}
202
- },
203
- {
204
- state: {id: 'meter.voltageL3', name: 'Phase 3 voltage', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:32264, len:2'},
205
- register: {reg: 32264, type: dataType.uint32, gain:100}
206
- },
207
- {
208
- state: {id: 'meter.currentL1', name: 'Phase 1 Current', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:32272, len:2'},
209
- register: {reg: 32272, type: dataType.int32, gain:10}
210
- },
211
- {
212
- state: {id: 'meter.currentL2', name: 'Phase 2 Current', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:32274, len:2'},
213
- register: {reg: 32274, type: dataType.int32, gain:10}
214
- },
215
- {
216
- state: {id: 'meter.currentL3', name: 'Phase 3 Current', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:32276, len:2'},
217
- register: {reg: 32276, type: dataType.int32, gain:10}
218
- },
219
- {
220
- state: {id: 'meter.activePower', name: 'ActivePower', type: 'number', unit: 'kW', role: 'value.power.active', desc: 'reg:32278, len:2 (>0: feed-in to grid. <0: supply from grid.)' },
221
- register: { reg: 32278, type: dataType.int32, gain:1000}
222
- },
223
- {
224
- state: {id: 'meter.reactivePower', name: 'Reactive Power', type: 'number', unit: 'VAr', role: 'value.power.reactive', desc: 'reg:32280, len:2'},
225
- register: {reg: 32280, type: dataType.int32}
226
- },
227
- {
228
- state: {id: 'meter.powerFactor', name: 'Power Factor', type: 'number', unit: '', role: 'value', desc: 'reg:32284, len:1'},
229
- register: {reg: 32284, type: dataType.int16, gain: 1000}
230
- },
231
- {
232
- state: {id: 'meter.voltageL1-L2', name: 'Voltage L1-L2', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:32266 , len:2'},
233
- register: {reg: 32266 , type: dataType.uint32, gain: 100}
234
- },
235
- {
236
- state: {id: 'meter.voltageL2-L3', name: 'Voltage L2-L3', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:32268 , len:2'},
237
- register: {reg: 32268, type: dataType.uint32, gain: 100}
238
- },
239
- {
240
- state: {id: 'meter.voltageL3-L1', name: 'Voltage L3-L1', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:32270, len:2'},
241
- register: {reg: 32270, type: dataType.uint32, gain: 100}
242
- },
243
- {
244
- state: {id: 'meter.activePowerL1', name: 'Active Power L1', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:32335, len:2'},
245
- register: {reg: 32335, type: dataType.int32, gain: 1000}
246
- },
247
- {
248
- state: {id: 'meter.activePowerL2', name: 'Active Power L2', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:32337, len:2'},
249
- register: {reg: 32337, type: dataType.int32, gain: 1000}
250
- },
251
- {
252
- state: {id: 'meter.activePowerL3', name: 'Active Power L3', type: 'number', unit: 'kW', role: 'value.power', desc: 'reg:32339, len:2'},
253
- register: {reg: 32339, type: dataType.int32, gain: 1000}
254
- },
255
- {
256
- state: {id: 'meter.positiveActiveEnergy', name: 'Positive Active Energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:32357, len:4'},
257
- register: {reg: 32357, type: dataType.int64, gain: 100}
258
- },
259
- {
260
- state: {id: 'meter.reverseActiveEnergy', name: 'Reverse Active Energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:32349, len:4'},
261
- register: {reg: 32349, type: dataType.int64, gain: 100}
262
- },
263
- {
264
- state: {id: 'meter.accumulatedReactivePower', name: 'Accumulated Reactive Power', type: 'number', unit: 'kVarh', role: 'value.power.reactive.consumption', desc: 'reg:32361, len:4'},
265
- register: {reg: 32361, type: dataType.int64, gain: 100}
266
- }
267
- ]
268
- }
269
- ];
270
-
271
- const newTestFields = [
272
- {
273
- address : 37100,
274
- length : 38,
275
- info : 'Test Emma external smart meter info',
276
- refresh : dataRefreshRate.high,
277
- type : deviceType.meter,
278
- states: [{
279
- state: {id: 'meter.voltageL1', name: 'Phase 1 voltage', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:37101, len:2'},
280
- register: {reg: 37101, type: dataType.int32, gain: 10}
281
- },
282
- {
283
- state: {id: 'meter.voltageL2', name: 'Phase 2 voltage', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:37103, len:2'},
284
- register: {reg: 37103, type: dataType.int32, gain:10}
285
- },
286
- {
287
- state: {id: 'meter.voltageL3', name: 'Phase 3 voltage', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:37105, len:2'},
288
- register: {reg: 37105, type: dataType.int32, gain:10}
289
- },
290
- {
291
- state: {id: 'meter.currentL1', name: 'Phase 1 Current', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:37107, len:2'},
292
- register: {reg: 37107, type: dataType.int32, gain:100}
293
- },
294
- {
295
- state: {id: 'meter.currentL2', name: 'Phase 2 Current', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:37109, len:2'},
296
- register: {reg: 37109, type: dataType.int32, gain:100}
297
- },
298
- {
299
- state: {id: 'meter.currentL3', name: 'Phase 3 Current', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:37111, len:2'},
300
- register: {reg: 37111, type: dataType.int32, gain:100}
301
- },
302
- {
303
- state: {id: 'meter.activePower', name: 'ActivePower', type: 'number', unit: 'kW', role: 'value.power.active', desc: 'reg:37113, len:2 (>0: feed-in to grid. <0: supply from grid.)' },
304
- register: { reg: 37113, type: dataType.int32, gain:1000 }
305
- },
306
- {
307
- state: {id: 'meter.reactivePower', name: 'Reactive Power', type: 'number', unit: 'VAr', role: 'value.power.reactive', desc: 'reg:37115, len:2'},
308
- register: {reg: 37115, type: dataType.int32}
309
- },
310
- {
311
- state: {id: 'meter.powerFactor', name: 'Power Factor', type: 'number', unit: '', role: 'value', desc: 'reg:37117, len:1'},
312
- register: {reg: 37117, type: dataType.int16, gain: 1000}
313
- },
314
- /*
315
- {
316
- state: {id: 'meter.gridFrequency', name: 'Grid Frequency', type: 'number', unit: 'Hz', role: 'value.frequency', desc: 'reg:37118, len:1'},
317
- register: {reg: 37118, type: dataType.int16, gain: 100}
318
- },
319
- */
320
- {
321
- state: {id: 'meter.positiveActiveEnergy', name: 'Positive Active Energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:37119, len:2'},
322
- register: {reg: 37119, type: dataType.int32, gain: 100}
323
- },
324
- {
325
- state: {id: 'meter.reverseActiveEnergy', name: 'Reverse Active Energy', type: 'number', unit: 'kWh', role: 'value.power.consumption', desc: 'reg:37121, len:2'},
326
- register: {reg: 37121, type: dataType.int32, gain: 100}
327
- },
328
- {
329
- state: {id: 'meter.accumulatedReactivePower', name: 'Accumulated Reactive Power', type: 'number', unit: 'kVarh', role: 'value.power.reactive.consumption', desc: 'reg:37123, len:2'},
330
- register: {reg: 37123, type: dataType.int32, gain: 100}
331
- },
332
- {
333
- state: {id: 'meter.voltageL1-L2', name: 'Voltage L1-L2', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:37126, len:2'},
334
- register: {reg: 37126, type: dataType.int32, gain: 10}
335
- },
336
- {
337
- state: {id: 'meter.voltageL2-L3', name: 'Voltage L2-L3', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:37128, len:2'},
338
- register: {reg: 37128, type: dataType.int32, gain: 10}
339
- },
340
- {
341
- state: {id: 'meter.voltageL3-L1', name: 'Voltage L3-L1', type: 'number', unit: 'V', role: 'value.voltage', desc: 'reg:37130, len:2'},
342
- register: {reg: 37130, type: dataType.int32, gain: 10}
343
- },
344
- {
345
- state: {id: 'meter.activePowerL1', name: 'Active Power L1', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:37132, len:2'},
346
- register: {reg: 37132, type: dataType.int32,}
347
- },
348
- {
349
- state: {id: 'meter.activePowerL2', name: 'Active Power L2', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:37134, len:2'},
350
- register: {reg: 37134, type: dataType.int32}
351
- },
352
- {
353
- state: {id: 'meter.activePowerL3', name: 'Active Power L3', type: 'number', unit: 'A', role: 'value.current', desc: 'reg:37136, len:2'},
354
- register: {reg: 37136, type: dataType.int32}
355
- }
356
- ]
357
- }
358
- ];
359
-
360
- if (this._testMode) this.registerFields.push.apply(this.registerFields,newTestFields);
361
- else this.registerFields.push.apply(this.registerFields,newFields);
362
- //this.postUpdateHooks.push.apply(this.postUpdateHooks,newHooks);
363
- }
364
-
365
- }
366
347
 
367
- module.exports = {Emma,EmmaMeter};
348
+ module.exports = Emma;
@@ -2,7 +2,7 @@
2
2
  const {driverClasses} = require(__dirname + '/../types.js');
3
3
  const {InverterInfo} = require(__dirname + '/driver_inverter.js');
4
4
  const {SmartLogger,SmartLoggerMeter} = require(__dirname + '/driver_slogger.js');
5
- const { Emma, EmmaMeter } = require(__dirname + '/driver_emma.js');
5
+ const { Emma } = require(__dirname + '/driver_emma.js');
6
6
  const Sdongle = require(__dirname + '/driver_sdongle.js');
7
7
  //const Scharger = require(__dirname + '/driver_scharger.js');
8
8
 
@@ -13,7 +13,6 @@ function getDriverHandler(driverClass) {
13
13
  if (driverClass == driverClasses.logger) return SmartLogger;
14
14
  if (driverClass == driverClasses.loggerMeter) return SmartLoggerMeter;
15
15
  if (driverClass == driverClasses.emma) return Emma;
16
- if (driverClass == driverClasses.emmaMeter) return EmmaMeter;
17
16
  }
18
17
 
19
18
  module.exports = getDriverHandler;
@@ -1,5 +1,7 @@
1
1
 
2
2
  const ModbusRTU = require('modbus-serial');
3
+ const {createAsyncLock} = require(__dirname + '/../tools.js');
4
+ const asynLock = createAsyncLock();
3
5
 
4
6
  const testMode = false;
5
7
 
@@ -178,7 +180,7 @@ class ModbusConnect extends DeviceInterface {
178
180
  }
179
181
 
180
182
 
181
- async readHoldingRegisters(address, length, logger) {
183
+ async _readHoldingRegistersOld(address, length, logger) {
182
184
  this.setLogger(logger);
183
185
 
184
186
  try {
@@ -195,13 +197,27 @@ class ModbusConnect extends DeviceInterface {
195
197
  }
196
198
  }
197
199
 
198
- async writeRegisters(address,buffer, logger) {
200
+ //wrapper with async-lock
201
+ async readHoldingRegisters(address, length, logger) {
202
+ return await asynLock(async () => {
203
+ this.setLogger(logger);
204
+ try {
205
+ await this.open();
206
+ await this.client.setID(this._id);
207
+ await this._delay();
208
+ const data = await this.client.readHoldingRegisters(address, length);
209
+ this._adjust.lastLength = length;
210
+ this._adjustDelay(undefined,true);
211
+ return data.data;
212
+ } catch (err) {
213
+ await this._checkError(err);
214
+ throw err;
215
+ }
216
+ });
217
+ }
218
+
219
+ async _writeRegistersOld(address,buffer, logger) {
199
220
  this.setLogger(logger);
200
- /*
201
- if (this._id === 0) {
202
- throw new Error('Modbus unit ID 0 is not permitted!');
203
- }
204
- */
205
221
  try {
206
222
  await this.open();
207
223
  await this.client.setID(this._id);
@@ -215,6 +231,41 @@ class ModbusConnect extends DeviceInterface {
215
231
  }
216
232
  }
217
233
 
234
+ //wrapper with async-lock
235
+ async writeRegisters(address,buffer, logger) {
236
+ return await asynLock(async () => {
237
+ this.setLogger(logger);
238
+ try {
239
+ await this.open();
240
+ await this.client.setID(this._id);
241
+ await this._delay();
242
+ await this.client.writeRegisters(address,buffer);
243
+ this._adjust.lastLength = buffer.length;
244
+ this._adjustDelay(undefined,true);
245
+ } catch (err) {
246
+ await this._checkError(err);
247
+ throw err;
248
+ }
249
+ });
250
+ }
251
+
252
+ async writeRegister(address,value, logger) {
253
+ return await asynLock(async () => {
254
+ this.setLogger(logger);
255
+ try {
256
+ await this.open();
257
+ await this.client.setID(this._id);
258
+ await this._delay();
259
+ await this.client.writeRegister(address,value);
260
+ this._adjust.lastLength = 1;
261
+ this._adjustDelay(undefined,true);
262
+ } catch (err) {
263
+ await this._checkError(err);
264
+ throw err;
265
+ }
266
+ });
267
+ }
268
+
218
269
  _adjustDelay(err,successful=true) {
219
270
 
220
271
  function getGradient(info) {
@@ -1,7 +1,7 @@
1
1
  const ModbusRTU = require('modbus-serial');
2
2
  const tcpPortUsed = require('tcp-port-used');
3
3
 
4
- // https://github.com/yaacov/node-modbus-serial/blob/master/examples/server.js
4
+ //https://github.com/yaacov/node-modbus-serial/blob/master/examples/server.js
5
5
  class ModbusServer {
6
6
  constructor (adapterInstance,ip, port) {
7
7
  this._ip = ip;
@@ -11,6 +11,7 @@ class ModbusServer {
11
11
  this._isConnected = false;
12
12
  this._stat = {};
13
13
 
14
+ //https://github.com/yaacov/node-modbus-serial/blob/master/ServerTCP.d.ts
14
15
  this.vector = {
15
16
  getInputRegister: (addr, unitId, callback) => {
16
17
  this._addInfoStat('#getInputRegister',addr, 1 , unitId);
@@ -30,9 +31,12 @@ class ModbusServer {
30
31
  this._addInfoStat('#getCoil',addr, 1 , unitId);
31
32
  callback({ modbusErrorCode: 0x01, msg: 'Illegal function (device does not support this read/write function)' });
32
33
  },
33
- setRegister: (addr, value,unitId, callback) => {
34
- this._addInfoStat('#readDeviceIdentification',addr, value, unitId);
35
- callback({ modbusErrorCode: 0x01, msg: 'Illegal function (device does not support this read/write function)' });
34
+ //https://github.com/yaacov/node-modbus-serial/blob/cbd4379bed9672c13ec3a8517d622b728a737a5e/servers/servertcp_handler.js#L925C16-L925C32
35
+ setRegisterArray: async (addr, values, unitId, callback) => {
36
+ await this._handleSetReg(addr,values,unitId, callback);
37
+ },
38
+ setRegister: async (addr, value,unitId, callback) => {
39
+ await this._handleSetReg(addr,value,unitId, callback);
36
40
  },
37
41
  setCoil: (addr, value, unitId, callback) => {
38
42
  this._addInfoStat('#setCoil',addr, value, unitId);
@@ -40,14 +44,13 @@ class ModbusServer {
40
44
  },
41
45
  readDeviceIdentification: () => { //function(addr)
42
46
  this._addInfoStat('readDeviceIdentification');
43
- console.log('DeviceIntification');
44
47
  return {
45
- 0x00: 'MyVendorName',
46
- 0x01: 'MyProductCode',
47
- 0x02: 'MyMajorMinorRevision',
48
- 0x05: 'MyModelName',
49
- 0x97: 'MyExtendedObject1',
50
- 0xAB: 'MyExtendedObject2'
48
+ 0x00: 'ioBroker',
49
+ 0x01: 'adapter.sun2000',
50
+ 0x02: this.adapter.version,
51
+ 0x05: 'modbus-proxy',
52
+ 0x97: '',
53
+ 0xAB: ''
51
54
  };
52
55
  }
53
56
  };
@@ -135,7 +138,6 @@ class ModbusServer {
135
138
  if (device.instance?.modbusId === unitId) return device.instance;
136
139
  }
137
140
  }
138
-
139
141
  }
140
142
 
141
143
  async _handleGetReg (startAddr, length, unitId, callback) {
@@ -146,7 +148,7 @@ class ModbusServer {
146
148
  //this.adapter.log.debug('Device Info '+JSON.stringify(device?.info));
147
149
  const values = device.getHoldingRegisters(startAddr,length);
148
150
  if (!this.adapter.isConnected) {
149
- this._addInfoStat('#WaitForConnected',startAddr, length, unitId);
151
+ //this._addInfoStat('#WaitForConnected',startAddr, length, unitId);
150
152
  await this.wait(500);
151
153
  callback({ modbusErrorCode: 0x05, msg: 'Acknowledge (requested data will be available later)' });
152
154
  } else {
@@ -171,6 +173,50 @@ class ModbusServer {
171
173
  }
172
174
  }
173
175
 
176
+ async _handleSetReg(address, data, unitId, callback) {
177
+ try {
178
+ this.log.debug('Modbus-proxy: Try to write data to id/address ' + unitId + '/' + address +'/'+ data);
179
+ const device = this.getDeviceInstance(unitId);
180
+ if (!device) {
181
+ await this.wait(500);
182
+ callback({ modbusErrorCode: 0x01, msg: 'Device ID '+unitId+' not supported by device' });
183
+ return;
184
+ }
185
+ if (!this.adapter.isConnected) {
186
+ this.log.info('Modbus-proxy: please wait until connected.');
187
+ callback({ modbusErrorCode: 0x05, msg: 'Acknowledge (requested data will be available later)' });
188
+ return;
189
+ }
190
+ if (!this.adapter.modbusClient) {
191
+ this.log.error('Modbus-proxy: no modbus-client is registered!');
192
+ callback({ modbusErrorCode: 0x04, msg: 'Slave device failure (device reports internal error)' });
193
+ return;
194
+ }
195
+ this.adapter.modbusClient.setID(unitId);
196
+ if (Array.isArray(data)) {
197
+ await this.adapter.modbusClient.writeRegisters(address,data);
198
+ //write also to the read cache
199
+ device.addHoldingRegisters(address,data);
200
+ this._addInfoStat('setRegisterArray',address,data.length, unitId);
201
+ } else {
202
+ await this.adapter.modbusClient.writeRegister(address,data);
203
+ device.addHoldingRegisters(address,[data]);
204
+ this._addInfoStat('setRegister',address,1, unitId);
205
+ }
206
+ callback();
207
+ } catch (err) {
208
+ this.log.warn('Modbus-proxy: can not write data to id/address ' + unitId + '/' + address +'/'+ data);
209
+ this.log.warn('Modbus-proxy: '+err?.message);
210
+ if (Array.isArray(data)) {
211
+ this._addInfoStat('#setRegisterArray',address,data.length, unitId);
212
+ } else {
213
+ this._addInfoStat('#setRegister',address,1, unitId);
214
+ }
215
+ await this.wait(500);
216
+ callback({ modbusErrorCode: err?.modbusCode, msg: err?.message });
217
+ }
218
+ }
219
+
174
220
  wait(ms){
175
221
  return new Promise(resolve => setTimeout(resolve, ms));
176
222
  }
package/lib/test.js CHANGED
@@ -21,8 +21,8 @@ class TypeTest {
21
21
 
22
22
  }
23
23
 
24
- const test = new TypeTest();
25
- test.int32([1,500]);
26
- test.int64([1,0,0,500]);
24
+ const test1 = new TypeTest();
25
+ test1.int32([1,500]);
26
+ test1.int64([1,0,0,500]);
27
27
 
28
28
  module.exports = TypeTest;
package/lib/tools.js CHANGED
@@ -188,6 +188,35 @@ class RiemannSum {
188
188
  }
189
189
  }
190
190
 
191
+ //https://stackoverflow.com/questions/38802959/how-to-lock-on-object-which-shared-by-multiple-async-method-in-nodejs
192
+ const createAsyncLock = () => {
193
+ const queue = [];
194
+ let active = false;
195
+ return (fn) => {
196
+ let deferredResolve;
197
+ let deferredReject;
198
+ const deferred = new Promise((resolve, reject) => {
199
+ deferredResolve = resolve;
200
+ deferredReject = reject;
201
+ });
202
+ const exec = async () => {
203
+ await fn().then(deferredResolve, deferredReject);
204
+ if (queue.length > 0) {
205
+ queue.shift()();
206
+ } else {
207
+ active = false;
208
+ }
209
+ };
210
+ if (active) {
211
+ queue.push(exec);
212
+ } else {
213
+ active = true;
214
+ exec();
215
+ }
216
+ return deferred;
217
+ };
218
+ };
219
+
191
220
 
192
221
  // Get longitude an latidude from system config
193
222
  async function getSystemData(adapter) {
@@ -256,6 +285,7 @@ function isSunshine(adapter) {
256
285
  return true;
257
286
  }
258
287
 
288
+ //contains a value in array
259
289
  function contains( r, val ) {
260
290
  const len = r.length;
261
291
  let i = 0;
@@ -273,6 +303,7 @@ module.exports = {
273
303
  StateMap,
274
304
  RegisterMap,
275
305
  RiemannSum,
306
+ createAsyncLock,
276
307
  getSystemData,
277
308
  getAstroDate,
278
309
  isSunshine,
package/lib/types.js CHANGED
@@ -79,8 +79,7 @@ const driverClasses = {
79
79
  charger : 'charger',
80
80
  logger : 'logger',
81
81
  loggerMeter : 'loggerMeter',
82
- emma : 'emma',
83
- emmaMeter : 'emmaMeter'
82
+ emma : 'emma'
84
83
  };
85
84
 
86
85
  const storeType = {
package/main.js CHANGED
@@ -61,7 +61,7 @@ class Sun2000 extends utils.Adapter {
61
61
  },
62
62
  ds: {
63
63
  batteryUnits : true,
64
- batterPacks : false
64
+ batteryPacks : false
65
65
  }
66
66
  };
67
67
 
@@ -190,11 +190,6 @@ class Sun2000 extends utils.Adapter {
190
190
  native: {}
191
191
  });
192
192
  }
193
- /*
194
- if (item.driverClass == driverClasses.emmaMeter) {
195
- item.path = '';
196
- }
197
- */
198
193
 
199
194
  }
200
195
  }
@@ -384,6 +379,17 @@ class Sun2000 extends utils.Adapter {
384
379
  meter: (i==0 && this.settings.integration === 0)
385
380
  });
386
381
  }
382
+
383
+ //SDongle
384
+ if (this.settings.integration === 0 && this.settings.sd.active) {
385
+ this.devices.push({
386
+ index: 0,
387
+ duration: 0,
388
+ modbusId: this.settings.sd.sDongleId,
389
+ driverClass: driverClasses.sdongle
390
+ });
391
+ }
392
+
387
393
  //SmartLogger
388
394
  if (this.settings.integration === 1) {
389
395
  this.devices.push({
@@ -403,7 +409,7 @@ class Sun2000 extends utils.Adapter {
403
409
  }
404
410
  }
405
411
 
406
- //Emma
412
+ //EMMA
407
413
  if (this.settings.integration === 2) {
408
414
  this.devices.push({
409
415
  index: 0,
@@ -415,16 +421,6 @@ class Sun2000 extends utils.Adapter {
415
421
  });
416
422
  }
417
423
 
418
- //SDongle
419
- if (this.settings.sd.active) {
420
- this.devices.push({
421
- index: 0,
422
- duration: 0,
423
- modbusId: this.settings.sd.sDongleId,
424
- driverClass: driverClasses.sdongle
425
- });
426
- }
427
-
428
424
  await this.adjustInverval();
429
425
  await this.StartProcess();
430
426
  } else {
@@ -456,8 +452,8 @@ class Sun2000 extends utils.Adapter {
456
452
  }
457
453
  await this.state.runPostProcessHooks(dataRefreshRate.high);
458
454
 
455
+ //Low Loop
459
456
  if (timeLeft(nextLoop) > 0) {
460
- //Low Loop
461
457
  for (const [i,item] of this.devices.entries()) {
462
458
  //this.log.debug('+++++ Loop: '+i+' Left Time: '+timeLeft(nextLoop,(i+1)/this.devices.length)+' Faktor '+((i+1)/this.devices.length));
463
459
  this.lastStateUpdatedLow += await this.state.updateStates(item,this.modbusClient,dataRefreshRate.low,timeLeft(nextLoop,(i+1)/this.devices.length));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.sun2000",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "sun2000",
5
5
  "author": {
6
6
  "name": "bolliy",