@enyo-energy/sunspec-sdk 0.0.7 → 0.0.9
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-interfaces.d.cts +5 -5
- package/dist/cjs/sunspec-modbus-client.cjs +76 -26
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/sunspec-interfaces.d.ts +5 -5
- package/dist/sunspec-modbus-client.js +76 -26
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -79,7 +79,7 @@ export interface SunspecInverterData extends SunspecBlock {
|
|
|
79
79
|
apparentPower?: number;
|
|
80
80
|
reactivePower?: number;
|
|
81
81
|
powerFactor?: number;
|
|
82
|
-
acEnergy?:
|
|
82
|
+
acEnergy?: number;
|
|
83
83
|
dcCurrent?: number;
|
|
84
84
|
dcVoltage?: number;
|
|
85
85
|
dcPower?: number;
|
|
@@ -109,7 +109,7 @@ export interface SunspecMPPTData extends SunspecBlock {
|
|
|
109
109
|
dcVoltageSF?: number;
|
|
110
110
|
dcPower?: number;
|
|
111
111
|
dcPowerSF?: number;
|
|
112
|
-
dcEnergy?:
|
|
112
|
+
dcEnergy?: number;
|
|
113
113
|
dcEnergySF?: number;
|
|
114
114
|
timestamp?: number;
|
|
115
115
|
temperature?: number;
|
|
@@ -141,9 +141,9 @@ export interface SunspecMeterData extends SunspecBlock {
|
|
|
141
141
|
phaseAPower?: number;
|
|
142
142
|
phaseBPower?: number;
|
|
143
143
|
phaseCPower?: number;
|
|
144
|
-
totalEnergy?:
|
|
145
|
-
exportedEnergy?:
|
|
146
|
-
importedEnergy?:
|
|
144
|
+
totalEnergy?: number;
|
|
145
|
+
exportedEnergy?: number;
|
|
146
|
+
importedEnergy?: number;
|
|
147
147
|
voltage?: number;
|
|
148
148
|
current?: number;
|
|
149
149
|
frequency?: number;
|
|
@@ -286,7 +286,7 @@ class SunspecModbusClient {
|
|
|
286
286
|
const baseAddr = model.address + 2; // Skip ID and Length
|
|
287
287
|
try {
|
|
288
288
|
// Read all scale factors first using fault-tolerant reader
|
|
289
|
-
console.log(`Reading Inverter Data from Model
|
|
289
|
+
console.log(`Reading Inverter Data from Model ${model.id} at base address: ${baseAddr}`);
|
|
290
290
|
const scaleFactors = await this.readInverterScaleFactors(baseAddr);
|
|
291
291
|
// Read values using fault-tolerant reader with proper data types
|
|
292
292
|
// Read raw voltage values to check for unimplemented phases
|
|
@@ -371,16 +371,15 @@ class SunspecModbusClient {
|
|
|
371
371
|
const acEnergyAddr = baseAddr + 24;
|
|
372
372
|
const acEnergy = await this.readRegisterValue(acEnergyAddr, 2, 'acc32');
|
|
373
373
|
console.log(`AC Energy: address=${acEnergyAddr}, raw=0x${acEnergy.toString(16).toUpperCase()} (${acEnergy}), SF=${scaleFactors.WH_SF}`);
|
|
374
|
-
data.acEnergy =
|
|
374
|
+
data.acEnergy = !this.isUnimplementedValue(acEnergy, 'uint32')
|
|
375
|
+
? acEnergy * Math.pow(10, scaleFactors.WH_SF) // Regular number with scale factor
|
|
376
|
+
: undefined;
|
|
375
377
|
// Log final calculated values
|
|
376
378
|
console.log('Inverter Final Values:', {
|
|
377
379
|
acPower: data.acPower,
|
|
378
|
-
dcPower: data.dcPower,
|
|
379
380
|
voltageAN: data.voltageAN,
|
|
380
381
|
voltageBN: data.voltageBN,
|
|
381
382
|
voltageCN: data.voltageCN,
|
|
382
|
-
dcVoltage: data.dcVoltage,
|
|
383
|
-
dcCurrent: data.dcCurrent,
|
|
384
383
|
acCurrent: data.acCurrent
|
|
385
384
|
});
|
|
386
385
|
return data;
|
|
@@ -548,7 +547,7 @@ class SunspecModbusClient {
|
|
|
548
547
|
// DC Energy - Offset 15-16 (32-bit accumulator)
|
|
549
548
|
// Only calculate if value is not unimplemented
|
|
550
549
|
dcEnergy: !this.isUnimplementedValue(dcEnergyRaw, 'uint32')
|
|
551
|
-
?
|
|
550
|
+
? dcEnergyRaw * Math.pow(10, scaleFactors.DCWH_SF) // Regular number with scale factor
|
|
552
551
|
: undefined,
|
|
553
552
|
dcEnergySF: scaleFactors.DCWH_SF,
|
|
554
553
|
// Timestamp - Offset 18-19 (32-bit)
|
|
@@ -612,17 +611,57 @@ class SunspecModbusClient {
|
|
|
612
611
|
const baseAddr = model.address + 2;
|
|
613
612
|
console.log(`Reading Meter Data from Model ${model.id} at base address: ${baseAddr}`);
|
|
614
613
|
try {
|
|
615
|
-
//
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
614
|
+
// Different meter models have different register offsets
|
|
615
|
+
console.log(`Meter is Model ${model.id}`);
|
|
616
|
+
let powerOffset;
|
|
617
|
+
let powerSFOffset;
|
|
618
|
+
let freqOffset;
|
|
619
|
+
let freqSFOffset;
|
|
620
|
+
let exportOffset;
|
|
621
|
+
let importOffset;
|
|
622
|
+
let energySFOffset;
|
|
623
|
+
switch (model.id) {
|
|
624
|
+
case 201: // Single-phase meter
|
|
625
|
+
console.log('Using Model 201 (Single-Phase Meter) offsets');
|
|
626
|
+
powerOffset = 18; // W - Total Real Power (int16)
|
|
627
|
+
powerSFOffset = 21; // W_SF - Power scale factor
|
|
628
|
+
freqOffset = 32; // Hz - Frequency (uint16)
|
|
629
|
+
freqSFOffset = 35; // Hz_SF - Frequency scale factor
|
|
630
|
+
exportOffset = 38; // TotWhExp - Total Wh Exported (acc32)
|
|
631
|
+
importOffset = 46; // TotWhImp - Total Wh Imported (acc32)
|
|
632
|
+
energySFOffset = 4; // TotWh_SF - Total Energy scale factor
|
|
633
|
+
break;
|
|
634
|
+
case 203: // 3-phase meter (Delta)
|
|
635
|
+
console.log('Using Model 203 (3-Phase Meter Delta) offsets');
|
|
636
|
+
powerOffset = 14; // W - Total Real Power (int16)
|
|
637
|
+
powerSFOffset = 17; // W_SF - Power scale factor
|
|
638
|
+
freqOffset = 24; // Hz - Frequency (uint16)
|
|
639
|
+
freqSFOffset = 27; // Hz_SF - Frequency scale factor
|
|
640
|
+
exportOffset = 38; // TotWhExp - Total Wh Exported (acc32)
|
|
641
|
+
importOffset = 46; // TotWhImp - Total Wh Imported (acc32)
|
|
642
|
+
energySFOffset = 4; // TotWh_SF - Total Energy scale factor
|
|
643
|
+
break;
|
|
644
|
+
case 204: // 3-phase meter (Wye)
|
|
645
|
+
console.log('Using Model 204 (3-Phase Meter Wye) offsets');
|
|
646
|
+
powerOffset = 14; // W - Total Real Power (int16)
|
|
647
|
+
powerSFOffset = 17; // W_SF - Power scale factor
|
|
648
|
+
freqOffset = 28; // Hz - Frequency (uint16)
|
|
649
|
+
freqSFOffset = 31; // Hz_SF - Frequency scale factor
|
|
650
|
+
exportOffset = 42; // TotWhExp - Total Wh Exported (acc32)
|
|
651
|
+
importOffset = 50; // TotWhImp - Total Wh Imported (acc32)
|
|
652
|
+
energySFOffset = 4; // TotWh_SF - Total Energy scale factor
|
|
653
|
+
break;
|
|
654
|
+
default:
|
|
655
|
+
console.error(`Unknown meter model ${model.id}, using Model 201 defaults`);
|
|
656
|
+
powerOffset = 18;
|
|
657
|
+
powerSFOffset = 21;
|
|
658
|
+
freqOffset = 32;
|
|
659
|
+
freqSFOffset = 35;
|
|
660
|
+
exportOffset = 38;
|
|
661
|
+
importOffset = 46;
|
|
662
|
+
energySFOffset = 4;
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
626
665
|
// Read scale factors
|
|
627
666
|
const powerSF = await this.readRegisterValue(baseAddr + powerSFOffset, 1, 'int16');
|
|
628
667
|
const freqSF = await this.readRegisterValue(baseAddr + freqSFOffset, 1, 'int16');
|
|
@@ -641,16 +680,27 @@ class SunspecModbusClient {
|
|
|
641
680
|
const importAddr = baseAddr + importOffset;
|
|
642
681
|
const importRaw = await this.readRegisterValue(importAddr, 2, 'acc32');
|
|
643
682
|
console.log(`Meter Import Energy: address=${importAddr}, raw=0x${importRaw.toString(16).toUpperCase()} (${importRaw}), SF=${energySF}`);
|
|
683
|
+
// Calculate final values with scale factors
|
|
684
|
+
const totalPower = this.applyScaleFactor(powerRaw, powerSF, 'int16');
|
|
685
|
+
const frequency = this.applyScaleFactor(freqRaw, freqSF);
|
|
686
|
+
const exportedEnergy = !this.isUnimplementedValue(exportRaw, 'uint32')
|
|
687
|
+
? exportRaw * Math.pow(10, energySF) // Regular number, not BigInt
|
|
688
|
+
: undefined;
|
|
689
|
+
const importedEnergy = !this.isUnimplementedValue(importRaw, 'uint32')
|
|
690
|
+
? importRaw * Math.pow(10, energySF) // Regular number, not BigInt
|
|
691
|
+
: undefined;
|
|
692
|
+
console.log('Meter Final Values:', {
|
|
693
|
+
totalPower,
|
|
694
|
+
frequency,
|
|
695
|
+
exportedEnergy,
|
|
696
|
+
importedEnergy
|
|
697
|
+
});
|
|
644
698
|
return {
|
|
645
699
|
blockNumber: model.id,
|
|
646
|
-
totalPower
|
|
647
|
-
frequency
|
|
648
|
-
exportedEnergy
|
|
649
|
-
|
|
650
|
-
: undefined,
|
|
651
|
-
importedEnergy: !this.isUnimplementedValue(importRaw, 'uint32')
|
|
652
|
-
? BigInt(importRaw) * BigInt(Math.pow(10, energySF))
|
|
653
|
-
: undefined
|
|
700
|
+
totalPower,
|
|
701
|
+
frequency,
|
|
702
|
+
exportedEnergy,
|
|
703
|
+
importedEnergy
|
|
654
704
|
};
|
|
655
705
|
}
|
|
656
706
|
catch (error) {
|
|
@@ -828,7 +878,7 @@ class SunspecModbusClient {
|
|
|
828
878
|
blockAddress: model.address,
|
|
829
879
|
blockLength: model.length,
|
|
830
880
|
// Connection control - Offsets 0-2
|
|
831
|
-
Conn_WinTms: await this.readRegisterValue(baseAddr
|
|
881
|
+
Conn_WinTms: await this.readRegisterValue(baseAddr, 1, 'uint16'),
|
|
832
882
|
Conn_RvrtTms: await this.readRegisterValue(baseAddr + 1, 1, 'uint16'),
|
|
833
883
|
Conn: await this.readRegisterValue(baseAddr + 2, 1, 'uint16'),
|
|
834
884
|
// Power limit control - Offsets 3-7
|
package/dist/cjs/version.cjs
CHANGED
package/dist/cjs/version.d.cts
CHANGED
|
@@ -79,7 +79,7 @@ export interface SunspecInverterData extends SunspecBlock {
|
|
|
79
79
|
apparentPower?: number;
|
|
80
80
|
reactivePower?: number;
|
|
81
81
|
powerFactor?: number;
|
|
82
|
-
acEnergy?:
|
|
82
|
+
acEnergy?: number;
|
|
83
83
|
dcCurrent?: number;
|
|
84
84
|
dcVoltage?: number;
|
|
85
85
|
dcPower?: number;
|
|
@@ -109,7 +109,7 @@ export interface SunspecMPPTData extends SunspecBlock {
|
|
|
109
109
|
dcVoltageSF?: number;
|
|
110
110
|
dcPower?: number;
|
|
111
111
|
dcPowerSF?: number;
|
|
112
|
-
dcEnergy?:
|
|
112
|
+
dcEnergy?: number;
|
|
113
113
|
dcEnergySF?: number;
|
|
114
114
|
timestamp?: number;
|
|
115
115
|
temperature?: number;
|
|
@@ -141,9 +141,9 @@ export interface SunspecMeterData extends SunspecBlock {
|
|
|
141
141
|
phaseAPower?: number;
|
|
142
142
|
phaseBPower?: number;
|
|
143
143
|
phaseCPower?: number;
|
|
144
|
-
totalEnergy?:
|
|
145
|
-
exportedEnergy?:
|
|
146
|
-
importedEnergy?:
|
|
144
|
+
totalEnergy?: number;
|
|
145
|
+
exportedEnergy?: number;
|
|
146
|
+
importedEnergy?: number;
|
|
147
147
|
voltage?: number;
|
|
148
148
|
current?: number;
|
|
149
149
|
frequency?: number;
|
|
@@ -283,7 +283,7 @@ export class SunspecModbusClient {
|
|
|
283
283
|
const baseAddr = model.address + 2; // Skip ID and Length
|
|
284
284
|
try {
|
|
285
285
|
// Read all scale factors first using fault-tolerant reader
|
|
286
|
-
console.log(`Reading Inverter Data from Model
|
|
286
|
+
console.log(`Reading Inverter Data from Model ${model.id} at base address: ${baseAddr}`);
|
|
287
287
|
const scaleFactors = await this.readInverterScaleFactors(baseAddr);
|
|
288
288
|
// Read values using fault-tolerant reader with proper data types
|
|
289
289
|
// Read raw voltage values to check for unimplemented phases
|
|
@@ -368,16 +368,15 @@ export class SunspecModbusClient {
|
|
|
368
368
|
const acEnergyAddr = baseAddr + 24;
|
|
369
369
|
const acEnergy = await this.readRegisterValue(acEnergyAddr, 2, 'acc32');
|
|
370
370
|
console.log(`AC Energy: address=${acEnergyAddr}, raw=0x${acEnergy.toString(16).toUpperCase()} (${acEnergy}), SF=${scaleFactors.WH_SF}`);
|
|
371
|
-
data.acEnergy =
|
|
371
|
+
data.acEnergy = !this.isUnimplementedValue(acEnergy, 'uint32')
|
|
372
|
+
? acEnergy * Math.pow(10, scaleFactors.WH_SF) // Regular number with scale factor
|
|
373
|
+
: undefined;
|
|
372
374
|
// Log final calculated values
|
|
373
375
|
console.log('Inverter Final Values:', {
|
|
374
376
|
acPower: data.acPower,
|
|
375
|
-
dcPower: data.dcPower,
|
|
376
377
|
voltageAN: data.voltageAN,
|
|
377
378
|
voltageBN: data.voltageBN,
|
|
378
379
|
voltageCN: data.voltageCN,
|
|
379
|
-
dcVoltage: data.dcVoltage,
|
|
380
|
-
dcCurrent: data.dcCurrent,
|
|
381
380
|
acCurrent: data.acCurrent
|
|
382
381
|
});
|
|
383
382
|
return data;
|
|
@@ -545,7 +544,7 @@ export class SunspecModbusClient {
|
|
|
545
544
|
// DC Energy - Offset 15-16 (32-bit accumulator)
|
|
546
545
|
// Only calculate if value is not unimplemented
|
|
547
546
|
dcEnergy: !this.isUnimplementedValue(dcEnergyRaw, 'uint32')
|
|
548
|
-
?
|
|
547
|
+
? dcEnergyRaw * Math.pow(10, scaleFactors.DCWH_SF) // Regular number with scale factor
|
|
549
548
|
: undefined,
|
|
550
549
|
dcEnergySF: scaleFactors.DCWH_SF,
|
|
551
550
|
// Timestamp - Offset 18-19 (32-bit)
|
|
@@ -609,17 +608,57 @@ export class SunspecModbusClient {
|
|
|
609
608
|
const baseAddr = model.address + 2;
|
|
610
609
|
console.log(`Reading Meter Data from Model ${model.id} at base address: ${baseAddr}`);
|
|
611
610
|
try {
|
|
612
|
-
//
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
611
|
+
// Different meter models have different register offsets
|
|
612
|
+
console.log(`Meter is Model ${model.id}`);
|
|
613
|
+
let powerOffset;
|
|
614
|
+
let powerSFOffset;
|
|
615
|
+
let freqOffset;
|
|
616
|
+
let freqSFOffset;
|
|
617
|
+
let exportOffset;
|
|
618
|
+
let importOffset;
|
|
619
|
+
let energySFOffset;
|
|
620
|
+
switch (model.id) {
|
|
621
|
+
case 201: // Single-phase meter
|
|
622
|
+
console.log('Using Model 201 (Single-Phase Meter) offsets');
|
|
623
|
+
powerOffset = 18; // W - Total Real Power (int16)
|
|
624
|
+
powerSFOffset = 21; // W_SF - Power scale factor
|
|
625
|
+
freqOffset = 32; // Hz - Frequency (uint16)
|
|
626
|
+
freqSFOffset = 35; // Hz_SF - Frequency scale factor
|
|
627
|
+
exportOffset = 38; // TotWhExp - Total Wh Exported (acc32)
|
|
628
|
+
importOffset = 46; // TotWhImp - Total Wh Imported (acc32)
|
|
629
|
+
energySFOffset = 4; // TotWh_SF - Total Energy scale factor
|
|
630
|
+
break;
|
|
631
|
+
case 203: // 3-phase meter (Delta)
|
|
632
|
+
console.log('Using Model 203 (3-Phase Meter Delta) offsets');
|
|
633
|
+
powerOffset = 14; // W - Total Real Power (int16)
|
|
634
|
+
powerSFOffset = 17; // W_SF - Power scale factor
|
|
635
|
+
freqOffset = 24; // Hz - Frequency (uint16)
|
|
636
|
+
freqSFOffset = 27; // Hz_SF - Frequency scale factor
|
|
637
|
+
exportOffset = 38; // TotWhExp - Total Wh Exported (acc32)
|
|
638
|
+
importOffset = 46; // TotWhImp - Total Wh Imported (acc32)
|
|
639
|
+
energySFOffset = 4; // TotWh_SF - Total Energy scale factor
|
|
640
|
+
break;
|
|
641
|
+
case 204: // 3-phase meter (Wye)
|
|
642
|
+
console.log('Using Model 204 (3-Phase Meter Wye) offsets');
|
|
643
|
+
powerOffset = 14; // W - Total Real Power (int16)
|
|
644
|
+
powerSFOffset = 17; // W_SF - Power scale factor
|
|
645
|
+
freqOffset = 28; // Hz - Frequency (uint16)
|
|
646
|
+
freqSFOffset = 31; // Hz_SF - Frequency scale factor
|
|
647
|
+
exportOffset = 42; // TotWhExp - Total Wh Exported (acc32)
|
|
648
|
+
importOffset = 50; // TotWhImp - Total Wh Imported (acc32)
|
|
649
|
+
energySFOffset = 4; // TotWh_SF - Total Energy scale factor
|
|
650
|
+
break;
|
|
651
|
+
default:
|
|
652
|
+
console.error(`Unknown meter model ${model.id}, using Model 201 defaults`);
|
|
653
|
+
powerOffset = 18;
|
|
654
|
+
powerSFOffset = 21;
|
|
655
|
+
freqOffset = 32;
|
|
656
|
+
freqSFOffset = 35;
|
|
657
|
+
exportOffset = 38;
|
|
658
|
+
importOffset = 46;
|
|
659
|
+
energySFOffset = 4;
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
623
662
|
// Read scale factors
|
|
624
663
|
const powerSF = await this.readRegisterValue(baseAddr + powerSFOffset, 1, 'int16');
|
|
625
664
|
const freqSF = await this.readRegisterValue(baseAddr + freqSFOffset, 1, 'int16');
|
|
@@ -638,16 +677,27 @@ export class SunspecModbusClient {
|
|
|
638
677
|
const importAddr = baseAddr + importOffset;
|
|
639
678
|
const importRaw = await this.readRegisterValue(importAddr, 2, 'acc32');
|
|
640
679
|
console.log(`Meter Import Energy: address=${importAddr}, raw=0x${importRaw.toString(16).toUpperCase()} (${importRaw}), SF=${energySF}`);
|
|
680
|
+
// Calculate final values with scale factors
|
|
681
|
+
const totalPower = this.applyScaleFactor(powerRaw, powerSF, 'int16');
|
|
682
|
+
const frequency = this.applyScaleFactor(freqRaw, freqSF);
|
|
683
|
+
const exportedEnergy = !this.isUnimplementedValue(exportRaw, 'uint32')
|
|
684
|
+
? exportRaw * Math.pow(10, energySF) // Regular number, not BigInt
|
|
685
|
+
: undefined;
|
|
686
|
+
const importedEnergy = !this.isUnimplementedValue(importRaw, 'uint32')
|
|
687
|
+
? importRaw * Math.pow(10, energySF) // Regular number, not BigInt
|
|
688
|
+
: undefined;
|
|
689
|
+
console.log('Meter Final Values:', {
|
|
690
|
+
totalPower,
|
|
691
|
+
frequency,
|
|
692
|
+
exportedEnergy,
|
|
693
|
+
importedEnergy
|
|
694
|
+
});
|
|
641
695
|
return {
|
|
642
696
|
blockNumber: model.id,
|
|
643
|
-
totalPower
|
|
644
|
-
frequency
|
|
645
|
-
exportedEnergy
|
|
646
|
-
|
|
647
|
-
: undefined,
|
|
648
|
-
importedEnergy: !this.isUnimplementedValue(importRaw, 'uint32')
|
|
649
|
-
? BigInt(importRaw) * BigInt(Math.pow(10, energySF))
|
|
650
|
-
: undefined
|
|
697
|
+
totalPower,
|
|
698
|
+
frequency,
|
|
699
|
+
exportedEnergy,
|
|
700
|
+
importedEnergy
|
|
651
701
|
};
|
|
652
702
|
}
|
|
653
703
|
catch (error) {
|
|
@@ -825,7 +875,7 @@ export class SunspecModbusClient {
|
|
|
825
875
|
blockAddress: model.address,
|
|
826
876
|
blockLength: model.length,
|
|
827
877
|
// Connection control - Offsets 0-2
|
|
828
|
-
Conn_WinTms: await this.readRegisterValue(baseAddr
|
|
878
|
+
Conn_WinTms: await this.readRegisterValue(baseAddr, 1, 'uint16'),
|
|
829
879
|
Conn_RvrtTms: await this.readRegisterValue(baseAddr + 1, 1, 'uint16'),
|
|
830
880
|
Conn: await this.readRegisterValue(baseAddr + 2, 1, 'uint16'),
|
|
831
881
|
// Power limit control - Offsets 3-7
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED