iobroker.senec 1.6.15 → 1.6.16
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 +4 -1
- package/io-package.json +14 -14
- package/main.js +35 -14
- package/package.json +18 -18
package/README.md
CHANGED
|
@@ -299,6 +299,9 @@ This channel contains values polled from SENEC App-API.
|
|
|
299
299
|
|
|
300
300
|
## Changelog
|
|
301
301
|
|
|
302
|
+
### 1.6.16
|
|
303
|
+
* Moved Dashboard to ApiV2. This invalidates existing datapoints under /Dashboard/ and introduces "Dashboard/currently" and "Dashboard/today" due to changes in the API.
|
|
304
|
+
|
|
302
305
|
### 1.6.15
|
|
303
306
|
* Maintenance update (dependencies, ...)
|
|
304
307
|
|
|
@@ -332,7 +335,7 @@ This channel contains values polled from SENEC App-API.
|
|
|
332
335
|
## License
|
|
333
336
|
MIT License
|
|
334
337
|
|
|
335
|
-
Copyright (c)
|
|
338
|
+
Copyright (c) 2025 Norbert Bluemle <github@bluemle.org>
|
|
336
339
|
|
|
337
340
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
338
341
|
of this software and associated documentation files (the "Software"), to deal
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "senec",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.16",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.6.16": {
|
|
7
|
+
"en": "Migrated Dashboard to ApiV2. This invalidates existing datapoints under /Dashboard/ and introduces \"Dashboard/currently\" and \"Dashboard/today\" due to changes in the API.",
|
|
8
|
+
"de": "Dashboard auf ApiV2 migriert. Dadurch werden bestehende Datenpunkte unter /Dashboard/ ungültig. Neu sind aufgrund von Änderungen in der API: \\\"Dashboard/current\\\" und \\\"Dashboard/today\\\".",
|
|
9
|
+
"ru": "Migrated Dashboard to ApiV2. Это аннулирует существующие точки данных под /Dashboard/ и вводит \\\"Dashboard/currently\\\" и \\\"Dashboard/today\\\" из-за изменений в API.",
|
|
10
|
+
"pt": "Painel Migrado para ApiV2. Isso invalida os datapoints existentes em /Dashboard/ e introduz \\\"Dashboard/currently\\\" e \\\"Dashboard/hoje\\\" devido a alterações na API.",
|
|
11
|
+
"nl": "Gemigreerd Dashboard naar ApiV2. Dit maakt bestaande datapunten ongeldig onder /Dashboard/ en introduceert \\\"Dashboard/momenteel\\\" en \\\"Dashboard/today\\\" vanwege wijzigingen in de API.",
|
|
12
|
+
"fr": "Tableau de bord modifié vers ApiV2. Cela invalide les points de données existants sous /Dashboard/ et introduit \\\"Dashboard/currently\\\" et \\\"Dashboard/today\\\" en raison des changements dans l'API.",
|
|
13
|
+
"it": "Migrato Dashboard ad ApiV2. Questo invalida i datapoint esistenti in /Dashboard/ e introduce \\\"Dashboard/currently\\\" e \\\"Dashboard/today\\\" a causa delle modifiche nell'API.",
|
|
14
|
+
"es": "Migrated Dashboard to ApiV2. Esto invalida los puntos de datos existentes bajo /Dashboard/ e introduce \\\"Dashboard/currently\\\" y \\\"Dashboard/today\\\" debido a cambios en la API.",
|
|
15
|
+
"pl": "Migrated Dashboard do ApiV2. To unieważnia istniejące punkty danych pod / Deska rozdzielcza / i wprowadza\\ \"Deska rozdzielcza / obecnie\\\" i\\ \"Deska rozdzielcza / dzisiaj\\\" ze względu na zmiany w API.",
|
|
16
|
+
"uk": "Migrated Dashboard до ApiV2. Це недійсні існуючі точки даних під / панель / і вводить \\ \"Дашборд/поточно\\\" і \\\"Dashboard/today\\\" через зміни в API.",
|
|
17
|
+
"zh-cn": "将 Dashboard 移动到 ApiV2. 这使得/Dashboard/下的现有数据点无效,并由于API的改变,引入了\\\"Dashboard/today\\\"和\\\"Dashboard/today\\\"."
|
|
18
|
+
},
|
|
6
19
|
"1.6.15": {
|
|
7
20
|
"en": "Maintenance update (dependencies, ...)",
|
|
8
21
|
"de": "Wartungsupdate (Abhängigkeiten, ..",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "Bugfix for AllTimeHistory (ang.)",
|
|
81
94
|
"uk": "Виправлення помилок для AllTimeHistory",
|
|
82
95
|
"zh-cn": "九. 一切制度"
|
|
83
|
-
},
|
|
84
|
-
"1.6.9": {
|
|
85
|
-
"en": "Improved battery forced loading, added switch in config to allow active control of appliance.",
|
|
86
|
-
"de": "Manuelles Laden verbessert, zusätzlicher Schalter in Config, um aktive Steuerung des Gerätes zu erlauben.",
|
|
87
|
-
"ru": "Улучшенная батарея принудительная загрузка, добавил переключатель в config, чтобы позволить активный контроль прибора.",
|
|
88
|
-
"pt": "Carga forçada da bateria melhorada, interruptor adicionado em config para permitir o controle ativo do aparelho.",
|
|
89
|
-
"nl": "Geïmproviseerde batterij geforceerde lading, toegevoegd schakelaar in config om actieve controle over goedkeuring toe te staan.",
|
|
90
|
-
"fr": "Amélioration du chargement forcé de la batterie, commutateur ajouté dans la configuration pour permettre le contrôle actif de l'appareil.",
|
|
91
|
-
"it": "Caricamento forzato della batteria migliorato, interruttore aggiunto in configurazione per consentire il controllo attivo dell'apparecchio.",
|
|
92
|
-
"es": "Carga forzada de batería mejorada, interruptor añadido en configuración para permitir el control activo del aparato.",
|
|
93
|
-
"pl": "Poprawione baterie wymusiły obciążenie, dodano przełącznik w celu umożliwienia aktywnej kontroli urządzenia.",
|
|
94
|
-
"uk": "Покращений акумулятор примусового навантаження, доданий перемикач в настройку, щоб забезпечити активний контроль за приладом.",
|
|
95
|
-
"zh-cn": "改善强迫装载的电池,加起来,允许积极控制输电。."
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"docs": {
|
package/main.js
CHANGED
|
@@ -18,8 +18,10 @@ const api_trans = require(__dirname + "/lib/api_trans.js");
|
|
|
18
18
|
const kiloList = ["W", "Wh"];
|
|
19
19
|
|
|
20
20
|
const apiUrl = "https://app-gateway.prod.senec.dev/v1/senec";
|
|
21
|
+
const api2Url = "https://app-gateway.prod.senec.dev/v2/senec";
|
|
21
22
|
const apiLoginUrl = apiUrl + "/login";
|
|
22
23
|
const apiSystemsUrl = apiUrl + "/systems";
|
|
24
|
+
const api2SystemsUrl = api2Url + "/systems";
|
|
23
25
|
const apiMonitorUrl = apiUrl + "/monitor";
|
|
24
26
|
const apiKnownSystems = [];
|
|
25
27
|
|
|
@@ -27,6 +29,8 @@ const batteryOn =
|
|
|
27
29
|
'{"ENERGY":{"SAFE_CHARGE_FORCE":"u8_01","SAFE_CHARGE_PROHIBIT":"","SAFE_CHARGE_RUNNING":"","LI_STORAGE_MODE_START":"","LI_STORAGE_MODE_STOP":"","LI_STORAGE_MODE_RUNNING":"","STAT_STATE":""}}';
|
|
28
30
|
const batteryOff =
|
|
29
31
|
'{"ENERGY":{"SAFE_CHARGE_FORCE":"","SAFE_CHARGE_PROHIBIT":"u8_01","SAFE_CHARGE_RUNNING":"","LI_STORAGE_MODE_START":"","LI_STORAGE_MODE_STOP":"","LI_STORAGE_MODE_RUNNING":"","STAT_STATE":""}}';
|
|
32
|
+
//const blockDischargeOn = '{"ENERGY":{"SAFE_CHARGE_FORCE":"","SAFE_CHARGE_PROHIBIT":"","SAFE_CHARGE_RUNNING":"","LI_STORAGE_MODE_START":"","LI_STORAGE_MODE_STOP":"","LI_STORAGE_MODE_RUNNING":"","STAT_STATE":""}}';
|
|
33
|
+
//const blockDischargeOff = '{"ENERGY":{"SAFE_CHARGE_FORCE":"","SAFE_CHARGE_PROHIBIT":"","SAFE_CHARGE_RUNNING":"","LI_STORAGE_MODE_START":"","LI_STORAGE_MODE_STOP":"","LI_STORAGE_MODE_RUNNING":"","STAT_STATE":""}}';
|
|
30
34
|
|
|
31
35
|
let apiConnected = false;
|
|
32
36
|
let lalaConnected = false;
|
|
@@ -500,6 +504,7 @@ class Senec extends utils.Adapter {
|
|
|
500
504
|
* @param form to post
|
|
501
505
|
*/
|
|
502
506
|
doGet(pUrl, pForm, caller, pollingTimeout, isPost) {
|
|
507
|
+
this.log.debug("Calling: " + pUrl);
|
|
503
508
|
return new Promise(function (resolve, reject) {
|
|
504
509
|
axios({
|
|
505
510
|
method: isPost ? "post" : "get",
|
|
@@ -634,7 +639,8 @@ class Senec extends utils.Adapter {
|
|
|
634
639
|
let body = "";
|
|
635
640
|
try {
|
|
636
641
|
for (let i = 0; i < apiKnownSystems.length; i++) {
|
|
637
|
-
const baseUrl = apiSystemsUrl + "/" + apiKnownSystems[i];
|
|
642
|
+
// const baseUrl = apiSystemsUrl + "/" + apiKnownSystems[i];
|
|
643
|
+
const baseUrl = api2SystemsUrl + "/" + apiKnownSystems[i];
|
|
638
644
|
const baseUrlMonitor = apiMonitorUrl + "/" + apiKnownSystems[i];
|
|
639
645
|
let url = "";
|
|
640
646
|
const tzObj = await this.getStateAsync("_api.Anlagen." + apiKnownSystems[i] + ".zeitzone");
|
|
@@ -655,7 +661,6 @@ class Senec extends utils.Adapter {
|
|
|
655
661
|
value +
|
|
656
662
|
"&locale=de_DE&timezone=" +
|
|
657
663
|
tz;
|
|
658
|
-
this.log.debug("Calling: " + url);
|
|
659
664
|
body = await this.doGet(url, "", this, this.config.pollingTimeout, false);
|
|
660
665
|
await this.decodeStatistik(apiKnownSystems[i], JSON.parse(body), api_trans[key].dp);
|
|
661
666
|
}
|
|
@@ -701,23 +706,20 @@ class Senec extends utils.Adapter {
|
|
|
701
706
|
async decodeDashboard(system, obj) {
|
|
702
707
|
const pfx = "_api.Anlagen." + system + ".Dashboard.";
|
|
703
708
|
for (const [key, value] of Object.entries(obj)) {
|
|
704
|
-
|
|
709
|
+
this.log.debug("(decodeDashboard) Key: " + key + " - Value:" + JSON.stringify(value));
|
|
710
|
+
if (key == "timestamp" || key == "electricVehicleConnected") {
|
|
705
711
|
await this.doState(pfx + key, value, "", "", false);
|
|
706
712
|
} else {
|
|
707
713
|
for (const [key2, value2] of Object.entries(value)) {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
value2.einheit,
|
|
713
|
-
false,
|
|
714
|
-
);
|
|
715
|
-
if (kiloList.includes(value2.einheit)) {
|
|
714
|
+
this.log.debug("(decodeDashboard) Key2: " + key2 + " - Value: " + JSON.stringify(value2));
|
|
715
|
+
const keyParts = ParseApi2KeyParts(key2);
|
|
716
|
+
await this.doState(pfx + key + "." + key2, Number(value2.toFixed(2)), "", keyParts.unit, false);
|
|
717
|
+
if (kiloList.includes(keyParts.unit)) {
|
|
716
718
|
await this.doState(
|
|
717
|
-
pfx + key + "." +
|
|
718
|
-
Number((value2
|
|
719
|
+
pfx + key + "." + keyParts.prefix + " (k" + keyParts.unit + ")",
|
|
720
|
+
Number((value2 / 1000).toFixed(2)),
|
|
719
721
|
"",
|
|
720
|
-
"k" +
|
|
722
|
+
"k" + keyParts.unit,
|
|
721
723
|
false,
|
|
722
724
|
);
|
|
723
725
|
}
|
|
@@ -1014,6 +1016,25 @@ const ValueTyping = (key, value) => {
|
|
|
1014
1016
|
}
|
|
1015
1017
|
};
|
|
1016
1018
|
|
|
1019
|
+
const ParseApi2KeyParts = (key) => {
|
|
1020
|
+
//const match = key.match(/In([A-Za-z]+)$/);
|
|
1021
|
+
//var unit = match ? match[1] : "";
|
|
1022
|
+
//if (unit == "Percent") unit = "%";
|
|
1023
|
+
//return unit;
|
|
1024
|
+
const match = key.match(/^(.*)In([A-Za-z]+)$/);
|
|
1025
|
+
if (match) {
|
|
1026
|
+
return {
|
|
1027
|
+
prefix: match[1], // part before "In"
|
|
1028
|
+
unit: match[2] === "Percent" ? "%" : match[2], // replace "Percent" with "%"
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
return {
|
|
1032
|
+
// default response for error
|
|
1033
|
+
prefix: "unknownKey",
|
|
1034
|
+
unit: "",
|
|
1035
|
+
};
|
|
1036
|
+
};
|
|
1037
|
+
|
|
1017
1038
|
/**
|
|
1018
1039
|
* Converts float value in hex format to js float32.
|
|
1019
1040
|
* Also fixes to 2 decimals.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.senec",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.16",
|
|
4
4
|
"description": "Senec Home",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "NoBl",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"photovoltaic"
|
|
22
22
|
],
|
|
23
23
|
"engines": {
|
|
24
|
-
"node": ">=
|
|
24
|
+
"node": ">=20.0.0"
|
|
25
25
|
},
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
@@ -29,38 +29,38 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"axios": "^1.7.8",
|
|
32
|
-
"@iobroker/adapter-core": "^3.2.
|
|
32
|
+
"@iobroker/adapter-core": "^3.2.3"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@alcalzone/release-script": "^3.8.0",
|
|
36
36
|
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
|
|
37
37
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
38
38
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
39
|
-
"@eslint/eslintrc": "^3.2.0",
|
|
40
|
-
"@eslint/js": "^9.16.0",
|
|
41
39
|
"@iobroker/adapter-dev": "^1.3.0",
|
|
42
40
|
"@iobroker/testing": "^5.0.0",
|
|
43
|
-
"@
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
42
|
+
"@eslint/js": "^9.17.0",
|
|
43
|
+
"@tsconfig/node20": "^20.1.4",
|
|
44
|
+
"@types/chai": "^4.3.19",
|
|
45
|
+
"@types/chai-as-promised": "^8.0.1",
|
|
46
46
|
"@types/mocha": "^10.0.10",
|
|
47
|
-
"@types/node": "^22.10.
|
|
47
|
+
"@types/node": "^22.10.7",
|
|
48
48
|
"@types/proxyquire": "^1.3.31",
|
|
49
49
|
"@types/sinon": "^17.0.3",
|
|
50
50
|
"@types/sinon-chai": "^3.2.12",
|
|
51
|
-
"chai": "^
|
|
52
|
-
"chai-as-promised": "^8.0.
|
|
53
|
-
"eslint": "^9.
|
|
54
|
-
"eslint-config-prettier": "^
|
|
51
|
+
"chai": "^5.1.2",
|
|
52
|
+
"chai-as-promised": "^8.0.1",
|
|
53
|
+
"eslint": "^9.17.0",
|
|
54
|
+
"eslint-config-prettier": "^10.0.1",
|
|
55
55
|
"eslint-plugin-prettier": "^5.2.1",
|
|
56
|
-
"globals": "^15.
|
|
57
|
-
"mocha": "^
|
|
56
|
+
"globals": "^15.14.0",
|
|
57
|
+
"mocha": "^11.0.1",
|
|
58
58
|
"mustache": "^4.2.0",
|
|
59
|
-
"prettier": "^3.4.
|
|
59
|
+
"prettier": "^3.4.2",
|
|
60
60
|
"proxyquire": "^2.1.3",
|
|
61
61
|
"sinon": "^19.0.2",
|
|
62
|
-
"sinon-chai": "^
|
|
63
|
-
"typescript": "~5.7.
|
|
62
|
+
"sinon-chai": "^4.0.0",
|
|
63
|
+
"typescript": "~5.7.3"
|
|
64
64
|
},
|
|
65
65
|
"main": "main.js",
|
|
66
66
|
"files": [
|