iobroker.sigenergy 2.2.7 → 2.3.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 +6 -0
- package/io-package.json +26 -13
- package/main.js +115 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -153,6 +153,12 @@ Status and power readings for the DC charger.
|
|
|
153
153
|
|
|
154
154
|
## Changelog
|
|
155
155
|
|
|
156
|
+
### 2.3.1 (2026-06-10)
|
|
157
|
+
- (ssbingo) feat: detect Modbus protocol level on startup by probing registers 30088/30200/30228/30286; read firmware version (30525); log result and store as info.protocolLevel state
|
|
158
|
+
|
|
159
|
+
### 2.3.0 (2026-06-10)
|
|
160
|
+
- (ssbingo) feat: add common.states enum maps for emsWorkMode/runningState/remoteEmsMode/dcCharger.runningState; wire PSS/PID/AC Charger write registers (FC06/FC10) with subscribe and onStateChange handlers
|
|
161
|
+
|
|
156
162
|
### 2.2.7 (2026-06-10)
|
|
157
163
|
- (ssbingo) fix: add missing native defaults enableSmartLoads/enableCumulativeEnergy/enableGridCode to io-package.json
|
|
158
164
|
- (ssbingo) fix: update register 30003 desc with V2.7 EMS modes 5 (FullFeedIn) and 9 (Custom)
|
package/io-package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "sigenergy",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.1",
|
|
5
5
|
"news": {
|
|
6
|
-
"2.
|
|
7
|
-
"en": "(ssbingo)
|
|
8
|
-
"de": "(ssbingo)
|
|
9
|
-
"ru": "(ssbingo)
|
|
10
|
-
"pt": "(ssbingo)
|
|
11
|
-
"nl": "(ssbingo)
|
|
12
|
-
"fr": "(ssbingo)
|
|
13
|
-
"it": "(ssbingo)
|
|
14
|
-
"es": "(ssbingo)
|
|
15
|
-
"pl": "(ssbingo)
|
|
16
|
-
"uk": "(ssbingo)
|
|
17
|
-
"zh-cn": "(ssbingo)
|
|
6
|
+
"2.3.1": {
|
|
7
|
+
"en": "(ssbingo) feat: detect Modbus protocol level on startup by probing registers 30088/30200/30228/30286; read firmware version (30525); log result and store as info.protocolLevel state",
|
|
8
|
+
"de": "(ssbingo) feat: Modbus-Protokollebene beim Start durch Probe von Registern 30088/30200/30228/30286 erkennen; Firmware-Version (30525) lesen; Ergebnis loggen und als info.protocolLevel-State speichern",
|
|
9
|
+
"ru": "(ssbingo) feat: определение уровня протокола Modbus при запуске путём опроса регистров 30088/30200/30228/30286; чтение версии прошивки (30525); журналирование результата и сохранение в состояние info.protocolLevel",
|
|
10
|
+
"pt": "(ssbingo) feat: detectar nível do protocolo Modbus no arranque sondando registos 30088/30200/30228/30286; ler versão de firmware (30525); registar resultado e guardar como estado info.protocolLevel",
|
|
11
|
+
"nl": "(ssbingo) feat: Modbus-protocolniveau bij opstarten detecteren door registers 30088/30200/30228/30286 te sonderen; firmwareversie (30525) lezen; resultaat loggen en opslaan als info.protocolLevel-state",
|
|
12
|
+
"fr": "(ssbingo) feat: détection du niveau de protocole Modbus au démarrage en sondant les registres 30088/30200/30228/30286 ; lecture de la version firmware (30525) ; journalisation du résultat et stockage dans l'état info.protocolLevel",
|
|
13
|
+
"it": "(ssbingo) feat: rilevamento del livello del protocollo Modbus all'avvio sondando i registri 30088/30200/30228/30286; lettura della versione firmware (30525); registrazione del risultato e salvataggio come stato info.protocolLevel",
|
|
14
|
+
"es": "(ssbingo) feat: detectar nivel de protocolo Modbus en el arranque sondeando registros 30088/30200/30228/30286; leer versión de firmware (30525); registrar resultado y almacenar como estado info.protocolLevel",
|
|
15
|
+
"pl": "(ssbingo) feat: wykrywanie poziomu protokołu Modbus przy uruchomieniu przez próbkowanie rejestrów 30088/30200/30228/30286; odczyt wersji firmware (30525); logowanie wyniku i zapis jako stan info.protocolLevel",
|
|
16
|
+
"uk": "(ssbingo) feat: виявлення рівня протоколу Modbus при запуску шляхом зондування регістрів 30088/30200/30228/30286; зчитування версії прошивки (30525); журналювання результату та збереження як стан info.protocolLevel",
|
|
17
|
+
"zh-cn": "(ssbingo) feat: 启动时通过探测寄存器 30088/30200/30228/30286 检测 Modbus 协议级别;读取固件版本(30525);记录结果并存储为 info.protocolLevel 状态"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"titleLang": {
|
|
@@ -178,6 +178,19 @@
|
|
|
178
178
|
"def": "idle"
|
|
179
179
|
},
|
|
180
180
|
"native": {}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"_id": "info.protocolLevel",
|
|
184
|
+
"type": "state",
|
|
185
|
+
"common": {
|
|
186
|
+
"name": "Detected Modbus protocol level",
|
|
187
|
+
"type": "string",
|
|
188
|
+
"role": "text",
|
|
189
|
+
"read": true,
|
|
190
|
+
"write": false,
|
|
191
|
+
"def": ""
|
|
192
|
+
},
|
|
193
|
+
"native": {}
|
|
181
194
|
}
|
|
182
195
|
]
|
|
183
196
|
}
|
package/main.js
CHANGED
|
@@ -20,11 +20,25 @@ const {
|
|
|
20
20
|
PLANT_WRITE_REGISTERS,
|
|
21
21
|
INVERTER_WRITE_REGISTERS,
|
|
22
22
|
DC_CHARGER_WRITE_REGISTERS,
|
|
23
|
+
AC_CHARGER_WRITE_REGISTERS,
|
|
24
|
+
PSS_WRITE_REGISTERS,
|
|
25
|
+
PID_WRITE_REGISTERS,
|
|
26
|
+
RUNNING_STATES,
|
|
27
|
+
EMS_WORK_MODES,
|
|
28
|
+
REMOTE_EMS_MODES,
|
|
29
|
+
DC_CHARGER_RUNNING_STATES,
|
|
23
30
|
} = require('./lib/registers');
|
|
24
31
|
const SigenMicroScanner = require('./lib/scanner');
|
|
25
32
|
const { getRegistersForDevice } = require('./lib/sigenMicroRegisters');
|
|
26
33
|
const adapterVersion = require('./package.json').version;
|
|
27
34
|
|
|
35
|
+
const ENUM_STATES_MAP = {
|
|
36
|
+
'plant.emsWorkMode': EMS_WORK_MODES,
|
|
37
|
+
'plant.runningState': RUNNING_STATES,
|
|
38
|
+
'dcCharger.runningState': DC_CHARGER_RUNNING_STATES,
|
|
39
|
+
'plant.control.remoteEmsMode': REMOTE_EMS_MODES,
|
|
40
|
+
};
|
|
41
|
+
|
|
28
42
|
class Sigenergy extends utils.Adapter {
|
|
29
43
|
/**
|
|
30
44
|
* @param {Partial<utils.AdapterOptions>} [options] - Adapter options
|
|
@@ -46,6 +60,7 @@ class Sigenergy extends utils.Adapter {
|
|
|
46
60
|
// calling setStateAsync on a stopped adapter.
|
|
47
61
|
this._stopped = false;
|
|
48
62
|
this._controlRegistersRead = false;
|
|
63
|
+
this._protocolDetected = false;
|
|
49
64
|
this._essPreheatingUnsupported = false;
|
|
50
65
|
|
|
51
66
|
this.on('ready', this.onReady.bind(this));
|
|
@@ -233,6 +248,10 @@ class Sigenergy extends utils.Adapter {
|
|
|
233
248
|
await this._readControlRegisters();
|
|
234
249
|
this._controlRegistersRead = true;
|
|
235
250
|
}
|
|
251
|
+
if (!this._protocolDetected) {
|
|
252
|
+
await this._detectProtocolLevel();
|
|
253
|
+
this._protocolDetected = true;
|
|
254
|
+
}
|
|
236
255
|
|
|
237
256
|
const _t0 = Date.now();
|
|
238
257
|
await this._readPlant();
|
|
@@ -487,6 +506,40 @@ class Sigenergy extends utils.Adapter {
|
|
|
487
506
|
}
|
|
488
507
|
}
|
|
489
508
|
|
|
509
|
+
async _detectProtocolLevel() {
|
|
510
|
+
const plantId = this.config.plantId || 247;
|
|
511
|
+
const inverterId = this.config.inverterId || 1;
|
|
512
|
+
|
|
513
|
+
const probes = [
|
|
514
|
+
{ addr: 30088, level: 'V2.6' },
|
|
515
|
+
{ addr: 30200, level: 'V2.7' },
|
|
516
|
+
{ addr: 30228, level: 'V2.8' },
|
|
517
|
+
{ addr: 30286, level: 'V2.9' },
|
|
518
|
+
];
|
|
519
|
+
|
|
520
|
+
let detectedLevel = null;
|
|
521
|
+
for (const probe of probes) {
|
|
522
|
+
try {
|
|
523
|
+
await this.modbus.readInputRegisters(plantId, probe.addr, 1);
|
|
524
|
+
detectedLevel = probe.level;
|
|
525
|
+
} catch {
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
let firmwareVersion = 'unknown';
|
|
531
|
+
try {
|
|
532
|
+
const raw = await this.modbus.readInputRegisters(inverterId, 30525, 15);
|
|
533
|
+
firmwareVersion = ModbusConnection.parseValue(raw, 'STRING', null) || 'unknown';
|
|
534
|
+
} catch {
|
|
535
|
+
// not critical
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const levelStr = detectedLevel ? `>=${detectedLevel}` : 'unknown';
|
|
539
|
+
this.log.info(`Detected protocol level: ${levelStr} (firmware: ${firmwareVersion})`);
|
|
540
|
+
await this.setStateAsync('info.protocolLevel', { val: levelStr, ack: true });
|
|
541
|
+
}
|
|
542
|
+
|
|
490
543
|
async _readControlRegisters() {
|
|
491
544
|
const plantId = this.config.plantId || 247;
|
|
492
545
|
const inverterId = this.config.inverterId || 1;
|
|
@@ -842,6 +895,14 @@ class Sigenergy extends utils.Adapter {
|
|
|
842
895
|
}
|
|
843
896
|
await this._createStateFromRegister(reg);
|
|
844
897
|
}
|
|
898
|
+
await this._createChannel('acCharger.control', 'AC Charger Control');
|
|
899
|
+
for (const reg of AC_CHARGER_WRITE_REGISTERS) {
|
|
900
|
+
if (this._stopped) {
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
await this._createWriteStateFromRegister(reg);
|
|
904
|
+
}
|
|
905
|
+
this.subscribeStates('acCharger.control.*');
|
|
845
906
|
}
|
|
846
907
|
|
|
847
908
|
if (this.config.hasDcCharger) {
|
|
@@ -882,17 +943,32 @@ class Sigenergy extends utils.Adapter {
|
|
|
882
943
|
}
|
|
883
944
|
await this._createStateFromRegister(reg);
|
|
884
945
|
}
|
|
946
|
+
for (const reg of PSS_WRITE_REGISTERS) {
|
|
947
|
+
if (this._stopped) {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
await this._createWriteStateFromRegister(reg);
|
|
951
|
+
}
|
|
952
|
+
this.subscribeStates('pss.control.*');
|
|
885
953
|
}
|
|
886
954
|
|
|
887
955
|
if (this.config.enablePid) {
|
|
888
956
|
this.log.debug('Creating PID objects');
|
|
889
957
|
await this._createChannel('pid', 'PV Insulation Detection');
|
|
958
|
+
await this._createChannel('pid.control', 'PID Control');
|
|
890
959
|
for (const reg of PID_READ_REGISTERS) {
|
|
891
960
|
if (this._stopped) {
|
|
892
961
|
return;
|
|
893
962
|
}
|
|
894
963
|
await this._createStateFromRegister(reg);
|
|
895
964
|
}
|
|
965
|
+
for (const reg of PID_WRITE_REGISTERS) {
|
|
966
|
+
if (this._stopped) {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
await this._createWriteStateFromRegister(reg);
|
|
970
|
+
}
|
|
971
|
+
this.subscribeStates('pid.control.*');
|
|
896
972
|
}
|
|
897
973
|
|
|
898
974
|
if (this.config.enableEssPreheating) {
|
|
@@ -960,16 +1036,22 @@ class Sigenergy extends utils.Adapter {
|
|
|
960
1036
|
type = 'number';
|
|
961
1037
|
}
|
|
962
1038
|
|
|
1039
|
+
const common = {
|
|
1040
|
+
name: reg.desc,
|
|
1041
|
+
type,
|
|
1042
|
+
role,
|
|
1043
|
+
unit: reg.unit || '',
|
|
1044
|
+
read: true,
|
|
1045
|
+
write: false,
|
|
1046
|
+
};
|
|
1047
|
+
const states = ENUM_STATES_MAP[reg.name];
|
|
1048
|
+
if (states) {
|
|
1049
|
+
common.states = states;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
963
1052
|
await this.setObjectNotExistsAsync(reg.name, {
|
|
964
1053
|
type: 'state',
|
|
965
|
-
common
|
|
966
|
-
name: reg.desc,
|
|
967
|
-
type,
|
|
968
|
-
role,
|
|
969
|
-
unit: reg.unit || '',
|
|
970
|
-
read: true,
|
|
971
|
-
write: false,
|
|
972
|
-
},
|
|
1054
|
+
common,
|
|
973
1055
|
native: {
|
|
974
1056
|
addr: reg.addr,
|
|
975
1057
|
qty: reg.qty,
|
|
@@ -981,16 +1063,21 @@ class Sigenergy extends utils.Adapter {
|
|
|
981
1063
|
|
|
982
1064
|
async _createWriteStateFromRegister(reg) {
|
|
983
1065
|
const type = reg.type === 'STRING' ? 'string' : 'number';
|
|
1066
|
+
const common = {
|
|
1067
|
+
name: reg.desc,
|
|
1068
|
+
type,
|
|
1069
|
+
role: 'value',
|
|
1070
|
+
unit: reg.unit || '',
|
|
1071
|
+
read: reg.perm === 'RW',
|
|
1072
|
+
write: true,
|
|
1073
|
+
};
|
|
1074
|
+
const states = ENUM_STATES_MAP[reg.name];
|
|
1075
|
+
if (states) {
|
|
1076
|
+
common.states = states;
|
|
1077
|
+
}
|
|
984
1078
|
await this.setObjectNotExistsAsync(reg.name, {
|
|
985
1079
|
type: 'state',
|
|
986
|
-
common
|
|
987
|
-
name: reg.desc,
|
|
988
|
-
type,
|
|
989
|
-
role: 'value',
|
|
990
|
-
unit: reg.unit || '',
|
|
991
|
-
read: reg.perm === 'RW',
|
|
992
|
-
write: true,
|
|
993
|
-
},
|
|
1080
|
+
common,
|
|
994
1081
|
native: {
|
|
995
1082
|
addr: reg.addr,
|
|
996
1083
|
qty: reg.qty,
|
|
@@ -1162,6 +1249,18 @@ class Sigenergy extends utils.Adapter {
|
|
|
1162
1249
|
reg = DC_CHARGER_WRITE_REGISTERS.find(r => r.name === localId);
|
|
1163
1250
|
slaveId = this.config.inverterId || 1;
|
|
1164
1251
|
category = 'dcCharger';
|
|
1252
|
+
} else if (localId.startsWith('pss.control.')) {
|
|
1253
|
+
reg = PSS_WRITE_REGISTERS.find(r => r.name === localId);
|
|
1254
|
+
slaveId = this.config.pssSlaveId || 5;
|
|
1255
|
+
category = 'pss';
|
|
1256
|
+
} else if (localId.startsWith('pid.control.')) {
|
|
1257
|
+
reg = PID_WRITE_REGISTERS.find(r => r.name === localId);
|
|
1258
|
+
slaveId = this.config.pidSlaveId || 6;
|
|
1259
|
+
category = 'pid';
|
|
1260
|
+
} else if (localId.startsWith('acCharger.control.')) {
|
|
1261
|
+
reg = AC_CHARGER_WRITE_REGISTERS.find(r => r.name === localId);
|
|
1262
|
+
slaveId = this.config.acChargerId || 2;
|
|
1263
|
+
category = 'acCharger';
|
|
1165
1264
|
}
|
|
1166
1265
|
|
|
1167
1266
|
if (!reg) {
|