Update the Growatt API and modbus

This commit is contained in:
atef 2025-11-12 16:11:19 +01:00
parent d067c5a57d
commit 8e029a1afd
2 changed files with 115 additions and 153 deletions

View File

@ -15,10 +15,10 @@ public partial class WITGrowatRecord
//public BatteriesRecord? BatteriesRecords => BatteriesRecord.FromBatteries(Batteries); //public BatteriesRecord? BatteriesRecords => BatteriesRecord.FromBatteries(Batteries);
public ActivePower ConsumptionPower => MeterPower + InverterActivePower ; public ActivePower ConsumptionPower => GridPower + InverterActivePower ;
public ActivePower InverterActivePower => _ActivePower; public ActivePower InverterActivePower => _activePower;
public ReactivePower InverterReactivePower => _ReactivePower; public ReactivePower InverterReactivePower => _reactivePower;
public Frequency Frequency => _Frequency; public Frequency Frequency => _frequency;
public VoltageRms GridAbLineVoltage => _GridAbLineVoltage; public VoltageRms GridAbLineVoltage => _GridAbLineVoltage;
public VoltageRms GridBcLineVoltage => _GridBcLineVoltage; public VoltageRms GridBcLineVoltage => _GridBcLineVoltage;
@ -27,7 +27,7 @@ public partial class WITGrowatRecord
public CurrentRms PhaseBCurrent => _PhaseBCurrent; public CurrentRms PhaseBCurrent => _PhaseBCurrent;
public CurrentRms PhaseCCurrent => _PhaseCCurrent; public CurrentRms PhaseCCurrent => _PhaseCCurrent;
public ActivePower MeterPower => _importedPowerFromGrid - _exportedPowerToGrid; public ActivePower GridPower => _importedPowerFromGrid - _exportedPowerToGrid;
public ActivePower ExportedPowerToGridMeter => _exportedPowerToGrid; public ActivePower ExportedPowerToGridMeter => _exportedPowerToGrid;
public ActivePower ImportedPowerFromGrid => _importedPowerFromGrid; public ActivePower ImportedPowerFromGrid => _importedPowerFromGrid;
@ -38,34 +38,33 @@ public partial class WITGrowatRecord
public Energy EnergyToGrid => _EnergyToGrid; public Energy EnergyToGrid => _EnergyToGrid;
public Energy TotalEnergyToGrid => _TotalEnergyToGrid; public Energy TotalEnergyToGrid => _TotalEnergyToGrid;
public GrowattSystemStatus SystemOperatingMode => (GrowattSystemStatus)_SystemOperatingMode; public GrowattSystemStatus SystemOperatingMode => (GrowattSystemStatus)_systemOperatingMode;
public BatteryoperatinStatus BatteryOperatingMode => (BatteryoperatinStatus) _BatteryOperatingMode; public BatteryoperatinStatus BatteryOperatingMode => (BatteryoperatinStatus) _batteryOperatingMode;
public OperatingPriority OperatingPriority => (OperatingPriority)_OperatingPriority; public OperatingPriority OperatingMode => (OperatingPriority)_operatingPriority;
public UInt16 FaultMainCode => _FaultMainCode; // need to pre proceesed public UInt16 FaultMainCode => _faultMainCode; // need to pre proceesed
public UInt16 FaultSubCode => _FaultSubCode; // need to pre proceesed public UInt16 FaultSubCode => _faultSubCode; // need to pre proceesed
public UInt16 WarningMainCode => _WarningMainCode; // need to pre proceesed public UInt16 WarningMainCode => _warningMainCode; // need to pre proceesed
public UInt16 WarningSubCode => _WarningSubCode; // need to pre proceesed public UInt16 WarningSubCode => _warningSubCode; // need to pre proceesed
public Voltage Pv1Voltage => _Pv1Voltage; public Voltage Pv1Voltage => _pv1Voltage;
public Current Pv1Current => _Pv1Current; public Current Pv1Current => _pv1Current;
public Voltage Pv2Voltage => _Pv2Voltage; public Voltage Pv2Voltage => _pv2Voltage;
public Current Pv2Current => _Pv2Current; public Current Pv2Current => _pv2Current;
public Voltage Pv3Voltage => _Pv3Voltage; public Voltage Pv3Voltage => _pv3Voltage;
public Current Pv3Current => _Pv3Current; public Current Pv3Current => _pv3Current;
public Voltage Pv4Voltage => _Pv4Voltage; public Voltage Pv4Voltage => _pv4Voltage;
public Current Pv4Current => _Pv4Current; public Current Pv4Current => _pv4Current;
public Voltage Pv5Voltage => _Pv5Voltage; public Voltage Pv5Voltage => _pv5Voltage;
public Current Pv5Current => _Pv5Current; public Current Pv5Current => _pv5Current;
public Voltage Pv6Voltage => _Pv6Voltage; public Voltage Pv6Voltage => _pv6Voltage;
public Current Pv6Current => _Pv6Current; public Current Pv6Current => _pv6Current;
public DcPower Pv1InpuPower => _Pv1InpuPower; public DcPower Pv1InpuPower => _pv1InpuPower;
public DcPower TotalPvPower => (Pv1Voltage * Pv1Current) + (Pv2Voltage * Pv2Current) + public DcPower PvPower => (Pv1Voltage * Pv1Current) + (Pv2Voltage * Pv2Current) +
(Pv3Voltage * Pv3Current) + (Pv4Voltage * Pv4Current) + (Pv3Voltage * Pv3Current) + (Pv4Voltage * Pv4Current) +
(Pv5Voltage * Pv5Current) + (Pv6Voltage * Pv6Current); (Pv5Voltage * Pv5Current) + (Pv6Voltage * Pv6Current);
// ********************************** Holding Registers (Control) ************************************************************* // ********************************** Holding Registers (Control) *************************************************************
@ -173,16 +172,16 @@ public partial class WITGrowatRecord
set => _BatteryMaxDischargePower = value; set => _BatteryMaxDischargePower = value;
} }
public Percent ChargeCutoffSoc public Percent ChargeCutoffSocVoltage
{ {
get => _ChargeCutoffSoc; get => _BatteryChargeCutoffVoltage;
set => _ChargeCutoffSoc = (UInt16)value; set => _BatteryChargeCutoffVoltage = (UInt16)value;
} }
public Percent DischargeCutoffSoc public Percent DischargeCutoffVoltage
{ {
get => _DischargeCutoffSoc; get => _BatteryDischargeCutoffVoltage;
set => _DischargeCutoffSoc = (UInt16)value; set => _BatteryDischargeCutoffVoltage = (UInt16)value;
} }
public Percent LoadPriorityDischargeCutoffSoc public Percent LoadPriorityDischargeCutoffSoc
@ -226,98 +225,61 @@ public partial class WITGrowatRecord
set => _OffGridDischargeCutoffSoc = (UInt16)(value); set => _OffGridDischargeCutoffSoc = (UInt16)(value);
} }
public UInt16 BatteryChargeCutoffVoltage public UInt16 MaxSoc
{ {
get => _BatteryChargeCutoffVoltage; get => _maxSoc;
set => _BatteryChargeCutoffVoltage = value; set => _maxSoc = value;
} }
public UInt16 BatteryDischargeCutoffVoltage public UInt16 MinSoc
{ {
get => _BatteryDischargeCutoffVoltage; get => _minSoc;
set => _BatteryDischargeCutoffVoltage = value; set => _minSoc = value;
} }
public Double BatteryMaxChargeCurrent public Double BatteryMaxChargingCurrent
{ {
get => _BatteryMaxChargeCurrent; get => _batteryMaxChargingCurrent;
set => _BatteryMaxChargeCurrent = (UInt16)value; set => _batteryMaxChargingCurrent = (UInt16)value;
} }
public Double BatteryMaxdischargeCurrent public Double BatteryMaxDischargingCurrent
{ {
get => _BatteryMaxdischargeCurrent; get => _batteryMaxDischargingCurrent;
set => _BatteryMaxdischargeCurrent = (UInt16) value; set => _batteryMaxDischargingCurrent = (UInt16) value;
} }
public Double Battery1MaxDischargingCurrent => _batteryMaxDischargingCurrent;
public Double Battery1MaxChargingCurrent => _batteryMaxChargingCurrent;
public IReadOnlyList<BatteryRecord> Batteries => new List<BatteryRecord>
{ public Percent Battery1Soc => _BatterySoc1;
new BatteryRecord public Percent Battery1Soh => _BatterySoh1;
{ public Current Battery1Current => _BatteryCurrent1;
Soc = _BatterySoc1, public Voltage Battery1Voltage => _BatteryVoltage1;
Soh = _BatterySoh1, public ActivePower Battery1Power => _BatteryPower1;
//ClusterTotalNumber = _ClusterTotalNumber1, public ActivePower Battery1MaxAllowableChargePower => _BatteryMaxAllowableChargePower1;
Current = _BatteryCurrent1, public ActivePower Battery1MaxAllowableDischargePower => _BatteryMaxAllowableDischargePower1;
Voltage = _BatteryVoltage1, public Energy Battery1DailyChargeEnergy => _DailyChargeEnergy1;
Power = _BatteryPower1, public Energy Battery1DailyDischargeEnergy => _DailyDischargeEnergy1;
MaxAllowableChargePower = _BatteryMaxAllowableChargePower1, public Energy Battery1AccumulatedChargeEnergy => _AccumulatedChargeEnergy1;
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower1, public Energy Battery1AccumulatedDischargeEnergy => _AccumulatedDishargeEnergy1;
DailyChargeEnergy = _DailyChargeEnergy1, public Temperature Battery1AmbientTemperature => _BatteryAmbientTemperature1;
DailyDischargeEnergy = _DailyDischargeEnergy1,
AccumulatedChargeEnergy = _AccumulatedChargeEnergy1, public Percent Battery2Soc => _BatterySoc2;
AccumulatedDischargeEnergy = _AccumulatedDishargeEnergy1, public Percent Battery2Soh => _BatterySoh2;
BatteryAmbientTemperature = _BatteryAmbientTemperature1 public Current Battery2Current => _BatteryCurrent2;
public Voltage Battery2Voltage => _BatteryVoltage2;
} public ActivePower Battery2Power => _batteryPower2;
/* public ActivePower Battery2MaxAllowableChargePower => _BatteryMaxAllowableChargePower2;
new BatteryRecord public ActivePower Battery2MaxAllowableDischargePower => _BatteryMaxAllowableDischargePower2;
{ public Energy Battery2DailyChargeEnergy => _DailyChargeEnergy2;
Soc = _BatterySoc2, public Energy Battery2DailyDischargeEnergy => _DailyDischargeEnergy2;
Soh = _BatterySoh2, public Energy Battery2AccumulatedChargeEnergy => _AccumulatedChargeEnergy2;
// ClusterTotalNumber = _ClusterTotalNumber2, public Energy Battery2AccumulatedDischargeEnergy => _AccumulatedDischargeEnergy2;
Current = _BatteryCurrent2, public Temperature Battery2AmbientTemperature => _BatteryAmbientTemperature2;
Voltage = _BatteryVoltage2,
Power = _BatteryPower2, public Energy BatteryDailyChargeEnergy => _DailyChargeEnergy1 + _DailyChargeEnergy2;
MaxAllowableChargePower = _BatteryMaxAllowableChargePower2, public Energy BatteryDailyDischargeEnergy => _DailyDischargeEnergy1 + _DailyDischargeEnergy2;
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower2,
DailyChargeEnergy = _DailyChargeEnergy2,
DailyDischargeEnergy = _DailyDischargeEnergy2,
AccumulatedChargeEnergy = _AccumulatedChargeEnergy2,
AccumulatedDischargeEnergy = _AccumulatedDischargeEnergy2,
BatteryAmbientTemperature = _BatteryAmbientTemperature2
},*/
/*
new BatteryRecord
{
Soc = _BatterySoc3,
Soh = _BatterySoh3,
ClusterTotalNumber = _ClusterTotalNumber3,
Current = _BatteryCurrent3,
Voltage = _BatteryVoltage3,
Power = _BatteryPower3,
MaxAllowableChargePower = _BatteryMaxAllowableChargePower3,
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower3,
DailyChargeEnergy = _DailyChargeEnergy3,
DailyDischargeEnergy = _DailyDischargeEnergy3
},
new BatteryRecord
{
Soc = _BatterySoc4,
Soh = _BatterySoh4,
ClusterTotalNumber = _ClusterTotalNumber4,
Current = _BatteryCurrent4,
Voltage = _BatteryVoltage4,
Power = _BatteryPower4,
MaxAllowableChargePower = _BatteryMaxAllowableChargePower4,
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower4,
DailyChargeEnergy = _DailyChargeEnergy4,
DailyDischargeEnergy = _DailyDischargeEnergy4
}*/
};
public BatteriesRecord? BatteriesRecords => BatteriesRecord.FromBatteries(Batteries);
} }

