iobroker.sun2000 2.4.5 → 2.5.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
@@ -27,7 +27,7 @@ Read and write register data from Huawei SUN2000 inverter and LUNA2000 battery u
27
27
  Feel free to follow the discussions in the german [iobroker forum](https://forum.iobroker.net/topic/71768/test-adapter-sun2000-v0-1-x-huawei-wechselrichter)
28
28
 
29
29
  ## Requirements
30
- * Node.js 20 or higher
30
+ * Node.js 22 or higher
31
31
  * ioBroker host (js-controller) 6.0.11 or higher
32
32
  * ioBroker admin 7.6.20 or higher
33
33
 
@@ -69,6 +69,9 @@ The sun2000 adapter calculates how much of your self-generated solar energy is a
69
69
  Placeholder for the next version (at the beginning of the line):
70
70
  ### **WORK IN PROGRESS**
71
71
  -->
72
+ ### 2.5.0 (2026-06-09)
73
+ * statistics: added live power chart (statistics.jsonLive)
74
+
72
75
  ### 2.4.5 (2026-05-14)
73
76
  * statistics fix: return weekly range up to current Monday
74
77
  * statistics: added support for generating statistics templates directly from built-in charts
@@ -91,10 +94,7 @@ The sun2000 adapter calculates how much of your self-generated solar energy is a
91
94
  * statistics: data placeholders (`%%solarYield%%`, `%%gridExport%%` etc.) allow complete chart layout control via template states
92
95
  * statistics: chart output states (`statistics.flexCharts.jsonOutput.hourly` etc.) updated automatically each hour
93
96
 
94
- ### 2.4.0 (2026-03-14)
95
- * fix: the order of bit assignment corrected of alarmsJSON
96
- * new state `inverter.x.emma.activeAlarmSN` and `inverter.x.emma.HistoricalAlarmSN` : emma alarms [#226](https://github.com/bolliy/ioBroker.sun2000/issues/226)
97
- * statistics: Aggregates historical collected datapoints into time-based summaries (e.g. hourly, daily, monthly, yearly). The data is stored in the path `statistics` as JSON.
97
+ [Older changelogs can be found there](CHANGELOG_OLD.md)
98
98
 
99
99
  ## License
100
100
  MIT License
@@ -385,6 +385,39 @@
385
385
  }
386
386
  }
387
387
  },
