iobroker.senec 1.3.10 → 1.4.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 CHANGED
@@ -366,53 +366,18 @@ This channel contains calculated values. Currently these are day/week/month/year
366
366
  *Read-only number, which designates the number of wallbox [0..3]. This is only available on systems with configured wallboxes.*
367
367
 
368
368
  ## Changelog
369
+ ### 1.4.1 (NoBl)
370
+ * Fix: Autarky calculations are working again.
371
+
372
+ ### 1.4.0 (NoBl)
373
+ * Added object caching along with some minor code updates. Due to the amount of objects we deal with caching is about mandatory.
374
+
369
375
  ### 1.3.10 (NoBl)
370
376
  * Fixed wrong Unit for STATISTIC.LIVE_WB_ENERGY
371
377
  * Updated to json Admin UI
372
378
  * Technical Updates
373
379
  * Added more state_attr definitions
374
380
 
375
- ### 1.3.9 (Nobl)
376
- * Added (some) Wallbox Datapoints to high-prio polling
377
- * Added more state definitions
378
-
379
- ### 1.3.8 (NoBl)
380
- * Removed (unnecessary) admin tab
381
-
382
- ### 1.3.7 (NoBl, noffycws, git-ZeR0)
383
- * Updates to state translations (new values when SENEC turned off appliances)
384
- * Added state definitions
385
- * Added high priority datapoints: temperatures, voltages, ... to better monitor safety relevant data
386
-
387
- ### 1.3.6 (NoBl)
388
- * Fixed log.warning error
389
-
390
- ### 1.3.5 (NoBl)
391
- * Added more state attributes (if you have updated descriptions or anything, please open an issue!)
392
- * Workaround in case SENEC reports bogus request data
393
-
394
- ### 1.3.4 (NoBl)
395
- * Moved from request to axios
396
- * Added more state attributes (if you have updated descriptions or anything, please open an issue!)
397
-
398
- ### 1.3.3 (NoBl)
399
- * Updated to current template.
400
-
401
- ### 1.3.2 (NoBl)
402
- * Autarky without decimal places (again). They are causing more updates than we really need.
403
- * Autarky values won't reset to 0 at change of timeframe (day, week, ...) anymore. They are calculated based on reference values anyways.
404
- * Ensuring that only values meant to be changeable by user are defined so (attribute changes upon the next update of value)
405
-
406
- ### 1.3.1 (NoBl) 20210513
407
- * Added calculation of autarky for day/week/month/year
408
-
409
- ### 1.3.0 (NoBl) 20210509
410
- * Rewrote translations handling
411
- * Added translations for wallbox status.
412
- * Translated status get an extra datapoint with _Text as postfix. Former translations that didn't add an extra dp will now revert to their numeric representation and add the _Text DP.
413
- * Translations are now handled via lib/state_trans.js for all 3 languages available in the senec system (german, english, italian).
414
- * Language used is decided by the language of the SENEC appliance.
415
-
416
381
  ### [Former Updates](CHANGELOG_old.md)
417
382
 
