@enyo-energy/sunspec-sdk 0.0.30 → 0.0.32
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/dist/cjs/sunspec-devices.cjs +26 -1
- package/dist/cjs/sunspec-devices.d.cts +10 -1
- package/dist/cjs/sunspec-interfaces.cjs +82 -1
- package/dist/cjs/sunspec-interfaces.d.cts +173 -0
- package/dist/cjs/sunspec-modbus-client.cjs +576 -234
- package/dist/cjs/sunspec-modbus-client.d.cts +18 -1
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/sunspec-devices.d.ts +10 -1
- package/dist/sunspec-devices.js +26 -1
- package/dist/sunspec-interfaces.d.ts +173 -0
- package/dist/sunspec-interfaces.js +81 -0
- package/dist/sunspec-modbus-client.d.ts +18 -1
- package/dist/sunspec-modbus-client.js +577 -235
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* - pad: 0x8000 (always returns this value)
|
|
17
17
|
* - string: all registers 0x0000 (NULL)
|
|
18
18
|
*/
|
|
19
|
-
import { SunspecModelId, SunspecBatteryChargeState, SunspecStorageControlMode, SunspecChargeSource, SunspecStorageMode } from "./sunspec-interfaces.js";
|
|
19
|
+
import { SunspecModelId, SunspecBatteryChargeState, SunspecStorageControlMode, SunspecChargeSource, SunspecStorageMode, SunspecBatteryType, SunspecBatteryBankState } from "./sunspec-interfaces.js";
|
|
20
20
|
import { ConnectionRetryManager } from "./connection-retry-manager.js";
|
|
21
21
|
import { EnergyAppModbusConnectionHealth } from "@enyo-energy/energy-app-sdk/dist/implementations/modbus/EnergyAppModbusConnectionHealth.js";
|
|
22
22
|
import { EnergyAppModbusFaultTolerantReader } from "@enyo-energy/energy-app-sdk/dist/implementations/modbus/EnergyAppModbusFaultTolerantReader.js";
|
|
@@ -227,6 +227,22 @@ export class SunspecModbusClient {
|
|
|
227
227
|
}
|
|
228
228
|
// If custom base address provided, try it first (1-based, then 0-based variant)
|
|
229
229
|
if (customBaseAddress !== undefined) {
|
|
230
|
+
console.log(`Detect models for custom base address '${customBaseAddress}' ...`);
|
|
231
|
+
// Try 0-based at custom address
|
|
232
|
+
try {
|
|
233
|
+
const sunspecId = await this.modbusClient.readRegisterStringValue(customBaseAddress, 2);
|
|
234
|
+
if (sunspecId.includes('SunS')) {
|
|
235
|
+
console.log(`Detected 0-based addressing mode (base address: ${customBaseAddress})`);
|
|
236
|
+
return {
|
|
237
|
+
baseAddress: customBaseAddress,
|
|
238
|
+
isZeroBased: true,
|
|
239
|
+
nextAddress: customBaseAddress + 2
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
console.debug(`Could not read SunS at ${customBaseAddress}:`, error);
|
|
245
|
+
}
|
|
230
246
|
// Try 1-based at custom address (customBaseAddress + 1)
|
|
231
247
|
try {
|
|
232
248
|
const sunspecId = await this.modbusClient.readRegisterStringValue(customBaseAddress + 1, 2);
|
|
@@ -242,54 +258,41 @@ export class SunspecModbusClient {
|
|
|
242
258
|
catch (error) {
|
|
243
259
|
console.debug(`Could not read SunS at ${customBaseAddress + 1}:`, error);
|
|
244
260
|
}
|
|
245
|
-
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// Try 1-based addressing first (most common)
|
|
246
264
|
try {
|
|
247
|
-
const sunspecId = await this.modbusClient.readRegisterStringValue(
|
|
265
|
+
const sunspecId = await this.modbusClient.readRegisterStringValue(40001, 2);
|
|
248
266
|
if (sunspecId.includes('SunS')) {
|
|
249
|
-
console.log(
|
|
267
|
+
console.log('Detected 1-based addressing mode (base address: 40001)');
|
|
250
268
|
return {
|
|
251
|
-
baseAddress:
|
|
252
|
-
isZeroBased:
|
|
253
|
-
nextAddress:
|
|
269
|
+
baseAddress: 40001,
|
|
270
|
+
isZeroBased: false,
|
|
271
|
+
nextAddress: 40003
|
|
254
272
|
};
|
|
255
273
|
}
|
|
256
274
|
}
|
|
257
275
|
catch (error) {
|
|
258
|
-
console.debug(
|
|
276
|
+
console.debug('Could not read SunS at 40001:', error);
|
|
259
277
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
278
|
+
// Try 0-based addressing
|
|
279
|
+
try {
|
|
280
|
+
const sunspecId = await this.modbusClient.readRegisterStringValue(40000, 2);
|
|
281
|
+
if (sunspecId.includes('SunS')) {
|
|
282
|
+
console.log('Detected 0-based addressing mode (base address: 40000)');
|
|
283
|
+
return {
|
|
284
|
+
baseAddress: 40000,
|
|
285
|
+
isZeroBased: true,
|
|
286
|
+
nextAddress: 40002
|
|
287
|
+
};
|
|
288
|
+
}
|
|
271
289
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
console.debug('Could not read SunS at 40001:', error);
|
|
275
|
-
}
|
|
276
|
-
// Try 0-based addressing
|
|
277
|
-
try {
|
|
278
|
-
const sunspecId = await this.modbusClient.readRegisterStringValue(40000, 2);
|
|
279
|
-
if (sunspecId.includes('SunS')) {
|
|
280
|
-
console.log('Detected 0-based addressing mode (base address: 40000)');
|
|
281
|
-
return {
|
|
282
|
-
baseAddress: 40000,
|
|
283
|
-
isZeroBased: true,
|
|
284
|
-
nextAddress: 40002
|
|
285
|
-
};
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.debug('Could not read SunS at 40000:', error);
|
|
286
292
|
}
|
|
287
293
|
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
console.debug('Could not read SunS at 40000:', error);
|
|
290
|
-
}
|
|
291
294
|
const addressesChecked = customBaseAddress !== undefined
|
|
292
|
-
? `${customBaseAddress}, ${customBaseAddress + 1}
|
|
295
|
+
? `${customBaseAddress}, ${customBaseAddress + 1}`
|
|
293
296
|
: '40000 or 40001';
|
|
294
297
|
throw new Error(`Device is not SunSpec compliant - "SunS" identifier not found at addresses ${addressesChecked}`);
|
|
295
298
|
}
|
|
@@ -519,64 +522,44 @@ export class SunspecModbusClient {
|
|
|
519
522
|
const voltageANRaw = await this.readRegisterValue(baseAddr + 10, 1, 'uint16');
|
|
520
523
|
const voltageBNRaw = await this.readRegisterValue(baseAddr + 11, 1, 'uint16');
|
|
521
524
|
const voltageCNRaw = await this.readRegisterValue(baseAddr + 12, 1, 'uint16');
|
|
525
|
+
// Read raw values for fields that need IIFEs removed
|
|
526
|
+
const acCurrentRaw = await this.readRegisterValue(baseAddr + 2, 1, 'uint16');
|
|
527
|
+
const acPowerRaw = await this.readRegisterValue(baseAddr + 14, 1, 'int16');
|
|
528
|
+
const dcCurrentRaw = await this.readRegisterValue(baseAddr + 27, 1, 'uint16');
|
|
529
|
+
const dcVoltageRaw = await this.readRegisterValue(baseAddr + 28, 1, 'uint16');
|
|
530
|
+
const dcPowerRaw = await this.readRegisterValue(baseAddr + 30, 1, 'int16');
|
|
522
531
|
const data = {
|
|
523
532
|
blockNumber: 103,
|
|
524
533
|
blockAddress: model.address,
|
|
525
534
|
blockLength: model.length,
|
|
526
535
|
// AC Current values - Offsets 2-5
|
|
527
|
-
acCurrent: this.applyScaleFactor(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
return raw;
|
|
532
|
-
})(), scaleFactors.A_SF, 'uint16', 'AC Current'),
|
|
533
|
-
phaseACurrent: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 3, 1, 'uint16'), scaleFactors.A_SF, 'uint16', 'Phase A Current'),
|
|
534
|
-
phaseBCurrent: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 4, 1, 'uint16'), scaleFactors.A_SF, 'uint16', 'Phase B Current'),
|
|
535
|
-
phaseCCurrent: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 5, 1, 'uint16'), scaleFactors.A_SF, 'uint16', 'Phase C Current'),
|
|
536
|
+
acCurrent: this.applyScaleFactor(acCurrentRaw, scaleFactors.A_SF, 'uint16', 'AC Current', 2, 103),
|
|
537
|
+
phaseACurrent: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 3, 1, 'uint16'), scaleFactors.A_SF, 'uint16', 'Phase A Current', 3, 103),
|
|
538
|
+
phaseBCurrent: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 4, 1, 'uint16'), scaleFactors.A_SF, 'uint16', 'Phase B Current', 4, 103),
|
|
539
|
+
phaseCCurrent: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 5, 1, 'uint16'), scaleFactors.A_SF, 'uint16', 'Phase C Current', 5, 103),
|
|
536
540
|
// Voltage values - Offsets 7-12
|
|
537
|
-
voltageAB: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 7, 1, 'uint16'), scaleFactors.V_SF, 'uint16', 'Voltage AB'),
|
|
538
|
-
voltageBC: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 8, 1, 'uint16'), scaleFactors.V_SF, 'uint16', 'Voltage BC'),
|
|
539
|
-
voltageCA: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 9, 1, 'uint16'), scaleFactors.V_SF, 'uint16', 'Voltage CA'),
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
voltageCN: this.applyScaleFactor(voltageCNRaw, scaleFactors.V_SF, 'uint16', 'Voltage CN'),
|
|
541
|
+
voltageAB: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 7, 1, 'uint16'), scaleFactors.V_SF, 'uint16', 'Voltage AB', 7, 103),
|
|
542
|
+
voltageBC: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 8, 1, 'uint16'), scaleFactors.V_SF, 'uint16', 'Voltage BC', 8, 103),
|
|
543
|
+
voltageCA: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 9, 1, 'uint16'), scaleFactors.V_SF, 'uint16', 'Voltage CA', 9, 103),
|
|
544
|
+
voltageAN: this.applyScaleFactor(voltageANRaw, scaleFactors.V_SF, 'uint16', 'Voltage AN', 10, 103),
|
|
545
|
+
voltageBN: this.applyScaleFactor(voltageBNRaw, scaleFactors.V_SF, 'uint16', 'Voltage BN', 11, 103),
|
|
546
|
+
voltageCN: this.applyScaleFactor(voltageCNRaw, scaleFactors.V_SF, 'uint16', 'Voltage CN', 12, 103),
|
|
544
547
|
// Power values - Offsets 14, 18, 20, 22
|
|
545
|
-
acPower: this.applyScaleFactor(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
return raw;
|
|
550
|
-
})(), scaleFactors.W_SF, 'int16', 'AC Power'),
|
|
551
|
-
apparentPower: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 18, 1, 'uint16'), scaleFactors.VA_SF, 'uint16', 'Apparent Power'),
|
|
552
|
-
reactivePower: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 20, 1, 'int16'), scaleFactors.VAr_SF, 'int16', 'Reactive Power'),
|
|
553
|
-
powerFactor: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 22, 1, 'int16'), scaleFactors.PF_SF, 'int16', 'Power Factor'),
|
|
548
|
+
acPower: this.applyScaleFactor(acPowerRaw, scaleFactors.W_SF, 'int16', 'AC Power', 14, 103),
|
|
549
|
+
apparentPower: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 18, 1, 'uint16'), scaleFactors.VA_SF, 'uint16', 'Apparent Power', 18, 103),
|
|
550
|
+
reactivePower: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 20, 1, 'int16'), scaleFactors.VAr_SF, 'int16', 'Reactive Power', 20, 103),
|
|
551
|
+
powerFactor: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 22, 1, 'int16'), scaleFactors.PF_SF, 'int16', 'Power Factor', 22, 103),
|
|
554
552
|
// Frequency - Offset 16
|
|
555
|
-
frequency: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 16, 1, 'uint16'), scaleFactors.Hz_SF, 'uint16', 'Frequency'),
|
|
553
|
+
frequency: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 16, 1, 'uint16'), scaleFactors.Hz_SF, 'uint16', 'Frequency', 16, 103),
|
|
556
554
|
// DC values - Offsets 27, 28, 30
|
|
557
|
-
dcCurrent: this.applyScaleFactor(
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
console.log(`DC Current: address=${addr}, raw=0x${raw.toString(16).toUpperCase()} (${raw})`);
|
|
561
|
-
return raw;
|
|
562
|
-
})(), scaleFactors.DCA_SF, 'uint16', 'DC Current'),
|
|
563
|
-
dcVoltage: this.applyScaleFactor(await (async () => {
|
|
564
|
-
const addr = baseAddr + 28;
|
|
565
|
-
const raw = await this.readRegisterValue(addr, 1, 'uint16');
|
|
566
|
-
console.log(`DC Voltage: address=${addr}, raw=0x${raw.toString(16).toUpperCase()} (${raw})`);
|
|
567
|
-
return raw;
|
|
568
|
-
})(), scaleFactors.DCV_SF, 'uint16', 'DC Voltage'),
|
|
569
|
-
dcPower: this.applyScaleFactor(await (async () => {
|
|
570
|
-
const addr = baseAddr + 30;
|
|
571
|
-
const raw = await this.readRegisterValue(addr, 1, 'int16');
|
|
572
|
-
console.log(`DC Power: address=${addr}, raw=0x${raw.toString(16).toUpperCase()} (${raw}), SF=${scaleFactors.DCW_SF}`);
|
|
573
|
-
return raw;
|
|
574
|
-
})(), scaleFactors.DCW_SF, 'int16', 'DC Power'),
|
|
555
|
+
dcCurrent: this.applyScaleFactor(dcCurrentRaw, scaleFactors.DCA_SF, 'uint16', 'DC Current', 27, 103),
|
|
556
|
+
dcVoltage: this.applyScaleFactor(dcVoltageRaw, scaleFactors.DCV_SF, 'uint16', 'DC Voltage', 28, 103),
|
|
557
|
+
dcPower: this.applyScaleFactor(dcPowerRaw, scaleFactors.DCW_SF, 'int16', 'DC Power', 30, 103),
|
|
575
558
|
// Temperature values - Offsets 32, 34, 35, 36
|
|
576
|
-
cabinetTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 32, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Cabinet Temperature'),
|
|
577
|
-
heatSinkTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 34, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Heat Sink Temperature'),
|
|
578
|
-
transformerTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 35, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Transformer Temperature'),
|
|
579
|
-
otherTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 36, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Other Temperature'),
|
|
559
|
+
cabinetTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 32, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Cabinet Temperature', 32, 103),
|
|
560
|
+
heatSinkTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 34, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Heat Sink Temperature', 34, 103),
|
|
561
|
+
transformerTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 35, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Transformer Temperature', 35, 103),
|
|
562
|
+
otherTemperature: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 36, 1, 'int16'), scaleFactors.Tmp_SF, 'int16', 'Other Temperature', 36, 103),
|
|
580
563
|
// Status values - Offsets 38, 39
|
|
581
564
|
operatingState: await this.readRegisterValue(baseAddr + 38, 1, 'uint16'),
|
|
582
565
|
vendorState: await this.readRegisterValue(baseAddr + 39, 1, 'uint16'),
|
|
@@ -588,11 +571,20 @@ export class SunspecModbusClient {
|
|
|
588
571
|
vendorEvents3: await this.readRegisterValue(baseAddr + 48, 2, 'uint32'),
|
|
589
572
|
vendorEvents4: await this.readRegisterValue(baseAddr + 50, 2, 'uint32')
|
|
590
573
|
};
|
|
574
|
+
// Log non-scaled fields
|
|
575
|
+
this.logRegisterRead(103, 38, 'Operating State', data.operatingState, 'enum16');
|
|
576
|
+
this.logRegisterRead(103, 39, 'Vendor State', data.vendorState, 'uint16');
|
|
577
|
+
this.logRegisterRead(103, 40, 'Events', data.events, 'bitfield32');
|
|
578
|
+
this.logRegisterRead(103, 42, 'Events2', data.events2, 'bitfield32');
|
|
579
|
+
this.logRegisterRead(103, 44, 'Vendor Events 1', data.vendorEvents1, 'bitfield32');
|
|
580
|
+
this.logRegisterRead(103, 46, 'Vendor Events 2', data.vendorEvents2, 'bitfield32');
|
|
581
|
+
this.logRegisterRead(103, 48, 'Vendor Events 3', data.vendorEvents3, 'bitfield32');
|
|
582
|
+
this.logRegisterRead(103, 50, 'Vendor Events 4', data.vendorEvents4, 'bitfield32');
|
|
591
583
|
// Read AC Energy (32-bit accumulator) - Offset 24-25
|
|
592
|
-
const
|
|
593
|
-
|
|
584
|
+
const acEnergy = await this.readRegisterValue(baseAddr + 24, 2, 'uint32');
|
|
585
|
+
this.logRegisterRead(103, 24, 'AC Energy', acEnergy, 'acc32');
|
|
594
586
|
data.acEnergy = !this.isUnimplementedValue(acEnergy, 'acc32')
|
|
595
|
-
? acEnergy * Math.pow(10, scaleFactors.WH_SF)
|
|
587
|
+
? acEnergy * Math.pow(10, scaleFactors.WH_SF)
|
|
596
588
|
: undefined;
|
|
597
589
|
return data;
|
|
598
590
|
}
|
|
@@ -620,41 +612,32 @@ export class SunspecModbusClient {
|
|
|
620
612
|
DCV_SF: await this.readRegisterValue(baseAddr + 19, 1, 'int16'),
|
|
621
613
|
DCW_SF: await this.readRegisterValue(baseAddr + 21, 1, 'int16')
|
|
622
614
|
};
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
const
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
const
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
const dcVoltageAddr = baseAddr + 15;
|
|
641
|
-
const dcVoltageRaw = await this.readRegisterValue(dcVoltageAddr, 1, 'uint16');
|
|
642
|
-
console.log(`DC Voltage: address=${dcVoltageAddr}, raw=0x${dcVoltageRaw.toString(16).toUpperCase()} (${dcVoltageRaw})`);
|
|
643
|
-
const dcPowerAddr = baseAddr + 20;
|
|
644
|
-
const dcPowerRaw = await this.readRegisterValue(dcPowerAddr, 1, 'int16');
|
|
645
|
-
console.log(`DC Power: address=${dcPowerAddr}, raw=0x${dcPowerRaw.toString(16).toUpperCase()} (${dcPowerRaw}), SF=${scaleFactors.DCW_SF}`);
|
|
646
|
-
const stateAddr = baseAddr + 24;
|
|
647
|
-
const stateRaw = await this.readRegisterValue(stateAddr, 1, 'uint16');
|
|
648
|
-
console.log(`Operating State: address=${stateAddr}, raw=0x${stateRaw.toString(16).toUpperCase()} (${stateRaw})`);
|
|
615
|
+
this.logRegisterRead(101, 6, 'A_SF', scaleFactors.A_SF, 'int16');
|
|
616
|
+
this.logRegisterRead(101, 13, 'V_SF', scaleFactors.V_SF, 'int16');
|
|
617
|
+
this.logRegisterRead(101, 10, 'W_SF', scaleFactors.W_SF, 'int16');
|
|
618
|
+
this.logRegisterRead(101, 12, 'Hz_SF', scaleFactors.Hz_SF, 'int16');
|
|
619
|
+
this.logRegisterRead(101, 18, 'DCA_SF', scaleFactors.DCA_SF, 'int16');
|
|
620
|
+
this.logRegisterRead(101, 19, 'DCV_SF', scaleFactors.DCV_SF, 'int16');
|
|
621
|
+
this.logRegisterRead(101, 21, 'DCW_SF', scaleFactors.DCW_SF, 'int16');
|
|
622
|
+
// Read raw values
|
|
623
|
+
const acCurrentRaw = await this.readRegisterValue(baseAddr + 2, 1, 'uint16');
|
|
624
|
+
const voltageRaw = await this.readRegisterValue(baseAddr + 7, 1, 'uint16');
|
|
625
|
+
const acPowerRaw = await this.readRegisterValue(baseAddr + 9, 1, 'int16');
|
|
626
|
+
const freqRaw = await this.readRegisterValue(baseAddr + 11, 1, 'uint16');
|
|
627
|
+
const dcCurrentRaw = await this.readRegisterValue(baseAddr + 14, 1, 'uint16');
|
|
628
|
+
const dcVoltageRaw = await this.readRegisterValue(baseAddr + 15, 1, 'uint16');
|
|
629
|
+
const dcPowerRaw = await this.readRegisterValue(baseAddr + 20, 1, 'int16');
|
|
630
|
+
const stateRaw = await this.readRegisterValue(baseAddr + 24, 1, 'uint16');
|
|
631
|
+
this.logRegisterRead(101, 24, 'Operating State', stateRaw, 'enum16');
|
|
649
632
|
return {
|
|
650
633
|
blockNumber: 101,
|
|
651
|
-
voltageAN: this.applyScaleFactor(voltageRaw, scaleFactors.V_SF, 'uint16', '
|
|
652
|
-
acCurrent: this.applyScaleFactor(acCurrentRaw, scaleFactors.A_SF, 'uint16', '
|
|
653
|
-
acPower: this.applyScaleFactor(acPowerRaw, scaleFactors.W_SF, 'int16', '
|
|
654
|
-
frequency: this.applyScaleFactor(freqRaw, scaleFactors.Hz_SF, 'uint16', '
|
|
655
|
-
dcCurrent: this.applyScaleFactor(dcCurrentRaw, scaleFactors.DCA_SF, 'uint16', '
|
|
656
|
-
dcVoltage: this.applyScaleFactor(dcVoltageRaw, scaleFactors.DCV_SF, 'uint16', '
|
|
657
|
-
dcPower: this.applyScaleFactor(dcPowerRaw, scaleFactors.DCW_SF, 'int16', '
|
|
634
|
+
voltageAN: this.applyScaleFactor(voltageRaw, scaleFactors.V_SF, 'uint16', 'Voltage AN', 7, 101),
|
|
635
|
+
acCurrent: this.applyScaleFactor(acCurrentRaw, scaleFactors.A_SF, 'uint16', 'AC Current', 2, 101),
|
|
636
|
+
acPower: this.applyScaleFactor(acPowerRaw, scaleFactors.W_SF, 'int16', 'AC Power', 9, 101),
|
|
637
|
+
frequency: this.applyScaleFactor(freqRaw, scaleFactors.Hz_SF, 'uint16', 'Frequency', 11, 101),
|
|
638
|
+
dcCurrent: this.applyScaleFactor(dcCurrentRaw, scaleFactors.DCA_SF, 'uint16', 'DC Current', 14, 101),
|
|
639
|
+
dcVoltage: this.applyScaleFactor(dcVoltageRaw, scaleFactors.DCV_SF, 'uint16', 'DC Voltage', 15, 101),
|
|
640
|
+
dcPower: this.applyScaleFactor(dcPowerRaw, scaleFactors.DCW_SF, 'int16', 'DC Power', 20, 101),
|
|
658
641
|
operatingState: stateRaw
|
|
659
642
|
};
|
|
660
643
|
}
|
|
@@ -681,24 +664,55 @@ export class SunspecModbusClient {
|
|
|
681
664
|
DCW_SF: await this.readRegisterValue(baseAddr + 31, 1, 'int16'), // Offset 31
|
|
682
665
|
Tmp_SF: await this.readRegisterValue(baseAddr + 36, 1, 'int16') // Offset 36
|
|
683
666
|
};
|
|
684
|
-
|
|
667
|
+
this.logRegisterRead(103, 6, 'A_SF', scaleFactors.A_SF, 'int16');
|
|
668
|
+
this.logRegisterRead(103, 13, 'V_SF', scaleFactors.V_SF, 'int16');
|
|
669
|
+
this.logRegisterRead(103, 15, 'W_SF', scaleFactors.W_SF, 'int16');
|
|
670
|
+
this.logRegisterRead(103, 17, 'Hz_SF', scaleFactors.Hz_SF, 'int16');
|
|
671
|
+
this.logRegisterRead(103, 19, 'VA_SF', scaleFactors.VA_SF, 'int16');
|
|
672
|
+
this.logRegisterRead(103, 21, 'VAr_SF', scaleFactors.VAr_SF, 'int16');
|
|
673
|
+
this.logRegisterRead(103, 23, 'PF_SF', scaleFactors.PF_SF, 'int16');
|
|
674
|
+
this.logRegisterRead(103, 26, 'WH_SF', scaleFactors.WH_SF, 'int16');
|
|
675
|
+
this.logRegisterRead(103, 28, 'DCA_SF', scaleFactors.DCA_SF, 'int16');
|
|
676
|
+
this.logRegisterRead(103, 29, 'DCV_SF', scaleFactors.DCV_SF, 'int16');
|
|
677
|
+
this.logRegisterRead(103, 31, 'DCW_SF', scaleFactors.DCW_SF, 'int16');
|
|
678
|
+
this.logRegisterRead(103, 36, 'Tmp_SF', scaleFactors.Tmp_SF, 'int16');
|
|
685
679
|
return scaleFactors;
|
|
686
680
|
}
|
|
687
681
|
/**
|
|
688
682
|
* Apply scale factor to a value
|
|
689
683
|
* Returns undefined if the value is unimplemented or scale factor is out of range
|
|
690
684
|
*/
|
|
691
|
-
applyScaleFactor(value, scaleFactor, dataType = 'uint16', fieldName) {
|
|
685
|
+
applyScaleFactor(value, scaleFactor, dataType = 'uint16', fieldName, offset, modelId) {
|
|
692
686
|
// Check for unimplemented values
|
|
693
687
|
if (this.isUnimplementedValue(value, dataType)) {
|
|
694
688
|
return undefined;
|
|
695
689
|
}
|
|
696
690
|
const scaledValue = value * Math.pow(10, scaleFactor);
|
|
697
|
-
// Log the raw and scaled values
|
|
698
|
-
|
|
699
|
-
|
|
691
|
+
// Log the raw and scaled values
|
|
692
|
+
if (offset !== undefined && modelId !== undefined && fieldName) {
|
|
693
|
+
const hex = value >= 0 ? value.toString(16).toUpperCase() : (value >>> 0).toString(16).toUpperCase();
|
|
694
|
+
console.log(`[Model ${modelId}] offset ${offset}: ${fieldName} raw=${value} (0x${hex}), SF=${scaleFactor}, scaled=${scaledValue}`);
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
const fieldPrefix = fieldName ? `${fieldName}: ` : '';
|
|
698
|
+
console.log(`Scale Factor Applied - ${fieldPrefix}raw=${value} (decimal), SF=${scaleFactor}, scaled=${scaledValue}`);
|
|
699
|
+
}
|
|
700
700
|
return scaledValue;
|
|
701
701
|
}
|
|
702
|
+
logRegisterRead(modelId, offset, fieldName, rawValue, dataType) {
|
|
703
|
+
const typeInfo = dataType ? ` (${dataType})` : '';
|
|
704
|
+
if (rawValue === undefined) {
|
|
705
|
+
console.log(`[Model ${modelId}] offset ${offset}: ${fieldName} = -${typeInfo}`);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
if (typeof rawValue === 'number') {
|
|
709
|
+
const hex = rawValue >= 0 ? rawValue.toString(16).toUpperCase() : (rawValue >>> 0).toString(16).toUpperCase();
|
|
710
|
+
console.log(`[Model ${modelId}] offset ${offset}: ${fieldName} = ${rawValue} (0x${hex})${typeInfo}`);
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
console.log(`[Model ${modelId}] offset ${offset}: ${fieldName} = "${rawValue}"${typeInfo}`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
702
716
|
/**
|
|
703
717
|
* Read MPPT Scale Factors for a specific module
|
|
704
718
|
* Returns the scale factors for DC Current, DC Voltage, DC Power, and DC Energy
|
|
@@ -732,10 +746,10 @@ export class SunspecModbusClient {
|
|
|
732
746
|
DCW_SF, // Power Scale Factor
|
|
733
747
|
DCWH_SF, // Energy Scale Factor
|
|
734
748
|
};
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
749
|
+
this.logRegisterRead(160, 2, 'DCA_SF', DCA_SF, 'int16');
|
|
750
|
+
this.logRegisterRead(160, 3, 'DCV_SF', DCV_SF, 'int16');
|
|
751
|
+
this.logRegisterRead(160, 4, 'DCW_SF', DCW_SF, 'int16');
|
|
752
|
+
this.logRegisterRead(160, 5, 'DCWH_SF', DCWH_SF, 'int16');
|
|
739
753
|
return scaleFactors;
|
|
740
754
|
}
|
|
741
755
|
catch (error) {
|
|
@@ -765,7 +779,6 @@ export class SunspecModbusClient {
|
|
|
765
779
|
console.error(`Failed to read scale factors for MPPT module ${moduleId}`);
|
|
766
780
|
return null;
|
|
767
781
|
}
|
|
768
|
-
console.log(`MPPT Module ${moduleId} Scale Factors:`, JSON.stringify(scaleFactors, null, 2));
|
|
769
782
|
const id = await this.readRegisterValue(moduleAddr, 1, 'uint16');
|
|
770
783
|
const idString = await this.readRegisterValue(moduleAddr + 1, 8, 'string');
|
|
771
784
|
const dcCurrentRaw = await this.readRegisterValue(moduleAddr + 9, 1, 'uint16');
|
|
@@ -774,6 +787,8 @@ export class SunspecModbusClient {
|
|
|
774
787
|
const dcEnergyRaw = await this.readRegisterValue(moduleAddr + 12, 2, 'uint32');
|
|
775
788
|
const temperatureRaw = await this.readRegisterValue(moduleAddr + 16, 1, 'int16');
|
|
776
789
|
const dcst = await this.readRegisterValue(moduleAddr + 17, 1, 'uint16');
|
|
790
|
+
this.logRegisterRead(160, 0, `MPPT ${moduleId} ID`, id, 'uint16');
|
|
791
|
+
this.logRegisterRead(160, 1, `MPPT ${moduleId} String ID`, idString, 'string');
|
|
777
792
|
// Map the DC module state to human-readable name
|
|
778
793
|
// Check if this module is actually implemented/connected
|
|
779
794
|
// If all key values are unimplemented, this module doesn't exist
|
|
@@ -787,24 +802,28 @@ export class SunspecModbusClient {
|
|
|
787
802
|
// Note: There appears to be a temperature scale factor in the original model,
|
|
788
803
|
// but it's not in the current register map. We'll apply a default scale factor.
|
|
789
804
|
const temperatureScaleFactor = -1; // Common default for temperature readings
|
|
805
|
+
this.logRegisterRead(160, 12, `MPPT ${moduleId} DC Energy`, dcEnergyRaw, 'acc32');
|
|
806
|
+
const timestampRaw = await this.readRegisterValue(moduleAddr + 14, 2, 'uint32');
|
|
807
|
+
this.logRegisterRead(160, 14, `MPPT ${moduleId} Timestamp`, timestampRaw, 'uint32');
|
|
808
|
+
this.logRegisterRead(160, 17, `MPPT ${moduleId} Operating State`, dcst, 'enum16');
|
|
790
809
|
const data = {
|
|
791
810
|
blockNumber: 160,
|
|
792
811
|
blockAddress: model.address,
|
|
793
812
|
blockLength: model.length,
|
|
794
813
|
id: id,
|
|
795
814
|
stringId: idString,
|
|
796
|
-
dcCurrent: this.applyScaleFactor(dcCurrentRaw, scaleFactors.DCA_SF, 'uint16', `MPPT ${moduleId} DC Current
|
|
815
|
+
dcCurrent: this.applyScaleFactor(dcCurrentRaw, scaleFactors.DCA_SF, 'uint16', `MPPT ${moduleId} DC Current`, 9, 160),
|
|
797
816
|
dcCurrentSF: scaleFactors.DCA_SF,
|
|
798
|
-
dcVoltage: this.applyScaleFactor(dcVoltageRaw, scaleFactors.DCV_SF, 'uint16', `MPPT ${moduleId} DC Voltage
|
|
817
|
+
dcVoltage: this.applyScaleFactor(dcVoltageRaw, scaleFactors.DCV_SF, 'uint16', `MPPT ${moduleId} DC Voltage`, 10, 160),
|
|
799
818
|
dcVoltageSF: scaleFactors.DCV_SF,
|
|
800
|
-
dcPower: this.applyScaleFactor(dcPowerRaw, scaleFactors.DCW_SF, 'uint16', `MPPT ${moduleId} DC Power
|
|
819
|
+
dcPower: this.applyScaleFactor(dcPowerRaw, scaleFactors.DCW_SF, 'uint16', `MPPT ${moduleId} DC Power`, 11, 160),
|
|
801
820
|
dcPowerSF: scaleFactors.DCW_SF,
|
|
802
821
|
dcEnergy: !this.isUnimplementedValue(dcEnergyRaw, 'acc32')
|
|
803
|
-
? dcEnergyRaw * Math.pow(10, scaleFactors.DCWH_SF)
|
|
822
|
+
? dcEnergyRaw * Math.pow(10, scaleFactors.DCWH_SF)
|
|
804
823
|
: undefined,
|
|
805
824
|
dcEnergySF: scaleFactors.DCWH_SF,
|
|
806
|
-
timestamp:
|
|
807
|
-
temperature: this.applyScaleFactor(temperatureRaw, temperatureScaleFactor, 'int16', `MPPT ${moduleId} Temperature
|
|
825
|
+
timestamp: timestampRaw,
|
|
826
|
+
temperature: this.applyScaleFactor(temperatureRaw, temperatureScaleFactor, 'int16', `MPPT ${moduleId} Temperature`, 16, 160),
|
|
808
827
|
temperatureSF: temperatureScaleFactor,
|
|
809
828
|
operatingState: dcst,
|
|
810
829
|
};
|
|
@@ -897,6 +916,238 @@ export class SunspecModbusClient {
|
|
|
897
916
|
return `UNKNOWN(${state})`;
|
|
898
917
|
}
|
|
899
918
|
}
|
|
919
|
+
/**
|
|
920
|
+
* Map battery type to human-readable name (Model 802)
|
|
921
|
+
*/
|
|
922
|
+
mapBatteryType(typ) {
|
|
923
|
+
switch (typ) {
|
|
924
|
+
case SunspecBatteryType.NOT_APPLICABLE_UNKNOWN:
|
|
925
|
+
return "NOT_APPLICABLE_UNKNOWN";
|
|
926
|
+
case SunspecBatteryType.LEAD_ACID:
|
|
927
|
+
return "LEAD_ACID";
|
|
928
|
+
case SunspecBatteryType.NICKEL_METAL_HYDRIDE:
|
|
929
|
+
return "NICKEL_METAL_HYDRIDE";
|
|
930
|
+
case SunspecBatteryType.NICKEL_CADMIUM:
|
|
931
|
+
return "NICKEL_CADMIUM";
|
|
932
|
+
case SunspecBatteryType.LITHIUM_ION:
|
|
933
|
+
return "LITHIUM_ION";
|
|
934
|
+
case SunspecBatteryType.CARBON_ZINC:
|
|
935
|
+
return "CARBON_ZINC";
|
|
936
|
+
case SunspecBatteryType.ZINC_CHLORIDE:
|
|
937
|
+
return "ZINC_CHLORIDE";
|
|
938
|
+
case SunspecBatteryType.ALKALINE:
|
|
939
|
+
return "ALKALINE";
|
|
940
|
+
case SunspecBatteryType.RECHARGEABLE_ALKALINE:
|
|
941
|
+
return "RECHARGEABLE_ALKALINE";
|
|
942
|
+
case SunspecBatteryType.SODIUM_SULFUR:
|
|
943
|
+
return "SODIUM_SULFUR";
|
|
944
|
+
case SunspecBatteryType.FLOW:
|
|
945
|
+
return "FLOW";
|
|
946
|
+
case SunspecBatteryType.SUPER_CAPACITOR:
|
|
947
|
+
return "SUPER_CAPACITOR";
|
|
948
|
+
case SunspecBatteryType.OTHER:
|
|
949
|
+
return "OTHER";
|
|
950
|
+
default:
|
|
951
|
+
if (this.isUnimplementedValue(typ, 'enum16')) {
|
|
952
|
+
return "NOT_IMPLEMENTED";
|
|
953
|
+
}
|
|
954
|
+
return `UNKNOWN(${typ})`;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Map battery bank state to human-readable name (Model 802)
|
|
959
|
+
*/
|
|
960
|
+
mapBatteryBankState(state) {
|
|
961
|
+
switch (state) {
|
|
962
|
+
case SunspecBatteryBankState.DISCONNECTED:
|
|
963
|
+
return "DISCONNECTED";
|
|
964
|
+
case SunspecBatteryBankState.INITIALIZING:
|
|
965
|
+
return "INITIALIZING";
|
|
966
|
+
case SunspecBatteryBankState.CONNECTED:
|
|
967
|
+
return "CONNECTED";
|
|
968
|
+
case SunspecBatteryBankState.STANDBY:
|
|
969
|
+
return "STANDBY";
|
|
970
|
+
case SunspecBatteryBankState.SOC_PROTECTION:
|
|
971
|
+
return "SOC_PROTECTION";
|
|
972
|
+
case SunspecBatteryBankState.SUSPENDING:
|
|
973
|
+
return "SUSPENDING";
|
|
974
|
+
case SunspecBatteryBankState.FAULT:
|
|
975
|
+
return "FAULT";
|
|
976
|
+
default:
|
|
977
|
+
if (this.isUnimplementedValue(state, 'enum16')) {
|
|
978
|
+
return "NOT_IMPLEMENTED";
|
|
979
|
+
}
|
|
980
|
+
return `UNKNOWN(${state})`;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Read Model 802 scale factors (offsets 52-63)
|
|
985
|
+
*/
|
|
986
|
+
async readBatteryBaseScaleFactors(baseAddr) {
|
|
987
|
+
const scaleFactors = {
|
|
988
|
+
AHRtg_SF: await this.readRegisterValue(baseAddr + 52, 1, 'int16'),
|
|
989
|
+
WHRtg_SF: await this.readRegisterValue(baseAddr + 53, 1, 'int16'),
|
|
990
|
+
WChaDisChaMax_SF: await this.readRegisterValue(baseAddr + 54, 1, 'int16'),
|
|
991
|
+
DisChaRte_SF: await this.readRegisterValue(baseAddr + 55, 1, 'int16'),
|
|
992
|
+
SoC_SF: await this.readRegisterValue(baseAddr + 56, 1, 'int16'),
|
|
993
|
+
DoD_SF: await this.readRegisterValue(baseAddr + 57, 1, 'int16'),
|
|
994
|
+
SoH_SF: await this.readRegisterValue(baseAddr + 58, 1, 'int16'),
|
|
995
|
+
V_SF: await this.readRegisterValue(baseAddr + 59, 1, 'int16'),
|
|
996
|
+
CellV_SF: await this.readRegisterValue(baseAddr + 60, 1, 'int16'),
|
|
997
|
+
A_SF: await this.readRegisterValue(baseAddr + 61, 1, 'int16'),
|
|
998
|
+
AMax_SF: await this.readRegisterValue(baseAddr + 62, 1, 'int16'),
|
|
999
|
+
W_SF: await this.readRegisterValue(baseAddr + 63, 1, 'int16'),
|
|
1000
|
+
};
|
|
1001
|
+
this.logRegisterRead(802, 52, 'AHRtg_SF', scaleFactors.AHRtg_SF, 'int16');
|
|
1002
|
+
this.logRegisterRead(802, 53, 'WHRtg_SF', scaleFactors.WHRtg_SF, 'int16');
|
|
1003
|
+
this.logRegisterRead(802, 54, 'WChaDisChaMax_SF', scaleFactors.WChaDisChaMax_SF, 'int16');
|
|
1004
|
+
this.logRegisterRead(802, 55, 'DisChaRte_SF', scaleFactors.DisChaRte_SF, 'int16');
|
|
1005
|
+
this.logRegisterRead(802, 56, 'SoC_SF', scaleFactors.SoC_SF, 'int16');
|
|
1006
|
+
this.logRegisterRead(802, 57, 'DoD_SF', scaleFactors.DoD_SF, 'int16');
|
|
1007
|
+
this.logRegisterRead(802, 58, 'SoH_SF', scaleFactors.SoH_SF, 'int16');
|
|
1008
|
+
this.logRegisterRead(802, 59, 'V_SF', scaleFactors.V_SF, 'int16');
|
|
1009
|
+
this.logRegisterRead(802, 60, 'CellV_SF', scaleFactors.CellV_SF, 'int16');
|
|
1010
|
+
this.logRegisterRead(802, 61, 'A_SF', scaleFactors.A_SF, 'int16');
|
|
1011
|
+
this.logRegisterRead(802, 62, 'AMax_SF', scaleFactors.AMax_SF, 'int16');
|
|
1012
|
+
this.logRegisterRead(802, 63, 'W_SF', scaleFactors.W_SF, 'int16');
|
|
1013
|
+
return scaleFactors;
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Read battery base data from Model 802 (Battery Base)
|
|
1017
|
+
*/
|
|
1018
|
+
async readBatteryBaseData() {
|
|
1019
|
+
const model = this.findModel(SunspecModelId.BatteryBase);
|
|
1020
|
+
if (!model) {
|
|
1021
|
+
console.log('Battery Base model 802 not found');
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
const baseAddr = model.address;
|
|
1025
|
+
console.log(`Reading Battery Base Data from Model 802 at base address: ${baseAddr}`);
|
|
1026
|
+
try {
|
|
1027
|
+
// Read scale factors first (offsets 52-63)
|
|
1028
|
+
const sf = await this.readBatteryBaseScaleFactors(baseAddr);
|
|
1029
|
+
// Read raw values
|
|
1030
|
+
const ahRtgRaw = await this.readRegisterValue(baseAddr + 2, 1, 'uint16');
|
|
1031
|
+
const whRtgRaw = await this.readRegisterValue(baseAddr + 3, 1, 'uint16');
|
|
1032
|
+
const wChaRteMaxRaw = await this.readRegisterValue(baseAddr + 4, 1, 'uint16');
|
|
1033
|
+
const wDisChaRteMaxRaw = await this.readRegisterValue(baseAddr + 5, 1, 'uint16');
|
|
1034
|
+
const disChaRteRaw = await this.readRegisterValue(baseAddr + 6, 1, 'uint16');
|
|
1035
|
+
const soCMaxRaw = await this.readRegisterValue(baseAddr + 7, 1, 'uint16');
|
|
1036
|
+
const soCMinRaw = await this.readRegisterValue(baseAddr + 8, 1, 'uint16');
|
|
1037
|
+
const soCRsvMaxRaw = await this.readRegisterValue(baseAddr + 9, 1, 'uint16');
|
|
1038
|
+
const soCRsvMinRaw = await this.readRegisterValue(baseAddr + 10, 1, 'uint16');
|
|
1039
|
+
const soCRaw = await this.readRegisterValue(baseAddr + 11, 1, 'uint16');
|
|
1040
|
+
const doDRaw = await this.readRegisterValue(baseAddr + 12, 1, 'uint16');
|
|
1041
|
+
const soHRaw = await this.readRegisterValue(baseAddr + 13, 1, 'uint16');
|
|
1042
|
+
const nCycRaw = await this.readRegisterValue(baseAddr + 14, 2, 'uint32');
|
|
1043
|
+
const chaStRaw = await this.readRegisterValue(baseAddr + 16, 1, 'uint16');
|
|
1044
|
+
const locRemCtlRaw = await this.readRegisterValue(baseAddr + 17, 1, 'uint16');
|
|
1045
|
+
const typRaw = await this.readRegisterValue(baseAddr + 21, 1, 'uint16');
|
|
1046
|
+
const stateRaw = await this.readRegisterValue(baseAddr + 22, 1, 'uint16');
|
|
1047
|
+
const evt1Raw = await this.readRegisterValue(baseAddr + 26, 2, 'uint32');
|
|
1048
|
+
const evt2Raw = await this.readRegisterValue(baseAddr + 28, 2, 'uint32');
|
|
1049
|
+
const evtVnd1Raw = await this.readRegisterValue(baseAddr + 30, 2, 'uint32');
|
|
1050
|
+
const evtVnd2Raw = await this.readRegisterValue(baseAddr + 32, 2, 'uint32');
|
|
1051
|
+
const vRaw = await this.readRegisterValue(baseAddr + 34, 1, 'uint16');
|
|
1052
|
+
const vMaxRaw = await this.readRegisterValue(baseAddr + 35, 1, 'uint16');
|
|
1053
|
+
const vMinRaw = await this.readRegisterValue(baseAddr + 36, 1, 'uint16');
|
|
1054
|
+
const cellVMaxRaw = await this.readRegisterValue(baseAddr + 37, 1, 'uint16');
|
|
1055
|
+
const cellVMaxStrRaw = await this.readRegisterValue(baseAddr + 38, 1, 'uint16');
|
|
1056
|
+
const cellVMaxModRaw = await this.readRegisterValue(baseAddr + 39, 1, 'uint16');
|
|
1057
|
+
const cellVMinRaw = await this.readRegisterValue(baseAddr + 40, 1, 'uint16');
|
|
1058
|
+
const cellVMinStrRaw = await this.readRegisterValue(baseAddr + 41, 1, 'uint16');
|
|
1059
|
+
const cellVMinModRaw = await this.readRegisterValue(baseAddr + 42, 1, 'uint16');
|
|
1060
|
+
const cellVAvgRaw = await this.readRegisterValue(baseAddr + 43, 1, 'uint16');
|
|
1061
|
+
const aRaw = await this.readRegisterValue(baseAddr + 44, 1, 'int16');
|
|
1062
|
+
const aChaMaxRaw = await this.readRegisterValue(baseAddr + 45, 1, 'uint16');
|
|
1063
|
+
const aDisChaMaxRaw = await this.readRegisterValue(baseAddr + 46, 1, 'uint16');
|
|
1064
|
+
const wRaw = await this.readRegisterValue(baseAddr + 47, 1, 'int16');
|
|
1065
|
+
const reqInvStateRaw = await this.readRegisterValue(baseAddr + 48, 1, 'uint16');
|
|
1066
|
+
const reqWRaw = await this.readRegisterValue(baseAddr + 49, 1, 'int16');
|
|
1067
|
+
const setOpRaw = await this.readRegisterValue(baseAddr + 50, 1, 'uint16');
|
|
1068
|
+
const setInvStateRaw = await this.readRegisterValue(baseAddr + 51, 1, 'uint16');
|
|
1069
|
+
// Map enum fields
|
|
1070
|
+
const chaStName = this.mapBatteryChargeState(chaStRaw);
|
|
1071
|
+
const typName = this.mapBatteryType(typRaw);
|
|
1072
|
+
const stateName = this.mapBatteryBankState(stateRaw);
|
|
1073
|
+
// Log non-scaled fields
|
|
1074
|
+
this.logRegisterRead(802, 14, 'nCyc', nCycRaw, 'uint32');
|
|
1075
|
+
this.logRegisterRead(802, 16, 'chaSt', chaStRaw, 'enum16');
|
|
1076
|
+
this.logRegisterRead(802, 17, 'locRemCtl', locRemCtlRaw, 'enum16');
|
|
1077
|
+
this.logRegisterRead(802, 21, 'typ', typRaw, 'enum16');
|
|
1078
|
+
this.logRegisterRead(802, 22, 'state', stateRaw, 'enum16');
|
|
1079
|
+
this.logRegisterRead(802, 26, 'evt1', evt1Raw, 'bitfield32');
|
|
1080
|
+
this.logRegisterRead(802, 28, 'evt2', evt2Raw, 'bitfield32');
|
|
1081
|
+
this.logRegisterRead(802, 30, 'evtVnd1', evtVnd1Raw, 'bitfield32');
|
|
1082
|
+
this.logRegisterRead(802, 32, 'evtVnd2', evtVnd2Raw, 'bitfield32');
|
|
1083
|
+
this.logRegisterRead(802, 38, 'cellVMaxStr', cellVMaxStrRaw, 'uint16');
|
|
1084
|
+
this.logRegisterRead(802, 39, 'cellVMaxMod', cellVMaxModRaw, 'uint16');
|
|
1085
|
+
this.logRegisterRead(802, 41, 'cellVMinStr', cellVMinStrRaw, 'uint16');
|
|
1086
|
+
this.logRegisterRead(802, 42, 'cellVMinMod', cellVMinModRaw, 'uint16');
|
|
1087
|
+
this.logRegisterRead(802, 48, 'reqInvState', reqInvStateRaw, 'enum16');
|
|
1088
|
+
this.logRegisterRead(802, 50, 'setOp', setOpRaw, 'enum16');
|
|
1089
|
+
this.logRegisterRead(802, 51, 'setInvState', setInvStateRaw, 'enum16');
|
|
1090
|
+
const data = {
|
|
1091
|
+
blockNumber: 802,
|
|
1092
|
+
blockAddress: model.address,
|
|
1093
|
+
blockLength: model.length,
|
|
1094
|
+
// Nameplate
|
|
1095
|
+
ahRtg: this.applyScaleFactor(ahRtgRaw, sf.AHRtg_SF, 'uint16', 'AH Rating', 2, 802),
|
|
1096
|
+
whRtg: this.applyScaleFactor(whRtgRaw, sf.WHRtg_SF, 'uint16', 'WH Rating', 3, 802),
|
|
1097
|
+
wChaRteMax: this.applyScaleFactor(wChaRteMaxRaw, sf.WChaDisChaMax_SF, 'uint16', 'Max Charge Rate', 4, 802),
|
|
1098
|
+
wDisChaRteMax: this.applyScaleFactor(wDisChaRteMaxRaw, sf.WChaDisChaMax_SF, 'uint16', 'Max Discharge Rate', 5, 802),
|
|
1099
|
+
// SoC/Health
|
|
1100
|
+
disChaRte: this.applyScaleFactor(disChaRteRaw, sf.DisChaRte_SF, 'uint16', 'Self Discharge Rate', 6, 802),
|
|
1101
|
+
soCMax: this.applyScaleFactor(soCMaxRaw, sf.SoC_SF, 'uint16', 'SoC Max', 7, 802),
|
|
1102
|
+
soCMin: this.applyScaleFactor(soCMinRaw, sf.SoC_SF, 'uint16', 'SoC Min', 8, 802),
|
|
1103
|
+
soCRsvMax: this.applyScaleFactor(soCRsvMaxRaw, sf.SoC_SF, 'uint16', 'SoC Reserve Max', 9, 802),
|
|
1104
|
+
soCRsvMin: this.applyScaleFactor(soCRsvMinRaw, sf.SoC_SF, 'uint16', 'SoC Reserve Min', 10, 802),
|
|
1105
|
+
soC: this.applyScaleFactor(soCRaw, sf.SoC_SF, 'uint16', 'State of Charge', 11, 802),
|
|
1106
|
+
doD: this.applyScaleFactor(doDRaw, sf.DoD_SF, 'uint16', 'Depth of Discharge', 12, 802),
|
|
1107
|
+
soH: this.applyScaleFactor(soHRaw, sf.SoH_SF, 'uint16', 'State of Health', 13, 802),
|
|
1108
|
+
// Status
|
|
1109
|
+
nCyc: !this.isUnimplementedValue(nCycRaw, 'uint32') ? nCycRaw : undefined,
|
|
1110
|
+
chaSt: !this.isUnimplementedValue(chaStRaw, 'enum16') ? chaStRaw : undefined,
|
|
1111
|
+
chaStName,
|
|
1112
|
+
locRemCtl: !this.isUnimplementedValue(locRemCtlRaw, 'enum16') ? locRemCtlRaw : undefined,
|
|
1113
|
+
typ: !this.isUnimplementedValue(typRaw, 'enum16') ? typRaw : undefined,
|
|
1114
|
+
typName,
|
|
1115
|
+
state: !this.isUnimplementedValue(stateRaw, 'enum16') ? stateRaw : undefined,
|
|
1116
|
+
stateName,
|
|
1117
|
+
// Events
|
|
1118
|
+
evt1: !this.isUnimplementedValue(evt1Raw, 'bitfield32') ? evt1Raw : undefined,
|
|
1119
|
+
evt2: !this.isUnimplementedValue(evt2Raw, 'bitfield32') ? evt2Raw : undefined,
|
|
1120
|
+
evtVnd1: !this.isUnimplementedValue(evtVnd1Raw, 'bitfield32') ? evtVnd1Raw : undefined,
|
|
1121
|
+
evtVnd2: !this.isUnimplementedValue(evtVnd2Raw, 'bitfield32') ? evtVnd2Raw : undefined,
|
|
1122
|
+
// Voltage
|
|
1123
|
+
v: this.applyScaleFactor(vRaw, sf.V_SF, 'uint16', 'Battery Voltage', 34, 802),
|
|
1124
|
+
vMax: this.applyScaleFactor(vMaxRaw, sf.V_SF, 'uint16', 'Max Battery Voltage', 35, 802),
|
|
1125
|
+
vMin: this.applyScaleFactor(vMinRaw, sf.V_SF, 'uint16', 'Min Battery Voltage', 36, 802),
|
|
1126
|
+
cellVMax: this.applyScaleFactor(cellVMaxRaw, sf.CellV_SF, 'uint16', 'Max Cell Voltage', 37, 802),
|
|
1127
|
+
cellVMaxStr: !this.isUnimplementedValue(cellVMaxStrRaw, 'uint16') ? cellVMaxStrRaw : undefined,
|
|
1128
|
+
cellVMaxMod: !this.isUnimplementedValue(cellVMaxModRaw, 'uint16') ? cellVMaxModRaw : undefined,
|
|
1129
|
+
cellVMin: this.applyScaleFactor(cellVMinRaw, sf.CellV_SF, 'uint16', 'Min Cell Voltage', 40, 802),
|
|
1130
|
+
cellVMinStr: !this.isUnimplementedValue(cellVMinStrRaw, 'uint16') ? cellVMinStrRaw : undefined,
|
|
1131
|
+
cellVMinMod: !this.isUnimplementedValue(cellVMinModRaw, 'uint16') ? cellVMinModRaw : undefined,
|
|
1132
|
+
cellVAvg: this.applyScaleFactor(cellVAvgRaw, sf.CellV_SF, 'uint16', 'Avg Cell Voltage', 43, 802),
|
|
1133
|
+
// Current
|
|
1134
|
+
a: this.applyScaleFactor(aRaw, sf.A_SF, 'int16', 'Battery Current', 44, 802),
|
|
1135
|
+
aChaMax: this.applyScaleFactor(aChaMaxRaw, sf.AMax_SF, 'uint16', 'Max Charge Current', 45, 802),
|
|
1136
|
+
aDisChaMax: this.applyScaleFactor(aDisChaMaxRaw, sf.AMax_SF, 'uint16', 'Max Discharge Current', 46, 802),
|
|
1137
|
+
// Power
|
|
1138
|
+
w: this.applyScaleFactor(wRaw, sf.W_SF, 'int16', 'Battery Power', 47, 802),
|
|
1139
|
+
reqInvState: !this.isUnimplementedValue(reqInvStateRaw, 'enum16') ? reqInvStateRaw : undefined,
|
|
1140
|
+
reqW: this.applyScaleFactor(reqWRaw, sf.W_SF, 'int16', 'Requested Power', 49, 802),
|
|
1141
|
+
setOp: !this.isUnimplementedValue(setOpRaw, 'enum16') ? setOpRaw : undefined,
|
|
1142
|
+
setInvState: !this.isUnimplementedValue(setInvStateRaw, 'enum16') ? setInvStateRaw : undefined,
|
|
1143
|
+
};
|
|
1144
|
+
return data;
|
|
1145
|
+
}
|
|
1146
|
+
catch (error) {
|
|
1147
|
+
console.error(`Error reading battery base data: ${error}`);
|
|
1148
|
+
return null;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
900
1151
|
/**
|
|
901
1152
|
* Read battery data from Model 124 (Basic Storage Controls)
|
|
902
1153
|
*/
|
|
@@ -931,7 +1182,14 @@ export class SunspecModbusClient {
|
|
|
931
1182
|
InBatV_SF: await this.readRegisterValue(baseAddr + 24, 1, 'int16'),
|
|
932
1183
|
InOutWRte_SF: await this.readRegisterValue(baseAddr + 25, 1, 'int16')
|
|
933
1184
|
};
|
|
934
|
-
|
|
1185
|
+
this.logRegisterRead(124, 18, 'WChaMax_SF', scaleFactors.WChaMax_SF, 'int16');
|
|
1186
|
+
this.logRegisterRead(124, 19, 'WChaDisChaGra_SF', scaleFactors.WChaDisChaGra_SF, 'int16');
|
|
1187
|
+
this.logRegisterRead(124, 20, 'VAChaMax_SF', scaleFactors.VAChaMax_SF, 'int16');
|
|
1188
|
+
this.logRegisterRead(124, 21, 'MinRsvPct_SF', scaleFactors.MinRsvPct_SF, 'int16');
|
|
1189
|
+
this.logRegisterRead(124, 22, 'ChaState_SF', scaleFactors.ChaState_SF, 'int16');
|
|
1190
|
+
this.logRegisterRead(124, 23, 'StorAval_SF', scaleFactors.StorAval_SF, 'int16');
|
|
1191
|
+
this.logRegisterRead(124, 24, 'InBatV_SF', scaleFactors.InBatV_SF, 'int16');
|
|
1192
|
+
this.logRegisterRead(124, 25, 'InOutWRte_SF', scaleFactors.InOutWRte_SF, 'int16');
|
|
935
1193
|
// Read raw values
|
|
936
1194
|
const wChaMaxRaw = await this.readRegisterValue(baseAddr + 2, 1, 'uint16');
|
|
937
1195
|
const wChaGraRaw = await this.readRegisterValue(baseAddr + 3, 1, 'uint16');
|
|
@@ -949,43 +1207,42 @@ export class SunspecModbusClient {
|
|
|
949
1207
|
const inOutWRteRvrtTmsRaw = await this.readRegisterValue(baseAddr + 15, 1, 'uint16');
|
|
950
1208
|
const inOutWRteRmpTmsRaw = await this.readRegisterValue(baseAddr + 16, 1, 'uint16');
|
|
951
1209
|
const chaGriSetRaw = await this.readRegisterValue(baseAddr + 17, 1, 'uint16');
|
|
952
|
-
// Map charge state
|
|
1210
|
+
// Map charge state and log non-scaled fields
|
|
953
1211
|
const chaStName = this.mapBatteryChargeState(chaStRaw);
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
1212
|
+
this.logRegisterRead(124, 5, 'storCtlMod', storCtlModRaw, 'bitfield16');
|
|
1213
|
+
this.logRegisterRead(124, 11, 'chaSt', chaStRaw, 'enum16');
|
|
1214
|
+
this.logRegisterRead(124, 14, 'inOutWRteWinTms', inOutWRteWinTmsRaw, 'uint16');
|
|
1215
|
+
this.logRegisterRead(124, 15, 'inOutWRteRvrtTms', inOutWRteRvrtTmsRaw, 'uint16');
|
|
1216
|
+
this.logRegisterRead(124, 16, 'inOutWRteRmpTms', inOutWRteRmpTmsRaw, 'uint16');
|
|
1217
|
+
this.logRegisterRead(124, 17, 'chaGriSet', chaGriSetRaw, 'enum16');
|
|
961
1218
|
// Calculate actual values with scale factors
|
|
962
1219
|
const data = {
|
|
963
1220
|
blockNumber: 124,
|
|
964
1221
|
blockAddress: model.address,
|
|
965
1222
|
blockLength: model.length,
|
|
966
1223
|
// Control settings
|
|
967
|
-
wChaMax: this.applyScaleFactor(wChaMaxRaw, scaleFactors.WChaMax_SF, 'uint16', 'Max Charge Power'),
|
|
1224
|
+
wChaMax: this.applyScaleFactor(wChaMaxRaw, scaleFactors.WChaMax_SF, 'uint16', 'Max Charge Power', 2, 124),
|
|
968
1225
|
wChaMaxSF: scaleFactors.WChaMax_SF,
|
|
969
|
-
wChaGra: this.applyScaleFactor(wChaGraRaw, scaleFactors.WChaDisChaGra_SF, 'uint16', 'Charge Rate Gradient'),
|
|
970
|
-
wDisChaGra: this.applyScaleFactor(wDisChaGraRaw, scaleFactors.WChaDisChaGra_SF, 'uint16', 'Discharge Rate Gradient'),
|
|
1226
|
+
wChaGra: this.applyScaleFactor(wChaGraRaw, scaleFactors.WChaDisChaGra_SF, 'uint16', 'Charge Rate Gradient', 3, 124),
|
|
1227
|
+
wDisChaGra: this.applyScaleFactor(wDisChaGraRaw, scaleFactors.WChaDisChaGra_SF, 'uint16', 'Discharge Rate Gradient', 4, 124),
|
|
971
1228
|
wChaDisChaGraSF: scaleFactors.WChaDisChaGra_SF,
|
|
972
1229
|
storCtlMod: !this.isUnimplementedValue(storCtlModRaw, 'bitfield16') ? storCtlModRaw : undefined,
|
|
973
|
-
vaChaMax: this.applyScaleFactor(vaChaMaxRaw, scaleFactors.VAChaMax_SF, 'uint16', 'Max Charging VA'),
|
|
1230
|
+
vaChaMax: this.applyScaleFactor(vaChaMaxRaw, scaleFactors.VAChaMax_SF, 'uint16', 'Max Charging VA', 6, 124),
|
|
974
1231
|
vaChaMaxSF: scaleFactors.VAChaMax_SF,
|
|
975
|
-
minRsvPct: this.applyScaleFactor(minRsvPctRaw, scaleFactors.MinRsvPct_SF, 'uint16', 'Min Reserve Percent'),
|
|
1232
|
+
minRsvPct: this.applyScaleFactor(minRsvPctRaw, scaleFactors.MinRsvPct_SF, 'uint16', 'Min Reserve Percent', 7, 124),
|
|
976
1233
|
minRsvPctSF: scaleFactors.MinRsvPct_SF,
|
|
977
1234
|
// Status values
|
|
978
|
-
chaState: this.applyScaleFactor(chaStateRaw, scaleFactors.ChaState_SF, 'uint16', 'State of Charge'),
|
|
1235
|
+
chaState: this.applyScaleFactor(chaStateRaw, scaleFactors.ChaState_SF, 'uint16', 'State of Charge', 8, 124),
|
|
979
1236
|
chaStateSF: scaleFactors.ChaState_SF,
|
|
980
|
-
storAval: this.applyScaleFactor(storAvalRaw, scaleFactors.StorAval_SF, 'uint16', 'Available Storage'),
|
|
1237
|
+
storAval: this.applyScaleFactor(storAvalRaw, scaleFactors.StorAval_SF, 'uint16', 'Available Storage', 9, 124),
|
|
981
1238
|
storAvalSF: scaleFactors.StorAval_SF,
|
|
982
|
-
inBatV: this.applyScaleFactor(inBatVRaw, scaleFactors.InBatV_SF, 'uint16', 'Battery Voltage'),
|
|
1239
|
+
inBatV: this.applyScaleFactor(inBatVRaw, scaleFactors.InBatV_SF, 'uint16', 'Battery Voltage', 10, 124),
|
|
983
1240
|
inBatVSF: scaleFactors.InBatV_SF,
|
|
984
1241
|
chaSt: !this.isUnimplementedValue(chaStRaw, 'enum16') ? chaStRaw : undefined,
|
|
985
1242
|
chaStName: chaStName,
|
|
986
1243
|
// Rate control
|
|
987
|
-
outWRte: this.applyScaleFactor(outWRteRaw, scaleFactors.InOutWRte_SF, 'int16', 'Discharge Rate'),
|
|
988
|
-
inWRte: this.applyScaleFactor(inWRteRaw, scaleFactors.InOutWRte_SF, 'int16', 'Charge Rate'),
|
|
1244
|
+
outWRte: this.applyScaleFactor(outWRteRaw, scaleFactors.InOutWRte_SF, 'int16', 'Discharge Rate', 12, 124),
|
|
1245
|
+
inWRte: this.applyScaleFactor(inWRteRaw, scaleFactors.InOutWRte_SF, 'int16', 'Charge Rate', 13, 124),
|
|
989
1246
|
inOutWRteSF: scaleFactors.InOutWRte_SF,
|
|
990
1247
|
// Timing parameters
|
|
991
1248
|
inOutWRteWinTms: !this.isUnimplementedValue(inOutWRteWinTmsRaw, 'uint16') ? inOutWRteWinTmsRaw : undefined,
|
|
@@ -1010,8 +1267,43 @@ export class SunspecModbusClient {
|
|
|
1010
1267
|
}
|
|
1011
1268
|
return data;
|
|
1012
1269
|
}
|
|
1270
|
+
else if (model.id === 802) {
|
|
1271
|
+
// Model 802: Battery Base
|
|
1272
|
+
console.log('Using Model 802 (Battery Base)');
|
|
1273
|
+
const baseData = await this.readBatteryBaseData();
|
|
1274
|
+
if (!baseData) {
|
|
1275
|
+
return null;
|
|
1276
|
+
}
|
|
1277
|
+
// Derive charge/discharge power from w field
|
|
1278
|
+
let chargePower;
|
|
1279
|
+
let dischargePower;
|
|
1280
|
+
if (baseData.w !== undefined) {
|
|
1281
|
+
if (baseData.w >= 0) {
|
|
1282
|
+
chargePower = baseData.w;
|
|
1283
|
+
dischargePower = 0;
|
|
1284
|
+
}
|
|
1285
|
+
else {
|
|
1286
|
+
chargePower = 0;
|
|
1287
|
+
dischargePower = Math.abs(baseData.w);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
return {
|
|
1291
|
+
blockNumber: 802,
|
|
1292
|
+
blockAddress: model.address,
|
|
1293
|
+
blockLength: model.length,
|
|
1294
|
+
soc: baseData.soC,
|
|
1295
|
+
soh: baseData.soH,
|
|
1296
|
+
voltage: baseData.v,
|
|
1297
|
+
current: baseData.a,
|
|
1298
|
+
chaSt: baseData.chaSt,
|
|
1299
|
+
chaStName: baseData.chaStName,
|
|
1300
|
+
status: baseData.state,
|
|
1301
|
+
chargePower,
|
|
1302
|
+
dischargePower,
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1013
1305
|
else {
|
|
1014
|
-
// Handle other battery models (
|
|
1306
|
+
// Handle other battery models (803) if needed
|
|
1015
1307
|
console.log(`Battery Model ${model.id} reading not yet implemented`);
|
|
1016
1308
|
return {
|
|
1017
1309
|
blockNumber: model.id,
|
|
@@ -1142,6 +1434,9 @@ export class SunspecModbusClient {
|
|
|
1142
1434
|
MinRsvPct_SF: await this.readRegisterValue(baseAddr + 21, 1, 'int16'),
|
|
1143
1435
|
InOutWRte_SF: await this.readRegisterValue(baseAddr + 25, 1, 'int16')
|
|
1144
1436
|
};
|
|
1437
|
+
this.logRegisterRead(124, 18, 'WChaMax_SF', scaleFactors.WChaMax_SF, 'int16');
|
|
1438
|
+
this.logRegisterRead(124, 21, 'MinRsvPct_SF', scaleFactors.MinRsvPct_SF, 'int16');
|
|
1439
|
+
this.logRegisterRead(124, 25, 'InOutWRte_SF', scaleFactors.InOutWRte_SF, 'int16');
|
|
1145
1440
|
// Read raw values
|
|
1146
1441
|
const wChaMaxRaw = await this.readRegisterValue(baseAddr + 2, 1, 'uint16');
|
|
1147
1442
|
const storCtlModRaw = await this.readRegisterValue(baseAddr + 5, 1, 'uint16');
|
|
@@ -1149,14 +1444,16 @@ export class SunspecModbusClient {
|
|
|
1149
1444
|
const outWRteRaw = await this.readRegisterValue(baseAddr + 12, 1, 'int16');
|
|
1150
1445
|
const inWRteRaw = await this.readRegisterValue(baseAddr + 13, 1, 'int16');
|
|
1151
1446
|
const chaGriSetRaw = await this.readRegisterValue(baseAddr + 17, 1, 'uint16');
|
|
1447
|
+
this.logRegisterRead(124, 5, 'storCtlMod', storCtlModRaw, 'bitfield16');
|
|
1448
|
+
this.logRegisterRead(124, 17, 'chaGriSet', chaGriSetRaw, 'enum16');
|
|
1152
1449
|
// Apply scale factors and return control settings
|
|
1153
1450
|
return {
|
|
1154
1451
|
storCtlMod: !this.isUnimplementedValue(storCtlModRaw, 'bitfield16') ? storCtlModRaw : undefined,
|
|
1155
1452
|
chaGriSet: !this.isUnimplementedValue(chaGriSetRaw, 'enum16') ? chaGriSetRaw : undefined,
|
|
1156
|
-
wChaMax: this.applyScaleFactor(wChaMaxRaw, scaleFactors.WChaMax_SF, 'uint16'),
|
|
1157
|
-
inWRte: this.applyScaleFactor(inWRteRaw, scaleFactors.InOutWRte_SF, 'int16'),
|
|
1158
|
-
outWRte: this.applyScaleFactor(outWRteRaw, scaleFactors.InOutWRte_SF, 'int16'),
|
|
1159
|
-
minRsvPct: this.applyScaleFactor(minRsvPctRaw, scaleFactors.MinRsvPct_SF, 'uint16')
|
|
1453
|
+
wChaMax: this.applyScaleFactor(wChaMaxRaw, scaleFactors.WChaMax_SF, 'uint16', 'Max Charge Power', 2, 124),
|
|
1454
|
+
inWRte: this.applyScaleFactor(inWRteRaw, scaleFactors.InOutWRte_SF, 'int16', 'Charge Rate', 13, 124),
|
|
1455
|
+
outWRte: this.applyScaleFactor(outWRteRaw, scaleFactors.InOutWRte_SF, 'int16', 'Discharge Rate', 12, 124),
|
|
1456
|
+
minRsvPct: this.applyScaleFactor(minRsvPctRaw, scaleFactors.MinRsvPct_SF, 'uint16', 'Min Reserve Percent', 7, 124)
|
|
1160
1457
|
};
|
|
1161
1458
|
}
|
|
1162
1459
|
catch (error) {
|
|
@@ -1227,25 +1524,21 @@ export class SunspecModbusClient {
|
|
|
1227
1524
|
const powerSF = await this.readRegisterValue(baseAddr + powerSFOffset, 1, 'int16');
|
|
1228
1525
|
const freqSF = await this.readRegisterValue(baseAddr + freqSFOffset, 1, 'int16');
|
|
1229
1526
|
const energySF = await this.readRegisterValue(baseAddr + energySFOffset, 1, 'int16');
|
|
1230
|
-
|
|
1527
|
+
this.logRegisterRead(model.id, powerSFOffset, 'W_SF', powerSF, 'int16');
|
|
1528
|
+
this.logRegisterRead(model.id, freqSFOffset, 'Hz_SF', freqSF, 'int16');
|
|
1529
|
+
this.logRegisterRead(model.id, energySFOffset, 'TotWh_SF', energySF, 'int16');
|
|
1231
1530
|
// Read raw values
|
|
1232
|
-
const
|
|
1233
|
-
const
|
|
1234
|
-
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
const exportAddr = baseAddr + exportOffset;
|
|
1239
|
-
const exportRaw = await this.readRegisterValue(exportAddr, 2, 'uint32');
|
|
1240
|
-
console.log(`Meter Export Energy: address=${exportAddr}, raw=0x${exportRaw.toString(16).toUpperCase()} (${exportRaw}), SF=${energySF}`);
|
|
1241
|
-
const importAddr = baseAddr + importOffset;
|
|
1242
|
-
const importRaw = await this.readRegisterValue(importAddr, 2, 'uint32');
|
|
1243
|
-
console.log(`Meter Import Energy: address=${importAddr}, raw=0x${importRaw.toString(16).toUpperCase()} (${importRaw}), SF=${energySF}`);
|
|
1531
|
+
const powerRaw = await this.readRegisterValue(baseAddr + powerOffset, 1, 'int16');
|
|
1532
|
+
const freqRaw = await this.readRegisterValue(baseAddr + freqOffset, 1, 'uint16');
|
|
1533
|
+
const exportRaw = await this.readRegisterValue(baseAddr + exportOffset, 2, 'uint32');
|
|
1534
|
+
const importRaw = await this.readRegisterValue(baseAddr + importOffset, 2, 'uint32');
|
|
1535
|
+
this.logRegisterRead(model.id, exportOffset, 'TotWhExp', exportRaw, 'acc32');
|
|
1536
|
+
this.logRegisterRead(model.id, importOffset, 'TotWhImp', importRaw, 'acc32');
|
|
1244
1537
|
// Calculate final values with scale factors
|
|
1245
|
-
const totalPower = this.applyScaleFactor(powerRaw, powerSF, 'int16', '
|
|
1246
|
-
const frequency = this.applyScaleFactor(freqRaw, freqSF, 'uint16', '
|
|
1247
|
-
const exportedEnergy = this.applyScaleFactor(exportRaw, energySF, "acc32");
|
|
1248
|
-
const importedEnergy = this.applyScaleFactor(importRaw, energySF, "acc32");
|
|
1538
|
+
const totalPower = this.applyScaleFactor(powerRaw, powerSF, 'int16', 'Total Power', powerOffset, model.id);
|
|
1539
|
+
const frequency = this.applyScaleFactor(freqRaw, freqSF, 'uint16', 'Frequency', freqOffset, model.id);
|
|
1540
|
+
const exportedEnergy = this.applyScaleFactor(exportRaw, energySF, "acc32", 'Exported Energy', exportOffset, model.id);
|
|
1541
|
+
const importedEnergy = this.applyScaleFactor(importRaw, energySF, "acc32", 'Imported Energy', importOffset, model.id);
|
|
1249
1542
|
return {
|
|
1250
1543
|
blockNumber: model.id,
|
|
1251
1544
|
totalPower,
|
|
@@ -1279,30 +1572,26 @@ export class SunspecModbusClient {
|
|
|
1279
1572
|
const versionAddr = baseAddr + 40; // Offset 40-47 (8 registers) from data start
|
|
1280
1573
|
const serialAddr = baseAddr + 48; // Offset 48-63 (16 registers) from data start
|
|
1281
1574
|
const deviceAddrAddr = baseAddr + 64; // Offset 64 from data start
|
|
1282
|
-
console.log(`Reading manufacturer from address ${manufacturerAddr} (16 registers)`);
|
|
1283
1575
|
const manufacturer = await this.readRegisterValue(manufacturerAddr, 16, 'string');
|
|
1284
|
-
|
|
1285
|
-
console.log(`Reading model from address ${modelAddr} (16 registers)`);
|
|
1576
|
+
this.logRegisterRead(1, 0, 'Manufacturer', manufacturer, 'string');
|
|
1286
1577
|
const modelName = await this.readRegisterValue(modelAddr, 16, 'string');
|
|
1287
|
-
|
|
1288
|
-
console.log(`Reading options from address ${optionsAddr} (8 registers)`);
|
|
1578
|
+
this.logRegisterRead(1, 16, 'Model', modelName, 'string');
|
|
1289
1579
|
const options = await this.readRegisterValue(optionsAddr, 8, 'string');
|
|
1290
|
-
|
|
1580
|
+
this.logRegisterRead(1, 32, 'Options', options, 'string');
|
|
1291
1581
|
const version = await this.readRegisterValue(versionAddr, 8, 'string');
|
|
1292
|
-
|
|
1582
|
+
this.logRegisterRead(1, 40, 'Version', version, 'string');
|
|
1293
1583
|
const serialNumber = await this.readRegisterValue(serialAddr, 16, 'string');
|
|
1294
|
-
|
|
1584
|
+
this.logRegisterRead(1, 48, 'Serial Number', serialNumber, 'string');
|
|
1295
1585
|
const deviceAddress = await this.readRegisterValue(deviceAddrAddr, 1, 'uint16');
|
|
1296
|
-
|
|
1297
|
-
|
|
1586
|
+
this.logRegisterRead(1, 64, 'Device Address', deviceAddress, 'uint16');
|
|
1587
|
+
return {
|
|
1588
|
+
manufacturer,
|
|
1298
1589
|
model: modelName,
|
|
1299
|
-
options
|
|
1300
|
-
version
|
|
1301
|
-
serialNumber
|
|
1302
|
-
deviceAddress
|
|
1590
|
+
options,
|
|
1591
|
+
version,
|
|
1592
|
+
serialNumber,
|
|
1593
|
+
deviceAddress
|
|
1303
1594
|
};
|
|
1304
|
-
console.log('Common Block Data:', JSON.stringify(result, null, 2));
|
|
1305
|
-
return result;
|
|
1306
1595
|
}
|
|
1307
1596
|
catch (error) {
|
|
1308
1597
|
console.error(`Error reading common block: ${error}`);
|
|
@@ -1358,47 +1647,64 @@ export class SunspecModbusClient {
|
|
|
1358
1647
|
MaxRmpRte_SF: await this.readRegisterValue(baseAddr + 30, 1, 'int16'),
|
|
1359
1648
|
ECPNomHz_SF: await this.readRegisterValue(baseAddr + 31, 1, 'int16')
|
|
1360
1649
|
};
|
|
1650
|
+
this.logRegisterRead(121, 22, 'WMax_SF', scaleFactors.WMax_SF, 'int16');
|
|
1651
|
+
this.logRegisterRead(121, 23, 'VRef_SF', scaleFactors.VRef_SF, 'int16');
|
|
1652
|
+
this.logRegisterRead(121, 24, 'VRefOfs_SF', scaleFactors.VRefOfs_SF, 'int16');
|
|
1653
|
+
this.logRegisterRead(121, 25, 'VMinMax_SF', scaleFactors.VMinMax_SF, 'int16');
|
|
1654
|
+
this.logRegisterRead(121, 26, 'VAMax_SF', scaleFactors.VAMax_SF, 'int16');
|
|
1655
|
+
this.logRegisterRead(121, 27, 'VArMax_SF', scaleFactors.VArMax_SF, 'int16');
|
|
1656
|
+
this.logRegisterRead(121, 28, 'WGra_SF', scaleFactors.WGra_SF, 'int16');
|
|
1657
|
+
this.logRegisterRead(121, 29, 'PFMin_SF', scaleFactors.PFMin_SF, 'int16');
|
|
1658
|
+
this.logRegisterRead(121, 30, 'MaxRmpRte_SF', scaleFactors.MaxRmpRte_SF, 'int16');
|
|
1659
|
+
this.logRegisterRead(121, 31, 'ECPNomHz_SF', scaleFactors.ECPNomHz_SF, 'int16');
|
|
1660
|
+
// Read non-scaled fields first for logging
|
|
1661
|
+
const vArActRaw = await this.readRegisterValue(baseAddr + 17, 1, 'uint16');
|
|
1662
|
+
const clcTotVARaw = await this.readRegisterValue(baseAddr + 18, 1, 'uint16');
|
|
1663
|
+
const connPhRaw = await this.readRegisterValue(baseAddr + 21, 1, 'uint16');
|
|
1664
|
+
this.logRegisterRead(121, 17, 'VArAct', vArActRaw, 'enum16');
|
|
1665
|
+
this.logRegisterRead(121, 18, 'ClcTotVA', clcTotVARaw, 'enum16');
|
|
1666
|
+
this.logRegisterRead(121, 21, 'ConnPh', connPhRaw, 'enum16');
|
|
1361
1667
|
return {
|
|
1362
1668
|
blockNumber: 121,
|
|
1363
1669
|
blockAddress: model.address,
|
|
1364
1670
|
blockLength: model.length,
|
|
1365
1671
|
// Power settings - Offset 2
|
|
1366
|
-
WMax: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 2, 1, 'uint16'), scaleFactors.WMax_SF, 'uint16', 'Max Power'),
|
|
1672
|
+
WMax: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 2, 1, 'uint16'), scaleFactors.WMax_SF, 'uint16', 'Max Power', 2, 121),
|
|
1367
1673
|
WMax_SF: scaleFactors.WMax_SF,
|
|
1368
1674
|
// Voltage settings - Offsets 3-6
|
|
1369
|
-
VRef: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 3, 1, 'uint16'), scaleFactors.VRef_SF, 'uint16', 'Voltage Reference'),
|
|
1675
|
+
VRef: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 3, 1, 'uint16'), scaleFactors.VRef_SF, 'uint16', 'Voltage Reference', 3, 121),
|
|
1370
1676
|
VRef_SF: scaleFactors.VRef_SF,
|
|
1371
|
-
VRefOfs: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 4, 1, 'int16'), scaleFactors.VRefOfs_SF, 'int16', 'Voltage Reference Offset'),
|
|
1677
|
+
VRefOfs: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 4, 1, 'int16'), scaleFactors.VRefOfs_SF, 'int16', 'Voltage Reference Offset', 4, 121),
|
|
1372
1678
|
VRefOfs_SF: scaleFactors.VRefOfs_SF,
|
|
1373
|
-
VMax: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 5, 1, 'uint16'), scaleFactors.VMinMax_SF, 'uint16', 'Max Voltage'),
|
|
1374
|
-
VMin: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 6, 1, 'uint16'), scaleFactors.VMinMax_SF, 'uint16', 'Min Voltage'),
|
|
1679
|
+
VMax: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 5, 1, 'uint16'), scaleFactors.VMinMax_SF, 'uint16', 'Max Voltage', 5, 121),
|
|
1680
|
+
VMin: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 6, 1, 'uint16'), scaleFactors.VMinMax_SF, 'uint16', 'Min Voltage', 6, 121),
|
|
1375
1681
|
VMinMax_SF: scaleFactors.VMinMax_SF,
|
|
1376
1682
|
// Apparent power settings - Offset 7
|
|
1377
|
-
VAMax: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 7, 1, 'uint16'), scaleFactors.VAMax_SF, 'uint16', 'Max Apparent Power'),
|
|
1683
|
+
VAMax: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 7, 1, 'uint16'), scaleFactors.VAMax_SF, 'uint16', 'Max Apparent Power', 7, 121),
|
|
1378
1684
|
VAMax_SF: scaleFactors.VAMax_SF,
|
|
1379
1685
|
// Reactive power settings - Offsets 8-11
|
|
1380
|
-
VArMaxQ1: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 8, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q1'),
|
|
1381
|
-
VArMaxQ2: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 9, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q2'),
|
|
1382
|
-
VArMaxQ3: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 10, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q3'),
|
|
1383
|
-
VArMaxQ4: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 11, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q4'),
|
|
1686
|
+
VArMaxQ1: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 8, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q1', 8, 121),
|
|
1687
|
+
VArMaxQ2: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 9, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q2', 9, 121),
|
|
1688
|
+
VArMaxQ3: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 10, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q3', 10, 121),
|
|
1689
|
+
VArMaxQ4: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 11, 1, 'int16'), scaleFactors.VArMax_SF, 'int16', 'Max Reactive Power Q4', 11, 121),
|
|
1384
1690
|
VArMax_SF: scaleFactors.VArMax_SF,
|
|
1385
1691
|
// Ramp rate settings - Offset 12
|
|
1386
|
-
WGra: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 12, 1, 'uint16'), scaleFactors.WGra_SF, 'uint16', 'Power Ramp Rate'),
|
|
1692
|
+
WGra: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 12, 1, 'uint16'), scaleFactors.WGra_SF, 'uint16', 'Power Ramp Rate', 12, 121),
|
|
1387
1693
|
WGra_SF: scaleFactors.WGra_SF,
|
|
1388
1694
|
// Power factor settings - Offsets 13-16
|
|
1389
|
-
PFMinQ1: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 13, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q1'),
|
|
1390
|
-
PFMinQ2: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 14, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q2'),
|
|
1391
|
-
PFMinQ3: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 15, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q3'),
|
|
1392
|
-
PFMinQ4: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 16, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q4'),
|
|
1695
|
+
PFMinQ1: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 13, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q1', 13, 121),
|
|
1696
|
+
PFMinQ2: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 14, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q2', 14, 121),
|
|
1697
|
+
PFMinQ3: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 15, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q3', 15, 121),
|
|
1698
|
+
PFMinQ4: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 16, 1, 'int16'), scaleFactors.PFMin_SF, 'int16', 'Min Power Factor Q4', 16, 121),
|
|
1393
1699
|
PFMin_SF: scaleFactors.PFMin_SF,
|
|
1394
1700
|
// Other settings - Offsets 17-21
|
|
1395
|
-
VArAct:
|
|
1396
|
-
ClcTotVA:
|
|
1397
|
-
MaxRmpRte: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 19, 1, 'uint16'), scaleFactors.MaxRmpRte_SF, 'uint16', 'Max Ramp Rate'),
|
|
1701
|
+
VArAct: vArActRaw,
|
|
1702
|
+
ClcTotVA: clcTotVARaw,
|
|
1703
|
+
MaxRmpRte: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 19, 1, 'uint16'), scaleFactors.MaxRmpRte_SF, 'uint16', 'Max Ramp Rate', 19, 121),
|
|
1398
1704
|
MaxRmpRte_SF: scaleFactors.MaxRmpRte_SF,
|
|
1399
|
-
ECPNomHz: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 20, 1, 'uint16'), scaleFactors.ECPNomHz_SF, 'uint16', 'Nominal Frequency'),
|
|
1705
|
+
ECPNomHz: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 20, 1, 'uint16'), scaleFactors.ECPNomHz_SF, 'uint16', 'Nominal Frequency', 20, 121),
|
|
1400
1706
|
ECPNomHz_SF: scaleFactors.ECPNomHz_SF,
|
|
1401
|
-
ConnPh:
|
|
1707
|
+
ConnPh: connPhRaw
|
|
1402
1708
|
};
|
|
1403
1709
|
}
|
|
1404
1710
|
catch (error) {
|
|
@@ -1423,38 +1729,74 @@ export class SunspecModbusClient {
|
|
|
1423
1729
|
OutPFSet_SF: await this.readRegisterValue(baseAddr + 22, 1, 'int16'),
|
|
1424
1730
|
VArPct_SF: await this.readRegisterValue(baseAddr + 23, 1, 'int16')
|
|
1425
1731
|
};
|
|
1732
|
+
this.logRegisterRead(123, 21, 'WMaxLimPct_SF', scaleFactors.WMaxLimPct_SF, 'int16');
|
|
1733
|
+
this.logRegisterRead(123, 22, 'OutPFSet_SF', scaleFactors.OutPFSet_SF, 'int16');
|
|
1734
|
+
this.logRegisterRead(123, 23, 'VArPct_SF', scaleFactors.VArPct_SF, 'int16');
|
|
1735
|
+
// Read non-scaled fields
|
|
1736
|
+
const connWinTmsRaw = await this.readRegisterValue(baseAddr, 1, 'uint16');
|
|
1737
|
+
const connRvrtTmsRaw = await this.readRegisterValue(baseAddr + 1, 1, 'uint16');
|
|
1738
|
+
const connRaw = await this.readRegisterValue(baseAddr + 2, 1, 'uint16');
|
|
1739
|
+
const wMaxLimPctWinTmsRaw = await this.readRegisterValue(baseAddr + 4, 1, 'uint16');
|
|
1740
|
+
const wMaxLimPctRvrtTmsRaw = await this.readRegisterValue(baseAddr + 5, 1, 'uint16');
|
|
1741
|
+
const wMaxLimPctRmpTmsRaw = await this.readRegisterValue(baseAddr + 6, 1, 'uint16');
|
|
1742
|
+
const wMaxLimEnaRaw = await this.readRegisterValue(baseAddr + 7, 1, 'uint16');
|
|
1743
|
+
const outPFSetWinTmsRaw = await this.readRegisterValue(baseAddr + 9, 1, 'uint16');
|
|
1744
|
+
const outPFSetRvrtTmsRaw = await this.readRegisterValue(baseAddr + 10, 1, 'uint16');
|
|
1745
|
+
const outPFSetRmpTmsRaw = await this.readRegisterValue(baseAddr + 11, 1, 'uint16');
|
|
1746
|
+
const outPFSetEnaRaw = await this.readRegisterValue(baseAddr + 12, 1, 'uint16');
|
|
1747
|
+
const vArPctWinTmsRaw = await this.readRegisterValue(baseAddr + 16, 1, 'uint16');
|
|
1748
|
+
const vArPctRvrtTmsRaw = await this.readRegisterValue(baseAddr + 17, 1, 'uint16');
|
|
1749
|
+
const vArPctRmpTmsRaw = await this.readRegisterValue(baseAddr + 18, 1, 'uint16');
|
|
1750
|
+
const vArPctModRaw = await this.readRegisterValue(baseAddr + 19, 1, 'uint16');
|
|
1751
|
+
const vArPctEnaRaw = await this.readRegisterValue(baseAddr + 20, 1, 'uint16');
|
|
1752
|
+
this.logRegisterRead(123, 0, 'Conn_WinTms', connWinTmsRaw, 'uint16');
|
|
1753
|
+
this.logRegisterRead(123, 1, 'Conn_RvrtTms', connRvrtTmsRaw, 'uint16');
|
|
1754
|
+
this.logRegisterRead(123, 2, 'Conn', connRaw, 'enum16');
|
|
1755
|
+
this.logRegisterRead(123, 4, 'WMaxLimPct_WinTms', wMaxLimPctWinTmsRaw, 'uint16');
|
|
1756
|
+
this.logRegisterRead(123, 5, 'WMaxLimPct_RvrtTms', wMaxLimPctRvrtTmsRaw, 'uint16');
|
|
1757
|
+
this.logRegisterRead(123, 6, 'WMaxLimPct_RmpTms', wMaxLimPctRmpTmsRaw, 'uint16');
|
|
1758
|
+
this.logRegisterRead(123, 7, 'WMaxLim_Ena', wMaxLimEnaRaw, 'enum16');
|
|
1759
|
+
this.logRegisterRead(123, 9, 'OutPFSet_WinTms', outPFSetWinTmsRaw, 'uint16');
|
|
1760
|
+
this.logRegisterRead(123, 10, 'OutPFSet_RvrtTms', outPFSetRvrtTmsRaw, 'uint16');
|
|
1761
|
+
this.logRegisterRead(123, 11, 'OutPFSet_RmpTms', outPFSetRmpTmsRaw, 'uint16');
|
|
1762
|
+
this.logRegisterRead(123, 12, 'OutPFSet_Ena', outPFSetEnaRaw, 'enum16');
|
|
1763
|
+
this.logRegisterRead(123, 16, 'VArPct_WinTms', vArPctWinTmsRaw, 'uint16');
|
|
1764
|
+
this.logRegisterRead(123, 17, 'VArPct_RvrtTms', vArPctRvrtTmsRaw, 'uint16');
|
|
1765
|
+
this.logRegisterRead(123, 18, 'VArPct_RmpTms', vArPctRmpTmsRaw, 'uint16');
|
|
1766
|
+
this.logRegisterRead(123, 19, 'VArPct_Mod', vArPctModRaw, 'enum16');
|
|
1767
|
+
this.logRegisterRead(123, 20, 'VArPct_Ena', vArPctEnaRaw, 'enum16');
|
|
1426
1768
|
const controls = {
|
|
1427
1769
|
blockNumber: 123,
|
|
1428
1770
|
blockAddress: model.address,
|
|
1429
1771
|
blockLength: model.length,
|
|
1430
1772
|
// Connection control - Offsets 0-2
|
|
1431
|
-
Conn_WinTms:
|
|
1432
|
-
Conn_RvrtTms:
|
|
1433
|
-
Conn:
|
|
1773
|
+
Conn_WinTms: connWinTmsRaw,
|
|
1774
|
+
Conn_RvrtTms: connRvrtTmsRaw,
|
|
1775
|
+
Conn: connRaw,
|
|
1434
1776
|
// Power limit control - Offsets 3-7
|
|
1435
|
-
WMaxLimPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 3, 1, 'uint16'), scaleFactors.WMaxLimPct_SF, 'uint16', 'Power Limit Percentage'),
|
|
1777
|
+
WMaxLimPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 3, 1, 'uint16'), scaleFactors.WMaxLimPct_SF, 'uint16', 'Power Limit Percentage', 3, 123),
|
|
1436
1778
|
WMaxLimPct_SF: scaleFactors.WMaxLimPct_SF,
|
|
1437
|
-
WMaxLimPct_WinTms:
|
|
1438
|
-
WMaxLimPct_RvrtTms:
|
|
1439
|
-
WMaxLimPct_RmpTms:
|
|
1440
|
-
WMaxLim_Ena:
|
|
1779
|
+
WMaxLimPct_WinTms: wMaxLimPctWinTmsRaw,
|
|
1780
|
+
WMaxLimPct_RvrtTms: wMaxLimPctRvrtTmsRaw,
|
|
1781
|
+
WMaxLimPct_RmpTms: wMaxLimPctRmpTmsRaw,
|
|
1782
|
+
WMaxLim_Ena: wMaxLimEnaRaw,
|
|
1441
1783
|
// Power factor control - Offsets 8-12
|
|
1442
|
-
OutPFSet: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 8, 1, 'int16'), scaleFactors.OutPFSet_SF, 'int16', 'Output Power Factor Set'),
|
|
1784
|
+
OutPFSet: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 8, 1, 'int16'), scaleFactors.OutPFSet_SF, 'int16', 'Output Power Factor Set', 8, 123),
|
|
1443
1785
|
OutPFSet_SF: scaleFactors.OutPFSet_SF,
|
|
1444
|
-
OutPFSet_WinTms:
|
|
1445
|
-
OutPFSet_RvrtTms:
|
|
1446
|
-
OutPFSet_RmpTms:
|
|
1447
|
-
OutPFSet_Ena:
|
|
1786
|
+
OutPFSet_WinTms: outPFSetWinTmsRaw,
|
|
1787
|
+
OutPFSet_RvrtTms: outPFSetRvrtTmsRaw,
|
|
1788
|
+
OutPFSet_RmpTms: outPFSetRmpTmsRaw,
|
|
1789
|
+
OutPFSet_Ena: outPFSetEnaRaw,
|
|
1448
1790
|
// Reactive power control - Offsets 13-20
|
|
1449
|
-
VArWMaxPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 13, 1, 'int16'), scaleFactors.VArPct_SF, 'int16', 'Reactive Power at Max Power %'),
|
|
1450
|
-
VArMaxPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 14, 1, 'int16'), scaleFactors.VArPct_SF, 'int16', 'Max Reactive Power %'),
|
|
1451
|
-
VArAvalPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 15, 1, 'int16'), scaleFactors.VArPct_SF, 'int16', 'Available Reactive Power %'),
|
|
1791
|
+
VArWMaxPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 13, 1, 'int16'), scaleFactors.VArPct_SF, 'int16', 'Reactive Power at Max Power %', 13, 123),
|
|
1792
|
+
VArMaxPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 14, 1, 'int16'), scaleFactors.VArPct_SF, 'int16', 'Max Reactive Power %', 14, 123),
|
|
1793
|
+
VArAvalPct: this.applyScaleFactor(await this.readRegisterValue(baseAddr + 15, 1, 'int16'), scaleFactors.VArPct_SF, 'int16', 'Available Reactive Power %', 15, 123),
|
|
1452
1794
|
VArPct_SF: scaleFactors.VArPct_SF,
|
|
1453
|
-
VArPct_WinTms:
|
|
1454
|
-
VArPct_RvrtTms:
|
|
1455
|
-
VArPct_RmpTms:
|
|
1456
|
-
VArPct_Mod:
|
|
1457
|
-
VArPct_Ena:
|
|
1795
|
+
VArPct_WinTms: vArPctWinTmsRaw,
|
|
1796
|
+
VArPct_RvrtTms: vArPctRvrtTmsRaw,
|
|
1797
|
+
VArPct_RmpTms: vArPctRmpTmsRaw,
|
|
1798
|
+
VArPct_Mod: vArPctModRaw,
|
|
1799
|
+
VArPct_Ena: vArPctEnaRaw
|
|
1458
1800
|
};
|
|
1459
1801
|
return controls;
|
|
1460
1802
|
}
|