388
+ "tab8": {
389
+ "type": "panel",
390
+ "label": "Statistics",
391
+ "items": {
392
+ "staticLink1": {
393
+ "type": "staticLink",
394
+ "text": "Information and settings regarding the statistics explained in the wiki",
395
+ "href": "https://github.com/bolliy/ioBroker.sun2000/wiki/Statistk-(statistics)",
396
+ "button": true,
397
+ "icon": "info",
398
+ "newLine": true,
399
+ "xs": 12,
400
+ "sm": 12,
401
+ "md": 6,
402
+ "lg": 3,
403
+ "xl": 3
404
+ },
405
+ "stat_liveInterval": {
406
+ "type": "number",
407
+ "label": "Live chart interval (min)",
408
+ "min" : 1,
409
+ "max" : 15,
410
+ "newLine": true,
411
+ "tooltip": "Live chart update interval in minutes",
412
+ "xs": 12,
413
+ "sm": 12,
414
+ "md": 6,
415
+ "lg": 4,
416
+ "xl": 4
417
+ }
418
+ }
419
+
420
+ },
388
421
  "tab7": {
389
422
  "type": "panel",
390
423
  "label": "Further Register",
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "sun2000",
4
- "version": "2.4.5",
4
+ "version": "2.5.0",
5
5
  "news": {
6
+ "2.5.0": {
7
+ "en": "statistics: added live power chart (statistics.jsonLive)\nrequires node.js >= 22",
8
+ "de": "statistiken: Live Power Chart hinzugefügt (statistics.jsonLive)\nrequires node.js >= 22",
9
+ "ru": "статистика: добавлена живая диаграмма мощности (statistics.jsonLive)\nrequires node.js >= 22",
10
+ "pt": "estatísticas: gráfico de potência ao vivo adicionado (statistics.jsonLive)\nrequires node.js >= 22",
11
+ "nl": "statistieken: toegevoegde live power chart (statistics.jsonLive)",
12
+ "fr": "statistiques: tableau de puissance en direct ajouté (statistiques.jsonLive)\nrequires node.js >= 22",
13
+ "it": "statistiche: aggiunto live power chart (statistics.jsonLive)\nrequires node.js >= 22",
14
+ "es": "estadística: añadido gráfico de potencia en vivo (statistics.jsonLive)\nrequires node.js >= 22",
15
+ "pl": "statystyki: dodany live power chart (statistics.jsonLive)\nrequires node.js >= 22",
16
+ "uk": "статистика: додано графік живої потужності (statistics.jsonLive)\nrequires node.js >= 22",
17
+ "zh-cn": "统计:增加的实电图(统计学.jsonLive)"
18
+ },
6
19
  "2.4.5": {
7
20
  "en": "statistics fix: return weekly range up to current Monday\nstatistics: added support for generating statistics templates directly from built-in charts\nstatistics: improved tooltip formatter - tooltip units are now provided explicitly via tooltip.valueFormatter",
8
21
  "de": "statistik fix: wöchentliche Rückgabe bis zum aktuellen Montag\nstatistik: unterstützung für die erstellung von statistiken vorlagen direkt aus integrierten diagrammen\nstatistiken: verbesserter Tooltip-Formater - Tooltip-Einheiten werden nun explizit über tooltip.valueFormatter bereitgestellt",
@@ -80,19 +93,6 @@
80
93
  "pl": "usunięty stan zdepregatowany \"collected.usableSurplusPower '",
81
94
  "uk": "вилучена депресована держава `collected.usableSurplusPower й",
82
95
  "zh-cn": "删除已贬值状态“ 已收集。 可使用 SurplusPower `"
83
- },
84
- "2.3.6": {
85
- "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)",
86
- "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)",
87
- "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)",
88
- "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)",
89
- "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)",
90
- "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)",
91
- "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)",
92
- "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)",
93
- "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)",
94
- "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)",
95
- "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)"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -251,7 +251,8 @@
251
251
  "ds_bu": true,
252
252
  "ds_bp": false,
253
253
  "cb_tou": false,
254
- "integration": 0
254
+ "integration": 0,
255
+ "stat_liveInterval": 5
255
256
  },
256
257
  "objects": [],
257
258
  "instanceObjects": [
@@ -707,9 +707,9 @@ class Emma extends DriverBase {
707
707
  type: 'number',
708
708
  unit: 'kW',
709
709
  role: 'value.power',
710
- desc: 'reg:31651, len:2',
710
+ desc: 'reg:31665, len:2',
711
711
  },
712
- register: { reg: 31651, type: dataType.int32, gain: 1000 },
712
+ register: { reg: 31665, type: dataType.int32, gain: 1000 },
713
713
  },
714
714
  {
715
715
  state: {
@@ -718,9 +718,9 @@ class Emma extends DriverBase {
718
718
  type: 'number',
719
719
  unit: 'kW',
720
720
  role: 'value.power',
721
- desc: 'reg:31653, len:2',
721
+ desc: 'reg:31667, len:2',
722
722
  },
723
- register: { reg: 31653, type: dataType.int32, gain: 1000 },
723
+ register: { reg: 31667, type: dataType.int32, gain: 1000 },
724
724
  },
725
725
  {
726
726
  state: {
@@ -729,9 +729,9 @@ class Emma extends DriverBase {
729
729
  type: 'number',
730
730
  unit: 'kW',
731
731
  role: 'value.power',
732
- desc: 'reg:31655, len:2',
732
+ desc: 'reg:31669, len:2',
733
733
  },
734
- register: { reg: 31655, type: dataType.int32, gain: 1000 },
734
+ register: { reg: 31669, type: dataType.int32, gain: 1000 },
735
735
  },
736
736
  {
737
737
  state: {
@@ -104,6 +104,19 @@ class InverterSun2000 extends DriverBase {
104
104
  }
105
105
  });
106
106
 
107
+ this.chargeSumHelper = new RiemannSum();
108
+ this.adapter.getState(`${this.deviceInfo.path}.battery.currentDayChargeCapacity`, (err, state) => {
109
+ if (!err && state) {
110
+ this.chargeSumHelper.setStart(state?.val, state?.ts, false);
111
+ }
112
+ });
113
+ this.dischargeSumHelper = new RiemannSum();
114
+ this.adapter.getState(`${this.deviceInfo.path}.battery.currentDayDischargeCapacity`, (err, state) => {
115
+ if (!err && state) {
116
+ this.dischargeSumHelper.setStart(state?.val, state?.ts, false);
117
+ }
118
+ });
119
+
107
120
  this.control = new ServiceQueueMap(this.adapter, this.deviceInfo);
108
121
 
109
122
  //https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/stateroles.md
@@ -222,6 +235,35 @@ class InverterSun2000 extends DriverBase {
222
235
  ],
223
236
  //Check if the address field is active
224
237
  checkIfActive: () => this._batteryExists(),
238
+ postHook: path => {
239
+ //calculate daily charge and discharge capacity
240
+ const chargeDischargePower = this.stateCache.get(`${path}battery.chargeDischargePower`)?.value ?? 0;
241
+ if (chargeDischargePower > 0) this.chargeSumHelper.add(chargeDischargePower); //riemann Sum for charge power
242
+ if (chargeDischargePower < 0) this.dischargeSumHelper.add(-chargeDischargePower); //riemann Sum for discharge power
243
+
244
+ const now = new Date();
245
+ const minute = now.getMinutes();
246
+ const hour = now.getHours();
247
+ //reset at 00:00 - until 00:05 if the inverter is a bit late with the update
248
+ if (hour !== 0 || minute > 5) {
249
+ const currentDayChargeCapacity = this.stateCache.get(`${path}battery.currentDayChargeCapacity`)?.value;
250
+ if (currentDayChargeCapacity !== undefined) {
251
+ if (!this.chargeSumHelper.startInitialized || currentDayChargeCapacity > this.chargeSumHelper.sum) {
252
+ this.chargeSumHelper.setStart(currentDayChargeCapacity);
253
+ }
254
+ }
255
+
256
+ const currentDayDischargeCapacity = this.stateCache.get(`${path}battery.currentDayDischargeCapacity`)?.value;
257
+ if (currentDayDischargeCapacity !== undefined) {
258
+ if (!this.dischargeSumHelper.startInitialized || currentDayDischargeCapacity > this.dischargeSumHelper.sum) {
259
+ this.dischargeSumHelper.setStart(currentDayDischargeCapacity);
260
+ }
261
+ }
262
+ }
263
+
264
+ this.stateCache.set(`${path}battery.statistics.currentDayChargeCapacity`, this.chargeSumHelper.sum, { type: 'number', stored: true }); //stored for statistics
265
+ this.stateCache.set(`${path}battery.statistics.currentDayDischargeCapacity`, this.dischargeSumHelper.sum, { type: 'number', stored: true }); //stored for statistics
266
+ },
225
267
  },
226
268
  {
227
269
  address: 32064,
@@ -236,7 +278,7 @@ class InverterSun2000 extends DriverBase {
236
278
  name: 'Input power',
237
279
  type: 'number',
238
280
  unit: 'kW',
239
- role: 'value.power.produced',
281
+ role: 'value.power',
240
282
  desc: 'reg:32064, len:2, Power from solar',
241
283
  },
242
284
  register: { reg: 32064, type: dataType.int32, gain: 1000 },
@@ -465,7 +507,7 @@ class InverterSun2000 extends DriverBase {
465
507
  name: 'Total charge',
466
508
  type: 'number',
467
509
  unit: 'kWh',
468
- role: 'value.power.consumption',
510
+ role: 'value.power.consumed',
469
511
  desc: 'reg:38238, len:2',
470
512
  },
471
513
  register: { reg: 38238, type: dataType.uint32, gain: 100 },
@@ -476,7 +518,7 @@ class InverterSun2000 extends DriverBase {
476
518
  name: 'Total discharge',
477
519
  type: 'number',
478
520
  unit: 'kWh',
479
- role: 'value.power.consumption',
521
+ role: 'value.power.produced',
480
522
  desc: 'reg:38240, len:2',
481
523
  },
482
524
  register: { reg: 38240, type: dataType.uint32, gain: 100 },
@@ -508,7 +550,7 @@ class InverterSun2000 extends DriverBase {
508
550
  name: 'Total charge',
509
551
  type: 'number',
510
552
  unit: 'kWh',
511
- role: 'value.power.consumption',
553
+ role: 'value.power.consumed',
512
554
  desc: 'reg:38280, len:2',
513
555
  },
514
556
  register: { reg: 38280, type: dataType.uint32, gain: 100 },
@@ -519,7 +561,7 @@ class InverterSun2000 extends DriverBase {
519
561
  name: 'Total discharge',
520
562
  type: 'number',
521
563
  unit: 'kWh',
522
- role: 'value.power.consumption',
564
+ role: 'value.power.produced',
523
565
  desc: 'reg:38282, len:2',
524
566
  },
525
567
  register: { reg: 38282, type: dataType.uint32, gain: 100 },
@@ -551,7 +593,7 @@ class InverterSun2000 extends DriverBase {
551
593
  name: 'Total charge',
552
594
  type: 'number',
553
595
  unit: 'kWh',
554
- role: 'value.power.consumption',
596
+ role: 'value.power.consumed',
555
597
  desc: 'reg:38322, len:2',
556
598
  },
557
599
  register: { reg: 38322, type: dataType.uint32, gain: 100 },
@@ -562,7 +604,7 @@ class InverterSun2000 extends DriverBase {
562
604
  name: 'Total discharge',
563
605
  type: 'number',
564
606
  unit: 'kWh',
565
- role: 'value.power.consumption',
607
+ role: 'value.power.produced',
566
608
  desc: 'reg:38324, len:2',
567
609
  },
568
610
  register: { reg: 38324, type: dataType.uint32, gain: 100 },
@@ -843,7 +885,7 @@ class InverterSun2000 extends DriverBase {
843
885
  name: 'Total charge',
844
886
  type: 'number',
845
887
  unit: 'kWh',
846
- role: 'value.power.consumption',
888
+ role: 'value.power.consumed',
847
889
  desc: 'reg:37780, len:2',
848
890
  },
849
891
  register: { reg: 37780, type: dataType.uint32, gain: 100 },
@@ -854,7 +896,7 @@ class InverterSun2000 extends DriverBase {
854
896
  name: 'Total discharge',
855
897
  type: 'number',
856
898
  unit: 'kWh',
857
- role: 'value.power.consumption',
899
+ role: 'value.power.produced',
858
900
  desc: 'reg:37782, len:2',
859
901
  },
860
902
  register: { reg: 37782, type: dataType.uint32, gain: 100 },
@@ -865,10 +907,11 @@ class InverterSun2000 extends DriverBase {
865
907
  name: 'Current day charge capacity',
866
908
  type: 'number',
867
909
  unit: 'kWh',
868
- role: 'value.power.consumption',
910
+ role: 'value.power.consumed',
869
911
  desc: 'reg:37784, len:2',
870
912
  },
871
913
  register: { reg: 37784, type: dataType.uint32, gain: 100 },
914
+ //store: storeType.never,
872
915
  },
873
916
  {
874
917
  state: {
@@ -876,10 +919,11 @@ class InverterSun2000 extends DriverBase {
876
919
  name: 'Current day discharge capacity',
877
920
  type: 'number',
878
921
  unit: 'kWh',
879
- role: 'value.power.consumption',
922
+ role: 'value.power.produced',
880
923
  desc: 'reg:37786, len:2',
881
924
  },
882
925
  register: { reg: 37786, type: dataType.uint32, gain: 100 },
926
+ //store: storeType.never,
883
927
  },
884
928
  ],
885
929
  checkIfActive: () => this._batteryExists(),
@@ -1466,7 +1510,7 @@ class InverterSun2000 extends DriverBase {
1466
1510
  name: 'Positive active energy',
1467
1511
  type: 'number',
1468
1512
  unit: 'kWh',
1469
- role: 'value.power.consumption',
1513
+ role: 'value.power.produced',
1470
1514
  desc: 'reg:37119, len:2',
1471
1515
  },
1472
1516
  register: { reg: 37119, type: dataType.int32, gain: 100 },
@@ -1477,7 +1521,7 @@ class InverterSun2000 extends DriverBase {
1477
1521
  name: 'Reverse active energy',
1478
1522
  type: 'number',
1479
1523
  unit: 'kWh',
1480
- role: 'value.power.consumption',
1524
+ role: 'value.power.consumed',
1481
1525
  desc: 'reg:37121, len:2',
1482
1526
  },
1483
1527
  register: { reg: 37121, type: dataType.int32, gain: 100 },
@@ -1488,7 +1532,7 @@ class InverterSun2000 extends DriverBase {
1488
1532
  name: 'Accumulated reactive power',
1489
1533
  type: 'number',
1490
1534
  unit: 'kVarh',
1491
- role: 'value.power.reactive.consumption',
1535
+ role: 'value.power.reactive.consumed',
1492
1536
  desc: 'reg:37123, len:2',
1493
1537
  },
1494
1538
  register: { reg: 37123, type: dataType.int32, gain: 100 },
@@ -1643,7 +1687,7 @@ class InverterSun2000 extends DriverBase {
1643
1687
  name: 'Portal yield today',
1644
1688
  type: 'number',
1645
1689
  unit: 'kWh',
1646
- role: 'value.power.consumption',
1690
+ role: 'value.power.produced',
1647
1691
  desc: 'yield from the portal',
1648
1692
  },
1649
1693
  fn: path => {
@@ -1666,7 +1710,7 @@ class InverterSun2000 extends DriverBase {
1666
1710
  name: 'Solar yield today',
1667
1711
  type: 'number',
1668
1712
  unit: 'kWh',
1669
- role: 'value.power.consumption',
1713
+ role: 'value.power.produced',
1670
1714
  desc: 'Riemann sum of input power with efficiency loss',
1671
1715
  },
1672
1716
  fn: path => {
@@ -1680,7 +1724,7 @@ class InverterSun2000 extends DriverBase {
1680
1724
  name: 'Active Energy today',
1681
1725
  type: 'number',
1682
1726
  unit: 'kWh',
1683
- role: 'value.power.consumption',
1727
+ role: 'value.power.produced',
1684
1728
  desc: 'Amount of Riemann sum of sum of active power',
1685
1729
  },
1686
1730
  fn: path => {
@@ -2104,7 +2148,7 @@ class InverterSun2000_M1 extends InverterSun2000 {
2104
2148
  name: 'Total charge',
2105
2149
  type: 'number',
2106
2150
  unit: 'kWh',
2107
- role: 'value.power.consumption',
2151
+ role: 'value.power.consumed',
2108
2152
  desc: 'reg:38364, len:2',
2109
2153
  },
2110
2154
  register: { reg: 38364, type: dataType.uint32, gain: 100 },
@@ -2115,7 +2159,7 @@ class InverterSun2000_M1 extends InverterSun2000 {
2115
2159
  name: 'Total discharge',
2116
2160
  type: 'number',
2117
2161
  unit: 'kWh',
2118
- role: 'value.power.consumption',
2162
+ role: 'value.power.produced',
2119
2163
  desc: 'reg:38366, len:2',
2120
2164
  },
2121
2165
  register: { reg: 38366, type: dataType.uint32, gain: 100 },
@@ -2147,7 +2191,7 @@ class InverterSun2000_M1 extends InverterSun2000 {
2147
2191
  name: 'Total charge',
2148
2192
  type: 'number',
2149
2193
  unit: 'kWh',
2150
- role: 'value.power.consumption',
2194
+ role: 'value.power.consumed',
2151
2195
  desc: 'reg:38406, len:2',
2152
2196
  },
2153
2197
  register: { reg: 38406, type: dataType.uint32, gain: 100 },
@@ -2158,7 +2202,7 @@ class InverterSun2000_M1 extends InverterSun2000 {
2158
2202
  name: 'Total discharge',
2159
2203
  type: 'number',
2160
2204
  unit: 'kWh',
2161
- role: 'value.power.consumption',
2205
+ role: 'value.power.produced',
2162
2206
  desc: 'reg:38408, len:2',
2163
2207
  },
2164
2208
  register: { reg: 38408, type: dataType.uint32, gain: 100 },
@@ -2190,7 +2234,7 @@ class InverterSun2000_M1 extends InverterSun2000 {
2190
2234
  name: 'Total charge',
2191
2235
  type: 'number',
2192
2236
  unit: 'kWh',
2193
- role: 'value.power.consumption',
2237
+ role: 'value.power.consumed',
2194
2238
  desc: 'reg:38448, len:2',
2195
2239
  },
2196
2240
  register: { reg: 38448, type: dataType.uint32, gain: 100 },
@@ -2201,7 +2245,7 @@ class InverterSun2000_M1 extends InverterSun2000 {
2201
2245
  name: 'Total discharge',
2202
2246
  type: 'number',
2203
2247
  unit: 'kWh',
2204
- role: 'value.power.consumption',
2248
+ role: 'value.power.produced',
2205
2249
  desc: 'reg:38450, len:2',
2206
2250
  },
2207
2251
  register: { reg: 38450, type: dataType.uint32, gain: 100 },
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * Serializes an object to JSON, converting functions to their string representation.
5
5
  *
6
- * @param {any} obj - The object to serialize.
6
+ * @param {object} obj - The object to serialize.
7
7
  * @returns {string} JSON string where functions are represented as strings.
8
8
  */
9
9
  function stringifyWithFunctions(obj) {
@@ -22,30 +22,8 @@ function stringifyWithFunctions(obj) {
22
22
  2,
23
23
  );
24
24
  }
25
- /*
26
- const FUNCTION_KEYS = ['formatter', 'render', 'parser'];
27
25
 
28
- function reviveFunctions(obj, key = '') {
29
- if (typeof obj === 'string' && FUNCTION_KEYS.includes(key)) {
30
- const str = obj.trim();
31
-
32
- try {
33
- return new Function(`return (${str})`)();
34
- } catch {
35
- return obj;
36
- }
37
- }
38
-
39
- if (typeof obj === 'object' && obj !== null) {
40
- for (const k in obj) {
41
- obj[k] = reviveFunctions(obj[k], k);
42
- }
43
- }
44
-
45
- return obj;
46
- }
47
- */
48
- const FUNCTION_KEYS = ['formatter', 'parser', 'render', 'labelFormatter', 'valueFormatter', 'position'];
26
+ const FUNCTION_KEYS = ['formatter', 'parser', 'render', 'labelFormatter', 'valueFormatter', 'position', 'interval'];
49
27
 
50
28
  function reviveFunctions(obj, key = '') {
51
29
  if (typeof obj === 'string' && FUNCTION_KEYS.includes(key)) {
@@ -109,7 +87,7 @@ function deepMerge(target, source) {
109
87
  *
110
88
  * @param {object} obj - The object to modify.
111
89
  * @param {string} path - Dot‑separated path (e.g., "a.b.c").
112
- * @param {any} value - The value to set at the specified path.
90
+ * @param {string} value - The value to set at the specified path.
113
91
  */
114
92
  function setByPath(obj, path, value) {
115
93
  const keys = path.split('.');
@@ -194,7 +194,7 @@ class ModbusServer {
194
194
  * @param {number} startAddr The start address of the register.
195
195
  * @param {number} length The length of the register.
196
196
  * @param {number} unitId The modbus unitId.
197
- * @param {Function} callback The callback function.
197
+ * @param {callback} callback The callback function.
198
198
  * @returns {Promise<void>}
199
199
  */
200
200