View File

@ -14,36 +14,36 @@ public partial class WITGrowatRecord
[InputRegister<Int32>(8083, Scale = 0.1)] private Int32 _exportedPowerToGrid; [InputRegister<Int32>(8083, Scale = 0.1)] private Int32 _exportedPowerToGrid;
// 3100031009 — Operating Status Info // 3100031009 — Operating Status Info
[InputRegister(31000)] private UInt16 _SystemOperatingMode; [InputRegister(31000)] private UInt16 _systemOperatingMode;
[InputRegister(31001)] private UInt16 _BatteryOperatingMode; [InputRegister(31001)] private UInt16 _batteryOperatingMode;
[InputRegister(31002)] private UInt16 _OperatingPriority; [InputRegister(31002)] private UInt16 _operatingPriority;
[InputRegister(31003)] private UInt16 _Reserved1; [InputRegister(31003)] private UInt16 _reserved1;
[InputRegister(31004)] private UInt16 _Reserved2; [InputRegister(31004)] private UInt16 _reserved2;
[InputRegister(31005)] private UInt16 _FaultMainCode;// Can we change this to warning? [InputRegister(31005)] private UInt16 _faultMainCode;// Can we change this to warning?
[InputRegister(31006)] private UInt16 _FaultSubCode; // Can we change this to warning? [InputRegister(31006)] private UInt16 _faultSubCode; // Can we change this to warning?
[InputRegister(31007)] private UInt16 _WarningMainCode; [InputRegister(31007)] private UInt16 _warningMainCode;
[InputRegister(31008)] private UInt16 _WarningSubCode; [InputRegister(31008)] private UInt16 _warningSubCode;
[InputRegister(31009)] private UInt16 _Reserved3; [InputRegister(31009)] private UInt16 _reserved3;
// 3101031099 — PV Parameters // 3101031099 — PV Parameters
[InputRegister(31010,Scale = 0.1)] private Int16 _Pv1Voltage; [InputRegister(31010,Scale = 0.1)] private Int16 _pv1Voltage;
[InputRegister(31011,Scale = 0.1)] private Int16 _Pv1Current; [InputRegister(31011,Scale = 0.1)] private Int16 _pv1Current;
[InputRegister(31012,Scale = 0.1)] private Int16 _Pv2Voltage; [InputRegister(31012,Scale = 0.1)] private Int16 _pv2Voltage;
[InputRegister(31013,Scale = 0.1)] private Int16 _Pv2Current; [InputRegister(31013,Scale = 0.1)] private Int16 _pv2Current;
[InputRegister(31014,Scale = 0.1)] private Int16 _Pv3Voltage; [InputRegister(31014,Scale = 0.1)] private Int16 _pv3Voltage;
[InputRegister(31015,Scale = 0.1)] private Int16 _Pv3Current; [InputRegister(31015,Scale = 0.1)] private Int16 _pv3Current;
[InputRegister(31016,Scale = 0.1)] private Int16 _Pv4Voltage; [InputRegister(31016,Scale = 0.1)] private Int16 _pv4Voltage;
[InputRegister(31017,Scale = 0.1)] private Int16 _Pv4Current; [InputRegister(31017,Scale = 0.1)] private Int16 _pv4Current;
[InputRegister(31018,Scale = 0.1)] private Int16 _Pv5Voltage; [InputRegister(31018,Scale = 0.1)] private Int16 _pv5Voltage;
[InputRegister(31019,Scale = 0.1)] private Int16 _Pv5Current; [InputRegister(31019,Scale = 0.1)] private Int16 _pv5Current;
[InputRegister(31020,Scale = 0.1)] private Int16 _Pv6Voltage; [InputRegister(31020,Scale = 0.1)] private Int16 _pv6Voltage;
[InputRegister(31021,Scale = 0.1)] private Int16 _Pv6Current; [InputRegister(31021,Scale = 0.1)] private Int16 _pv6Current;
[InputRegister(31058)] private Int16 _Pv1InpuPower; [InputRegister(31058)] private Int16 _pv1InpuPower;
//— AC Side 31100 - 31199 //— AC Side 31100 - 31199
[InputRegister<Int32>(31100, Scale = 0.1)] private Int32 _ActivePower; // Positive: feed to grid, Negative: draw from the grid [InputRegister<Int32>(31100, Scale = 0.1)] private Int32 _activePower; // Positive: feed to grid, Negative: draw from the grid
[InputRegister<Int32>(31102, Scale = 0.1)] private Int32 _ReactivePower; // Positive: capacitive, Negative: Inductive [InputRegister<Int32>(31102, Scale = 0.1)] private Int32 _reactivePower; // Positive: capacitive, Negative: Inductive
[InputRegister(31104, Scale = 0.1)] private Int16 _Reserved4; [InputRegister(31104, Scale = 0.1)] private Int16 _reserved4;
[InputRegister(31105, Scale = 0.01)] private UInt16 _Frequency; [InputRegister(31105, Scale = 0.01)] private UInt16 _frequency;
[InputRegister(31106, Scale = 0.1)] private UInt16 _GridAbLineVoltage; [InputRegister(31106, Scale = 0.1)] private UInt16 _GridAbLineVoltage;
[InputRegister(31107, Scale = 0.1)] private UInt16 _GridBcLineVoltage; [InputRegister(31107, Scale = 0.1)] private UInt16 _GridBcLineVoltage;
@ -88,7 +88,7 @@ public partial class WITGrowatRecord
// 3130031399 — Second Battery Cluster Info (incl. BDC and BMS) // 3130031399 — Second Battery Cluster Info (incl. BDC and BMS)
/* [InputRegister<Int32>(31300)] private Int32 _BatteryPower2; // positive Charge, Negative Discharge [InputRegister<Int32>(31300)] private Int32 _batteryPower2; // positive Charge, Negative Discharge
[InputRegister<UInt32>(31302)] private UInt32 _DailyChargeEnergy2; [InputRegister<UInt32>(31302)] private UInt32 _DailyChargeEnergy2;
[InputRegister<UInt32>(31304)] private UInt32 _AccumulatedChargeEnergy2; [InputRegister<UInt32>(31304)] private UInt32 _AccumulatedChargeEnergy2;
[InputRegister<UInt32>(31206)] private UInt32 _DailyDischargeEnergy2; //0.1kw [InputRegister<UInt32>(31206)] private UInt32 _DailyDischargeEnergy2; //0.1kw
@ -164,26 +164,26 @@ public partial class WITGrowatRecord
//[HoldingRegister<UInt32>(30152, writable: true)] private UInt16 _Reserved11; // //[HoldingRegister<UInt32>(30152, writable: true)] private UInt16 _Reserved11; //
[HoldingRegister(30154, writable: true)] private UInt16 _ActivePowerPercent; // Limit percentage: [0, 100]; Default: 100; takes the smaller value of 30151 and 30154 as actual active limit; Not stored [HoldingRegister(30154, writable: true)] private UInt16 _ActivePowerPercent; // Limit percentage: [0, 100]; Default: 100; takes the smaller value of 30151 and 30154 as actual active limit; Not stored
[HoldingRegister(30162)] private UInt16 _PowerFactor; // [0, 2000] [18000, 20000]; Default: 20000; Actual PF = (Register Value - 10000) [HoldingRegister(30162)] private UInt16 _PowerFactor; // [0, 2000] [18000, 20000]; Default: 20000; Actual PF = (Register Value - 10000)
[HoldingRegister(30203, writable : true)] private UInt16 _EmsCommunicationFailureTime; // [1,300] TODO to 30 [HoldingRegister(30203, writable : true)] private UInt16 _EmsCommunicationFailureTime; // [1,300] TODO to 30
[HoldingRegister(30204, writable : true)] private Boolean _EnableEmsCommunicationFailureTime; // 0: disabled, 1 = enabled we should enable this TODO [HoldingRegister(30204, writable : true)] private Boolean _EnableEmsCommunicationFailureTime; // 0: disabled, 1 = enabled we should enable this TODO
[HoldingRegister(30300)] private UInt16 _BatteryClusterIndex; // [0..3] [HoldingRegister(30300)] private UInt16 _BatteryClusterIndex; // [0..3]
[HoldingRegister<UInt32>(30400 , writable: true)] private UInt32 _BatteryMaxChargePower; // [HoldingRegister<UInt32>(30400 , writable: true)] private UInt32 _BatteryMaxChargePower; //
[HoldingRegister<UInt32>(30402 , writable: true)] private UInt32 _BatteryMaxDischargePower; // [HoldingRegister<UInt32>(30402 , writable: true)] private UInt32 _BatteryMaxDischargePower; //
[HoldingRegister(30404, writable: true)] private UInt16 _ChargeCutoffSoc; // [HoldingRegister(30404, writable: true)] private UInt16 _maxSoc; //
[HoldingRegister(30405, writable: true)] private UInt16 _DischargeCutoffSoc; // [HoldingRegister(30405, writable: true)] private UInt16 _minSoc; //
[HoldingRegister(30406, writable: true)] private UInt16 _LoadPriorityDischargeCutoffSoc; // [HoldingRegister(30406, writable: true)] private UInt16 _LoadPriorityDischargeCutoffSoc; //
[HoldingRegister(30407, writable: true)] private Boolean _RemotePowerControl; // [HoldingRegister(30407, writable: true)] private Boolean _RemotePowerControl; //
[HoldingRegister(30408, writable: true)] private UInt16 _RemotePowerControlChargeDuration; // [HoldingRegister(30408, writable: true)] private UInt16 _RemotePowerControlChargeDuration; //
[HoldingRegister<Int16>(30409, writable: true)] private Int16 _RemoteChargDischargePower; // [HoldingRegister<Int16>(30409, writable: true)] private Int16 _RemoteChargDischargePower; //
[HoldingRegister(30410, writable: true)] private Boolean _AcChargeEnable; // [HoldingRegister(30410, writable: true)] private Boolean _AcChargeEnable; //
[HoldingRegister(30474)] private UInt16 _ActualChargeDischargePowerControlValue; // [HoldingRegister(30474)] private UInt16 _ActualChargeDischargePowerControlValue; //
[HoldingRegister(30475)] private UInt16 _OffGridDischargeCutoffSoc; // [HoldingRegister(30475)] private UInt16 _OffGridDischargeCutoffSoc; //
[HoldingRegister(30496, writable: true, Scale = 0.1)] private UInt16 _BatteryChargeCutoffVoltage; // [HoldingRegister(30496, writable: true, Scale = 0.1)] private UInt16 _BatteryChargeCutoffVoltage; //
[HoldingRegister(30497, writable: true, Scale = 0.1)] private UInt16 _BatteryDischargeCutoffVoltage; // [HoldingRegister(30497, writable: true, Scale = 0.1)] private UInt16 _BatteryDischargeCutoffVoltage; //
[HoldingRegister(30498, writable: true, Scale = 0.1)] private UInt16 _BatteryMaxChargeCurrent; // [HoldingRegister(30498, writable: true, Scale = 0.1)] private UInt16 _batteryMaxChargingCurrent; //
[HoldingRegister(30499, writable: true, Scale = 0.1)] private UInt16 _BatteryMaxdischargeCurrent; //*/ [HoldingRegister(30499, writable: true, Scale = 0.1)] private UInt16 _batteryMaxDischargingCurrent; //*/
} }