418
383
  ## License
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "senec",
4
- "version": "1.3.10",
4
+ "version": "1.4.1",
5
5
  "news": {
6
+ "1.4.1": {
7
+ "en": "Autarky calculations are working again.",
8
+ "de": "Autarkieberechnungen funktionieren wieder.",
9
+ "ru": "Расчеты Autarky снова работают.",
10
+ "pt": "Cálculos autarcos estão a funcionar outra vez.",
11
+ "nl": "Autarische berekeningen werken weer.",
12
+ "fr": "Les calculs Autarky fonctionnent à nouveau.",
13
+ "it": "I calcoli autarky funzionano di nuovo.",
14
+ "es": "Los cálculos autárquicos están funcionando de nuevo.",
15
+ "pl": "Ponowne obliczenia autarktyczne działają ponownie.",
16
+ "uk": "Аутарки знову працюють.",
17
+ "zh-cn": "Autarky的计算正再次工作。."
18
+ },
19
+ "1.4.0": {
20
+ "en": "Added object caching and minor code updates. Due to the amount of objects we deal with caching is about mandatory.",
21
+ "de": "Objekt-Caching und kleinere Code-Updates hinzugefügt. Aufgrund der Menge an Objekten, die der Adapter bearbeitet, ist Caching zwingend notwendig.",
22
+ "ru": "Добавлена кэшировка объекта и незначительные обновления кода. В связи с количеством объектов, с которыми мы занимаемся кэшированием, является обязательным.",
23
+ "pt": "Adicionado cache de objeto e pequenas atualizações de código. Devido à quantidade de objetos que lidamos com caching é sobre obrigatória.",
24
+ "nl": "Toegevoegd voorwerp caching en kleine code updates. Gezien de hoeveelheid objecten die we met caching hebben, gaat het over verplichting.",
25
+ "fr": "Ajout de cache d'objet et de mises à jour de code mineur. En raison de la quantité d'objets que nous traitons avec le cache est environ obligatoire.",
26
+ "it": "Aggiunti caching oggetto e aggiornamenti di codice minori. A causa della quantità di oggetti che abbiamo a che fare con il caching è circa obbligatorio.",
27
+ "es": "Añadido objeto caching y actualizaciones de código menor. Debido a la cantidad de objetos que tratamos con el caché es sobre obligatorio.",
28
+ "pl": "Dodany obiekt caching i drobnych aktualizacji kodu. Ze względu na ilość przedmiotów, które traktują z cachingiem, dotyczy obowiązkowych.",
29
+ "uk": "Додано кешування об'єкта та оновлення коду неповного розміру. У зв'язку з кількістю об'єктів, які ми маємо справу з кешуванням, є обов'язковим.",
30
+ "zh-cn": "添加了目标包和小法典的更新。 由于我们所处理的物品数量是强制性的。."
31
+ },
6
32
  "1.3.10": {
7
33
  "en": "Fixed wrong Unit for STATISTIC.LIVE_WB_ENERGY, added more state_attr. Moved to json admin UI and other technical updates.",
8
34
  "de": "Fehler behoben Einheit für STATISTIC.LIVE_WB_ENERGY, hinzugefügt mehr state_attr. Umgezogen zu json admin UI und anderen technischen Updates.",
@@ -48,17 +74,17 @@
48
74
  "zh-cn": "塞内克"
49
75
  },
50
76
  "desc": {
51
- "en": "This adapter reads available values from a Senec Home V2.1 system using lala.cgi",
52
- "de": "Dieser Adapter liest verfügbare Werte von einem Senec Home V2.1 System mit lala.cgi",
53
- "ru": "Этот адаптер читает доступные значения от системы Senec Home V2.1 с использованием lala.cgi",
54
- "pt": "Este adaptador lê valores disponíveis de um sistema Senec Home V2.1 usando lala.cgi",
55
- "nl": "Deze adapter leest beschikbare waarden van een Senec Home V2.1 systeem met lala",
56
- "fr": "Cet adaptateur lit les valeurs disponibles d'un système Senec Home V2.1 en utilisant lala.cgi",
57
- "it": "Questo adattatore legge i valori disponibili da un sistema Senec Home V2.1 utilizzando lala.cgi",
58
- "es": "Este adaptador lee los valores disponibles de un sistema Senec Home V2.1 utilizando lala.cgi",
59
- "pl": "Ten adapter odczytuje dostępne wartości z systemu Senec Home V2.1 używając lala.cgi",
60
- "uk": "Цей адаптер читає доступні значення з системи Senec Home V2.1 за допомогою lala.cgi",
61
- "zh-cn": "这种适应者用Fla.cgi改为Senec Home V2.1系统可得到的数值。"
77
+ "en": "This adapter reads available values from a Senec Home V2.1 (and later) system using lala.cgi",
78
+ "de": "Dieser Adapter liest verfügbare Werte von einem Senec Home V2.1 (und später) System mit lala.cgi",
79
+ "ru": "Этот адаптер считывает доступные значения от системы Senec Home V2.1 (и позже) с помощью lala.cgi",
80
+ "pt": "Este adaptador lê valores disponíveis de um sistema Senec Home V2.1 (e posterior) usando lala.cgi",
81
+ "nl": "Deze adapter leest beschikbare waarden van een Senec Home V21 (en later) systeem met lala",
82
+ "fr": "Cet adaptateur lit les valeurs disponibles d'un système Senec Home V2.1 (et plus tard) utilisant lala.cgi",
83
+ "it": "Questo adattatore legge i valori disponibili da un sistema Senec Home V2.1 (e successivamente) utilizzando lala.cgi",
84
+ "es": "Este adaptador lee los valores disponibles de un sistema Senec Home V2.1 (y más tarde) usando lala.cgi",
85
+ "pl": "Ta adapter przeczytała dostępne wartości z systemu Senec Home V2.1 (a później) używając lala.cgi",
86
+ "uk": "Цей адаптер зчитуває доступні значення від Senec Home V2.1 (і пізніше) системи за допомогою lala.cgi",
87
+ "zh-cn": "这种适应者从Senec Home V2.1(和以后)利用Fla.cgi阅读了可使用的数值。"
62
88
  },
63
89
  "authors": [
64
90
  "NoBl <github@bluemle.org>"
package/main.js CHANGED
@@ -1,13 +1,17 @@
1
1
  'use strict';
2
2
 
3
3
  const utils = require('@iobroker/adapter-core');
4
- const axios = require('axios');
4
+ const axios = require('axios').default;
5
5
  const state_attr = require(__dirname + '/lib/state_attr.js');
6
6
  const state_trans = require(__dirname + '/lib/state_trans.js');
7
7
 
8
8
  let retry = 0; // retry-counter
9
9
  let retryLowPrio = 0; // retry-counter
10
10
 
11
+ let unloaded = false;
12
+
13
+ const knownObjects = {};
14
+
11
15
  class Senec extends utils.Adapter {
12
16
 
13
17
  /**
@@ -47,6 +51,7 @@ class Senec extends utils.Adapter {
47
51
  */
48
52
  onUnload(callback) {
49
53
  try {
54
+ unloaded = true;
50
55
  if (this.timer) {
51
56
  clearTimeout(this.timer);
52
57
  }
@@ -114,7 +119,7 @@ class Senec extends utils.Adapter {
114
119
  * @param url to read from
115
120
  * @param form to post
116
121
  */
117
- async doGet(pUrl, pForm, caller, pollingTimeout) {
122
+ doGet(pUrl, pForm, caller, pollingTimeout) {
118
123
  return new Promise(function (resolve, reject) {
119
124
  axios({
120
125
  method: 'post',
@@ -187,6 +192,7 @@ class Senec extends utils.Adapter {
187
192
  await this.evalPoll(obj);
188
193
 
189
194
  retry = 0;
195
+ if (unloaded) return;
190
196
  this.timer = setTimeout(() => this.readSenecV21(), this.config.interval * 1000);
191
197
  } catch (error) {
192
198
  if ((retry == this.config.retries) && this.config.retries < 999) {
@@ -224,6 +230,7 @@ class Senec extends utils.Adapter {
224
230
  await this.evalPoll(obj);
225
231
 
226
232
  retryLowPrio = 0;
233
+ if (unloaded) return;
227
234
  this.timerLowPrio = setTimeout(() => this.readSenecV21LowPrio(), this.config.intervalLow * 1000 * 60);
228
235
  } catch (error) {
229
236
  if ((retryLowPrio == this.config.retries) && this.config.retries < 999) {
@@ -247,50 +254,51 @@ class Senec extends utils.Adapter {
247
254
  return;
248
255
  }
249
256
  this.log.silly('(doState) Update: ' + name + ': ' + value);
250
- await this.setObjectNotExistsAsync(name, {
251
- type: 'state',
252
- common: {
253
- name: description,
254
- type: typeof(value),
255
- role: 'value',
256
- unit: unit,
257
- read: true,
258
- write: write
259
- },
260
- native: {}
261
- });
262
-
257
+
258
+ const valueType = value !== null && value !== undefined ? typeof value : "mixed";
259
+
263
260
  // Check object for changes:
264
- var obj = await this.getObjectAsync(name);
265
- if (obj.common.name != description) {
266
- this.log.debug("(doState) Updating object: " + name + " (desc): " + obj.common.name + " -> " + description);
267
- await this.extendObject(name, {common: {name: description}});
268
- }
269
- if (obj.common.type != typeof(value)) {
270
- this.log.debug("(doState) Updating object: " + name + " (type): " + obj.common.type + " -> " + typeof(value));
271
- await this.extendObject(name, {common: {type: typeof(value)}});
272
- }
273
- if (obj.common.unit != unit) {
274
- this.log.debug("(doState) Updating object: " + name + " (unit): " + obj.common.unit + " -> " + unit);
275
- await this.extendObject(name, {common: {unit: unit}});
276
- }
277
- if (obj.common.write != write) {
278
- this.log.debug("(doState) Updating object: " + name + " (write): " + obj.common.write + " -> " + write);
279
- await this.extendObject(name, {common: {write: write}});
280
- }
281
-
282
- var oldState = await this.getStateAsync(name);
283
- if (oldState) {
284
- if (oldState.val === value) {
285
- await this.checkUpdateSelfStat(name);
286
- return;
261
+ const obj = knownObjects[name] ? knownObjects[name] : await this.getObjectAsync(name);
262
+ if (obj) {
263
+ const newCommon = {};
264
+ if (obj.common.name !== description) {
265
+ this.log.debug("(doState) Updating object: " + name + " (desc): " + obj.common.name + " -> " + description);
266
+ newCommon.name = description;
287
267
  }
288
- this.log.debug('(doState) Update: ' + name + ': ' + oldState.val + ' -> ' + value);
289
- }
290
- await this.setStateAsync(name, {
291
- val: value,
292
- ack: true
293
- });
268
+ if (obj.common.type !== valueType) {
269
+ this.log.debug("(doState) Updating object: " + name + " (type): " + obj.common.type + " -> " + typeof value);
270
+ newCommon.type = valueType;
271
+ }
272
+ if (obj.common.unit !== unit) {
273
+ this.log.debug("(doState) Updating object: " + name + " (unit): " + obj.common.unit + " -> " + unit);
274
+ newCommon.unit = unit;
275
+ }
276
+ if (obj.common.write !== write) {
277
+ this.log.debug("(doState) Updating object: " + name + " (write): " + obj.common.write + " -> " + write);
278
+ newCommon.write = write;
279
+ }
280
+ if (Object.keys(newCommon).length > 0) {
281
+ await this.extendObjectAsync(name, { common: newCommon });
282
+ }
283
+ } else {
284
+ knownObjects[name] = {
285
+ type: "state",
286
+ common: {
287
+ name: description,
288
+ type: valueType,
289
+ role: "value",
290
+ unit: unit,
291
+ read: true,
292
+ write: write
293
+ },
294
+ native: {}
295
+ };
296
+ await this.setObjectNotExistsAsync(name, knownObjects[name]);
297
+ }
298
+ await this.setStateChangedAsync(name, {
299
+ val: value,
300
+ ack: true
301
+ });
294
302
  await this.checkUpdateSelfStat(name);
295
303
  await this.doDecode(name, value);
296
304
  }
@@ -332,8 +340,9 @@ class Senec extends utils.Adapter {
332
340
  * creates / updates the state.
333
341
  */
334
342
  async evalPoll(obj) {
335
- for (let[key1, value1]of Object.entries(obj)) {
336
- for (let[key2, value2]of Object.entries(value1)) {
343
+ if (unloaded) return;
344
+ for (const[key1, value1] of Object.entries(obj)) {
345
+ for (const[key2, value2] of Object.entries(value1)) {
337
346
  if (value2 !== "VARIABLE_NOT_FOUND" && key2 !== "OBJECT_NOT_FOUND") {
338
347
  const key = key1 + '.' + key2;
339
348
  if (state_attr[key] === undefined) {
@@ -397,7 +406,7 @@ class Senec extends utils.Adapter {
397
406
  this.log.warn("(Calc) Not updating reference value for: " + name.substring(10) + "! Old RefValue (" + valRef + ") >= new RefValue (" + valCur + "). Impossible situation. If this is intentional, please update via admin!");
398
407
  }
399
408
  } else {
400
- this.log.silly("(Calc) Updating " + day +" value for: " + name.substring(10) + ": " + Number((valCur - valRef).toFixed(2)));
409
+ this.log.debug("(Calc) Updating " + day +" value for: " + name.substring(10) + ": " + Number((valCur - valRef).toFixed(2)));
401
410
  // update today's value
402
411
  await this.doState(key + today, Number((valCur - valRef).toFixed(2)), descToday, unitToday, false);
403
412
  }
@@ -447,9 +456,11 @@ class Senec extends utils.Adapter {
447
456
  }
448
457
  // update today's value - but beware of div/0
449
458
  var newVal = 0;
450
- if (valHouseCons > 0) newVal = Number((((valPVGen - valGridExp - valBatCharge + valBatDischarge) / valHouseCons) * 100).toFixed(0));
451
- this.log.silly("(Autarky) Updating Autarky " + day +" value for: " + key + today + ": " + newVal);
452
- if (valHouseCons > 0) await this.doState(key + today, newVal, descToday, unitToday, false);
459
+ if (valHouseCons > 0) {
460
+ newVal = Number((((valPVGen - valGridExp - valBatCharge + valBatDischarge) / valHouseCons) * 100).toFixed(0));
461
+ this.log.debug("(Autarky) Updating Autarky " + day +" value for: " + key + today + ": " + newVal);
462
+ await this.doState(key + today, newVal, descToday, unitToday, false);
463
+ }
453
464
  }
454
465
 
455
466
  }
@@ -474,7 +485,7 @@ const ValueTyping = (key, value) => {
474
485
  } else if (isIP) {
475
486
  return DecToIP(value);
476
487
  } else if (multiply !== 1) {
477
- return (value *= multiply).toFixed(2);
488
+ return parseFloat((value * multiply).toFixed(2));
478
489
  } else {
479
490
  return value;
480
491
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.senec",
3
- "version": "1.3.10",
3
+ "version": "1.4.1",
4
4
  "description": "Senec Home",
5
5
  "author": {
6
6
  "name": "NoBl",
@@ -47,9 +47,9 @@
47
47
  "eslint": "^8.47.0",
48
48
  "mocha": "^10.2.0",
49
49
  "proxyquire": "^2.1.3",
50
- "sinon": "^15.0.4",
50
+ "sinon": "^15.2.0",
51
51
  "sinon-chai": "^3.7.0",
52
- "typescript": "~4.9.5"
52
+ "typescript": "~5.1.6"
53
53
  },
54
54
  "main": "main.js",
55
55
  "files": [