iobroker.sun2000 2.4.5 → 2.5.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/README.md +15 -13
- package/admin/jsonConfig.json5 +33 -0
- package/io-package.json +39 -38
- package/lib/controls/inverter_service_queue.js +1 -1
- package/lib/drivers/driver_base.js +2 -1
- package/lib/drivers/driver_emma.js +14 -16
- package/lib/drivers/driver_inverter.js +70 -23
- package/lib/json_helper.js +3 -25
- package/lib/modbus/modbus_server.js +2 -2
- package/lib/register.js +178 -39
- package/lib/statistics/breakdownChartHelper.js +131 -0
- package/lib/statistics/consumptionBreakdown.js +304 -0
- package/lib/statistics/statistics.js +1458 -0
- package/lib/tools.js +24 -5
- package/main.js +18 -5
- package/package.json +12 -13
- package/lib/statistics.js +0 -1412
package/lib/tools.js
CHANGED
|
@@ -57,6 +57,7 @@ class Logging {
|
|
|
57
57
|
class StateMap {
|
|
58
58
|
constructor() {
|
|
59
59
|
this.stateMap = new Map();
|
|
60
|
+
this._mapDecimalPlaces = 10; //internal
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
round(num, decimalPlaces = 0) {
|
|
@@ -65,7 +66,12 @@ class StateMap {
|
|
|
65
66
|
return Math.round(n) / p;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
get(id) {
|
|
69
|
+
get(id, decimalPlaces = -1) {
|
|
70
|
+
const mapItem = this.stateMap.get(id);
|
|
71
|
+
if (decimalPlaces >= 0 && mapItem?.type === 'number') {
|
|
72
|
+
return { ...mapItem, value: this.round(mapItem.value, decimalPlaces) };
|
|
73
|
+
}
|
|
74
|
+
|
|
69
75
|
return this.stateMap.get(id);
|
|
70
76
|
}
|
|
71
77
|
|
|
@@ -78,7 +84,7 @@ class StateMap {
|
|
|
78
84
|
if (value !== null) {
|
|
79
85
|
if (options?.type == 'number') {
|
|
80
86
|
//value = Math.round((value + Number.EPSILON) * 1000) / 1000; //3rd behind
|
|
81
|
-
value = this.round(value,
|
|
87
|
+
value = this.round(Number(value), this._mapDecimalPlaces);
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
const existing = this.get(id); //existing entry
|
|
@@ -86,6 +92,7 @@ class StateMap {
|
|
|
86
92
|
const mapOptions = {
|
|
87
93
|
id: id,
|
|
88
94
|
value: value,
|
|
95
|
+
type: options?.type ? options.type : existing?.type ? existing.type : typeof value,
|
|
89
96
|
stored: existing?.stored ? existing.stored : false,
|
|
90
97
|
};
|
|
91
98
|
if (options?.renew || existing?.value !== value) {
|
|
@@ -166,6 +173,11 @@ class RiemannSum {
|
|
|
166
173
|
constructor(autoResetAtMitnight = true) {
|
|
167
174
|
this._resetAtMitnight = autoResetAtMitnight;
|
|
168
175
|
this.reset();
|
|
176
|
+
this._startInitialized = false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
get startInitialized() {
|
|
180
|
+
return this._startInitialized;
|
|
169
181
|
}
|
|
170
182
|
|
|
171
183
|
get lastDate() {
|
|
@@ -211,10 +223,17 @@ class RiemannSum {
|
|
|
211
223
|
return this._sum;
|
|
212
224
|
}
|
|
213
225
|
|
|
214
|
-
setStart(sum, ts) {
|
|
226
|
+
setStart(sum, ts, setStartInitialized = true) {
|
|
215
227
|
if (!isNaN(sum)) {
|
|
216
228
|
this._sum = sum;
|
|
217
|
-
|
|
229
|
+
if (ts === undefined) {
|
|
230
|
+
this._lastDate = new Date();
|
|
231
|
+
} else {
|
|
232
|
+
this._lastDate = new Date(ts);
|
|
233
|
+
}
|
|
234
|
+
if (setStartInitialized) {
|
|
235
|
+
this._startInitialized = true;
|
|
236
|
+
}
|
|
218
237
|
} else {
|
|
219
238
|
this.reset();
|
|
220
239
|
}
|
|
@@ -253,7 +272,7 @@ const createAsyncLock = () => {
|
|
|
253
272
|
/**
|
|
254
273
|
* Warten auf einen Wert, der von einer Funktion zurückgegeben wird.
|
|
255
274
|
* Der Wert wird alle 100ms geprüft. Wenn der Wert innerhalb der angegebenen Zeit nicht gesetzt wurde, wird ein Timeout-Fehler zurückgegeben.
|
|
256
|
-
* @param {
|
|
275
|
+
* @param {unknown} func - Die Funktion, die den Wert zurückgibt.
|
|
257
276
|
* @param {number} [timeout] - Die maximale Wartezeit in ms.
|
|
258
277
|
* @returns {Promise} - Ein Promise, das den Wert zurückgibt oder einen Timeout-Fehler wirft.
|
|
259
278
|
*/
|
package/main.js
CHANGED
|
@@ -486,6 +486,8 @@ class Sun2000 extends utils.Adapter {
|
|
|
486
486
|
//further battery register
|
|
487
487
|
this.settings.ds.batteryUnits = this.config.ds_bu;
|
|
488
488
|
this.settings.ds.batteryPacks = this.config.ds_bp;
|
|
489
|
+
//statistics
|
|
490
|
+
this.settings.statistics = { liveInterval: this.config.stat_liveInterval || 5 }; //min
|
|
489
491
|
|
|
490
492
|
if (this.settings.modbusAdjust) {
|
|
491
493
|
await this.setState('info.JSONhealth', { val: '{message: "Adjust modbus settings"}', ack: true });
|
|
@@ -554,9 +556,9 @@ class Sun2000 extends utils.Adapter {
|
|
|
554
556
|
this.devices.push({
|
|
555
557
|
index: 0,
|
|
556
558
|
duration: 0,
|
|
557
|
-
//modbusId: 1, --> testMode
|
|
558
559
|
modbusId: 0,
|
|
559
560
|
meter: true,
|
|
561
|
+
//testMode: true,
|
|
560
562
|
driverClass: driverClasses.emma,
|
|
561
563
|
});
|
|
562
564
|
}
|
|
@@ -683,6 +685,9 @@ class Sun2000 extends utils.Adapter {
|
|
|
683
685
|
this.pollingTimer && this.clearTimeout(this.pollingTimer);
|
|
684
686
|
this.mitnightTimer && this.clearTimeout(this.mitnightTimer);
|
|
685
687
|
this.watchDogHandle && this.clearInterval(this.watchDogHandle);
|
|
688
|
+
if (typeof this.state.destroy === 'function') {
|
|
689
|
+
this.state.destroy();
|
|
690
|
+
}
|
|
686
691
|
this.modbusClient && this.modbusClient.close();
|
|
687
692
|
this.setState('info.connection', false, true);
|
|
688
693
|
callback();
|
|
@@ -702,19 +707,20 @@ class Sun2000 extends utils.Adapter {
|
|
|
702
707
|
if (state) {
|
|
703
708
|
// The state was changed
|
|
704
709
|
if (state.ack) {
|
|
705
|
-
//this.logger.
|
|
710
|
+
//this.logger.warn(`state ${id} was changed but the ack flag was set. Therefore, no processing takes place!`);
|
|
706
711
|
return;
|
|
707
712
|
}
|
|
708
713
|
const idArray = id.split('.');
|
|
709
714
|
// sun2000.0.inverter.0.control
|
|
710
715
|
if (idArray[2] == 'inverter') {
|
|
711
|
-
const
|
|
712
|
-
|
|
716
|
+
const inverter = this.devices.find(d => d.driverClass == driverClasses.inverter && d.index == Number(idArray[3]));
|
|
717
|
+
//const control = this.devices[Number(idArray[3])].instance.control;
|
|
718
|
+
if (inverter && inverter.instance.control) {
|
|
713
719
|
let serviceId = idArray[5];
|
|
714
720
|
for (let i = 6; i < idArray.length; i++) {
|
|
715
721
|
serviceId += `.${idArray[i]}`;
|
|
716
722
|
}
|
|
717
|
-
control.set(serviceId, state);
|
|
723
|
+
inverter.instance.control.set(serviceId, state);
|
|
718
724
|
}
|
|
719
725
|
//this.log.info(`### state ${id} changed: ${state.val} (ack = ${state.ack})`);
|
|
720
726
|
}
|
|
@@ -747,6 +753,13 @@ class Sun2000 extends utils.Adapter {
|
|
|
747
753
|
this.state.statistics.handleTemplateChange(chartType, state);
|
|
748
754
|
}
|
|
749
755
|
}
|
|
756
|
+
|
|
757
|
+
//sun2000.0.statistics.dataDef.consumptionBreakdown
|
|
758
|
+
if (idArray[2] == 'statistics' && idArray[3] == 'dataDef' && idArray[4] == 'consumptionBreakdown') {
|
|
759
|
+
if (this.state.statistics && typeof this.state.statistics.handleBreakdownChange === 'function') {
|
|
760
|
+
this.state.statistics.handleBreakdownChange(state);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
750
763
|
} else {
|
|
751
764
|
// The state was deleted
|
|
752
765
|
this.logger.info(`state ${id} deleted`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.sun2000",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "sun2000",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bolliy",
|
|
@@ -24,27 +24,26 @@
|
|
|
24
24
|
"url": "https://github.com/bolliy/ioBroker.sun2000.git"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">= 22"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@iobroker/adapter-core": "^3.
|
|
30
|
+
"@iobroker/adapter-core": "^3.4.1",
|
|
31
|
+
"javascript-stringify": "^2.1.0",
|
|
31
32
|
"modbus-serial": "^8.0.25",
|
|
32
33
|
"suncalc2": "^1.8.1",
|
|
33
|
-
"tcp-port-used": "^1.0.
|
|
34
|
-
"javascript-stringify": "^2.1.0"
|
|
34
|
+
"tcp-port-used": "^1.0.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@alcalzone/release-script": "^5.
|
|
38
|
-
"@alcalzone/release-script-plugin-iobroker": "^5.
|
|
39
|
-
"@alcalzone/release-script-plugin-license": "^5.
|
|
40
|
-
"@alcalzone/release-script-plugin-manual-review": "^5.
|
|
37
|
+
"@alcalzone/release-script": "^5.2.1",
|
|
38
|
+
"@alcalzone/release-script-plugin-iobroker": "^5.2.0",
|
|
39
|
+
"@alcalzone/release-script-plugin-license": "^5.2.0",
|
|
40
|
+
"@alcalzone/release-script-plugin-manual-review": "^5.2.0",
|
|
41
41
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
42
|
-
"@iobroker/eslint-config": "^2.
|
|
42
|
+
"@iobroker/eslint-config": "^2.3.4",
|
|
43
43
|
"@iobroker/testing": "^5.2.2",
|
|
44
44
|
"@tsconfig/node22": "^22.0.5",
|
|
45
|
-
"@types/node": "^
|
|
46
|
-
"
|
|
47
|
-
"typescript": "~5.9.3"
|
|
45
|
+
"@types/node": "^22.19.21",
|
|
46
|
+
"typescript": "~6.0.3"
|
|
48
47
|
},
|
|
49
48
|
"main": "main.js",
|
|
50
49
|
"files": [
|