iobroker.sun2000 2.3.7 → 2.4.2

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/lib/tools.js CHANGED
@@ -70,8 +70,10 @@ class StateMap {
70
70
  }
71
71
 
72
72
  set(id, value, options) {
73
- if (options?.type == 'number' && isNaN(value)) {
74
- return;
73
+ if (options?.type == 'number') {
74
+ if (typeof value !== 'number' || isNaN(value)) {
75
+ return;
76
+ }
75
77
  }
76
78
  if (value !== null) {
77
79
  if (options?.type == 'number') {
@@ -170,6 +172,14 @@ class RiemannSum {
170
172
  return this._lastDate ? this._lastDate : new Date();
171
173
  }
172
174
 
175
+ /**
176
+ * Adds the new value to calculate the Riemann sum.
177
+ *
178
+ * This function calculates the Riemann sum by adding the new value multiplied by the time elapsed since the last value,
179
+ * updating the total sum. If the auto reset at midnight is enabled, it resets the sum at midnight.
180
+ *
181
+ * @param {number} newValue - The new value to be added for Riemann sum calculation.
182
+ */
173
183
  add(newValue) {
174
184
  //Obersumme bilden
175
185
  const now = new Date();
@@ -182,12 +192,12 @@ class RiemannSum {
182
192
  0,
183
193
  0, // ...at 00:00:00 hours
184
194
  );
185
- if (this.lastDate?.getTime() <= lastnight.getTime()) {
195
+ if (this.lastDate?.getTime() < lastnight.getTime()) {
186
196
  this.reset();
187
197
  }
188
198
  }
189
199
  if (!isNaN(newValue)) {
190
- this._sum += (newValue * (now.getTime() - this.lastDate.getTime())) / 3600 / 1000; //Hour/Sekunden
200
+ this._sum += (newValue * (now.getTime() - this.lastDate.getTime())) / 3600000; //Hour/Sekunden
191
201
  this._lastDate = now;
192
202
  }
193
203
  }
@@ -240,6 +250,30 @@ const createAsyncLock = () => {
240
250
  };
241
251
  };
242
252
 
253
+ /**
254
+ * Warten auf einen Wert, der von einer Funktion zurückgegeben wird.
255
+ * 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 {Function} func - Die Funktion, die den Wert zurückgibt.
257
+ * @param {number} [timeout] - Die maximale Wartezeit in ms.
258
+ * @returns {Promise} - Ein Promise, das den Wert zurückgibt oder einen Timeout-Fehler wirft.
259
+ */
260
+ const waitForValue = (func, timeout = 5000) => {
261
+ return new Promise((resolve, reject) => {
262
+ const timer = setInterval(() => {
263
+ const variable = func();
264
+ if (variable !== undefined && variable !== null) {
265
+ clearInterval(timer);
266
+ resolve(variable);
267
+ }
268
+ timeout -= 200;
269
+ if (timeout <= 0) {
270
+ clearInterval(timer);
271
+ reject('Timeout: Wert wurde nicht rechtzeitig gesetzt.');
272
+ }
273
+ }, 200); // alle 200ms prüfen
274
+ });
275
+ };
276
+
243
277
  // Get longitude an latidude from system config
244
278
  async function getSystemData(adapter) {
245
279
  const state = await adapter.getForeignObjectAsync('system.config');
@@ -343,6 +377,7 @@ module.exports = {
343
377
  RegisterMap,
344
378
  RiemannSum,
345
379
  createAsyncLock,
380
+ waitForValue,
346
381
  getSystemData,
347
382
  getAstroDate,
348
383
  isSunshine,
package/lib/types.js CHANGED
@@ -258,6 +258,12 @@ const dataType = {
258
258
  },
259
259
  };
260
260
 
261
+ const statisticsType = {
262
+ deltaReset: 'deltaReset',
263
+ delta: 'delta',
264
+ level: 'level',
265
+ };
266
+
261
267
  module.exports = {
262
268
  modbusErrorMessages,
263
269
  getDeviceStatusInfo,
@@ -267,4 +273,5 @@ module.exports = {
267
273
  driverClasses,
268
274
  storeType,
269
275
  dataType,
276
+ statisticsType,
270
277
  };
package/main.js CHANGED
@@ -70,7 +70,8 @@ class Sun2000 extends utils.Adapter {
70
70
  this.on('ready', this.onReady.bind(this));
71
71
  this.on('stateChange', this.onStateChange.bind(this));
72
72
  // this.on('objectChange', this.onObjectChange.bind(this));
73
- // this.on('message', this.onMessage.bind(this));
73
+ // enable message handling for statistics/flexcharts requests
74
+ this.on('message', this.onMessage.bind(this));
74
75
  this.on('unload', this.onUnload.bind(this));
75
76
  }
76
77
 
@@ -356,9 +357,9 @@ class Sun2000 extends utils.Adapter {
356
357
  this.config.timeout = this.config.timeout * 1000;
357
358
  this.updateConfig(this.config);
358
359
  }
359
- if (this.config.sl_active) {
360
+ if (this.config['sl_active']) {
360
361
  //old Smartlogger
361
- this.config.sl_active = false;
362
+ this.config['sl_active'] = false;
362
363
  this.config.integration = 1;
363
364
  this.updateConfig(this.config);
364
365
  }
@@ -658,6 +659,14 @@ class Sun2000 extends utils.Adapter {
658
659
  emma.instance.control.set(serviceId, state);
659
660
  }
660
661
  }
662
+
663
+ //sun2000.0.statistics.flexCharts.template
664
+ if (idArray[2] == 'statistics' && idArray[3] == 'flexCharts' && idArray[4] == 'template') {
665
+ const chartType = idArray[5];
666
+ if (this.state.statistics && typeof this.state.statistics.handleTemplateChange === 'function') {
667
+ this.state.statistics.handleTemplateChange(chartType, state);
668
+ }
669
+ }
661
670
  } else {
662
671
  // The state was deleted
663
672
  this.logger.info(`state ${id} deleted`);
@@ -670,17 +679,22 @@ class Sun2000 extends utils.Adapter {
670
679
  // * Using this method requires "common.messagebox" property to be set to true in io-package.json
671
680
  // * @param {ioBroker.Message} obj
672
681
  // */
673
- // onMessage(obj) {
674
- // if (typeof obj === 'object' && obj.message) {
675
- // if (obj.command === 'send') {
676
- // // e.g. send email or pushover or whatever
677
- // this.log.info('send command');
678
-
679
- // // Send response in callback if required
680
- // if (obj.callback) this.sendTo(obj.from, obj.command, 'Message received', obj.callback);
681
- // }
682
- // }
683
- // }
682
+
683
+ // handle incoming messages (used by flexcharts script source)
684
+ onMessage(obj) {
685
+ if (typeof obj === 'object' && obj.message) {
686
+ // support a dedicated command 'statistics' to generate chart data
687
+ if (obj.command === 'statistics') {
688
+ if (this.state.statistics && typeof this.state.statistics.handleFlexMessage === 'function') {
689
+ this.state.statistics.handleFlexMessage(obj.message, result => {
690
+ if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback);
691
+ });
692
+ } else {
693
+ if (obj.callback) this.sendTo(obj.from, obj.command, { error: 'statistics unavailable' }, obj.callback);
694
+ }
695
+ }
696
+ }
697
+ }
684
698
  }
685
699
 
686
700
  if (require.main !== module) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.sun2000",
3
- "version": "2.3.7",
3
+ "version": "2.4.2",
4
4
  "description": "sun2000",
5
5
  "author": {
6
6
  "name": "bolliy",
@@ -28,20 +28,21 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@iobroker/adapter-core": "^3.3.2",
31
- "modbus-serial": "^8.0.23",
31
+ "modbus-serial": "^8.0.25",
32
32
  "suncalc2": "^1.8.1",
33
- "tcp-port-used": "^1.0.2"
33
+ "tcp-port-used": "^1.0.2",
34
+ "javascript-stringify": "^2.1.0"
34
35
  },
35
36
  "devDependencies": {
36
- "@alcalzone/release-script": "^5.0.0",
37
- "@alcalzone/release-script-plugin-iobroker": "^4.0.0",
38
- "@alcalzone/release-script-plugin-license": "^4.0.0",
39
- "@alcalzone/release-script-plugin-manual-review": "^4.0.0",
37
+ "@alcalzone/release-script": "^5.1.1",
38
+ "@alcalzone/release-script-plugin-iobroker": "^5.1.2",
39
+ "@alcalzone/release-script-plugin-license": "^5.1.1",
40
+ "@alcalzone/release-script-plugin-manual-review": "^5.1.1",
40
41
  "@iobroker/adapter-dev": "^1.5.0",
41
42
  "@iobroker/eslint-config": "^2.2.0",
42
43
  "@iobroker/testing": "^5.2.2",
43
- "@tsconfig/node20": "^20.1.8",
44
- "@types/node": "^25.0.10",
44
+ "@tsconfig/node22": "^22.0.5",
45
+ "@types/node": "^25.5.0",
45
46
  "globals": "^16.5.0",
46
47
  "typescript": "~5.9.3"
47
48
  },