iobroker.sigenergy 2.2.3 → 2.2.4
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 +3 -0
- package/io-package.json +13 -13
- package/lib/modbus.js +20 -0
- package/main.js +76 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -153,6 +153,9 @@ Status and power readings for the DC charger.
|
|
|
153
153
|
|
|
154
154
|
## Changelog
|
|
155
155
|
|
|
156
|
+
### 2.2.4 (2026-06-10)
|
|
157
|
+
- (ssbingo) fix: implement ESS Preheating TOU polling (FC03, 50000–50183, 94 registers) and write-back via onStateChange; add encodeValue to ModbusConnection
|
|
158
|
+
|
|
156
159
|
### 2.2.3 (2026-06-10)
|
|
157
160
|
- (ssbingo) fix: add 25 missing admin i18n keys for PSS, PID, ESS Preheating, Extended Registers across all 11 languages
|
|
158
161
|
|
package/io-package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "sigenergy",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.4",
|
|
5
5
|
"news": {
|
|
6
|
-
"2.2.
|
|
7
|
-
"en": "(ssbingo) fix:
|
|
8
|
-
"de": "(ssbingo) fix:
|
|
9
|
-
"ru": "(ssbingo) fix:
|
|
10
|
-
"pt": "(ssbingo) fix:
|
|
11
|
-
"nl": "(ssbingo) fix:
|
|
12
|
-
"fr": "(ssbingo) fix:
|
|
13
|
-
"it": "(ssbingo) fix:
|
|
14
|
-
"es": "(ssbingo) fix:
|
|
15
|
-
"pl": "(ssbingo) fix:
|
|
16
|
-
"uk": "(ssbingo) fix:
|
|
17
|
-
"zh-cn": "(ssbingo) fix:
|
|
6
|
+
"2.2.4": {
|
|
7
|
+
"en": "(ssbingo) fix: implement ESS Preheating TOU read (FC03 registers 50000–50183) and write-back; 94 states with read+write; subscribe to state changes",
|
|
8
|
+
"de": "(ssbingo) fix: ESS-Vorheizung TOU-Lesen (FC03 Register 50000–50183) und Rückschreiben implementiert; 94 States mit read+write; Zustandsänderungen werden abonniert",
|
|
9
|
+
"ru": "(ssbingo) fix: реализовано чтение TOU предварительного нагрева ESS (FC03 регистры 50000–50183) и запись; 94 состояния read+write",
|
|
10
|
+
"pt": "(ssbingo) fix: implementada leitura TOU de pré-aquecimento ESS (FC03 registos 50000–50183) e escrita; 94 estados read+write",
|
|
11
|
+
"nl": "(ssbingo) fix: ESS-voorverwarming TOU lezen (FC03 registers 50000–50183) en terugschrijven geïmplementeerd; 94 states read+write",
|
|
12
|
+
"fr": "(ssbingo) fix: lecture TOU préchauffage ESS (FC03 registres 50000–50183) et écriture implémentées; 94 états read+write",
|
|
13
|
+
"it": "(ssbingo) fix: implementata lettura TOU preriscaldamento ESS (FC03 registri 50000–50183) e scrittura; 94 stati read+write",
|
|
14
|
+
"es": "(ssbingo) fix: implementada lectura TOU precalentamiento ESS (FC03 registros 50000–50183) y escritura; 94 estados read+write",
|
|
15
|
+
"pl": "(ssbingo) fix: zaimplementowano odczyt TOU podgrzewania ESS (FC03 rejestry 50000–50183) i zapis; 94 stany read+write",
|
|
16
|
+
"uk": "(ssbingo) fix: реалізовано читання TOU попереднього нагрівання ESS (FC03 регістри 50000–50183) та запис; 94 стани read+write",
|
|
17
|
+
"zh-cn": "(ssbingo) fix: 实现 ESS 预热 TOU 读取(FC03 寄存器 50000–50183)和写回;94 个 read+write 状态"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"titleLang": {
|
package/lib/modbus.js
CHANGED
|
@@ -244,6 +244,26 @@ class ModbusConnection {
|
|
|
244
244
|
* @param {number|null} gain - Scaling factor
|
|
245
245
|
* @returns {number|string} Decoded value
|
|
246
246
|
*/
|
|
247
|
+
static encodeValue(value, type, gain) {
|
|
248
|
+
const raw = gain && gain !== 1 ? Math.round(value * gain) : Math.round(value);
|
|
249
|
+
switch (type) {
|
|
250
|
+
case 'U16':
|
|
251
|
+
return [raw & 0xffff];
|
|
252
|
+
case 'S16':
|
|
253
|
+
return [raw < 0 ? (raw + 65536) & 0xffff : raw & 0xffff];
|
|
254
|
+
case 'U32': {
|
|
255
|
+
const u = raw >>> 0;
|
|
256
|
+
return [(u >>> 16) & 0xffff, u & 0xffff];
|
|
257
|
+
}
|
|
258
|
+
case 'S32': {
|
|
259
|
+
const u32 = (raw < 0 ? raw + 4294967296 : raw) >>> 0;
|
|
260
|
+
return [(u32 >>> 16) & 0xffff, u32 & 0xffff];
|
|
261
|
+
}
|
|
262
|
+
default:
|
|
263
|
+
return [raw & 0xffff];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
247
267
|
static parseValue(rawData, type, gain) {
|
|
248
268
|
let raw;
|
|
249
269
|
|
package/main.js
CHANGED
|
@@ -16,6 +16,7 @@ const {
|
|
|
16
16
|
AC_CHARGER_READ_REGISTERS,
|
|
17
17
|
PSS_READ_REGISTERS,
|
|
18
18
|
PID_READ_REGISTERS,
|
|
19
|
+
ESS_PREHEATING_WRITE_REGISTERS,
|
|
19
20
|
} = require('./lib/registers');
|
|
20
21
|
const SigenMicroScanner = require('./lib/scanner');
|
|
21
22
|
const { getRegistersForDevice } = require('./lib/sigenMicroRegisters');
|
|
@@ -43,6 +44,7 @@ class Sigenergy extends utils.Adapter {
|
|
|
43
44
|
this._stopped = false;
|
|
44
45
|
|
|
45
46
|
this.on('ready', this.onReady.bind(this));
|
|
47
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
46
48
|
this.on('message', this.onMessage.bind(this));
|
|
47
49
|
this.on('unload', this.onUnload.bind(this));
|
|
48
50
|
}
|
|
@@ -263,6 +265,12 @@ class Sigenergy extends utils.Adapter {
|
|
|
263
265
|
return;
|
|
264
266
|
}
|
|
265
267
|
}
|
|
268
|
+
if (this.config.enableEssPreheating) {
|
|
269
|
+
await this._readEssPreheating();
|
|
270
|
+
if (this._stopped) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
266
274
|
|
|
267
275
|
await this._updateStatistics();
|
|
268
276
|
await this._updatePvStringPowers();
|
|
@@ -433,6 +441,27 @@ class Sigenergy extends utils.Adapter {
|
|
|
433
441
|
}
|
|
434
442
|
}
|
|
435
443
|
|
|
444
|
+
async _readEssPreheating() {
|
|
445
|
+
const plantId = this.config.plantId || 247;
|
|
446
|
+
const batchSize = 50;
|
|
447
|
+
const groups = this._buildReadGroups(ESS_PREHEATING_WRITE_REGISTERS, batchSize);
|
|
448
|
+
this.log.debug(`Reading ESS Preheating (slaveId=${plantId}): ${groups.length} group(s)`);
|
|
449
|
+
|
|
450
|
+
for (const group of groups) {
|
|
451
|
+
if (this._stopped) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
this.log.debug(`[essPreheating] FC03 addr=${group.startAddr} qty=${group.totalQty}`);
|
|
456
|
+
const raw = await this.modbus.readHoldingRegisters(plantId, group.startAddr, group.totalQty);
|
|
457
|
+
await this._processReadGroup(group, raw, 'essPreheating');
|
|
458
|
+
await this._sleep(100);
|
|
459
|
+
} catch (err) {
|
|
460
|
+
this.log.warn(`ESS Preheating read error at ${group.startAddr}: ${err.message}`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
436
465
|
/**
|
|
437
466
|
* Read all active SigenMicro devices
|
|
438
467
|
*/
|
|
@@ -754,6 +783,21 @@ class Sigenergy extends utils.Adapter {
|
|
|
754
783
|
for (let n = 1; n <= 30; n++) {
|
|
755
784
|
await this._createChannel(`plant.essPreheating.tou${n}`, `TOU Window ${n}`);
|
|
756
785
|
}
|
|
786
|
+
for (const reg of ESS_PREHEATING_WRITE_REGISTERS) {
|
|
787
|
+
await this.setObjectNotExistsAsync(reg.name, {
|
|
788
|
+
type: 'state',
|
|
789
|
+
common: {
|
|
790
|
+
name: reg.desc,
|
|
791
|
+
type: 'number',
|
|
792
|
+
role: 'value',
|
|
793
|
+
unit: reg.unit || '',
|
|
794
|
+
read: true,
|
|
795
|
+
write: true,
|
|
796
|
+
},
|
|
797
|
+
native: { addr: reg.addr, qty: reg.qty, dataType: reg.type, gain: reg.gain },
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
this.subscribeStates('plant.essPreheating.*');
|
|
757
801
|
}
|
|
758
802
|
|
|
759
803
|
await this._createStatisticsStates();
|
|
@@ -928,7 +972,38 @@ class Sigenergy extends utils.Adapter {
|
|
|
928
972
|
/**
|
|
929
973
|
* Handle messages from admin (connection test, etc.)
|
|
930
974
|
*
|
|
931
|
-
* @param {
|
|
975
|
+
* @param {ioBroker.Object} obj - Message object
|
|
976
|
+
*/
|
|
977
|
+
async onStateChange(id, state) {
|
|
978
|
+
if (!state || state.ack) {
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
// Strip namespace prefix (e.g. "sigenergy.0.")
|
|
982
|
+
const localId = id.replace(/^[^.]+\.\d+\./, '');
|
|
983
|
+
if (!localId.startsWith('plant.essPreheating.')) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
const reg = ESS_PREHEATING_WRITE_REGISTERS.find(r => r.name === localId);
|
|
987
|
+
if (!reg) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
const plantId = this.config.plantId || 247;
|
|
991
|
+
const raw = ModbusConnection.encodeValue(state.val, reg.type, reg.gain);
|
|
992
|
+
try {
|
|
993
|
+
if (raw.length === 1) {
|
|
994
|
+
await this.modbus.writeSingleRegister(plantId, reg.addr, raw[0]);
|
|
995
|
+
} else {
|
|
996
|
+
await this.modbus.writeMultipleRegisters(plantId, reg.addr, raw);
|
|
997
|
+
}
|
|
998
|
+
await this.setStateAsync(id, { val: state.val, ack: true });
|
|
999
|
+
this.log.debug(`[essPreheating] wrote ${localId} = ${state.val} → addr ${reg.addr}`);
|
|
1000
|
+
} catch (err) {
|
|
1001
|
+
this.log.error(`ESS Preheating write error for ${localId}: ${err.message}`);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* @param {ioBroker.Object} obj - Message object
|
|
932
1007
|
*/
|
|
933
1008
|
async onMessage(obj) {
|
|
934
1009
|
if (!obj || !obj.command) {
|