diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/ControlRecord.cs b/csharp/Lib/Devices/Trumpf/SystemControl/ControlRecord.cs deleted file mode 100644 index b5879384e..000000000 --- a/csharp/Lib/Devices/Trumpf/SystemControl/ControlRecord.cs +++ /dev/null @@ -1,84 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; - -public record ControlRecord -{ - private static readonly TimeSpan DefaultCommunicationTimeOut = TimeSpan.FromSeconds(10); - - // TODO - - // public UInt32 Date { get; init;} - // public UInt32 Time { get; init;} - // public UInt32 IpAddress { get; init;} //= 0x C0A80102; - // public UInt32 Subnet { get; init;} //= 0x FFFFFF00; - // public UInt32 Gateway { get; init;} //= 0x C0A80102; - // public Boolean ResetParamToDefault { get; init;} = false ; // Coil - // public TimeSpan CommunicationTimeout { get; init;} = DefaultCommunicationTimeOut; - // public Boolean FactoryResetParameters { get; init;} = false; - // public SystemConfig ConnectedSystemConfig { get; init;} = 0; - // public UInt16 UpdateSwTrigger { get; init;} = 0; - // public UInt16 AutomaticSwUpdate { get; init;} = 0; - // public UInt16 CustomerValuesSaveReset { get; init;} = 0; - // public UInt16 SerialNumberSystemControl { get; init;} = 0; - // public UInt16 SerialNumberAcDc { get; init;} = 0; - // public UInt16 IntegrationLevel { get; init;} = 0; - // public UInt16 IlBuildnumber { get; init;} = 0; - // public Boolean PowerStageEnable { get; init;} = true; - // public SymmetricAcOperationMode SetValueConfig { get; init;} = 0; - // public Boolean ResetsAlarmAndWarning { get; init;} = false; - // public PreChargeDcLinkConfig PreChargeDcLinkConfig { get; init;} = (PreChargeDcLinkConfig)0; - // public PowerFactorConvention PowerFactorConvention { get; init;} = 0; //0 = producer - // public UInt16 SlaveAddress { get; init;} = Slave.Broadcast; - // public ErrorPolicy ErrorHandlingPolicy { get; init;} = 0; - // public AcDcGridType GridType { get; init;} = 0; - // public UInt16 SubSlaveAddress { get; init;} = 0; - // public Boolean UseModbusSlaveIdForAddressing { get; init;} = false; - // public UInt16 SubSlaveErrorPolicy { get; init;} = 0; // must be an enum - // public Decimal SignedPowerNominalValue { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal SignedPowerSetValueL1 { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal SignedPowerSetValueL2 { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal SignedPowerSetValueL3 { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal PowerSetValue { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal PowerSetValueL1 { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal PowerSetValueL2 { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal PowerSetValueL3 { get; init;} = 0; // resolution 0.001 and Unit kva, - // public Decimal MaximumGridCurrentRmsL1 { get; init;} = 0; // resolution : 0.01 - // public Decimal MaximumGridCurrentRmsL2 { get; init;} = 0; // resolution : 0.01 - // public Decimal MaximumGridCurrentRmsL3 { get; init;} = 0; // resolution : 0.01 - // public Decimal CosPhiSetValueL1 { get; init;} = 0; // resolution : 0.01 - // public Decimal CosPhiSetValueL2 { get; init;} = 0; // resolution : 0.01 - // public Decimal CosPhiSetValueL3 { get; init;} = 0; // resolution : 0.01 - // public Boolean PhaseL1IsCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - // public Boolean PhaseL2IsCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - // public Boolean PhaseL3IsCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - // public Boolean PhasesAreCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - // public Double SetPointCosPhi { get; init;} = 0; // resolution 0.01 - // public Double SetPointSinPhi { get; init;} = 0; // resolution 0.01 - // public Double SetPointSinPhiL1 { get; init;} = 0; // resolution 0.01 - // public Double SetPointSinPhiL2 { get; init;} = 0; // resolution 0.01 - // public Double SetPointSinPhiL3 { get; init;} = 0; // resolution 0.01 - // public Decimal FrequencyOffsetIm { get; init;} = 0; // resolution 0.01 - // public UInt16 VoltageAdjustmentFactorIm { get; init;} = 0; - // public UInt16 PreChargeDcLinkVoltage { get; init;} = 0; - // public Decimal MaxPeakCurrentVoltageControlL1 { get; init;} = 0; // resolution 0.01 - // public Decimal MaxPeakCurrentVoltageControlL2 { get; init;} = 0; // resolution 0.01 - // public Decimal MaxPeakCurrentVoltageControlL3 { get; init;} = 0; // resolution 0.01 - // public UInt16 GridFormingMode { get; init;} = 1; // 0 = not grid-forming (grid-tied) ,1 = grid-forming - // public UInt16 DcLinkRefVoltage { get; init;} = 800; - // public UInt16 DcLinkMinVoltage { get; init;} = 780; - // public UInt16 DcLinkMaxVoltage { get; init;} = 820; - // public UInt16 DcVoltageRefUs { get; init;} = 900; - // public UInt16 DcMinVoltageUs { get; init;} = 880; - // public UInt16 DcMaxVoltageUs { get; init;} = 920; - // // Need to discuss this with Ivo - // // public UInt16 FrequencySlopeIslandMode { get; init;} = 200; // resolution 0.01 - // // public UInt16 VoltageSlopeIslandMode { get; init;} = 500; // resolution 0.01 - // public UInt16 AcDcGcBypassMode { get; init;} = 0; - // public UInt16 AcDcGcPMaxThresholdPercent { get; init;} = 0; // resolution 0.01 - // public UInt16 AcDcGcStartupRampEnable { get; init;} = 0; - // public DcStageConfiguration DcConfigModule { get; init;} = 0; // this must be an enum - // public UInt16 DcDcPowerDistribution { get; init;} = 0; // 0.1 resolution - // public AcDcDistributionMode AcDcDistributionMode { get; init;} = 0; - - - -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/AlarmMessage.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/AlarmMessage.cs similarity index 88% rename from csharp/Lib/Devices/Trumpf/SystemControl/AlarmMessage.cs rename to csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/AlarmMessage.cs index d63b5dfb8..7ec586580 100644 --- a/csharp/Lib/Devices/Trumpf/SystemControl/AlarmMessage.cs +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/AlarmMessage.cs @@ -1,18 +1,18 @@ using System.Diagnostics.CodeAnalysis; -namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; [SuppressMessage("ReSharper", "UnusedMember.Global")] -public enum AlarmMessage +public enum AlarmMessage : UInt16 { NoAlarm = 0, BmsCommunicationTimeoutHasOccured = 40302, // BMS communication timeout has occured. Rs485CommunicationAlarm = 40303, // RS-485 communication alarm. + NoSlaveModuleWasFoundPleaseCheckRs485Connection = 40304, // No slave module was found, please check RS-485 connection(s). + NumberOfOrCombinationOfConnectedSlaveTypesNotSupported = 40305, // Number of or combination of connected slave types not supported. SoftwareVersionsOfSystemControlAndModulesDoNotMatch1 = 40412, // Software versions of system control and module(s) do not match. SoftwareVersionsOfSystemControlAndModulesDoNotMatch2 = 40413, // Software versions of system control and module(s) do not match. SoftwareVersionsOfSystemControlAndModulesDoNotMatch3 = 40414, // Software versions of system control and module(s) do not match. SoftwareVersionsOfSystemControlAndModulesDoNotMatch4 = 40415, // Software versions of system control and module(s) do not match. - SoftwareVersionsOfSystemControlAndModulesDoNotMatch5 = 40416, // Software versions of system control and module(s) do not match. - NoSlaveModuleWasFoundPleaseCheckRs485Connection = 40304, // No slave module was found, please check RS-485 connection(s). - NumberOfOrCombinationOfConnectedSlaveTypesNotSupported = 40305, // Number of or combination of connected slave types not supported. + SoftwareVersionsOfSystemControlAndModulesDoNotMatch5 = 40416, // Software versions of system control and module(s) do not match. } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvert/MainState.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/DeviceState.cs similarity index 52% rename from csharp/Lib/Devices/Trumpf/TruConvert/MainState.cs rename to csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/DeviceState.cs index a4cfa89e5..630853c59 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvert/MainState.cs +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/DeviceState.cs @@ -1,6 +1,6 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert; +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; -public enum MainState : UInt16 +public enum DeviceState : UInt16 { PowerUp = 0, Alarm = 1, diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcDcGridType.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/GridType.cs similarity index 73% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcDcGridType.cs rename to csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/GridType.cs index cbb766adf..edcc5f036 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcDcGridType.cs +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/GridType.cs @@ -1,6 +1,6 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; -public enum AcDcGridType : UInt16 +public enum GridType : UInt16 { GridTied400V50Hz = 0, // grid-tied, 400V, 50Hz GridTied480V60Hz = 1, // grid-tied, 480V, 60Hz diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/PowerSetPointActivation.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/PowerSetPointActivation.cs new file mode 100644 index 000000000..88de61135 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/PowerSetPointActivation.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +public enum PowerSetPointActivation : UInt16 +{ + Immediate = 0, + Trigger = 1, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/PowerSetPointTrigger.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/PowerSetPointTrigger.cs new file mode 100644 index 000000000..d1604bf4f --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/PowerSetPointTrigger.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +public enum PowerSetPointTrigger : UInt16 +{ + Wait = 0, + Trigger = 1, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/ReferenceFrame.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/ReferenceFrame.cs new file mode 100644 index 000000000..fb78475c6 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/ReferenceFrame.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +public enum ReferenceFrame : UInt16 +{ + Producer = 0, + Consumer = 1, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SlaveErrorHandling.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SlaveErrorHandling.cs new file mode 100644 index 000000000..c076b0b1f --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SlaveErrorHandling.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +public enum SlaveErrorHandling : UInt16 +{ + Relaxed = 0, // System keeps running even if some slaves are in error state. + Strict = 1, // System shuts down as soon as one component is in error state. +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SubSlaveErrorHandling.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SubSlaveErrorHandling.cs new file mode 100644 index 000000000..7897fae09 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SubSlaveErrorHandling.cs @@ -0,0 +1,8 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +public enum SubSlaveErrorHandling : UInt16 +{ + Strict = 0, // SystemControl switches to error state if at least one submodules is in error state + Relaxed = 1, // SystemControl switches to error state if all submodules are in error state. + Off = 2, // If possible AC-DC module continues operation even if all submodules are in error state. +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvert/SystemConfig.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SystemConfig.cs similarity index 53% rename from csharp/Lib/Devices/Trumpf/TruConvert/SystemConfig.cs rename to csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SystemConfig.cs index 4967389e0..c380a851f 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvert/SystemConfig.cs +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/SystemConfig.cs @@ -1,9 +1,9 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert; +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; public enum SystemConfig : UInt16 { NoConfig = 0, Simulator = 1, DcDcOnly = 2, - AcDcAndDcDc = 3, + AcDcAndDcDc = 3 } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/WarningMessage.cs b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/WarningMessage.cs new file mode 100644 index 000000000..4566d665e --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/DataTypes/WarningMessage.cs @@ -0,0 +1,10 @@ +using System.Diagnostics.CodeAnalysis; + +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +[SuppressMessage("ReSharper", "UnusedMember.Global")] +public enum WarningMessage : UInt16 +{ + NoWarning = 0, + // TODO: ??? +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/ErrorPolicy.cs b/csharp/Lib/Devices/Trumpf/SystemControl/ErrorPolicy.cs deleted file mode 100644 index 9a57a9f3d..000000000 --- a/csharp/Lib/Devices/Trumpf/SystemControl/ErrorPolicy.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; - -public enum ErrorPolicy : UInt16 -{ - Relaxed = 0, // 0 = relaxed (System keeps running even if some slaves are in error state.) - Strict = 1, // 1 = strict (System shuts down as soon as one component is in error state.) -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/Program.cs b/csharp/Lib/Devices/Trumpf/SystemControl/Program.cs new file mode 100644 index 000000000..aacd72a30 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/Program.cs @@ -0,0 +1,46 @@ +// using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +// using InnovEnergy.Lib.Utils; +// +// namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; +// +// // TODO: remove +// +// public static class Program +// { +// public static void Main(String[] args) +// { +// var d = new SystemControlDevice("localhost", 5001); +// +// while (true) +// { +// var r = d.Read(); +// +// Console.WriteLine(DateTime.Now); +// r.ToString().Replace(",", "\n").Replace(" {", "\n").WriteLine(); +// +// "Alarms".WriteLine(); +// r.Alarms.Count.WriteLine(); +// r.Alarms.Select(a => a.ToString()).JoinLines().WriteLine(); +// +// "Warnings".WriteLine(); +// r.NumberOfWarnings.WriteLine(); +// r.Warnings.Select(a => a.ToString()).JoinLines().WriteLine(); +// +// var c = r with +// { +// UseSlaveIdForAddressing = true, +// ReferenceFrame = ReferenceFrame.Consumer, +// GridType = GridType.GridTied400V50Hz, +// SystemConfig = SystemConfig.AcDcAndDcDc, +// CommunicationTimeout = null, +// SlaveErrorHandling = SlaveErrorHandling.Relaxed, +// SubSlaveErrorHandling = SubSlaveErrorHandling.Off +// }; +// +// +// +// d.Write(c); +// +// } +// } +// } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/StatusRecord.cs b/csharp/Lib/Devices/Trumpf/SystemControl/StatusRecord.cs deleted file mode 100644 index 511019b83..000000000 --- a/csharp/Lib/Devices/Trumpf/SystemControl/StatusRecord.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; - -using AlarmMessages = IReadOnlyList; -using WarningMessages = IReadOnlyList; - - -// ReSharper disable UnusedAutoPropertyAccessor.Global -#pragma warning disable CS8618 - - -public record StatusRecord -{ - - // TODO - - // public MainState MainState { get; init; } - // public String SerialNumber { get; init; } - // public AcDcGridType GridType { get; init; } - // public WarningMessages Warnings { get; init; } - // public AlarmMessages Alarms { get; init; } - // public Decimal NumberOfConnectedSlaves { get; init; } - // public Decimal NumberOfConnectedSubSlaves { get; init; } - // public Frequency AcDcNominalGridFrequency { get; init; } - // public Voltage AcDcNominalGridVoltage { get; init; } - // public Power AcDcActNominalPower { get; init; } - // public Decimal AcDcPowerLimitingStatusAct { get; init; } // TODO: enum - // public Voltage AcDcDcVoltageReference { get; init; } - // public Voltage AcDcDcLinkVoltageMinAct { get; init; } - // public Voltage AcDcDcLinkVoltageMaxAct { get; init; } - // public Voltage AcDcDcLinkChargedMinVoltage { get; init; } - // public Decimal AcDcStmActCustomer { get; init; } - // public Decimal AcDcOverloadIntegratorStatusL1 { get; init; } - // public Decimal AcDcOverloadIntegratorStatusL2 { get; init; } - // public Decimal AcDcOverloadIntegratorStatusL3 { get; init; } - // public Power AcSignedPowerValue { get; init; } - // public Voltage ActualDcLinkVoltageUpperHalf { get; init; } - // public Voltage ActualDcLinkVoltageLowerHalf { get; init; } - // public Voltage ActualDcLinkVoltageUpperHalfExt { get; init; } - // public Voltage ActualDcLinkVoltageLowerHalfExt { get; init; } - // public Voltage VoltageIntNtoPe { get; init; } - // public Voltage VoltageExtNtoPe { get; init; } - // public Temperature InletAirTemperature { get; init; } -} diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SubSlavesErrorPolicy.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SubSlavesErrorPolicy.cs deleted file mode 100644 index 107b6b42b..000000000 --- a/csharp/Lib/Devices/Trumpf/SystemControl/SubSlavesErrorPolicy.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; - -public enum SubSlavesErrorPolicy : UInt16 -{ - Strict = 0, // (AC-DC module switches to error state if at least one submodules is in error state - Relaxed = 1, // (AC-DC module switches to error state if all submodules are in error state.) - Off = 2, // (If possible AC-DC module continues operation even if all submodules are in error state. -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControl.csproj b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControl.csproj index 2197231aa..098c470f3 100644 --- a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControl.csproj +++ b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControl.csproj @@ -1,11 +1,12 @@ - - Debug;Release;Release-Server - AnyCPU;linux-arm - - + + + + + - + + diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlDevice.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlDevice.cs index cc3e94af0..6d088f4b2 100644 --- a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlDevice.cs +++ b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlDevice.cs @@ -1,8 +1,7 @@ using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Protocols.Modbus.Channels; using InnovEnergy.Lib.Protocols.Modbus.Clients; -using InnovEnergy.Lib.Protocols.Modbus.Connections; -using InnovEnergy.Lib.Utils; -using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.SystemControlRegisters; +using InnovEnergy.Lib.Protocols.Modbus.Slaves; namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; @@ -10,315 +9,21 @@ namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] public class SystemControlDevice { - private ModbusTcpClient ModbusTcpClient { get; } + private readonly ModbusDevice _SystemControlSlave; + public Channel Channel { get; } - public SystemControlDevice(String hostname, UInt16 port = ModbusTcpClient.DefaultPort, Byte slaveAddress = 0) + public SystemControlDevice(String hostname, Int32 port = 502) : this(new TcpChannel(hostname, port)) { - var connection = new ModbusTcpConnection(hostname, port); - ModbusTcpClient = new ModbusTcpClient(connection, slaveAddress); } - - - public void WriteControl(ControlRecord c) - { - /* - WriteRegs(AcControlRegisters.Date, new List { c.Date.ConvertTo()}); - WriteRegs(AcControlRegisters.Time, new List { c.Time.ConvertTo()}); - WriteRegs(AcControlRegisters.IpAddress, new List { c.IpAddress.ConvertTo()}); - WriteRegs(AcControlRegisters.Subnet, new List { c.Subnet.ConvertTo()}); - WriteRegs(AcControlRegisters.Gateway, new List { c.Gateway.ConvertTo()}); - WriteCoils(AcControlRegisters.ResetParamToDefault, c.ResetParamToDefault); - WriteCoils(AcControlRegisters.FactoryResetParameters, c.FactoryResetParameters); - ModbusTcpClient.WriteRegisters(AcControlRegisters.UpdateSwTrigger, c.UpdateSwTrigger, c.AutomaticSwUpdate, c.CustomerValuesSaveReset); - */ - - - WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo()); - - WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig); - - - WriteCoils(PowerStageConfig, c.PowerStageEnable, - c.SetValueConfig.ConvertTo(), - c.ResetsAlarmAndWarning); - WriteRegs(PreChargeDcLinkConfigR, c.PreChargeDcLinkConfig, - c.PowerFactorConvention, c.SlaveAddress, - c.ErrorHandlingPolicy, - c.GridType, c.SubSlaveAddress); - WriteCoils(ModbusSlaveId, c.UseModbusSlaveIdForAddressing); - WriteRegs(SubSlaveErrorPolicy, c.SubSlaveErrorPolicy); - - WriteRegs(SignedPowerNominalValue, -1.0m, c.SignedPowerNominalValue);/*, c.SignedPowerSetValueL1, - c.SignedPowerSetValueL2, c.SignedPowerSetValueL3, - c.PowerSetValue, c.PowerSetValueL1, - c.PowerSetValueL2, c.PowerSetValuesL3);*/ - - - WriteRegs(MaximumGridCurrentRmsL1, 0.01m, c.MaximumGridCurrentRmsL1, c.MaximumGridCurrentRmsL2, - c.MaximumGridCurrentRmsL3, c.CosPhiSetValueL1, - c.CosPhiSetValueL2, c.CosPhiSetValueL3); - - WriteCoils(PhaseL1IsCapacitive, c.PhaseL1IsCapacitive, - c.PhaseL2IsCapacitive, - c.PhaseL3IsCapacitive, - c.PhasesAreCapacitive); - - /* WriteRegs(SetPointCosPhi, 0.01m, c.SetPointCosPhi.ConvertTo(), - c.SetPointSinPhi.ConvertTo(), - c.SetPointSinPhiL1.ConvertTo(), - c.SetPointSinPhiL2.ConvertTo(), - c.SetPointSinPhiL3.ConvertTo(), - c.FrequencyOffsetIm);*/ - - WriteRegs(VoltageAdjustmentFactorIm, c.VoltageAdjustmentFactorIm); - WriteRegs(PreChargeDcLinkVoltage, c.PreChargeDcLinkVoltage); - WriteRegs(MaxPeakCurrentVoltageControlL1, 0.01m, c.MaxPeakCurrentVoltageControlL1, - c.MaxPeakCurrentVoltageControlL2, - c.MaxPeakCurrentVoltageControlL3); - WriteRegs(GridFormingMode, c.GridFormingMode, c.DcLinkRefVoltage, - c.DcLinkMinVoltage, c.DcLinkMaxVoltage, - c.DcVoltageRefUs, c.DcMinVoltageUs, c.DcMaxVoltageUs); - WriteRegs(AcDcGcBypassMode, c.AcDcGcBypassMode); - WriteRegs(AcDcGcPMaxThresholdPercent, 0.01m, c.AcDcGcPMaxThresholdPercent); - WriteRegs(AcDcGcStartupRampEnable, c.AcDcGcStartupRampEnable); - WriteRegs(DcConfigModule, c.DcConfigModule); - WriteRegs(DcDcPowerDistribution, 0.1m, c.DcDcPowerDistribution); - WriteRegs(SystemControlRegisters.AcDcDistributionMode, c.AcDcDistributionMode); - } - - private void WriteRegs (UInt16 a, Decimal res = 1.0m, params Decimal[] regs) => ModbusTcpClient.WriteRegisters(a, regs.ToUInt16(res)); - private void WriteRegs (UInt16 a, params IConvertible[] regs) => ModbusTcpClient.WriteRegisters(a, regs.Select(v => v.ConvertTo()).ToArray()); - private void WriteRegs (UInt16 a, params UInt16[] regs) => ModbusTcpClient.WriteRegisters(a, regs); - private void WriteCoils(UInt16 a, params Boolean[] coils) => ModbusTcpClient.WriteMultipleCoils(a, coils); - - private static Decimal GetPhi(Decimal cosPhi) => cosPhi.Clamp(-1m, 1m).Apply(ACos); - public StatusRecord? ReadStatus() + public SystemControlDevice(Channel channel) { - try - { - return TryReadStatus(); - } - catch (Exception e) - { - ModbusTcpClient.CloseConnection(); - Console.WriteLine("Failed to read inverter status"); - e.Message.WriteLine(); - - return null; - } + Channel = channel; + + var tcpClient = new ModbusTcpClient(channel, 0); + _SystemControlSlave = new ModbusDevice(tcpClient); } - private StatusRecord TryReadStatus() - { - // Console.WriteLine("Reading Ac Device"); - - var acSerialNumber = ModbusTcpClient.ReadInputRegisters(2009, 2); - var acActualMain = ModbusTcpClient.ReadInputRegisters(5001, 3); - var acActualAcDc = ModbusTcpClient.ReadInputRegisters(5021, 9); - var acActualAcDc2 = ModbusTcpClient.ReadInputRegisters(5031, 1); - var acActualAcDc3 = ModbusTcpClient.ReadInputRegisters(5131, 6); - var acActualMeasurement = ModbusTcpClient.ReadInputRegisters(5141, 3); - var acActualMeasurement1 = ModbusTcpClient.ReadInputRegisters(5151, 3); - var acActualMeasurement2 = ModbusTcpClient.ReadInputRegisters(5161, 3); - var acActualMeasurement3 = ModbusTcpClient.ReadInputRegisters(5171, 3); - var acActualMeasurement4 = ModbusTcpClient.ReadInputRegisters(5187, 2); - var acActualMeasurement5 = ModbusTcpClient.ReadInputRegisters(5189, 2); - var acActualMeasurement6 = ModbusTcpClient.ReadInputRegisters(5191, 2); - var acActualMeasurement7 = ModbusTcpClient.ReadInputRegisters(5201, 1); - var acActualMeasurement8 = ModbusTcpClient.ReadInputRegisters(5211, 4); - var acActualMeasurement9 = ModbusTcpClient.ReadInputRegisters(5221, 2); - var acActualTemp = ModbusTcpClient.ReadInputRegisters(5501, 1); - var acWarningValues = ModbusTcpClient.ReadInputRegisters(2402, 22); - var acAlarmValues = ModbusTcpClient.ReadInputRegisters(2809, 22); - var acSetValues = ModbusTcpClient.ReadInputRegisters(4196, 1); - - var warnings = Enumerable - .Range(2404, 20) - .Select(n => acWarningValues.GetUInt16((UInt16)n).ConvertTo()) - .ToArray(); - - var alarms = Enumerable - .Range(2811, 20) - .Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo()) - .Where(m => m != AlarmMessage.NoAlarm) - .ToArray(); - - - var dcPower = acActualMeasurement.GetInt16(5141) * 1m + acActualMeasurement.GetInt16(5142) * 1m + acActualMeasurement.GetInt16(5143) * 1m; - var dcVoltage = acActualMeasurement8.GetUInt16(5214) + acActualMeasurement8.GetUInt16(5213); - var dcCurrent = dcVoltage != 0m - ? dcPower / dcVoltage - : 0m; - - - // //acActualMeasurement - // PowerAcL1 = acActualMeasurement.GetInt16(5141) * 1m, // in Watt - // PowerAcL2 = acActualMeasurement.GetInt16(5142) * 1m, // in Watt - // PowerAcL3 = acActualMeasurement.GetInt16(5143) * 1m, // in Watt - // - //acActualMeasurement1 - // PhaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m, - // PhaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m, - // PhaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m, - - //acActualMeasurement2 - // GridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m, - // GridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m, - // GridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m, - - //acActualMeasurement3 - // CosPhiL1 = acActualMeasurement3.GetInt16(5171) * 0.01m, - // CosPhiL2 = acActualMeasurement3.GetInt16(5172) * 0.01m, - // CosPhiL3 = acActualMeasurement3.GetInt16(5173) * 0.01m, - - // //acActualMeasurement4 - // SumPowerL1 = acActualMeasurement4.GetUInt32(5187) * 1m, // in Watt - // //acActualMeasurement5 - // SumPowerL2 = acActualMeasurement5.GetUInt32(5189) * 1m, // in Watt - // //acActualMeasurement6 - // SumPowerL3 = acActualMeasurement6.GetUInt32(5191) * 1m, // in Watt - // //acActualMeasurement9 - // GridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m, - - //acActualMeasurement11 - // VoltageIntNtoPE = acActualMeasurement9.GetInt16(5221) * 0.1m, - // VoltageExtNtoPE = acActualMeasurement9.GetInt16(5222) * 0.1m, - - // - // ApparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m, // in VA - // ApparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m, // in VA - // ApparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m, // in VA - - var apparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m; - var apparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m; - var apparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m; - - var powerAcL1 = acActualMeasurement.GetInt16(5141) * 1m; // in Watt - var powerAcL2 = acActualMeasurement.GetInt16(5142) * 1m; // in Watt - var powerAcL3 = acActualMeasurement.GetInt16(5143) * 1m; // in Watt - - var phaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m; - var phaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m; - var phaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m; - - var gridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m; - var gridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m; - var gridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m; - - var gridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m; - - return new StatusRecord - { - Ac = new Ac3Bus - { - Frequency = gridFrequency, - - L1 = new AcPhase - { - Voltage = gridVoltageL1, - Current = phaseCurrentL1, - Phi = ACos(powerAcL1 / apparentPowerAcL1), // TODO: 2pi - }, - L2 = new AcPhase - { - Voltage = gridVoltageL2, - Current = phaseCurrentL2, - Phi = ACos(powerAcL2 / apparentPowerAcL2), // TODO: 2pi - }, - L3 = new AcPhase - { - Voltage = gridVoltageL3, - Current = phaseCurrentL3, - Phi = ACos(powerAcL3 / apparentPowerAcL3), // TODO: 2pi - } - }, - Dc = new DcBus - { - Current = dcCurrent, - Voltage = dcVoltage, - }, - - MainState = acActualMain.GetInt16(5001).ConvertTo(), - Alarms = alarms, - Warnings = warnings, - GridType = acActualAcDc.GetUInt16(5024).ConvertTo(), - SerialNumber = acSerialNumber.GetInt32(2009).ToString(), // TODO: why tostring ? - NumberOfConnectedSlaves = acActualMain.GetUInt16(5002), - NumberOfConnectedSubSlaves = acActualMain.GetUInt16(5003), - AcDcNominalGridFrequency = acActualAcDc.GetUInt16(5021) * 0.1m, - AcDcNominalGridVoltage = acActualAcDc.GetUInt16(5022), - AcDcActNominalPower = acActualAcDc.GetUInt16(5023), - AcDcPowerLimitingStatusAct = acActualAcDc.GetUInt16(5025), - AcDcDcVoltageReference = acActualAcDc.GetUInt16(5026), // DC link reference - AcDcDcLinkVoltageMinAct = acActualAcDc.GetUInt16(5027), // DC link min voltage - AcDcDcLinkVoltageMaxAct = acActualAcDc.GetUInt16(5028), // DC link max voltage - AcDcDcLinkChargedMinVoltage = acActualAcDc.GetUInt16(5029) * 0.01m, - AcDcStmActCustomer = acActualAcDc2.GetUInt16(5031), //need to check - AcDcOverloadIntegratorStatusL1 = acActualAcDc3.GetUInt16(5134) * 0.1m, - AcDcOverloadIntegratorStatusL2 = acActualAcDc3.GetUInt16(5135) * 0.1m, - AcDcOverloadIntegratorStatusL3 = acActualAcDc3.GetUInt16(5136) * 0.1m, - AcSignedPowerValue = acSetValues.GetInt16(4196) * -1.0m, // this is also used for control - ActualDcLinkVoltageUpperHalf = acActualMeasurement8.GetUInt16(5211), - ActualDcLinkVoltageLowerHalf = acActualMeasurement8.GetUInt16(5212), - ActualDcLinkVoltageUpperHalfExt = acActualMeasurement8.GetUInt16(5213), - ActualDcLinkVoltageLowerHalfExt = acActualMeasurement8.GetUInt16(5214), - VoltageIntNtoPe = acActualMeasurement9.GetInt16(5221) * 0.1m, - VoltageExtNtoPe = acActualMeasurement9.GetInt16(5222) * 0.1m, - InletAirTemperature = acActualTemp.GetInt16(5501) * 0.1m, - - }; - - - - // ( - // Ac: new Ac3Bus - // ( - // new AcPhase(gridVoltageL1,phaseCurrentL1, ACos(powerAcL1/apparentPowerAcL1)), - // new AcPhase(gridVoltageL2,phaseCurrentL2, ACos(powerAcL2/apparentPowerAcL2)), - // new AcPhase(gridVoltageL3,phaseCurrentL3, ACos(powerAcL3/apparentPowerAcL3)), - // gridFrequency // Gird Frequency - // ), - // Dc: new DcConnection(dcVoltage, dcCurrent), - // - // SerialNumber : acSerialNumber.GetInt32(2009).ToString(), - // - // // acActualMainValues - // MainState : acActualMain.GetInt16(5001).ConvertTo(), - // NumberOfConnectedSlaves : acActualMain.GetUInt16(5002), - // NumberOfConnectedSubSlaves : acActualMain.GetUInt16(5003), - // - // //acActualAcDc - // AcDcNominalGridFrequency : acActualAcDc.GetUInt16(5021) * 0.1m, - // AcDcNominalGridVoltage : acActualAcDc.GetUInt16(5022), - // AcDcActNominalPower : acActualAcDc.GetUInt16(5023), - // AcDcActiveGridType : acActualAcDc.GetUInt16(5024).ConvertTo(), - // AcDcPowerLimitingStatusAct : acActualAcDc.GetUInt16(5025), - // AcDcDcVoltageReference : acActualAcDc.GetUInt16(5026), // DC link reference - // AcDcDcLinkVoltageMinAct : acActualAcDc.GetUInt16(5027), // DC link min voltage - // AcDcDcLinkVoltageMaxAct : acActualAcDc.GetUInt16(5028), // DC link max voltage - // AcDcDcLinkChargedMinVoltage : acActualAcDc.GetUInt16(5029) * 0.01m, - // - // //ac Actual AcDc 2 - // AcDcStmActCustomer : acActualAcDc2.GetUInt16(5031), //need to check - // AcDcOverloadIntegratorStatusL1 : acActualAcDc3.GetUInt16(5134) * 0.1m, - // AcDcOverloadIntegratorStatusL2 : acActualAcDc3.GetUInt16(5135) * 0.1m, - // AcDcOverloadIntegratorStatusL3 : acActualAcDc3.GetUInt16(5136) * 0.1m, - // AcSignedPowerValue : acSetValues.GetInt16(4196) * -1.0m, // this is also used for control - // - // //acActualMeasurement10 - // ActualDcLinkVoltageUpperHalf : acActualMeasurement8.GetUInt16(5211), - // ActualDcLinkVoltageLowerHalf : acActualMeasurement8.GetUInt16(5212), - // ActualDcLinkVoltageUpperHalfExt : acActualMeasurement8.GetUInt16(5213), - // ActualDcLinkVoltageLowerHalfExt : acActualMeasurement8.GetUInt16(5214), - // - // VoltageIntNtoPe : acActualMeasurement9.GetInt16(5221) * 0.1m, - // VoltageExtNtoPe : acActualMeasurement9.GetInt16(5222) * 0.1m, - // //acActualTemp - // InletAirTemperature : acActualTemp.GetInt16(5501) * 0.1m, - // - // Warnings : warnings, - // Alarms : alarms - // ); - } + public void Write(SystemControlRegisters c) => _SystemControlSlave.Write(c); + public SystemControlRegisters Read() => _SystemControlSlave.Read(); } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Alarms.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Alarms.cs new file mode 100644 index 000000000..7b0ff8640 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Alarms.cs @@ -0,0 +1,41 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; + +#pragma warning disable CS0649 + +[SuppressMessage("ReSharper", "InconsistentNaming")] +public partial record SystemControlRegisters +{ + private IEnumerable GetAlarms() + { + yield return Alarm1; + yield return Alarm2; + yield return Alarm3; + yield return Alarm4; + yield return Alarm5; + yield return Alarm6; + yield return Alarm7; + yield return Alarm8; + yield return Alarm9; + yield return Alarm10; + yield return Alarm11; + yield return Alarm12; + yield return Alarm13; + yield return Alarm14; + yield return Alarm15; + yield return Alarm16; + yield return Alarm17; + yield return Alarm18; + yield return Alarm19; + yield return Alarm20; + } + + public IReadOnlyList Alarms => GetAlarms() + .Take(NumberOfAlarms) + .Where(IsSystemControlAlarm) + .ToList(); + + private static Boolean IsSystemControlAlarm(AlarmMessage alarm) => (UInt16)alarm is >= 40000 and < 50000; +} diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.CommunicationTimeout.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.CommunicationTimeout.cs new file mode 100644 index 000000000..65804eec3 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.CommunicationTimeout.cs @@ -0,0 +1,17 @@ +using InnovEnergy.Lib.Utils; + +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; + +public partial record SystemControlRegisters +{ + public TimeSpan? CommunicationTimeout + { + get => _CommunicationTimeoutSeconds != NoTimeout + ? TimeSpan.FromSeconds(_CommunicationTimeoutSeconds) + : null; + + set => _CommunicationTimeoutSeconds = value is not null + ? value.Value.TotalSeconds.ConvertTo() + : NoTimeout; + } +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Modbus.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Modbus.cs new file mode 100644 index 000000000..4ea2187dc --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Modbus.cs @@ -0,0 +1,90 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +using InnovEnergy.Lib.Protocols.Modbus.Reflection.Attributes; +using SystemConfig = InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig; + + +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; + +#pragma warning disable CS0169 +#pragma warning disable CS0649 +// using the same record for status & control + + + +[SuppressMessage("ReSharper", "UnusedMember.Global")] +[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] +[SuppressMessage("ReSharper", "InconsistentNaming")] +public partial record SystemControlRegisters +{ + private const UInt16 NoTimeout = UInt16.MaxValue; + + [HoldingRegister(1016)] private UInt16 _CommunicationTimeoutSeconds; + + [HoldingRegister(1018)] public SystemConfig SystemConfig { get; set; } + + //[Coil(4002)] + [HoldingRegister(4002)] public Boolean ResetAlarmsAndWarnings { get; set; } + + [HoldingRegister(4007)] public UInt16 TargetSlave { get; set; } + + //[Coil(4011)] + [HoldingRegister(4011)] public Boolean UseSlaveIdForAddressing { get; set; } + [HoldingRegister(4006)] public ReferenceFrame ReferenceFrame { get; set; } + + [HoldingRegister(4008)] public SlaveErrorHandling SlaveErrorHandling { get; set; } + [HoldingRegister(4012)] public SubSlaveErrorHandling SubSlaveErrorHandling { get; set; } + + + [HoldingRegister(4182)] public PowerSetPointActivation PowerSetPointActivation { get; set; } + [HoldingRegister(4183)] public PowerSetPointTrigger PowerSetPointTrigger { get; set; } + + [InputRegister(5000)] public DeviceState DeviceState { get; private set; } + [InputRegister(5001)] public UInt16 NumberOfConnectedSlaves { get; private set; } + [InputRegister(5002)] public UInt16 NumberOfConnectedSubSlaves { get; private set; } + + [InputRegister(2402)] public UInt16 NumberOfWarnings; + [InputRegister(2403)] private WarningMessage Warning1; + [InputRegister(2404)] private WarningMessage Warning2; + [InputRegister(2405)] private WarningMessage Warning3; + [InputRegister(2406)] private WarningMessage Warning4; + [InputRegister(2407)] private WarningMessage Warning5; + [InputRegister(2408)] private WarningMessage Warning6; + [InputRegister(2409)] private WarningMessage Warning7; + [InputRegister(2410)] private WarningMessage Warning8; + [InputRegister(2411)] private WarningMessage Warning9; + [InputRegister(2412)] private WarningMessage Warning10; + [InputRegister(2413)] private WarningMessage Warning11; + [InputRegister(2414)] private WarningMessage Warning12; + [InputRegister(2415)] private WarningMessage Warning13; + [InputRegister(2416)] private WarningMessage Warning14; + [InputRegister(2417)] private WarningMessage Warning15; + [InputRegister(2418)] private WarningMessage Warning16; + [InputRegister(2419)] private WarningMessage Warning17; + [InputRegister(2420)] private WarningMessage Warning18; + [InputRegister(2421)] private WarningMessage Warning19; + [InputRegister(2422)] private WarningMessage Warning20; + + + [InputRegister(2809)] private UInt16 NumberOfAlarms; + [InputRegister(2810)] private AlarmMessage Alarm1; + [InputRegister(2811)] private AlarmMessage Alarm2; + [InputRegister(2812)] private AlarmMessage Alarm3; + [InputRegister(2813)] private AlarmMessage Alarm4; + [InputRegister(2814)] private AlarmMessage Alarm5; + [InputRegister(2815)] private AlarmMessage Alarm6; + [InputRegister(2816)] private AlarmMessage Alarm7; + [InputRegister(2817)] private AlarmMessage Alarm8; + [InputRegister(2818)] private AlarmMessage Alarm9; + [InputRegister(2819)] private AlarmMessage Alarm10; + [InputRegister(2820)] private AlarmMessage Alarm11; + [InputRegister(2821)] private AlarmMessage Alarm12; + [InputRegister(2822)] private AlarmMessage Alarm13; + [InputRegister(2823)] private AlarmMessage Alarm14; + [InputRegister(2824)] private AlarmMessage Alarm15; + [InputRegister(2825)] private AlarmMessage Alarm16; + [InputRegister(2826)] private AlarmMessage Alarm17; + [InputRegister(2827)] private AlarmMessage Alarm18; + [InputRegister(2828)] private AlarmMessage Alarm19; + [InputRegister(2829)] private AlarmMessage Alarm20; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Warnings.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Warnings.cs new file mode 100644 index 000000000..42106bb00 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.Warnings.cs @@ -0,0 +1,39 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; + +namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; + +#pragma warning disable CS0649 + +[SuppressMessage("ReSharper", "InconsistentNaming")] +public partial record SystemControlRegisters +{ + private IEnumerable GetWarnings() + { + yield return Warning1; + yield return Warning2; + yield return Warning3; + yield return Warning4; + yield return Warning5; + yield return Warning6; + yield return Warning7; + yield return Warning8; + yield return Warning9; + yield return Warning10; + yield return Warning11; + yield return Warning12; + yield return Warning13; + yield return Warning14; + yield return Warning15; + yield return Warning16; + yield return Warning17; + yield return Warning18; + yield return Warning19; + yield return Warning20; + } + + public IReadOnlyList Warnings => GetWarnings() + .Take(NumberOfWarnings) + .Where(w => w != WarningMessage.NoWarning) + .ToList(); +} diff --git a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.cs b/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.cs deleted file mode 100644 index 6ab3817f2..000000000 --- a/csharp/Lib/Devices/Trumpf/SystemControl/SystemControlRegisters.cs +++ /dev/null @@ -1,83 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl; - -public static class SystemControlRegisters -{ - - // TODO - - // public const UInt16 Date = 1001; - // public const UInt16 Time = 1003; - // public const UInt16 IpAddress = 1005; - // public const UInt16 Subnet = 1007; - // public const UInt16 Gateway = 1009; - // public const UInt16 ResetParamToDefault = 1011; - // public const UInt16 CommunicationTimeout = 1017; - // public const UInt16 RestartFlag = 1018; - // public const UInt16 ConnectedSystemConfig = 1019; - // public const UInt16 UpdateSwTrigger = 1027; - // public const UInt16 AutomaticSwUpdate = 1028; - // public const UInt16 CustomerValuesSaveReset = 1029; - // public const UInt16 SerialNumberSystemControl = 2001; - // public const UInt16 SerialNumberAcDc = 2009; - // public const UInt16 IntegrationLevel = 2051; - // public const UInt16 IlBuildnumber = 2052; - // public const UInt16 PowerStageConfig = 4001; - // public const UInt16 SetValueConfig = 4002; - // public const UInt16 ResetsAlarmAndWarning = 4003; - // public const UInt16 PreChargeDcLinkConfigR = 4006; - // public const UInt16 ReferenceFrameConvention = 4007; - // public const UInt16 SlaveAddress = 4008; - // public const UInt16 ErrorHandlingPolicy = 4009; - // public const UInt16 GridType = 4010; - // public const UInt16 SubSlaveAddress = 4011; - // public const UInt16 ModbusSlaveId = 4012; - // public const UInt16 SubSlaveErrorPolicy = 4013; - // public const UInt16 SignedPowerNominalValue = 4196; - // public const UInt16 SignedPowerSetValueL1 = 4197; - // public const UInt16 SignedPowerSetValueL2 = 4198; - // public const UInt16 SignedPowerSetValueL3 = 4199; - // public const UInt16 PowerSetValue = 4200; - // public const UInt16 PowerSetValueL1 = 4201; - // public const UInt16 PowerSetValueL2 = 4202; - // public const UInt16 PowerSetValueL3 = 4203; - // public const UInt16 MaximumGridCurrentRmsL1 = 4204; - // public const UInt16 MaximumGridCurrentRmsL2 = 4205; - // public const UInt16 MaximumGridCurrentRmsL3 = 4206; - // public const UInt16 CosPhiSetValueL1 = 4207; - // public const UInt16 CosPhiSetValueL2 = 4208; - // public const UInt16 CosPhiSetValueL3 = 4209; - // public const UInt16 PhaseL1IsCapacitive = 4214; // True = Capacitive, false = Inductive - // public const UInt16 PhaseL2IsCapacitive = 4215; // True = Capacitive, false = Inductive - // public const UInt16 PhaseL3IsCapacitive = 4216; // True = Capacitive, false = Inductive - // public const UInt16 PhasesAreCapacitive = 4217; // True = Capacitive, false = Inductive - // public const UInt16 SetPointCosPhi = 4218; - // public const UInt16 SetPointSinPhi = 4219; - // public const UInt16 SetPointSinPhiL1 = 4220; - // public const UInt16 SetPointSinPhiL2 = 4221; - // public const UInt16 SetPointSinPhiL3 = 4222; - // public const UInt16 FrequencyOffsetIm = 4223; //Im: Island mode - // public const UInt16 VoltageAdjustmentFactorIm = 4224; //Im: Island mode - // public const UInt16 PreChargeDcLinkVoltage = 4226; - // public const UInt16 MaxPeakCurrentVoltageControlL1 = 4227; - // public const UInt16 MaxPeakCurrentVoltageControlL2 = 4228; - // public const UInt16 MaxPeakCurrentVoltageControlL3 = 4229; - // public const UInt16 GridFormingMode = 4230; - // public const UInt16 DcLinkReferenceVoltage = 4231; - // public const UInt16 DcLinkMinVoltage = 4232; - // public const UInt16 DcLinkMaxVoltage = 4233; - // public const UInt16 AcDcDcVoltageRefUs = 4234; - // public const UInt16 AcDcMinDcLinkVoltageUs = 4235; - // public const UInt16 AcDcMaxDcLinkVoltageUs = 4236; - // // public const UInt16 FrequencySlopeIslandMode = 4237, // Function fN = f(active grid-power) of droop control - // // public const UInt16 VoltageSlopeIslandMode = 4238, // VN = f(reactive grid power) of droop control in island operation. - // public const UInt16 AcDcGcBypassMode = 4281; - // public const UInt16 AcDcGcPMaxThresholdPercent = 4282; // res - // public const UInt16 AcDcGcStartupRampEnable = 4283; - // public const UInt16 DcConfigModule = 4301; // 0 = DC module is off, battery voltage can be measured - // // 1 = DC module is active (DC link voltage control) - // // 2 = DC module is active(current source mode orin DC droop mode) - // public const UInt16 DcDcPowerDistribution = 4304; - // public const UInt16 AcDcDistributionMode = 4307; -} - - diff --git a/csharp/Lib/Devices/Trumpf/TruConvert/AlarmState.cs b/csharp/Lib/Devices/Trumpf/TruConvert/AlarmState.cs deleted file mode 100644 index 7417d9af3..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvert/AlarmState.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert; - -public enum InverterAlarmState : UInt16 -{ - AlarmOff = 0, - ResetAlarmAc = 1, -} - -public enum DcAlarmState : UInt16 -{ - AlarmOff = 0, - ResetAlarmDc = 1, -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvert/Slave.cs b/csharp/Lib/Devices/Trumpf/TruConvert/Slave.cs deleted file mode 100644 index 702fb1f62..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvert/Slave.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert; - -public static class Slave -{ - public const UInt16 Broadcast = 0; -} - - diff --git a/csharp/Lib/Devices/Trumpf/TruConvert/TruConvert.csproj b/csharp/Lib/Devices/Trumpf/TruConvert/TruConvert.csproj index a4f729801..517a59172 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvert/TruConvert.csproj +++ b/csharp/Lib/Devices/Trumpf/TruConvert/TruConvert.csproj @@ -7,6 +7,7 @@ + diff --git a/csharp/Lib/Devices/Trumpf/TruConvert/Utils.cs b/csharp/Lib/Devices/Trumpf/TruConvert/Utils.cs deleted file mode 100644 index 91ba7993f..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvert/Utils.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert; - -public static class Utils -{ - public static UInt16[] ToUInt16(this IEnumerable regs, Decimal resolution) - { - // LINQ - return regs - .Select(v => (Int16)(v / resolution)) - .Select(v => unchecked((UInt16)v)) - .ToArray(); - } -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/AcControlRegisters.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcControlRegisters.cs deleted file mode 100644 index 61205ca7c..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/AcControlRegisters.cs +++ /dev/null @@ -1,80 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; - -public static class AcControlRegisters -{ - public const UInt16 Date = 1001; - public const UInt16 Time = 1003; - public const UInt16 IpAddress = 1005; - public const UInt16 Subnet = 1007; - public const UInt16 Gateway = 1009; - public const UInt16 ResetParamToDefault = 1011; - public const UInt16 CommunicationTimeout = 1017; - public const UInt16 RestartFlag = 1018; - public const UInt16 ConnectedSystemConfig = 1019; - public const UInt16 UpdateSwTrigger = 1027; - public const UInt16 AutomaticSwUpdate = 1028; - public const UInt16 CustomerValuesSaveReset = 1029; - public const UInt16 SerialNumberSystemControl = 2001; - public const UInt16 SerialNumberAcDc = 2009; - public const UInt16 IntegrationLevel = 2051; - public const UInt16 IlBuildnumber = 2052; - public const UInt16 PowerStageConfig = 4001; - public const UInt16 SetValueConfig = 4002; - public const UInt16 ResetsAlarmAndWarning = 4003; - public const UInt16 PreChargeDcLinkConfigR = 4006; - public const UInt16 ReferenceFrameConvention = 4007; - public const UInt16 SlaveAddress = 4008; - public const UInt16 ErrorHandlingPolicy = 4009; - public const UInt16 GridType = 4010; - public const UInt16 SubSlaveAddress = 4011; - public const UInt16 ModbusSlaveId = 4012; - public const UInt16 SubSlaveErrorPolicy = 4013; - public const UInt16 SignedPowerNominalValue = 4196; - public const UInt16 SignedPowerSetValueL1 = 4197; - public const UInt16 SignedPowerSetValueL2 = 4198; - public const UInt16 SignedPowerSetValueL3 = 4199; - public const UInt16 PowerSetValue = 4200; - public const UInt16 PowerSetValueL1 = 4201; - public const UInt16 PowerSetValueL2 = 4202; - public const UInt16 PowerSetValueL3 = 4203; - public const UInt16 MaximumGridCurrentRmsL1 = 4204; - public const UInt16 MaximumGridCurrentRmsL2 = 4205; - public const UInt16 MaximumGridCurrentRmsL3 = 4206; - public const UInt16 CosPhiSetValueL1 = 4207; - public const UInt16 CosPhiSetValueL2 = 4208; - public const UInt16 CosPhiSetValueL3 = 4209; - public const UInt16 PhaseL1IsCapacitive = 4214; // True = Capacitive, false = Inductive - public const UInt16 PhaseL2IsCapacitive = 4215; // True = Capacitive, false = Inductive - public const UInt16 PhaseL3IsCapacitive = 4216; // True = Capacitive, false = Inductive - public const UInt16 PhasesAreCapacitive = 4217; // True = Capacitive, false = Inductive - public const UInt16 SetPointCosPhi = 4218; - public const UInt16 SetPointSinPhi = 4219; - public const UInt16 SetPointSinPhiL1 = 4220; - public const UInt16 SetPointSinPhiL2 = 4221; - public const UInt16 SetPointSinPhiL3 = 4222; - public const UInt16 FrequencyOffsetIm = 4223; //Im: Island mode - public const UInt16 VoltageAdjustmentFactorIm = 4224; //Im: Island mode - public const UInt16 PreChargeDcLinkVoltage = 4226; - public const UInt16 MaxPeakCurrentVoltageControlL1 = 4227; - public const UInt16 MaxPeakCurrentVoltageControlL2 = 4228; - public const UInt16 MaxPeakCurrentVoltageControlL3 = 4229; - public const UInt16 GridFormingMode = 4230; - public const UInt16 DcLinkReferenceVoltage = 4231; - public const UInt16 DcLinkMinVoltage = 4232; - public const UInt16 DcLinkMaxVoltage = 4233; - public const UInt16 AcDcDcVoltageRefUs = 4234; - public const UInt16 AcDcMinDcLinkVoltageUs = 4235; - public const UInt16 AcDcMaxDcLinkVoltageUs = 4236; - // public const UInt16 FrequencySlopeIslandMode = 4237, // Function fN = f(active grid-power) of droop control - // public const UInt16 VoltageSlopeIslandMode = 4238, // VN = f(reactive grid power) of droop control in island operation. - public const UInt16 AcDcGcBypassMode = 4281; - public const UInt16 AcDcGcPMaxThresholdPercent = 4282; // res - public const UInt16 AcDcGcStartupRampEnable = 4283; - public const UInt16 DcConfigModule = 4301; // 0 = DC module is off, battery voltage can be measured - // 1 = DC module is active (DC link voltage control) - // 2 = DC module is active(current source mode orin DC droop mode) - public const UInt16 DcDcPowerDistribution = 4304; - public const UInt16 AcDcDistributionMode = 4307; -} - - diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcDevicesRecord.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcDevicesRecord.cs new file mode 100644 index 000000000..cae0fbb1c --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcDevicesRecord.cs @@ -0,0 +1,70 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; +using InnovEnergy.Lib.StatusApi.DeviceTypes; +using InnovEnergy.Lib.Units.Composite; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; + +public class AcDcDevicesRecord : IAcDc3 +{ + + // private static readonly AcPhase NoAcPhase = Ac3Bus.FromPhasesAndFrequency() + // private static readonly Ac3Bus NoAcDevice = Ac3Bus.FromPhasesAndFrequency() + + public AcDcDevicesRecord(SystemControlRegisters? systemControl, IReadOnlyList devices) + { + SystemControl = systemControl; + Devices = devices; + } + + public SystemControlRegisters? SystemControl { get; } + public IReadOnlyList Devices { get; init; } + + public IEnumerable Alarms => Devices.SelectMany(d => d.Status.Alarms).Distinct(); + public IEnumerable Warnings => Devices.SelectMany(d => d.Status.Warnings).Distinct(); + + public Ac3Bus Ac + { + get + { + if (Devices.Count == 0) + return Ac3Bus.Null; + + var l1 = AcPhase.FromVoltageCurrentActiveReactive + ( + voltageRms : Devices.Average(d => d.Status.Ac.L1.Voltage), + currentRms : Devices.Sum(d => d.Status.Ac.L1.Current), + activePower : Devices.Sum(d => d.Status.Ac.L1.Power.Active), + reactivePower: Devices.Sum(d => d.Status.Ac.L1.Power.Reactive) + ); + + var l2 = AcPhase.FromVoltageCurrentActiveReactive + ( + voltageRms : Devices.Average(d => d.Status.Ac.L2.Voltage), + currentRms : Devices.Sum(d => d.Status.Ac.L2.Current), + activePower : Devices.Sum(d => d.Status.Ac.L2.Power.Active), + reactivePower: Devices.Sum(d => d.Status.Ac.L2.Power.Reactive) + ); + + var l3 = AcPhase.FromVoltageCurrentActiveReactive + ( + voltageRms : Devices.Average(d => d.Status.Ac.L3.Voltage), + currentRms : Devices.Sum(d => d.Status.Ac.L3.Current), + activePower : Devices.Sum(d => d.Status.Ac.L3.Power.Active), + reactivePower: Devices.Sum(d => d.Status.Ac.L3.Power.Reactive) + ); + + var f = Devices.Average(d => d.Status.Ac.Frequency); + + return Ac3Bus.FromPhasesAndFrequency(l1, l2, l3, f); + } + } + + public DcBus Dc => Devices.Count == 0 + ? DcBus.Null + : DcBus.FromVoltageCurrent + ( + voltage: Devices.Average(d => d.Status.Dc.Voltage), + current: Devices.Sum(d => d.Status.Dc.Current) + ); +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcRecord.Modbus.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcRecord.Modbus.cs new file mode 100644 index 000000000..c27cc0208 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcRecord.Modbus.cs @@ -0,0 +1,159 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; +using InnovEnergy.Lib.Protocols.Modbus.Reflection.Attributes; +using AlarmMessage = InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes.AlarmMessage; +using WarningMessage = InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes.WarningMessage; + +#pragma warning disable CS0649 + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; + + +public partial class AcDcRecord +{ + [HoldingRegister(4000)] internal Boolean PowerStageEnable; + [HoldingRegister(4001)] internal PhaseControl PhaseControl; + [HoldingRegister(4002)] internal Boolean ResetAlarmsAndWarnings; + + [HoldingRegister(4005)] internal DcPrechargeConfig DcPrechargeConfig; + + [HoldingRegister(4009)] internal GridType GridType; + [HoldingRegister(4200)] internal Double PowerSetpointL1; // VA + [HoldingRegister(4201)] internal Double PowerSetpointL2; // VA + [HoldingRegister(4202)] internal Double PowerSetpointL3; // VA + + [HoldingRegister(4206)] internal Double CosPhiSetpointL1; + [HoldingRegister(4207)] internal Double CosPhiSetpointL2; + [HoldingRegister(4208)] internal Double CosPhiSetpointL3; + + [HoldingRegister(4219)] internal Double SinPhiSetpointL1; + [HoldingRegister(4220)] internal Double SinPhiSetpointL2; + [HoldingRegister(4221)] internal Double SinPhiSetpointL3; + + [HoldingRegister(4213)] internal ReactivePowerKind ReactivePowerKindL1; + [HoldingRegister(4214)] internal ReactivePowerKind ReactivePowerKindL2; + [HoldingRegister(4215)] internal ReactivePowerKind ReactivePowerKindL3; + + [HoldingRegister(4222, Scale = .01)] internal Double IslandModeFrequencyOffset; + [HoldingRegister(4223)] internal Double IslandModeVoltageAdjustmentFactor; + + [HoldingRegister(4229)] internal GridMode GridMode; + + [HoldingRegister(4230)] internal Double DcLinkReferenceVoltage380400VGrid; + [HoldingRegister(4231)] internal Double DcLinkMinVoltage380400VGrid; + [HoldingRegister(4232)] internal Double DcLinkMaxVoltage380400VGrid; + + [HoldingRegister(4233)] internal Double DcLinkReferenceVoltage480VGrid; + [HoldingRegister(4234)] internal Double DcLinkMinVoltage480VGrid; + [HoldingRegister(4235)] internal Double DcLinkMaxVoltage480VGrid; + + + [InputRegister(5023)] internal readonly GridType ActiveGridType; + [InputRegister(5024)] internal readonly PowerLimit PowerLimitedBy; + + [InputRegister(5030)] internal readonly InverterState InverterState; + [InputRegister(5031)] internal readonly InverterState StateOnLastAlarm; + + [InputRegister(5025)] internal readonly Double DcReferenceVoltage; + [InputRegister(5026)] internal readonly Double DcMinVoltage; + [InputRegister(5027)] internal readonly Double DcMaxVoltage; + [InputRegister(5028, Scale = .01)] internal readonly Double DcHalfVoltageThreshold; + + [InputRegister(5020, Scale = .1)] internal readonly Double NominalAcFrequency; + [InputRegister(5021)] internal readonly Double NominalAcVoltage; + [InputRegister(5022)] internal readonly Double NominalPower; + + [InputRegister(5130)] internal readonly Double ApparentPowerL1; + [InputRegister(5131)] internal readonly Double ApparentPowerL2; + [InputRegister(5132)] internal readonly Double ApparentPowerL3; + + [InputRegister(5133, Scale = .1)] internal readonly Double OverloadCapacityL1; + [InputRegister(5134, Scale = .1)] internal readonly Double OverloadCapacityL2; + [InputRegister(5135, Scale = .1)] internal readonly Double OverloadCapacityL3; + + [InputRegister(5140)] internal readonly Double ActivePowerL1; + [InputRegister(5141)] internal readonly Double ActivePowerL2; + [InputRegister(5142)] internal readonly Double ActivePowerL3; + + [InputRegister(5231)] internal readonly Double ReactivePowerL1; + [InputRegister(5232)] internal readonly Double ReactivePowerL2; + [InputRegister(5233)] internal readonly Double ReactivePowerL3; + + [InputRegister(5100, Scale = .01)] internal readonly Double BatteryVoltage; + [InputRegister(5110)] internal readonly Double BatteryCurrent; + + [InputRegister(5150, Scale = .01)] internal readonly Double GridCurrentL1; + [InputRegister(5151, Scale = .01)] internal readonly Double GridCurrentL2; + [InputRegister(5152, Scale = .01)] internal readonly Double GridCurrentL3; + + [InputRegister(5160, Scale = .1)] internal readonly Double GridVoltageL1; + [InputRegister(5161, Scale = .1)] internal readonly Double GridVoltageL2; + [InputRegister(5162, Scale = .1)] internal readonly Double GridVoltageL3; + + [InputRegister(5170, Scale = .01)] internal readonly Double CosPhiL1;// TODO: check that those agree with computed ones in AC + [InputRegister(5171, Scale = .01)] internal readonly Double CosPhiL2;// TODO: remove + [InputRegister(5172, Scale = .01)] internal readonly Double CosPhiL3; + + [InputRegister(5200, Scale = .01)] internal readonly Double GridFrequency;// Grid freq in doc + + [InputRegister(5210)] internal readonly Double InternDcVoltageUpperHalf; + [InputRegister(5211)] internal readonly Double InternDcVoltageLowerHalf; + [InputRegister(5220, Scale = .1)] internal readonly Double InternVoltageNToPe; + + [InputRegister(5212)] internal readonly Double ExternDcVoltageUpperHalf; + [InputRegister(5213)] internal readonly Double ExternDcVoltageLowerHalf; + [InputRegister(5221, Scale = .1)] internal readonly Double ExternVoltageNToPe; + + [InputRegister(5500, Scale = .1)] internal readonly Double InletAirTemperature; + [InputRegister(5501, Scale = .1)] internal readonly Double IgbtL1Temperature; + [InputRegister(5502, Scale = .1)] internal readonly Double IgbtL2Temperature; + [InputRegister(5503, Scale = .1)] internal readonly Double IgbtL3Temperature; + [InputRegister(5504, Scale = .1)] internal readonly Double IgbtBalancerTemperature; + + [InputRegister(2809)] internal readonly UInt16 NumberOfAlarms; + + [InputRegister(2810)] internal readonly AlarmMessage Alarm1; + [InputRegister(2811)] internal readonly AlarmMessage Alarm2; + [InputRegister(2812)] internal readonly AlarmMessage Alarm3; + [InputRegister(2813)] internal readonly AlarmMessage Alarm4; + [InputRegister(2814)] internal readonly AlarmMessage Alarm5; + [InputRegister(2815)] internal readonly AlarmMessage Alarm6; + [InputRegister(2816)] internal readonly AlarmMessage Alarm7; + [InputRegister(2817)] internal readonly AlarmMessage Alarm8; + [InputRegister(2818)] internal readonly AlarmMessage Alarm9; + [InputRegister(2819)] internal readonly AlarmMessage Alarm10; + [InputRegister(2820)] internal readonly AlarmMessage Alarm11; + [InputRegister(2821)] internal readonly AlarmMessage Alarm12; + [InputRegister(2822)] internal readonly AlarmMessage Alarm13; + [InputRegister(2823)] internal readonly AlarmMessage Alarm14; + [InputRegister(2824)] internal readonly AlarmMessage Alarm15; + [InputRegister(2825)] internal readonly AlarmMessage Alarm16; + [InputRegister(2826)] internal readonly AlarmMessage Alarm17; + [InputRegister(2827)] internal readonly AlarmMessage Alarm18; + [InputRegister(2828)] internal readonly AlarmMessage Alarm19; + [InputRegister(2829)] internal readonly AlarmMessage Alarm20; + + + [InputRegister(2402)] internal readonly UInt16 NumberOfWarnings; + + [InputRegister(2403)] internal readonly WarningMessage Warning1; + [InputRegister(2404)] internal readonly WarningMessage Warning2; + [InputRegister(2405)] internal readonly WarningMessage Warning3; + [InputRegister(2406)] internal readonly WarningMessage Warning4; + [InputRegister(2407)] internal readonly WarningMessage Warning5; + [InputRegister(2408)] internal readonly WarningMessage Warning6; + [InputRegister(2409)] internal readonly WarningMessage Warning7; + [InputRegister(2410)] internal readonly WarningMessage Warning8; + [InputRegister(2411)] internal readonly WarningMessage Warning9; + [InputRegister(2412)] internal readonly WarningMessage Warning10; + [InputRegister(2413)] internal readonly WarningMessage Warning11; + [InputRegister(2414)] internal readonly WarningMessage Warning12; + [InputRegister(2415)] internal readonly WarningMessage Warning13; + [InputRegister(2416)] internal readonly WarningMessage Warning14; + [InputRegister(2417)] internal readonly WarningMessage Warning15; + [InputRegister(2418)] internal readonly WarningMessage Warning16; + [InputRegister(2419)] internal readonly WarningMessage Warning17; + [InputRegister(2420)] internal readonly WarningMessage Warning18; + [InputRegister(2421)] internal readonly WarningMessage Warning19; + [InputRegister(2422)] internal readonly WarningMessage Warning20; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcRecord.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcRecord.cs new file mode 100644 index 000000000..9d5f452f7 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/AcDcRecord.cs @@ -0,0 +1,10 @@ +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Control; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; + +public partial class AcDcRecord +{ + public AcDcStatus Status => new(this); + public AcDcControl Control => new(this); +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcControl.cs new file mode 100644 index 000000000..07c2f0056 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcControl.cs @@ -0,0 +1,35 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Control; + +public class AcControl +{ + public AcPowerControl Power => new (_Self); + + public PhaseControl PhaseControl + { + get => _Self.PhaseControl; + set => _Self.PhaseControl = value; + } + + public GridType GridType + { + get => _Self.GridType; + set + { + _Self.GridType = value; + _Self.GridMode = value switch + { + GridType.Island400V50Hz => GridMode.Island, + GridType.Island480V60Hz => GridMode.Island, + _ => GridMode.GridTied + }; + } + } + + public IslandMode IslandMode => new(_Self); + + internal AcControl(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcDcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcDcControl.cs new file mode 100644 index 000000000..0ffae612c --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcDcControl.cs @@ -0,0 +1,23 @@ + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Control; + +public class AcDcControl +{ + public AcControl Ac => new (_Self); + public DcControl Dc => new (_Self); + + public Boolean PowerStageEnable + { + get => _Self.PowerStageEnable; + set => _Self.PowerStageEnable = value; + } + + public Boolean ResetAlarmsAndWarnings + { + get => _Self.ResetAlarmsAndWarnings; + set => _Self.ResetAlarmsAndWarnings = value; + } + + internal AcDcControl(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcPowerControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcPowerControl.cs new file mode 100644 index 000000000..a23b522ee --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/AcPowerControl.cs @@ -0,0 +1,97 @@ +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; +using InnovEnergy.Lib.Units.Composite; +using InnovEnergy.Lib.Utils; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Control; + +public class AcPowerControl +{ + public AcPower L1 + { + get + { + var s = _Self.PowerSetpointL1; + var cosPhi = _Self.CosPhiSetpointL1.Clamp(-1, 1); + var rpk = _Self.ReactivePowerKindL1; + var phi = cosPhi.Apply(Math.Acos) * (rpk == ReactivePowerKind.Inductive ? 1 : -1); + var sinPhi = Math.Sin(phi); + + return AcPower.FromActiveReactive(s * cosPhi, s * sinPhi); + } + + set + { + _Self.PowerSetpointL1 = value.Apparent.Value; + _Self.CosPhiSetpointL1 = value.CosPhi; + _Self.SinPhiSetpointL1 = Math.Sin(value.Phi); + _Self.ReactivePowerKindL1 = value.Reactive >= 0 + ? ReactivePowerKind.Inductive + : ReactivePowerKind.Capacitive; + } + } + + + public AcPower L2 + { + get + { + var s = _Self.PowerSetpointL2; + var cosPhi = _Self.CosPhiSetpointL2.Clamp(-1, 1); + var rpk = _Self.ReactivePowerKindL2; + var phi = cosPhi.Apply(Math.Acos) * (rpk == ReactivePowerKind.Inductive ? 1 : -1); + var sinPhi = Math.Sin(phi); + + return AcPower.FromActiveReactive(s * cosPhi, s * sinPhi); + } + + set + { + _Self.PowerSetpointL2 = value.Apparent.Value; + _Self.CosPhiSetpointL2 = value.CosPhi; + _Self.SinPhiSetpointL2 = Math.Sin(value.Phi); + _Self.ReactivePowerKindL2 = value.Reactive >= 0 + ? ReactivePowerKind.Inductive + : ReactivePowerKind.Capacitive; + } + } + + public AcPower L3 + { + get + { + var s = _Self.PowerSetpointL3; + var cosPhi = _Self.CosPhiSetpointL3.Clamp(-1, 1); + var rpk = _Self.ReactivePowerKindL3; + var phi = cosPhi.Apply(Math.Acos) * (rpk == ReactivePowerKind.Inductive ? 1 : -1); + var sinPhi = Math.Sin(phi); + + return AcPower.FromActiveReactive(s * cosPhi, s * sinPhi); + } + + set + { + _Self.PowerSetpointL3 = value.Apparent.Value; + _Self.CosPhiSetpointL3 = value.CosPhi; + _Self.SinPhiSetpointL3 = Math.Sin(value.Phi); + _Self.ReactivePowerKindL3 = value.Reactive >= 0 + ? ReactivePowerKind.Inductive + : ReactivePowerKind.Capacitive; + } + } + + + internal AcPowerControl(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; + + // public IEnumerator GetEnumerator() + // { + // yield return L1; + // yield return L2; + // yield return L3; + // } + // + // IEnumerator IEnumerable.GetEnumerator() + // { + // return GetEnumerator(); + // } +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs new file mode 100644 index 000000000..baac43651 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs @@ -0,0 +1,45 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Control; + +public class DcControl +{ + public Voltage ReferenceVoltage + { + get => Is480V ? _Self.DcLinkReferenceVoltage480VGrid : _Self.DcLinkReferenceVoltage380400VGrid; + set + { + _Self.DcLinkReferenceVoltage480VGrid = value; + _Self.DcLinkReferenceVoltage380400VGrid = value; + } + } + + public Voltage MinVoltage + { + get => Is480V ? _Self.DcLinkMinVoltage480VGrid : _Self.DcLinkMinVoltage380400VGrid; + set + { + _Self.DcLinkMinVoltage480VGrid = value; + _Self.DcLinkMinVoltage380400VGrid = value; + } + } + + public Voltage MaxVoltage + { + get => Is480V ? _Self.DcLinkMaxVoltage480VGrid : _Self.DcLinkMaxVoltage380400VGrid; + set + { + _Self.DcLinkMaxVoltage480VGrid = value; + _Self.DcLinkMaxVoltage380400VGrid = value; + } + } + + public DcPrechargeConfig PrechargeConfig => _Self.DcPrechargeConfig; + + private Boolean Is480V => _Self.GridType is GridType.GridTied480V60Hz or GridType.Island480V60Hz; + + internal DcControl(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/IslandMode.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/IslandMode.cs new file mode 100644 index 000000000..694977730 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/IslandMode.cs @@ -0,0 +1,21 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Control; + +public class IslandMode +{ + public Frequency FrequencyOffset + { + get => _Self.IslandModeFrequencyOffset; + set => _Self.IslandModeFrequencyOffset = value; + } + + public Percent VoltageAdjustmentFactor + { + get => _Self.IslandModeVoltageAdjustmentFactor; + set => _Self.IslandModeVoltageAdjustmentFactor = value; + } + + internal IslandMode(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcControlRegisters.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcControlRegisters.cs new file mode 100644 index 000000000..4d6e1fc1c --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcControlRegisters.cs @@ -0,0 +1,80 @@ +// namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; +// +// public static class AcControlRegisters +// { +// public const UInt16 Date = 1001; +// public const UInt16 Time = 1003; +// public const UInt16 IpAddress = 1005; +// public const UInt16 Subnet = 1007; +// public const UInt16 Gateway = 1009; +// public const UInt16 ResetParamToDefault = 1011; +// public const UInt16 CommunicationTimeout = 1017; +// public const UInt16 RestartFlag = 1018; +// public const UInt16 ConnectedSystemConfig = 1019; +// public const UInt16 UpdateSwTrigger = 1027; +// public const UInt16 AutomaticSwUpdate = 1028; +// public const UInt16 CustomerValuesSaveReset = 1029; +// public const UInt16 SerialNumberSystemControl = 2001; +// public const UInt16 SerialNumberAcDc = 2009; +// public const UInt16 IntegrationLevel = 2051; +// public const UInt16 IlBuildnumber = 2052; +// public const UInt16 PowerStageConfig = 4001; +// public const UInt16 SetValueConfig = 4002; +// public const UInt16 ResetsAlarmAndWarning = 4003; +// public const UInt16 PreChargeDcLinkConfigR = 4006; +// public const UInt16 ReferenceFrameConvention = 4007; +// public const UInt16 SlaveAddress = 4008; +// public const UInt16 ErrorHandlingPolicy = 4009; +// public const UInt16 GridType = 4010; +// public const UInt16 SubSlaveAddress = 4011; +// public const UInt16 ModbusSlaveId = 4012; +// public const UInt16 SubSlaveErrorPolicy = 4013; +// public const UInt16 SignedPowerNominalValue = 4196; +// public const UInt16 SignedPowerSetValueL1 = 4197; +// public const UInt16 SignedPowerSetValueL2 = 4198; +// public const UInt16 SignedPowerSetValueL3 = 4199; +// public const UInt16 Powe0rSetValue = 4200; +// public const UInt16 PowerSetValueL1 = 4201; +// public const UInt16 PowerSetValueL2 = 4202; +// public const UInt16 PowerSetValueL3 = 4203; +// public const UInt16 MaximumGridCurrentRmsL1 = 4204; +// public const UInt16 MaximumGridCurrentRmsL2 = 4205; +// public const UInt16 MaximumGridCurrentRmsL3 = 4206; +// public const UInt16 CosPhiSetValueL1 = 4207; +// public const UInt16 CosPhiSetValueL2 = 4208; +// public const UInt16 CosPhiSetValueL3 = 4209; +// public const UInt16 PhaseL1IsCapacitive = 4214; // True = Capacitive, false = Inductive +// public const UInt16 PhaseL2IsCapacitive = 4215; // True = Capacitive, false = Inductive +// public const UInt16 PhaseL3IsCapacitive = 4216; // True = Capacitive, false = Inductive +// public const UInt16 PhasesAreCapacitive = 4217; // True = Capacitive, false = Inductive +// public const UInt16 SetPointCosPhi = 4218; +// public const UInt16 SetPointSinPhi = 4219; +// public const UInt16 SetPointSinPhiL1 = 4220; +// public const UInt16 SetPointSinPhiL2 = 4221; +// public const UInt16 SetPointSinPhiL3 = 4222; +// public const UInt16 FrequencyOffsetIm = 4223; //Im: Island mode +// public const UInt16 VoltageAdjustmentFactorIm = 4224; //Im: Island mode +// public const UInt16 PreChargeDcLinkVoltage = 4226; +// public const UInt16 MaxPeakCurrentVoltageControlL1 = 4227; +// public const UInt16 MaxPeakCurrentVoltageControlL2 = 4228; +// public const UInt16 MaxPeakCurrentVoltageControlL3 = 4229; +// public const UInt16 GridFormingMode = 4230; +// public const UInt16 DcLinkReferenceVoltage = 4231; +// public const UInt16 DcLinkMinVoltage = 4232; +// public const UInt16 DcLinkMaxVoltage = 4233; +// public const UInt16 AcDcDcVoltageRefUs = 4234; +// public const UInt16 AcDcMinDcLinkVoltageUs = 4235; +// public const UInt16 AcDcMaxDcLinkVoltageUs = 4236; +// // public const UInt16 FrequencySlopeIslandMode = 4237, // Function fN = f(active grid-power) of droop control +// // public const UInt16 VoltageSlopeIslandMode = 4238, // VN = f(reactive grid power) of droop control in island operation. +// public const UInt16 AcDcGcBypassMode = 4281; +// public const UInt16 AcDcGcPMaxThresholdPercent = 4282; // res +// public const UInt16 AcDcGcStartupRampEnable = 4283; +// public const UInt16 DcConfigModule = 4301; // 0 = DC module is off, battery voltage can be measured +// // 1 = DC module is active (DC link voltage control) +// // 2 = DC module is active(current source mode orin DC droop mode) +// public const UInt16 DcDcPowerDistribution = 4304; +// public const UInt16 AcDcDistributionMode = 4307; +// } +// +// diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcDcDistributionMode.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcDcDistributionMode.cs similarity index 69% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcDcDistributionMode.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcDcDistributionMode.cs index 80f6f625c..64a029118 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcDcDistributionMode.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcDcDistributionMode.cs @@ -1,4 +1,4 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum AcDcDistributionMode : UInt16 { diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcErrorPolicy.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcErrorPolicy.cs similarity index 77% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcErrorPolicy.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcErrorPolicy.cs index 8dd96d128..9033c779f 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/AcErrorPolicy.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AcErrorPolicy.cs @@ -1,4 +1,4 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum AcErrorPolicy : UInt16 { diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/AlarmMessage.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AlarmMessage.cs similarity index 86% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/AlarmMessage.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AlarmMessage.cs index df5535008..4d9476fd2 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/AlarmMessage.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/AlarmMessage.cs @@ -1,22 +1,12 @@ using System.Diagnostics.CodeAnalysis; -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; [SuppressMessage("ReSharper", "IdentifierTypo")] [SuppressMessage("ReSharper", "UnusedMember.Global")] [SuppressMessage("ReSharper", "CommentTypo")] -public enum AlarmMessage +public enum AlarmMessage : UInt16 { - NoAlarm = 0, - BmsCommunicationTimeoutHasOccured = 40302, // BMS communication timeout has occured. - Rs485CommunicationAlarm1 = 40303, // RS-485 communication alarm. - SoftwareVersionsOfSystemControlAndModulesDoNotMatch1 = 40412, // Software versions of system control and module(s) do not match. - SoftwareVersionsOfSystemControlAndModulesDoNotMatch2 = 40413, // Software versions of system control and module(s) do not match. - SoftwareVersionsOfSystemControlAndModulesDoNotMatch3 = 40414, // Software versions of system control and module(s) do not match. - SoftwareVersionsOfSystemControlAndModulesDoNotMatch4 = 40415, // Software versions of system control and module(s) do not match. - SoftwareVersionsOfSystemControlAndModulesDoNotMatch5 = 40416, // Software versions of system control and module(s) do not match. - NoSlaveModuleWasFoundPleaseCheckRs485Connection = 40304, // No slave module was found, please check RS-485 connection(s). - NumberOfOrCombinationOfConnectedSlaveTypesNotSupported = 40305, // Number of or combination of connected slave types not supported. OvertemperatureIgbtBridge1 = 50000, // Overtemperature IGBT bridge 1. OvertemperatureIgbtBridge2 = 50001, // Overtemperature IGBT bridge 2. OvertemperatureIgbtBridge3 = 50002, // Overtemperature IGBT bridge 3. diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs new file mode 100644 index 000000000..7eddb6be1 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs @@ -0,0 +1,9 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +public enum DcPrechargeConfig : UInt16 +{ + WaitForExternalPrecharge = 0, + PrechargeDcWithSystemCtl = 1, + PrechargeDcWithDcDcs = 2, + PrechargeDcWithSystemCtlAndWait = 3, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/DcStageConfiguration.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcStageConfiguration.cs similarity index 89% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/DcStageConfiguration.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcStageConfiguration.cs index 32ee16596..58a6e58e9 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/DcStageConfiguration.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcStageConfiguration.cs @@ -1,4 +1,4 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum DcStageConfiguration : UInt16 { diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/GridMode.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/GridMode.cs new file mode 100644 index 000000000..6ac2cca49 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/GridMode.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +public enum GridMode +{ + GridTied = 0, + Island = 1 +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/InverterState.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/InverterState.cs new file mode 100644 index 000000000..f1adab68b --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/InverterState.cs @@ -0,0 +1,13 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +public enum InverterState : UInt16 +{ + Idle = 0, + DcLinkChargeDischargeTest = 1, + DcLinkSyncToExt = 2, + DcLinkCharge = 3, + AcSyncToGrid = 4, + AcCloseContactor = 5, + AcConnected = 6, + Alarm = 99 +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PhaseControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PhaseControl.cs new file mode 100644 index 000000000..5c433899e --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PhaseControl.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +public enum PhaseControl : Byte +{ + Asymmetric = 0, + Symmetric = 1, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/PowerFactorConvention.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PowerFactorConvention.cs similarity index 69% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/PowerFactorConvention.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PowerFactorConvention.cs index cfdaec558..7134db9a8 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/PowerFactorConvention.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PowerFactorConvention.cs @@ -1,4 +1,4 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum PowerFactorConvention : UInt16 { diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PowerLimit.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PowerLimit.cs new file mode 100644 index 000000000..39f6be32f --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PowerLimit.cs @@ -0,0 +1,10 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +public enum PowerLimit : UInt16 +{ + Nothing = 0, + DcLink = 1, + GridCode = 2, + Overload = 3, + Temperature = 4, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/PreChargeDcLinkConfig.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PreChargeDcLinkConfig.cs similarity index 88% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/PreChargeDcLinkConfig.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PreChargeDcLinkConfig.cs index 206c656fd..1f53d038e 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/PreChargeDcLinkConfig.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/PreChargeDcLinkConfig.cs @@ -1,4 +1,4 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum PreChargeDcLinkConfig : UInt16 { diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/ReactivePowerKind.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/ReactivePowerKind.cs new file mode 100644 index 000000000..52a0ac452 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/ReactivePowerKind.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +public enum ReactivePowerKind +{ + Inductive = 0, + Capacitive = 1 +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/SymmetricAcOperationMode.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/SymmetricAcOperationMode.cs similarity index 68% rename from csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/SymmetricAcOperationMode.cs rename to csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/SymmetricAcOperationMode.cs index df9d01eca..ce1767c40 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/SymmetricAcOperationMode.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/SymmetricAcOperationMode.cs @@ -1,4 +1,4 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum SymmetricAcOperationMode : UInt16 { diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/WarningMessage.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/WarningMessage.cs new file mode 100644 index 000000000..11ec4cdd2 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/WarningMessage.cs @@ -0,0 +1,32 @@ +using System.Diagnostics.CodeAnalysis; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +[SuppressMessage("ReSharper", "IdentifierTypo")] +[SuppressMessage("ReSharper", "UnusedMember.Global")] +[SuppressMessage("ReSharper", "CommentTypo")] + +public enum WarningMessage : UInt16 +{ + NoWarning = 00000, + + /* + + // these warnings are not official (not in the manual), and they seem to collide with the DCDC warnings + // so I commented them + + Fan = 10500, //AC-DC module warning + IOffset = 10503, //AC-DC module warning + VgOffset = 10504, //AC-DC module warning + VcOffset = 10505, //AC-DC module warning + DcOffset = 10506, //AC-DC module warning + NtcProtect = 10507, //DC-link circuit need more time for cool down + AirTemp = 10508, //Overtemperature inlet air: power is derated + SurgeDetected = 10509, //Temporary overvoltage in grid measurement detected (surge) + TempDerating = 11021, //Temperature derating active + Overload = 11022, //Overload handling is active + RuntimeEeprom = 11023, //AC-DC module warning + Overcurrent = 11024 //Overcurrent handling is active + + */ +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/SubSlavesErrorPolicy.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/SubSlavesErrorPolicy.cs deleted file mode 100644 index 190072c0c..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Enums/SubSlavesErrorPolicy.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; - -public enum SubSlavesErrorPolicy : UInt16 -{ - Strict = 0, // (AC-DC module switches to error state if at least one submodules is in error state - Relaxed = 1, // (AC-DC module switches to error state if all submodules are in error state.) - Off = 2, // (If possible AC-DC module continues operation even if all submodules are in error state. -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Program.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Program.cs new file mode 100644 index 000000000..6af219c56 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Program.cs @@ -0,0 +1,61 @@ +// using InnovEnergy.Lib.Devices.Trumpf.SystemControl; +// using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +// using InnovEnergy.Lib.Units; +// using InnovEnergy.Lib.Utils; +// +// namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; +// +// // TODO :remove +// +// public static class Program +// { +// public static void Main(String[] args) +// { +// var sc = new SystemControlDevice("localhost", 5001); +// var acDc1 = sc.AcDcSlave(1); +// var acDc2 = sc.AcDcSlave(2); +// +// +// while (true) +// { +// "================================================".WriteLine(); +// +// var r = sc.Read(); +// +// Console.WriteLine(DateTime.Now); +// r.ToString().Replace(",", "\n").Replace(" {", "\n").WriteLine("\n"); +// +// var c = r with +// { +// UseSlaveIdForAddressing = true, +// ReferenceFrame = ReferenceFrame.Consumer, +// GridType = GridType.GridTied400V50Hz, +// SystemConfig = SystemConfig.AcDcAndDcDc, +// CommunicationTimeout = null, +// SlaveErrorHandling = SlaveErrorHandling.Relaxed, +// SubSlaveErrorHandling = SubSlaveErrorHandling.Off +// }; +// +// sc.Write(c); +// +// var s1 = acDc1.Read(); +// +// s1.ToCsv().Replace(",", "\n").Replace(" {", "\n").WriteLine("\n"); +// +// +// s1.ResetAlarmsAndWarnings = true; +// s1.PowerStageEnable = true; +// +// acDc1.Write(s1); +// +// var s2 = acDc2.Read(); +// +// +// s2.ToString().Replace(",", "\n").Replace(" {", "\n").WriteLine("\n"); +// +// acDc2.Write(s2 with { ResetAlarmsAndWarnings = true, PowerStageEnable = true }); +// } +// +// +// } +// } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/AcDcStatus.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/AcDcStatus.cs new file mode 100644 index 000000000..88f27bf09 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/AcDcStatus.cs @@ -0,0 +1,110 @@ + +using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; +using InnovEnergy.Lib.Units.Composite; +using AlarmMessage = InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes.AlarmMessage; +using WarningMessage = InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes.WarningMessage; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class AcDcStatus +{ + public Ac3Bus Ac => Ac3Bus.FromPhasesAndFrequency(L1, L2, L3, _Self.GridFrequency); + public DcBus Dc => DcBus.FromVoltageCurrent(_Self.BatteryVoltage, _Self.BatteryCurrent); + public PowerLimit PowerLimitedBy => _Self.PowerLimitedBy; + public InverterStates InverterState => new(_Self); + public GridType ActiveGridType => _Self.ActiveGridType; + public Voltages Voltage => new(_Self); + public Temperatures Temperature => new(_Self); + public OverloadCapacity OverloadCapacity => new(_Self); + public Nominals Nominal => new(_Self); + + public IReadOnlyList Alarms => GetAlarms ().Take(_Self.NumberOfAlarms ).Where(IsAcDcAlarm ).ToList(); + public IReadOnlyList Warnings => GetWarnings().Take(_Self.NumberOfWarnings).Where(IsAcDcWarning).ToList(); + + private IEnumerable GetAlarms() + { + yield return _Self.Alarm1; + yield return _Self.Alarm2; + yield return _Self.Alarm3; + yield return _Self.Alarm4; + yield return _Self.Alarm5; + yield return _Self.Alarm6; + yield return _Self.Alarm7; + yield return _Self.Alarm8; + yield return _Self.Alarm9; + yield return _Self.Alarm10; + yield return _Self.Alarm11; + yield return _Self.Alarm12; + yield return _Self.Alarm13; + yield return _Self.Alarm14; + yield return _Self.Alarm15; + yield return _Self.Alarm16; + yield return _Self.Alarm17; + yield return _Self.Alarm18; + yield return _Self.Alarm19; + yield return _Self.Alarm20; + } + + private static Boolean IsAcDcAlarm(AlarmMessage alarm) => (UInt16)alarm is >= 50000 and < 60000; + + private IEnumerable GetWarnings() + { + yield return _Self.Warning1; + yield return _Self.Warning2; + yield return _Self.Warning3; + yield return _Self.Warning4; + yield return _Self.Warning5; + yield return _Self.Warning6; + yield return _Self.Warning7; + yield return _Self.Warning8; + yield return _Self.Warning9; + yield return _Self.Warning10; + yield return _Self.Warning11; + yield return _Self.Warning12; + yield return _Self.Warning13; + yield return _Self.Warning14; + yield return _Self.Warning15; + yield return _Self.Warning16; + yield return _Self.Warning17; + yield return _Self.Warning18; + yield return _Self.Warning19; + yield return _Self.Warning20; + } + + // TODO: there are no AcDc Warnings defined in doc + private static Boolean IsAcDcWarning(WarningMessage warning) => warning != WarningMessage.NoWarning; + + private AcPhase L1 => AcPhase.FromVoltageCurrentActiveReactiveApparent + ( + voltageRms : _Self.GridVoltageL1, + currentRms : _Self.GridCurrentL1, + activePower : _Self.ActivePowerL1, + reactivePower: _Self.ReactivePowerL1, + apparentPower: _Self.ApparentPowerL1 + ); + + private AcPhase L2 => AcPhase.FromVoltageCurrentActiveReactiveApparent + ( + voltageRms : _Self.GridVoltageL2, + currentRms : _Self.GridCurrentL2, + activePower : _Self.ActivePowerL2, + reactivePower: _Self.ReactivePowerL2, + apparentPower: _Self.ApparentPowerL2 + ); + + private AcPhase L3 => AcPhase.FromVoltageCurrentActiveReactiveApparent + ( + voltageRms : _Self.GridVoltageL3, + currentRms : _Self.GridCurrentL3, + activePower : _Self.ActivePowerL3, + reactivePower: _Self.ReactivePowerL3, + apparentPower: _Self.ApparentPowerL3 + ); + + + internal AcDcStatus(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; + +} + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/ExternVoltages.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/ExternVoltages.cs new file mode 100644 index 000000000..ec0c5e426 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/ExternVoltages.cs @@ -0,0 +1,13 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class ExternVoltages +{ + public Voltage DcUpperHalf => _Self.ExternDcVoltageUpperHalf; + public Voltage DcLowerHalf => _Self.ExternDcVoltageLowerHalf; + public Voltage NToPe => _Self.ExternVoltageNToPe; + + internal ExternVoltages(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/InternVoltages.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/InternVoltages.cs new file mode 100644 index 000000000..634e29c4b --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/InternVoltages.cs @@ -0,0 +1,13 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class InternVoltages +{ + public Voltage DcUpperHalf => _Self.InternDcVoltageUpperHalf; + public Voltage DcLowerHalf => _Self.InternDcVoltageLowerHalf; + public Voltage NToPe => _Self.InternVoltageNToPe; + + private readonly AcDcRecord _Self; + internal InternVoltages(AcDcRecord self) => _Self = self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/InverterStates.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/InverterStates.cs new file mode 100644 index 000000000..39bd1482c --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/InverterStates.cs @@ -0,0 +1,12 @@ +using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class InverterStates +{ + public InverterState Current => _Self.InverterState; + public InverterState OnLastAlarm => _Self.StateOnLastAlarm; + + internal InverterStates(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Nominals.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Nominals.cs new file mode 100644 index 000000000..6959419d9 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Nominals.cs @@ -0,0 +1,14 @@ +using InnovEnergy.Lib.Units; +using InnovEnergy.Lib.Units.Power; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class Nominals +{ + public Frequency AcFrequency => _Self.NominalAcFrequency; + public Voltage AcVoltage => _Self.NominalAcVoltage; + public DcPower Power => _Self.NominalPower; + + private readonly AcDcRecord _Self; + internal Nominals(AcDcRecord self) => _Self = self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/OverloadCapacity.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/OverloadCapacity.cs new file mode 100644 index 000000000..a49a9d2e3 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/OverloadCapacity.cs @@ -0,0 +1,13 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class OverloadCapacity +{ + public Percent L1 => _Self.OverloadCapacityL1; + public Percent L2 => _Self.OverloadCapacityL2; + public Percent L3 => _Self.OverloadCapacityL3; + + internal OverloadCapacity(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Temperatures.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Temperatures.cs new file mode 100644 index 000000000..06845ef5a --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Temperatures.cs @@ -0,0 +1,15 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + +public class Temperatures +{ + public Temperature InletAir => _Self.InletAirTemperature; + public Temperature IgbtL1 => _Self.IgbtL1Temperature; + public Temperature IgbtL2 => _Self.IgbtL2Temperature; + public Temperature IgbtL3 => _Self.IgbtL3Temperature; + public Temperature IgbtBalancer => _Self.IgbtBalancerTemperature; + + private readonly AcDcRecord _Self; + internal Temperatures(AcDcRecord self) => _Self = self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Voltages.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Voltages.cs new file mode 100644 index 000000000..feb1ce640 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Status/Voltages.cs @@ -0,0 +1,11 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Status; + + +public class Voltages +{ + public InternVoltages Intern => new(_Self); + public ExternVoltages Extern => new(_Self); + + internal Voltages(AcDcRecord self) => _Self = self; + private readonly AcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj index 34e08f495..85ad936c7 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj @@ -5,10 +5,12 @@ + + - + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs deleted file mode 100644 index 9844f5f5b..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs +++ /dev/null @@ -1,85 +0,0 @@ -using InnovEnergy.Lib.Devices.Trumpf.TruConvert; -using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; - -public record TruConvertAcControl -{ - private static readonly TimeSpan DefaultCommunicationTimeOut = TimeSpan.FromSeconds(10); - - public UInt32 Date { get; init;} - public UInt32 Time { get; init;} - public UInt32 IpAddress { get; init;} //= 0x C0A80102; - public UInt32 Subnet { get; init;} //= 0x FFFFFF00; - public UInt32 Gateway { get; init;} //= 0x C0A80102; - public Boolean ResetParamToDefault { get; init;} = false ; // Coil - public TimeSpan CommunicationTimeout { get; init;} = DefaultCommunicationTimeOut; - public Boolean FactoryResetParameters { get; init;} = false; - public SystemConfig ConnectedSystemConfig { get; init;} = 0; - public UInt16 UpdateSwTrigger { get; init;} = 0; - public UInt16 AutomaticSwUpdate { get; init;} = 0; - public UInt16 CustomerValuesSaveReset { get; init;} = 0; - public UInt16 SerialNumberSystemControl { get; init;} = 0; - public UInt16 SerialNumberAcDc { get; init;} = 0; - public UInt16 IntegrationLevel { get; init;} = 0; - public UInt16 IlBuildnumber { get; init;} = 0; - public Boolean PowerStageEnable { get; init;} = true; - public SymmetricAcOperationMode SetValueConfig { get; init;} = 0; - public Boolean ResetsAlarmAndWarning { get; init;} = false; - public PreChargeDcLinkConfig PreChargeDcLinkConfig { get; init;} = (PreChargeDcLinkConfig)0; - public PowerFactorConvention PowerFactorConvention { get; init;} = 0; //0 = producer - public UInt16 SlaveAddress { get; init;} = Slave.Broadcast; - public AcErrorPolicy ErrorHandlingPolicy { get; init;} = 0; - public AcDcGridType GridType { get; init;} = 0; - public UInt16 SubSlaveAddress { get; init;} = 0; - public Boolean UseModbusSlaveIdForAddressing { get; init;} = false; - public UInt16 SubSlaveErrorPolicy { get; init;} = 0; // must be an enum - public Decimal SignedPowerNominalValue { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal SignedPowerSetValueL1 { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal SignedPowerSetValueL2 { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal SignedPowerSetValueL3 { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal PowerSetValue { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal PowerSetValueL1 { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal PowerSetValueL2 { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal PowerSetValueL3 { get; init;} = 0; // resolution 0.001 and Unit kva, - public Decimal MaximumGridCurrentRmsL1 { get; init;} = 0; // resolution : 0.01 - public Decimal MaximumGridCurrentRmsL2 { get; init;} = 0; // resolution : 0.01 - public Decimal MaximumGridCurrentRmsL3 { get; init;} = 0; // resolution : 0.01 - public Decimal CosPhiSetValueL1 { get; init;} = 0; // resolution : 0.01 - public Decimal CosPhiSetValueL2 { get; init;} = 0; // resolution : 0.01 - public Decimal CosPhiSetValueL3 { get; init;} = 0; // resolution : 0.01 - public Boolean PhaseL1IsCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - public Boolean PhaseL2IsCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - public Boolean PhaseL3IsCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - public Boolean PhasesAreCapacitive { get; init;} = true; // True = Capacitive, false = Inductive - public Double SetPointCosPhi { get; init;} = 0; // resolution 0.01 - public Double SetPointSinPhi { get; init;} = 0; // resolution 0.01 - public Double SetPointSinPhiL1 { get; init;} = 0; // resolution 0.01 - public Double SetPointSinPhiL2 { get; init;} = 0; // resolution 0.01 - public Double SetPointSinPhiL3 { get; init;} = 0; // resolution 0.01 - public Decimal FrequencyOffsetIm { get; init;} = 0; // resolution 0.01 - public UInt16 VoltageAdjustmentFactorIm { get; init;} = 0; - public UInt16 PreChargeDcLinkVoltage { get; init;} = 0; - public Decimal MaxPeakCurrentVoltageControlL1 { get; init;} = 0; // resolution 0.01 - public Decimal MaxPeakCurrentVoltageControlL2 { get; init;} = 0; // resolution 0.01 - public Decimal MaxPeakCurrentVoltageControlL3 { get; init;} = 0; // resolution 0.01 - public UInt16 GridFormingMode { get; init;} = 1; // 0 = not grid-forming (grid-tied) ,1 = grid-forming - public UInt16 DcLinkRefVoltage { get; init;} = 800; - public UInt16 DcLinkMinVoltage { get; init;} = 780; - public UInt16 DcLinkMaxVoltage { get; init;} = 820; - public UInt16 DcVoltageRefUs { get; init;} = 900; - public UInt16 DcMinVoltageUs { get; init;} = 880; - public UInt16 DcMaxVoltageUs { get; init;} = 920; - // Need to discuss this with Ivo - // public UInt16 FrequencySlopeIslandMode { get; init;} = 200; // resolution 0.01 - // public UInt16 VoltageSlopeIslandMode { get; init;} = 500; // resolution 0.01 - public UInt16 AcDcGcBypassMode { get; init;} = 0; - public UInt16 AcDcGcPMaxThresholdPercent { get; init;} = 0; // resolution 0.01 - public UInt16 AcDcGcStartupRampEnable { get; init;} = 0; - public DcStageConfiguration DcConfigModule { get; init;} = 0; // this must be an enum - public UInt16 DcDcPowerDistribution { get; init;} = 0; // 0.1 resolution - public AcDcDistributionMode AcDcDistributionMode { get; init;} = 0; - - - -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcDcDevices.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcDcDevices.cs new file mode 100644 index 000000000..8a049cbb8 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcDcDevices.cs @@ -0,0 +1,75 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl; +using InnovEnergy.Lib.Protocols.Modbus.Channels; +using InnovEnergy.Lib.Protocols.Modbus.Clients; +using InnovEnergy.Lib.Protocols.Modbus.Slaves; +using InnovEnergy.Lib.Utils; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; + +public class TruConvertAcDcDevices +{ + private readonly ModbusDevice _SystemControl; + private readonly IEnumerable> _AcDcs; + + public TruConvertAcDcDevices(String hostname, UInt16 port) : this(new TcpChannel(hostname, port)) + { + } + + public TruConvertAcDcDevices(Channel transport) + { + var modbusClient = new ModbusTcpClient(transport, 0); + + _SystemControl = new ModbusDevice(modbusClient); + + _AcDcs = Enumerable + .Range(1, Byte.MaxValue - 1) + .Memoize(CreateAcDc); + + ModbusDevice CreateAcDc(Int32 i) + { + var mb = new ModbusTcpClient(transport, (Byte)i); + return new ModbusDevice(mb); + } + } + + + public AcDcDevicesRecord Read() + { + try + { + var scStatus = _SystemControl.Read(); + var n = scStatus.NumberOfConnectedSlaves; + + var acDcRecords = _AcDcs + .Take(n) + .Select(acDc => acDc.Read()) + .ToArray(n); + + return new AcDcDevicesRecord(scStatus, acDcRecords); + } + catch + { + return new AcDcDevicesRecord(null, Array.Empty()); + } + } + + public void Write(AcDcDevicesRecord r) + { + if (r.SystemControl is not null) + _SystemControl.Write(r.SystemControl); // must run BEFORE the attached devices + + foreach (var (ctrl, device) in r.Devices.Zip(_AcDcs)) + { + try + { + device.Write(ctrl); + } + catch (Exception e) + { + Console.WriteLine(e); + // TODO: log + } + } + } + +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs deleted file mode 100644 index f964f0441..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs +++ /dev/null @@ -1,330 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using InnovEnergy.Lib.Devices.Trumpf.TruConvert; -using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; -using InnovEnergy.Lib.Protocols.Modbus.Clients; -using InnovEnergy.Lib.Protocols.Modbus.Connections; -using InnovEnergy.Lib.Units.Composite; -using InnovEnergy.Lib.Utils; -using static DecimalMath.DecimalEx; -using static InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.AcControlRegisters; - - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; - -using UInt16s = IReadOnlyList; - -[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] -public class TruConvertAcDevice -{ - private ModbusTcpClient ModbusTcpClient { get; } - - public TruConvertAcDevice(String hostname, UInt16 port = ModbusTcpClient.DefaultPort, Byte slaveAddress = 0) - { - var connection = new ModbusTcpConnection(hostname, port); - ModbusTcpClient = new ModbusTcpClient(connection, slaveAddress); - } - - - public void WriteControl(TruConvertAcControl c) - { - /* - WriteRegs(AcControlRegisters.Date, new List { c.Date.ConvertTo()}); - WriteRegs(AcControlRegisters.Time, new List { c.Time.ConvertTo()}); - WriteRegs(AcControlRegisters.IpAddress, new List { c.IpAddress.ConvertTo()}); - WriteRegs(AcControlRegisters.Subnet, new List { c.Subnet.ConvertTo()}); - WriteRegs(AcControlRegisters.Gateway, new List { c.Gateway.ConvertTo()}); - WriteCoils(AcControlRegisters.ResetParamToDefault, c.ResetParamToDefault); - WriteCoils(AcControlRegisters.FactoryResetParameters, c.FactoryResetParameters); - ModbusTcpClient.WriteRegisters(AcControlRegisters.UpdateSwTrigger, c.UpdateSwTrigger, c.AutomaticSwUpdate, c.CustomerValuesSaveReset); - */ - - - WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo()); - - WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig); - - - WriteCoils(PowerStageConfig, c.PowerStageEnable, - c.SetValueConfig.ConvertTo(), - c.ResetsAlarmAndWarning); - WriteRegs(PreChargeDcLinkConfigR, c.PreChargeDcLinkConfig, - c.PowerFactorConvention, c.SlaveAddress, - c.ErrorHandlingPolicy, - c.GridType, c.SubSlaveAddress); - WriteCoils(ModbusSlaveId, c.UseModbusSlaveIdForAddressing); - WriteRegs(SubSlaveErrorPolicy, c.SubSlaveErrorPolicy); - - WriteRegs(SignedPowerNominalValue, -1.0m, c.SignedPowerNominalValue);/*, c.SignedPowerSetValueL1, - c.SignedPowerSetValueL2, c.SignedPowerSetValueL3, - c.PowerSetValue, c.PowerSetValueL1, - c.PowerSetValueL2, c.PowerSetValuesL3);*/ - - - WriteRegs(MaximumGridCurrentRmsL1, 0.01m, c.MaximumGridCurrentRmsL1, c.MaximumGridCurrentRmsL2, - c.MaximumGridCurrentRmsL3, c.CosPhiSetValueL1, - c.CosPhiSetValueL2, c.CosPhiSetValueL3); - - WriteCoils(PhaseL1IsCapacitive, c.PhaseL1IsCapacitive, - c.PhaseL2IsCapacitive, - c.PhaseL3IsCapacitive, - c.PhasesAreCapacitive); - - /* WriteRegs(SetPointCosPhi, 0.01m, c.SetPointCosPhi.ConvertTo(), - c.SetPointSinPhi.ConvertTo(), - c.SetPointSinPhiL1.ConvertTo(), - c.SetPointSinPhiL2.ConvertTo(), - c.SetPointSinPhiL3.ConvertTo(), - c.FrequencyOffsetIm);*/ - - WriteRegs(VoltageAdjustmentFactorIm, c.VoltageAdjustmentFactorIm); - WriteRegs(PreChargeDcLinkVoltage, c.PreChargeDcLinkVoltage); - WriteRegs(MaxPeakCurrentVoltageControlL1, 0.01m, c.MaxPeakCurrentVoltageControlL1, - c.MaxPeakCurrentVoltageControlL2, - c.MaxPeakCurrentVoltageControlL3); - WriteRegs(GridFormingMode, c.GridFormingMode, c.DcLinkRefVoltage, - c.DcLinkMinVoltage, c.DcLinkMaxVoltage, - c.DcVoltageRefUs, c.DcMinVoltageUs, c.DcMaxVoltageUs); - WriteRegs(AcDcGcBypassMode, c.AcDcGcBypassMode); - WriteRegs(AcDcGcPMaxThresholdPercent, 0.01m, c.AcDcGcPMaxThresholdPercent); - WriteRegs(AcDcGcStartupRampEnable, c.AcDcGcStartupRampEnable); - WriteRegs(DcConfigModule, c.DcConfigModule); - WriteRegs(DcDcPowerDistribution, 0.1m, c.DcDcPowerDistribution); - WriteRegs(AcControlRegisters.AcDcDistributionMode, c.AcDcDistributionMode); - } - - private void WriteRegs (UInt16 a, Decimal res = 1.0m, params Decimal[] regs) => ModbusTcpClient.WriteRegisters(a, regs.ToUInt16(res)); - private void WriteRegs (UInt16 a, params IConvertible[] regs) => ModbusTcpClient.WriteRegisters(a, regs.Select(v => v.ConvertTo()).ToArray()); - private void WriteRegs (UInt16 a, params UInt16[] regs) => ModbusTcpClient.WriteRegisters(a, regs); - private void WriteCoils(UInt16 a, params Boolean[] coils) => ModbusTcpClient.WriteMultipleCoils(a, coils); - - private static Decimal GetPhi(Decimal cosPhi) => cosPhi.Clamp(-1m, 1m).Apply(ACos); - - public TruConvertAcStatus? ReadStatus() - { - try - { - return TryReadStatus(); - } - catch (Exception e) - { - ModbusTcpClient.CloseConnection(); - Console.WriteLine("Failed to read inverter status"); - e.Message.WriteLine(); - - return null; - } - } - - private TruConvertAcStatus TryReadStatus() - { - // Console.WriteLine("Reading Ac Device"); - - var acSerialNumber = ModbusTcpClient.ReadInputRegisters(2009, 2); - var acActualMain = ModbusTcpClient.ReadInputRegisters(5001, 3); - var acActualAcDc = ModbusTcpClient.ReadInputRegisters(5021, 9); - var acActualAcDc2 = ModbusTcpClient.ReadInputRegisters(5031, 1); - var acActualAcDc3 = ModbusTcpClient.ReadInputRegisters(5131, 6); - var acActualMeasurement = ModbusTcpClient.ReadInputRegisters(5141, 3); - var acActualMeasurement1 = ModbusTcpClient.ReadInputRegisters(5151, 3); - var acActualMeasurement2 = ModbusTcpClient.ReadInputRegisters(5161, 3); - var acActualMeasurement3 = ModbusTcpClient.ReadInputRegisters(5171, 3); - var acActualMeasurement4 = ModbusTcpClient.ReadInputRegisters(5187, 2); - var acActualMeasurement5 = ModbusTcpClient.ReadInputRegisters(5189, 2); - var acActualMeasurement6 = ModbusTcpClient.ReadInputRegisters(5191, 2); - var acActualMeasurement7 = ModbusTcpClient.ReadInputRegisters(5201, 1); - var acActualMeasurement8 = ModbusTcpClient.ReadInputRegisters(5211, 4); - var acActualMeasurement9 = ModbusTcpClient.ReadInputRegisters(5221, 2); - var acActualTemp = ModbusTcpClient.ReadInputRegisters(5501, 1); - var acWarningValues = ModbusTcpClient.ReadInputRegisters(2402, 22); - var acAlarmValues = ModbusTcpClient.ReadInputRegisters(2809, 22); - var acSetValues = ModbusTcpClient.ReadInputRegisters(4196, 1); - - var warnings = Enumerable - .Range(2404, 20) - .Select(n => acWarningValues.GetUInt16((UInt16)n).ConvertTo()) - .ToArray(); - - var alarms = Enumerable - .Range(2811, 20) - .Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo()) - .Where(m => m != AlarmMessage.NoAlarm) - .ToArray(); - - - var dcPower = acActualMeasurement.GetInt16(5141) * 1m + acActualMeasurement.GetInt16(5142) * 1m + acActualMeasurement.GetInt16(5143) * 1m; - var dcVoltage = acActualMeasurement8.GetUInt16(5214) + acActualMeasurement8.GetUInt16(5213); - var dcCurrent = dcVoltage != 0m - ? dcPower / dcVoltage - : 0m; - - - // //acActualMeasurement - // PowerAcL1 = acActualMeasurement.GetInt16(5141) * 1m, // in Watt - // PowerAcL2 = acActualMeasurement.GetInt16(5142) * 1m, // in Watt - // PowerAcL3 = acActualMeasurement.GetInt16(5143) * 1m, // in Watt - // - //acActualMeasurement1 - // PhaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m, - // PhaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m, - // PhaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m, - - //acActualMeasurement2 - // GridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m, - // GridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m, - // GridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m, - - //acActualMeasurement3 - // CosPhiL1 = acActualMeasurement3.GetInt16(5171) * 0.01m, - // CosPhiL2 = acActualMeasurement3.GetInt16(5172) * 0.01m, - // CosPhiL3 = acActualMeasurement3.GetInt16(5173) * 0.01m, - - // //acActualMeasurement4 - // SumPowerL1 = acActualMeasurement4.GetUInt32(5187) * 1m, // in Watt - // //acActualMeasurement5 - // SumPowerL2 = acActualMeasurement5.GetUInt32(5189) * 1m, // in Watt - // //acActualMeasurement6 - // SumPowerL3 = acActualMeasurement6.GetUInt32(5191) * 1m, // in Watt - // //acActualMeasurement9 - // GridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m, - - //acActualMeasurement11 - // VoltageIntNtoPE = acActualMeasurement9.GetInt16(5221) * 0.1m, - // VoltageExtNtoPE = acActualMeasurement9.GetInt16(5222) * 0.1m, - - // - // ApparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m, // in VA - // ApparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m, // in VA - // ApparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m, // in VA - - var apparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m; - var apparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m; - var apparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m; - - var powerAcL1 = acActualMeasurement.GetInt16(5141) * 1m; // in Watt - var powerAcL2 = acActualMeasurement.GetInt16(5142) * 1m; // in Watt - var powerAcL3 = acActualMeasurement.GetInt16(5143) * 1m; // in Watt - - var phaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m; - var phaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m; - var phaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m; - - var gridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m; - var gridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m; - var gridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m; - - var gridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m; - - return new TruConvertAcStatus - { - Ac = new Ac3Bus - { - Frequency = gridFrequency, - - L1 = new AcPhase - { - Voltage = gridVoltageL1, - Current = phaseCurrentL1, - Phi = ACos(powerAcL1 / apparentPowerAcL1), // TODO: 2pi - }, - L2 = new AcPhase - { - Voltage = gridVoltageL2, - Current = phaseCurrentL2, - Phi = ACos(powerAcL2 / apparentPowerAcL2), // TODO: 2pi - }, - L3 = new AcPhase - { - Voltage = gridVoltageL3, - Current = phaseCurrentL3, - Phi = ACos(powerAcL3 / apparentPowerAcL3), // TODO: 2pi - } - }, - Dc = new DcBus - { - Current = dcCurrent, - Voltage = dcVoltage, - }, - - MainState = acActualMain.GetInt16(5001).ConvertTo(), - Alarms = alarms, - Warnings = warnings, - GridType = acActualAcDc.GetUInt16(5024).ConvertTo(), - SerialNumber = acSerialNumber.GetInt32(2009).ToString(), // TODO: why tostring ? - NumberOfConnectedSlaves = acActualMain.GetUInt16(5002), - NumberOfConnectedSubSlaves = acActualMain.GetUInt16(5003), - AcDcNominalGridFrequency = acActualAcDc.GetUInt16(5021) * 0.1m, - AcDcNominalGridVoltage = acActualAcDc.GetUInt16(5022), - AcDcActNominalPower = acActualAcDc.GetUInt16(5023), - AcDcPowerLimitingStatusAct = acActualAcDc.GetUInt16(5025), - AcDcDcVoltageReference = acActualAcDc.GetUInt16(5026), // DC link reference - AcDcDcLinkVoltageMinAct = acActualAcDc.GetUInt16(5027), // DC link min voltage - AcDcDcLinkVoltageMaxAct = acActualAcDc.GetUInt16(5028), // DC link max voltage - AcDcDcLinkChargedMinVoltage = acActualAcDc.GetUInt16(5029) * 0.01m, - AcDcStmActCustomer = acActualAcDc2.GetUInt16(5031), //need to check - AcDcOverloadIntegratorStatusL1 = acActualAcDc3.GetUInt16(5134) * 0.1m, - AcDcOverloadIntegratorStatusL2 = acActualAcDc3.GetUInt16(5135) * 0.1m, - AcDcOverloadIntegratorStatusL3 = acActualAcDc3.GetUInt16(5136) * 0.1m, - AcSignedPowerValue = acSetValues.GetInt16(4196) * -1.0m, // this is also used for control - ActualDcLinkVoltageUpperHalf = acActualMeasurement8.GetUInt16(5211), - ActualDcLinkVoltageLowerHalf = acActualMeasurement8.GetUInt16(5212), - ActualDcLinkVoltageUpperHalfExt = acActualMeasurement8.GetUInt16(5213), - ActualDcLinkVoltageLowerHalfExt = acActualMeasurement8.GetUInt16(5214), - VoltageIntNtoPe = acActualMeasurement9.GetInt16(5221) * 0.1m, - VoltageExtNtoPe = acActualMeasurement9.GetInt16(5222) * 0.1m, - InletAirTemperature = acActualTemp.GetInt16(5501) * 0.1m, - - }; - - - - // ( - // Ac: new Ac3Bus - // ( - // new AcPhase(gridVoltageL1,phaseCurrentL1, ACos(powerAcL1/apparentPowerAcL1)), - // new AcPhase(gridVoltageL2,phaseCurrentL2, ACos(powerAcL2/apparentPowerAcL2)), - // new AcPhase(gridVoltageL3,phaseCurrentL3, ACos(powerAcL3/apparentPowerAcL3)), - // gridFrequency // Gird Frequency - // ), - // Dc: new DcConnection(dcVoltage, dcCurrent), - // - // SerialNumber : acSerialNumber.GetInt32(2009).ToString(), - // - // // acActualMainValues - // MainState : acActualMain.GetInt16(5001).ConvertTo(), - // NumberOfConnectedSlaves : acActualMain.GetUInt16(5002), - // NumberOfConnectedSubSlaves : acActualMain.GetUInt16(5003), - // - // //acActualAcDc - // AcDcNominalGridFrequency : acActualAcDc.GetUInt16(5021) * 0.1m, - // AcDcNominalGridVoltage : acActualAcDc.GetUInt16(5022), - // AcDcActNominalPower : acActualAcDc.GetUInt16(5023), - // AcDcActiveGridType : acActualAcDc.GetUInt16(5024).ConvertTo(), - // AcDcPowerLimitingStatusAct : acActualAcDc.GetUInt16(5025), - // AcDcDcVoltageReference : acActualAcDc.GetUInt16(5026), // DC link reference - // AcDcDcLinkVoltageMinAct : acActualAcDc.GetUInt16(5027), // DC link min voltage - // AcDcDcLinkVoltageMaxAct : acActualAcDc.GetUInt16(5028), // DC link max voltage - // AcDcDcLinkChargedMinVoltage : acActualAcDc.GetUInt16(5029) * 0.01m, - // - // //ac Actual AcDc 2 - // AcDcStmActCustomer : acActualAcDc2.GetUInt16(5031), //need to check - // AcDcOverloadIntegratorStatusL1 : acActualAcDc3.GetUInt16(5134) * 0.1m, - // AcDcOverloadIntegratorStatusL2 : acActualAcDc3.GetUInt16(5135) * 0.1m, - // AcDcOverloadIntegratorStatusL3 : acActualAcDc3.GetUInt16(5136) * 0.1m, - // AcSignedPowerValue : acSetValues.GetInt16(4196) * -1.0m, // this is also used for control - // - // //acActualMeasurement10 - // ActualDcLinkVoltageUpperHalf : acActualMeasurement8.GetUInt16(5211), - // ActualDcLinkVoltageLowerHalf : acActualMeasurement8.GetUInt16(5212), - // ActualDcLinkVoltageUpperHalfExt : acActualMeasurement8.GetUInt16(5213), - // ActualDcLinkVoltageLowerHalfExt : acActualMeasurement8.GetUInt16(5214), - // - // VoltageIntNtoPe : acActualMeasurement9.GetInt16(5221) * 0.1m, - // VoltageExtNtoPe : acActualMeasurement9.GetInt16(5222) * 0.1m, - // //acActualTemp - // InletAirTemperature : acActualTemp.GetInt16(5501) * 0.1m, - // - // Warnings : warnings, - // Alarms : alarms - // ); - } -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs deleted file mode 100644 index b605d9ecc..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs +++ /dev/null @@ -1,45 +0,0 @@ -using InnovEnergy.Lib.Devices.Trumpf.TruConvert; -using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums; -using InnovEnergy.Lib.StatusApi; -using InnovEnergy.Lib.Units; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; - -using AlarmMessages = IReadOnlyList; -using WarningMessages = IReadOnlyList; - - -// ReSharper disable UnusedAutoPropertyAccessor.Global -#pragma warning disable CS8618 - - -public record TruConvertAcStatus : ThreePhaseInverterStatus -{ - public MainState MainState { get; init; } - public String SerialNumber { get; init; } - public AcDcGridType GridType { get; init; } - public WarningMessages Warnings { get; init; } - public AlarmMessages Alarms { get; init; } - public Decimal NumberOfConnectedSlaves { get; init; } - public Decimal NumberOfConnectedSubSlaves { get; init; } - public Frequency AcDcNominalGridFrequency { get; init; } - public Voltage AcDcNominalGridVoltage { get; init; } - public Power AcDcActNominalPower { get; init; } - public Decimal AcDcPowerLimitingStatusAct { get; init; } // TODO: enum - public Voltage AcDcDcVoltageReference { get; init; } - public Voltage AcDcDcLinkVoltageMinAct { get; init; } - public Voltage AcDcDcLinkVoltageMaxAct { get; init; } - public Voltage AcDcDcLinkChargedMinVoltage { get; init; } - public Decimal AcDcStmActCustomer { get; init; } - public Decimal AcDcOverloadIntegratorStatusL1 { get; init; } - public Decimal AcDcOverloadIntegratorStatusL2 { get; init; } - public Decimal AcDcOverloadIntegratorStatusL3 { get; init; } - public Power AcSignedPowerValue { get; init; } - public Voltage ActualDcLinkVoltageUpperHalf { get; init; } - public Voltage ActualDcLinkVoltageLowerHalf { get; init; } - public Voltage ActualDcLinkVoltageUpperHalfExt { get; init; } - public Voltage ActualDcLinkVoltageLowerHalfExt { get; init; } - public Voltage VoltageIntNtoPe { get; init; } - public Voltage VoltageExtNtoPe { get; init; } - public Temperature InletAirTemperature { get; init; } -} diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/WarningMessage.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/WarningMessage.cs deleted file mode 100644 index 4ceffc228..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/WarningMessage.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; - -[SuppressMessage("ReSharper", "IdentifierTypo")] -[SuppressMessage("ReSharper", "UnusedMember.Global")] -[SuppressMessage("ReSharper", "CommentTypo")] - -public enum WarningMessage -{ - ERR_WARN_FAN = 10500, //AC-DC module warning - ERR_WARN_I_OFFSET = 10503, //AC-DC module warning - ERR_WARN_VG_OFFSET = 10504, //AC-DC module warning - ERR_WARN_VC_OFFSET = 10505, //AC-DC module warning - ERR_WARN_DC_OFFSET = 10506, //AC-DC module warning - ERR_WARN_NTC_PROTECT = 10507, //DC-link circuit need more time for cool down - ERR_WARN_AIR_TEMP = 10508, //Overtemperature inlet air: power is derated - SurgeDetected = 10509, //Temporary overvoltage in grid measurement detected (surge) - ERR_WARN_TEMP_DERATING = 11021, //Temperature derating active - ERR_WARN_OVERLOAD = 11022, //Overload handling is active - ERR_WARN_RUNTIME_EEPROM = 11023, //AC-DC module warning - ERR_WARN_OVERCURRENT = 11024 //Overcurrent handling is active -} - diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/AlarmMessage.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/AlarmMessage.cs deleted file mode 100644 index 8c9ef6251..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/AlarmMessage.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; - -[SuppressMessage("ReSharper", "IdentifierTypo")] -[SuppressMessage("ReSharper", "UnusedMember.Global")] -[SuppressMessage("ReSharper", "CommentTypo")] -public enum AlarmMessage -{ - NoAlarm = 0, // No Alarm - Iboosterhv = 60081, // DC-DC power module alarm - Iboosterhv1 = 60082, // wildcard to allocate TypeMessageNumber - Iboosterhv2 = 60083, // wildcard to allocate TypeMessageNumber - Ibat = 60084, // DC-DC power module alarm - Ibat1 = 60085, // wildcard to allocate TypeMessageNumber - Ibat2 = 60086, // wildcard to allocate TypeMessageNumber - Itrafolv = 60087, // DC-DC power module alarm - Itrafolv1 = 60088, // wildcard to allocate TypeMessageNumber - Itrafolv2 = 60089, // wildcard to allocate TypeMessageNumber - UbatHigh = 60090, // Battery overvoltage - UbatHigh1 = 60091, // wildcard to allocate TypeMessageNumber - UbatHigh2 = 60092, // wildcard to allocate TypeMessageNumber - Udclp = 60093, // DC link overvoltage - Udclp1 = 60094, // wildcard to allocate TypeMessageNumber - Udclp2 = 60095, // wildcard to allocate TypeMessageNumber - Udcln = 60096, // DC link overvoltage (lower half) - Udcln1 = 60097, // wildcard to allocate TypeMessageNumber - Udcln2 = 60098, // wildcard to allocate TypeMessageNumber - Udclllc = 60099, // DC-DC power module alarm - Udclllc1 = 60100, // wildcard to allocate TypeMessageNumber - Udclllc2 = 60101, // wildcard to allocate TypeMessageNumber - UdclLow = 60102, // DC link voltage too low for operation - UdclLow1 = 60103, // wildcard to allocate TypeMessageNumber - UdclLow2 = 60104, // wildcard to allocate TypeMessageNumber - VauxHigh = 60700, // Auxiliary supply overvoltage - VauxHigh1 = 60701, // wildcard to allocate TypeMessageNumber - VauxHigh2 = 60702, // wildcard to allocate TypeMessageNumber - UbatLow = 60142, // Battery undervoltage - UbatLow1 = 60143, // wildcard to allocate TypeMessageNumber - UbatLow2 = 60144, // wildcard to allocate TypeMessageNumber - VauxLow = 60703, // Auxiliary supply undervoltage - VauxLow1 = 60704, // wildcard to allocate TypeMessageNumber - VauxLow2 = 60705, // wildcard to allocate TypeMessageNumber - IbatIboosterPlausi = 60197, // DC-DC power module alarm -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs new file mode 100644 index 000000000..a37303051 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs @@ -0,0 +1,22 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; + +public class CurrentControl +{ + public Current CurrentSetpoint + { + get => _Self.DcDcCurrentSetpoint; + set => _Self.DcDcCurrentSetpoint = value.Value; + } + + public Current MaxCurrentChangePerMs + { + get => _Self.MaxCurrentChangePerMs; + set => _Self.MaxCurrentChangePerMs = value.Value; + } + + private readonly DcDcRecord _Self; + internal CurrentControl(DcDcRecord self) => _Self = self; +} + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DcControlMode.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DcControlMode.cs new file mode 100644 index 000000000..9d096ef93 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DcControlMode.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; + +public enum DcControlMode : UInt16 +{ + CurrentSetpoint = 0, + VoltageDroop = 1 +} diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DcDcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DcDcControl.cs new file mode 100644 index 000000000..b2cc6b2b4 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DcDcControl.cs @@ -0,0 +1,43 @@ +using InnovEnergy.Lib.Units.Power; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; + + +// https://stackoverflow.com/q/63724308 + + +public class DcDcControl +{ + public Vcc Vcc => new(_Self); + public VoltageLimits VoltageLimits => new(_Self); + public DroopControl DroopControl => new(_Self); + public CurrentControl CurrentControl => new(_Self); + + public ActivePower MaxDcPower + { + get => _Self.MaxDcPower; + set => _Self.MaxDcPower = value.Value; + } + + public DcControlMode ControlMode + { + get => _Self.DcControlMode; + set => _Self.DcControlMode = value; + } + + public Boolean ResetAlarmsAndWarnings + { + get => _Self.ResetAlarmsAndWarnings; + set => _Self.ResetAlarmsAndWarnings = value; + } + + public Boolean PowerStageEnable + { + get => _Self.PowerStageEnable; + set => _Self.PowerStageEnable = value; + } + + private readonly DcDcRecord _Self; + internal DcDcControl(DcDcRecord self) => _Self = self; +} + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DroopControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DroopControl.cs new file mode 100644 index 000000000..ecc226da9 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/DroopControl.cs @@ -0,0 +1,33 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; + +public class DroopControl +{ + public Voltage ReferenceVoltage + { + get => _Self.DroopControlReferenceVoltage; + set => _Self.DroopControlReferenceVoltage = value.Value; + } + + public Voltage LowerVoltage + { + get => _Self.DroopControlLowerVoltage; + set => _Self.DroopControlLowerVoltage = value.Value; + } + + public Voltage UpperVoltage + { + get => _Self.DroopControlUpperVoltage; + set => _Self.DroopControlUpperVoltage = value.Value; + } + + public Voltage VoltageDeadband + { + get => _Self.DroopControlVoltageDeadband; + set => _Self.DroopControlVoltageDeadband = value.Value; + } + + private readonly DcDcRecord _Self; + internal DroopControl(DcDcRecord self) => _Self = self; +}; \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/Vcc.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/Vcc.cs new file mode 100644 index 000000000..0185ea6d1 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/Vcc.cs @@ -0,0 +1,27 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; + +public class Vcc +{ + public Current EndPointCurrent + { + get => _Self.VccEndPointCurrent; + set => _Self.VccEndPointCurrent = value.Value; + } + + public Voltage EndPointVoltage + { + get => _Self.VccEndPointCurrent; + set => _Self.VccEndPointCurrent = value.Value; + } + + public Current StartPointCurrent + { + get => _Self.VccStartPointCurrent; + set => _Self.VccStartPointCurrent = value.Value; + } + + private readonly DcDcRecord _Self; + internal Vcc(DcDcRecord self) => _Self = self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/VoltageLimits.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/VoltageLimits.cs new file mode 100644 index 000000000..ce8941f46 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/VoltageLimits.cs @@ -0,0 +1,33 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; + +public class VoltageLimits +{ + public Voltage MinBatteryVoltageAlarm + { + get => _Self.MinVoltageAlarm; + set => _Self.MinVoltageAlarm = value.Value; + } + + public Voltage MaxBatteryVoltageAlarm + { + get => _Self.MaxVoltageAlarm; + set => _Self.MaxVoltageAlarm = value.Value; + } + + public Voltage MinBatteryVoltage + { + get => _Self.MinBatteryVoltage; + set => _Self.MinBatteryVoltage = value.Value; + } + + public Voltage MaxBatteryVoltage + { + get => _Self.MaxBatteryVoltage; + set => _Self.MaxBatteryVoltage = value.Value; + } + + private readonly DcDcRecord _Self; + internal VoltageLimits(DcDcRecord self) => _Self = self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcControlRegisters.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcControlRegisters.cs deleted file mode 100644 index 90b0552b6..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcControlRegisters.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; - -public static class DcControlRegisters -{ - public const UInt16 Date = 1001; - public const UInt16 Time = 1003; - public const UInt16 IpAddress = 1005; - public const UInt16 Subnet = 1007; - public const UInt16 Gateway = 1009; - public const UInt16 ResetParamToDefault = 1011; - public const UInt16 TimeoutCommunication = 1017; - public const UInt16 RestartFlag = 1018; - public const UInt16 ConnectedSystemConfig = 1019; - public const UInt16 UpdateSwTrigger = 1027; - public const UInt16 AutomaticSwUpdate = 1028; - public const UInt16 CustomerValuesSaveReset = 1029; - public const UInt16 SerialNumberSystemControl = 2001; - public const UInt16 SerialNumberDcDc = 2003; - public const UInt16 MaterialNumberDcDc = 2005; - public const UInt16 PowerStageOperation = 4001; - public const UInt16 ResetsAlarmAndWarning = 4003; - public const UInt16 SlaveAddress = 4008; - public const UInt16 SlaveAlarmPolicy = 4009; - public const UInt16 SubSlaveAddress = 4011; - public const UInt16 ModbusSlaveId = 4012; - public const UInt16 MaximumBatteryVoltage = 4101; - public const UInt16 MinimumBatteryVoltage = 4102; - public const UInt16 MaximumBatteryVoltageR = 4103; // same as the two previous ones just Different resolution// not sure - public const UInt16 MinimumBatteryVoltageR = 4104; // same as the two previous ones just Different resolution// not sure - public const UInt16 MaximumBatteryChargingCurrent = 4107; - public const UInt16 MaximumBatteryDischargingCurrent = 4110; - public const UInt16 MaximumVoltageOfVcc = 4113; - public const UInt16 MaximumCurrentOfVcc = 4116; - public const UInt16 StartCurrentOfVcc = 4119; - public const UInt16 MaximalPowerAtDc = 4122; - public const UInt16 MaximumVoltageAlarmThreshold = 4125; - public const UInt16 MinimumVoltageAlarmThreshold = 4128; - - //DcDc operation only - public const UInt16 BatteryCurrentSet = 4501; - public const UInt16 DynamicCurrentPerMillisecond = 4502; - - public const UInt16 DcLinkControlMode = 4505; - public const UInt16 ReferenceVoltage = 4506; - public const UInt16 UpperVoltageWindow = 4507; - public const UInt16 LowerVoltageWindow = 4508; - public const UInt16 VoltageDeadBand = 4509; -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcCurrentLimitState.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcCurrentLimitState.cs deleted file mode 100644 index 1895221af..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcCurrentLimitState.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; - -[Flags] -public enum DcCurrentLimitState : UInt16 -{ - PMax = 0b_00001, - MaxChargingCurrent = 0b_00010, - MaxDischargingCurrent = 0b_00100, - MaxBatteryVoltage = 0b_01000, - MinBatteryVoltage = 0b_10000, -} - diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcDevicesRecord.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcDevicesRecord.cs new file mode 100644 index 000000000..8ea6ac807 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcDevicesRecord.cs @@ -0,0 +1,42 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; +using InnovEnergy.Lib.Units.Composite; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; + +public class DcDcDevicesRecord +{ + private static readonly DcBus NoDevice = DcBus.FromVoltageCurrent(0, 0); + + public DcDcDevicesRecord(SystemControlRegisters? systemControl, IReadOnlyList devices) + { + SystemControl = systemControl; + Devices = devices; + } + + public DcStatus Dc => new DcStatus + { + Battery = Devices.Count == 0 ? NoDevice + : DcBus.FromVoltageCurrent + ( + Devices.Average(r => r.Status.Dc.Battery.Voltage.Value), + Devices.Sum(r => r.Status.Dc.Battery.Current.Value) + ), + + Link = Devices.Count == 0 + ? NoDevice + : DcBus.FromVoltageCurrent + ( + Devices.Average(r => r.Status.Dc.Link.Voltage.Value), + Devices.Sum(r => r.Status.Dc.Link.Current.Value) + ) + }; + + public SystemControlRegisters? SystemControl { get; } + public IReadOnlyList Devices { get; } + + public IEnumerable Alarms => Devices.SelectMany(d => d.Status.Alarms ).Distinct(); + public IEnumerable Warnings => Devices.SelectMany(d => d.Status.Warnings).Distinct(); + + public static DcDcDevicesRecord Null { get; } = new DcDcDevicesRecord(null, Array.Empty()); +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Alarms.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Alarms.cs new file mode 100644 index 000000000..0c30b93f1 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Alarms.cs @@ -0,0 +1,51 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +#pragma warning disable CS0649 + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; + +[SuppressMessage("ReSharper", "UnusedMember.Global")] +[SuppressMessage("ReSharper", "InconsistentNaming")] +[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] +public partial class DcDcRecord +{ + private IEnumerable GetAlarms() + { + yield return Alarm1; + yield return Alarm2; + yield return Alarm3; + yield return Alarm4; + yield return Alarm5; + yield return Alarm6; + yield return Alarm7; + yield return Alarm8; + yield return Alarm9; + yield return Alarm10; + yield return Alarm11; + yield return Alarm12; + yield return Alarm13; + yield return Alarm14; + yield return Alarm15; + yield return Alarm16; + yield return Alarm17; + yield return Alarm18; + yield return Alarm19; + yield return Alarm20; + } + + internal IReadOnlyList Alarms => GetAlarms() + .Take(NumberOfAlarms) + .Where(IsDcDcAlarm) + .ToList(); + + private static Boolean IsDcDcAlarm(AlarmMessage alarm) => (UInt16)alarm >= 60000; +} + + + + + + + + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs new file mode 100644 index 000000000..92a27a346 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs @@ -0,0 +1,116 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; +using InnovEnergy.Lib.Protocols.Modbus.Reflection.Attributes; + +#pragma warning disable CS0649 + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; + +[SuppressMessage("ReSharper", "InconsistentNaming")] +[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] +public partial class DcDcRecord +{ + //[Coil(4000)] + [HoldingRegister(4000)] internal Boolean PowerStageEnable ; + + //[Coil(4002)] + [HoldingRegister(4002)] internal Boolean ResetAlarmsAndWarnings ; + + [HoldingRegister(4100, Scale = .01)] internal Double MaxBatteryVoltage ; + [HoldingRegister(4101, Scale = .01)] internal Double MinBatteryVoltage ; + + [HoldingRegister(4112, Scale = .1)] internal Double VccEndPointVoltage ; + [HoldingRegister(4115)] internal Double VccEndPointCurrent ; + [HoldingRegister(4118)] internal Double VccStartPointCurrent ; + + [HoldingRegister(4118)] internal Double MaxDcPower ; + + [HoldingRegister(4124, Scale = .1)] internal Double MaxVoltageAlarm ; + [HoldingRegister(4127, Scale = .1)] internal Double MinVoltageAlarm ; + + [HoldingRegister(4500)] internal Double DcDcCurrentSetpoint ; + [HoldingRegister(4501, Scale = .01)] internal Double MaxCurrentChangePerMs ; + + [HoldingRegister(4504)] internal DcControlMode DcControlMode ; + + [HoldingRegister(4505, Scale = .1)] internal Double DroopControlReferenceVoltage ; + [HoldingRegister(4506, Scale = .1)] internal Double DroopControlUpperVoltage ; + [HoldingRegister(4507, Scale = .1)] internal Double DroopControlLowerVoltage ; + [HoldingRegister(4508, Scale = .1)] internal Double DroopControlVoltageDeadband ; + + [InputRegister(5100, Scale = .1)] internal Double BatteryVoltage ; + [InputRegister(5110)] internal Double BatteryCurrent ; + + [InputRegister(5123)] internal BatteryPowerLimit BatteryPowerLimit ; + + [InputRegister(5126, Scale = .1)] internal Double OverloadCapacity ; + [InputRegister(5127)] internal Double DcLinkVoltage; + + // TODO: [InputRegister(5300)] + + [InputRegister(5510)] internal Double InletAirTemperature ; + [InputRegister(5511)] internal Double HighVoltageModuleTemperature ; + [InputRegister(5512)] internal Double LowVoltageModuleTemperature ; + + [InputRegister(2402)] internal UInt16 NumberOfWarnings; + + [InputRegister(2403)] internal WarningMessage Warning1; + [InputRegister(2404)] internal WarningMessage Warning2; + [InputRegister(2405)] internal WarningMessage Warning3; + [InputRegister(2406)] internal WarningMessage Warning4; + [InputRegister(2407)] internal WarningMessage Warning5; + [InputRegister(2408)] internal WarningMessage Warning6; + [InputRegister(2409)] internal WarningMessage Warning7; + [InputRegister(2410)] internal WarningMessage Warning8; + [InputRegister(2411)] internal WarningMessage Warning9; + [InputRegister(2412)] internal WarningMessage Warning10; + [InputRegister(2413)] internal WarningMessage Warning11; + [InputRegister(2414)] internal WarningMessage Warning12; + [InputRegister(2415)] internal WarningMessage Warning13; + [InputRegister(2416)] internal WarningMessage Warning14; + [InputRegister(2417)] internal WarningMessage Warning15; + [InputRegister(2418)] internal WarningMessage Warning16; + [InputRegister(2419)] internal WarningMessage Warning17; + [InputRegister(2420)] internal WarningMessage Warning18; + [InputRegister(2421)] internal WarningMessage Warning19; + [InputRegister(2422)] internal WarningMessage Warning20; + + [InputRegister(2809)] internal UInt16 NumberOfAlarms; + + [InputRegister(2810)] internal AlarmMessage Alarm1; + [InputRegister(2811)] internal AlarmMessage Alarm2; + [InputRegister(2812)] internal AlarmMessage Alarm3; + [InputRegister(2813)] internal AlarmMessage Alarm4; + [InputRegister(2814)] internal AlarmMessage Alarm5; + [InputRegister(2815)] internal AlarmMessage Alarm6; + [InputRegister(2816)] internal AlarmMessage Alarm7; + [InputRegister(2817)] internal AlarmMessage Alarm8; + [InputRegister(2818)] internal AlarmMessage Alarm9; + [InputRegister(2819)] internal AlarmMessage Alarm10; + [InputRegister(2820)] internal AlarmMessage Alarm11; + [InputRegister(2821)] internal AlarmMessage Alarm12; + [InputRegister(2822)] internal AlarmMessage Alarm13; + [InputRegister(2823)] internal AlarmMessage Alarm14; + [InputRegister(2824)] internal AlarmMessage Alarm15; + [InputRegister(2825)] internal AlarmMessage Alarm16; + [InputRegister(2826)] internal AlarmMessage Alarm17; + [InputRegister(2827)] internal AlarmMessage Alarm18; + [InputRegister(2828)] internal AlarmMessage Alarm19; + [InputRegister(2829)] internal AlarmMessage Alarm20; + + // #region IDcDc + // + // internal DcBus DcLeft => DcBus.FromVoltageCurrent(DcLinkVoltage, Double.NaN); // HV current not measured + // internal DcBus DcRight => DcBus.FromVoltageCurrent(BatteryVoltage, BatteryCurrent); + // + // #endregion IDcDc +} + + + + + + + + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Warnings.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Warnings.cs new file mode 100644 index 000000000..d229df10a --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Warnings.cs @@ -0,0 +1,52 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +#pragma warning disable CS0649 + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; + +[SuppressMessage("ReSharper", "UnusedMember.Global")] +[SuppressMessage("ReSharper", "InconsistentNaming")] +[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] +public partial class DcDcRecord +{ + private IEnumerable GetWarnings() + { + yield return Warning1; + yield return Warning2; + yield return Warning3; + yield return Warning4; + yield return Warning5; + yield return Warning6; + yield return Warning7; + yield return Warning8; + yield return Warning9; + yield return Warning10; + yield return Warning11; + yield return Warning12; + yield return Warning13; + yield return Warning14; + yield return Warning15; + yield return Warning16; + yield return Warning17; + yield return Warning18; + yield return Warning19; + yield return Warning20; + } + + internal IReadOnlyList Warnings => GetWarnings() + .Take(NumberOfWarnings) + .Where(IsDcDcWarning) + .ToList(); + + private static Boolean IsDcDcWarning(WarningMessage warning) => (UInt16)warning is >= 11000 and < 12000; + +} + + + + + + + + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.cs new file mode 100644 index 000000000..9fca2eae4 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.cs @@ -0,0 +1,10 @@ +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; + +public partial class DcDcRecord +{ + public DcDcStatus Status => new(this); + public DcDcControl Control => new(this); +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/AlarmMessage.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/AlarmMessage.cs new file mode 100644 index 000000000..ddbed76da --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/AlarmMessage.cs @@ -0,0 +1,73 @@ +using System.Diagnostics.CodeAnalysis; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +[SuppressMessage("ReSharper", "IdentifierTypo")] +[SuppressMessage("ReSharper", "UnusedMember.Global")] +[SuppressMessage("ReSharper", "CommentTypo")] +public enum AlarmMessage +{ + NoAlarm = 0, + + Iboosterhv = 60081, + Iboosterhv1 = 60082, + Iboosterhv2 = 60083, + + Ibat = 60084, + Ibat1 = 60085, + Ibat2 = 60086, + + Itrafolv = 60087, + Itrafolv2 = 60089, + + BatteryVoltageTooHigh = 60090, + BatteryVoltageTooHigh1 = 60091, + BatteryVoltageTooHigh2 = 60092, + + DcLinkVoltageTooHigh = 60093, + DcLinkVoltageTooHigh1 = 60094, + DcLinkVoltageTooHigh2 = 60095, + + Udcln = 60096, + Udcln1 = 60097, + Udcln2 = 60098, + + Udclllc = 60099, + Udclllc1 = 60100, + Udclllc2 = 60101, + + DcLinkVoltageTooLow = 60102, + DcLinkVoltageTooLow1 = 60103, + DcLinkVoltageTooLow2 = 60104, + + BatteryVoltageUnderTresholdSetting = 60129, + + Rs485CommunicationAlarm = 60132, + + BatteryVoltageTooLow = 60142, + BatteryVoltageTooLow1 = 60143, + BatteryVoltageTooLow2 = 60144, + + WrongDcPolarity = 60145, + + + BatteryVoltageOverTresholdSetting = 60150, + AmbientTemperatureTooHigh = 60168, + AmbientTemperatureTooLow = 60186, + + FanDefectiveOrStuck = 60192, + IbatIboosterPlausi = 60197, + PreChargeConditionsCouldNotBeMet = 60200, + AttachedLoadOnDcLinkCannotBeHandled = 60201, + DcLinkCouldNotBeCharged = 60202, + + AuxiliarySupplyOvervoltage = 60700, + AuxiliarySupplyOvervoltage1 = 60701, + AuxiliarySupplyOvervoltage2 = 60702, + + AuxiliarySupplyUndervoltage = 60703, + AuxiliarySupplyUndervoltage1 = 60704, + AuxiliarySupplyUndervoltage2 = 60705, + DcDcPrecharge = 60200, // DC-DC Precharge Conditions could not be met. + +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/BatteryPowerLimit.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/BatteryPowerLimit.cs new file mode 100644 index 000000000..d992497d6 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/BatteryPowerLimit.cs @@ -0,0 +1,11 @@ +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +[Flags] +public enum BatteryPowerLimit : UInt16 +{ + MaxPower = 0b_00001, + MaxChargeCurrent = 0b_00010, + MaxDischargeCurrent = 0b_00100, + MaxVoltage = 0b_01000, + MinVoltage = 0b_10000, +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/DcDcStatus.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/DcDcStatus.cs new file mode 100644 index 000000000..3b27cc4a6 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/DcDcStatus.cs @@ -0,0 +1,118 @@ +using InnovEnergy.Lib.Units; +using InnovEnergy.Lib.Units.Composite; +using InnovEnergy.Lib.Utils; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +public class DcDcStatus +{ + public DcStatus Dc + { + get + { + // if battery voltage is 0, Trumpf reports a nonsensical battery current + + var batteryCurrent = _Self.BatteryVoltage == 0 + ? 0 + : _Self.BatteryCurrent; + + // link current is not measured by trumpf, calculate it assuming 0 losses + // TODO: calculate losses + var linkCurrent = batteryCurrent == 0 + ? 0 + : _Self.BatteryVoltage * _Self.BatteryCurrent / _Self.DcLinkVoltage; + + return new() + { + Link = DcBus.FromVoltageCurrent + ( + voltage: _Self.DcLinkVoltage, + current: linkCurrent + ), + Battery = DcBus.FromVoltageCurrent + ( + voltage: _Self.BatteryVoltage, + current: batteryCurrent + ) + }; + } + } + + public Percent OverloadCapacity => _Self.OverloadCapacity; + public Temperatures Temperature => new(_Self); + public IReadOnlyList PowerLimitedBy => ListActivePowerLimits(); + public IReadOnlyList Alarms => ListAlarms(); + public IReadOnlyList Warnings => ListWarnings(); + + /////////////////////////////////////////////////////////////////////////////// + + + private AlarmMessage[] ListAlarms() => EnumerateAlarms() + .Take(_Self.NumberOfAlarms) + .ToArray(_Self.NumberOfAlarms); + + private WarningMessage[] ListWarnings() => EnumerateWarnings() + .Take(_Self.NumberOfWarnings) + .ToArray(_Self.NumberOfWarnings); + + private IEnumerable EnumerateWarnings() + { + yield return _Self.Warning1; + yield return _Self.Warning2; + yield return _Self.Warning3; + yield return _Self.Warning4; + yield return _Self.Warning5; + yield return _Self.Warning6; + yield return _Self.Warning7; + yield return _Self.Warning8; + yield return _Self.Warning9; + yield return _Self.Warning10; + yield return _Self.Warning11; + yield return _Self.Warning12; + yield return _Self.Warning13; + yield return _Self.Warning14; + yield return _Self.Warning15; + yield return _Self.Warning16; + yield return _Self.Warning17; + yield return _Self.Warning18; + yield return _Self.Warning19; + yield return _Self.Warning20; + } + + private IEnumerable EnumerateAlarms() + { + yield return _Self.Alarm1; + yield return _Self.Alarm2; + yield return _Self.Alarm3; + yield return _Self.Alarm4; + yield return _Self.Alarm5; + yield return _Self.Alarm6; + yield return _Self.Alarm7; + yield return _Self.Alarm8; + yield return _Self.Alarm9; + yield return _Self.Alarm10; + yield return _Self.Alarm11; + yield return _Self.Alarm12; + yield return _Self.Alarm13; + yield return _Self.Alarm14; + yield return _Self.Alarm15; + yield return _Self.Alarm16; + yield return _Self.Alarm17; + yield return _Self.Alarm18; + yield return _Self.Alarm19; + yield return _Self.Alarm20; + } + + + private List ListActivePowerLimits() + { + return Utils + .Utils + .GetEnumValues() + .Where(t => _Self.BatteryPowerLimit.HasFlag(t)) + .ToList(); + } + + private readonly DcDcRecord _Self; + internal DcDcStatus(DcDcRecord self) => _Self = self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/DcStatus.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/DcStatus.cs new file mode 100644 index 000000000..baad91b11 --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/DcStatus.cs @@ -0,0 +1,9 @@ +using InnovEnergy.Lib.Units.Composite; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +public class DcStatus +{ + public DcBus Link { get; init; } + public DcBus Battery { get; init; } +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/Temperatures.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/Temperatures.cs new file mode 100644 index 000000000..66df3946a --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/Temperatures.cs @@ -0,0 +1,14 @@ +using InnovEnergy.Lib.Units; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; + +public class Temperatures +{ + public Temperature InletAir => _Self.InletAirTemperature; + public Temperature HighVoltageModule => _Self.HighVoltageModuleTemperature; + public Temperature LowVoltageModule => _Self.LowVoltageModuleTemperature; + + + internal Temperatures(DcDcRecord self) => _Self = self; + private readonly DcDcRecord _Self; +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/WarningMessage.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/WarningMessage.cs similarity index 96% rename from csharp/Lib/Devices/Trumpf/TruConvertDc/WarningMessage.cs rename to csharp/Lib/Devices/Trumpf/TruConvertDc/Status/WarningMessage.cs index bb44edcbf..2686739c0 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/WarningMessage.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Status/WarningMessage.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status; [SuppressMessage("ReSharper", "IdentifierTypo")] [SuppressMessage("ReSharper", "UnusedMember.Global")] @@ -29,5 +29,4 @@ public enum WarningMessage HveepromWrite1 = 11018, //DC-DC module warning HveepromWrite2 = 11019, //DC-DC module warning HveepromWrite3 = 11020 //DC-DC module warning - } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj index f640e856c..66e6f2cb1 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj @@ -7,8 +7,8 @@ - + diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs deleted file mode 100644 index 82a4e4dcc..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs +++ /dev/null @@ -1,44 +0,0 @@ -using InnovEnergy.Lib.Devices.Trumpf.TruConvert; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; - -public record TruConvertDcControl -{ - public UInt32 Date { get; init;} - public UInt32 Time { get; init;} - public UInt32 IpAddress { get; init;} //= 0x C0A80102; - public UInt32 Subnet { get; init;} //= 0x FFFFFF00; - public UInt32 Gateway { get; init;} //= 0x C0A80102; - public Boolean ResetParamToDefault { get; init;} = false ; // Coil - public TimeSpan TimeoutForCommunication { get; init;} = DefaultCommunicationTimeOut; - public Boolean RestartFlag { get; init;} = false ; // Coil - public SystemConfig ConnectedSystemConfig { get; init;} = SystemConfig.NoConfig ; - public UInt16 UpdateSwTrigger { get; init;} = 0 ; - public UInt16 AutomaticSwUpdate { get; init;} = 0 ; - public UInt16 CustomerValuesSaveReset { get; init;} = 0 ; - public UInt32 SerialNumberSystemControl { get; init;} - public UInt32 SerialNumberDcDc { get; init;} - public UInt32 MaterialNumberDcDc { get; init;} - public Boolean PowerStageEnable { get; init;} = true; //Coil - public Boolean ResetsAlarmAndWarning { get; init;} = false; //Coil - public UInt16 SlaveAddress { get; init;} = Slave.Broadcast; - public UInt16 SlaveAlarmPolicy { get; init;} = 0; // this is must be a an enum - public UInt16 SubSlaveAddress { get; init;} = 0; - public Boolean ModbusSlaveId { get; init;} = false; // Coil - public Decimal MaximumBatteryVoltage { get; init;} = 0; // resolution 0.01 - public Decimal MinimumBatteryVoltage { get; init;} = 0; // resolution 0.01 - public Decimal MaximumBatteryChargingCurrent { get; init;} = 0; // resolution 0.1 - public Decimal MaximumBatteryDischargingCurrent { get; init;} = 0; // resolution 0.1 - public Decimal MaximalPowerAtDc { get; init;} = 0; - public Decimal MaximumVoltageAlarmThreshold { get; init;} = 55; // resolution 0.1 - public Decimal MinimumVoltageAlarmThreshold { get; init;} = 0; // resolution 0.1 - public Decimal BatteryCurrentSet { get; init;} = 0; // resolution 1.0 - public Decimal DynamicCurrentPerMillisecond { get; init;} = 0; // resolution : 0.01 - public Decimal DcLinkControlMode { get; init;} = 0; // Parameter aktiviert/deaktiviert "DC link voltage droop mode" - public Decimal ReferenceVoltage { get; init;} = 800; // resolution : 0.1 - public Decimal UpperVoltageWindow { get; init;} = 40; // resolution : 0.1 - public Decimal LowerVoltageWindow { get; init;} = 40; // resolution : 0.1 - public Decimal VoltageDeadBand { get; init;} = 0; // resolution : 0.1 - - private static readonly TimeSpan DefaultCommunicationTimeOut = TimeSpan.FromMinutes(10); -} diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs new file mode 100644 index 000000000..54c374dce --- /dev/null +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs @@ -0,0 +1,88 @@ +using InnovEnergy.Lib.Devices.Trumpf.SystemControl; +using InnovEnergy.Lib.Protocols.Modbus.Channels; +using InnovEnergy.Lib.Protocols.Modbus.Clients; +using InnovEnergy.Lib.Protocols.Modbus.Slaves; +using InnovEnergy.Lib.Utils; + +namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; + +public class TruConvertDcDcDevices +{ + private readonly ModbusDevice _SystemControl; + private readonly IEnumerable> _DcDcs; + + public TruConvertDcDcDevices(String hostname, UInt16 port) : this(new TcpChannel(hostname, port)) + { + } + + public TruConvertDcDcDevices(Channel transport) + { + var modbusClient = new ModbusTcpClient(transport, 0); + + _SystemControl = new ModbusDevice(modbusClient); + + _DcDcs = Enumerable + .Range(1, Byte.MaxValue - 1) + .Memoize(CreateDcDc); + + ModbusDevice CreateDcDc(Int32 i) + { + var mb = new ModbusTcpClient(transport, (Byte)i); + return new ModbusDevice(mb); + } + } + + + public DcDcDevicesRecord Read() + { + SystemControlRegisters? scStatus; + + try + { + scStatus = _SystemControl.Read(); + } + catch (Exception e) + { + Console.WriteLine(e); + return DcDcDevicesRecord.Null; + } + + var n = scStatus.NumberOfConnectedSlaves; + + try + { + var dcDcRecords = _DcDcs + .Take(n) + .Select(dcdc => dcdc.Read()) + .ToArray(n); + + return new DcDcDevicesRecord(scStatus, dcDcRecords); + } + catch (Exception e) + { + Console.WriteLine(e); + return new DcDcDevicesRecord(scStatus, Array.Empty()); + } + } + + public void Write(DcDcDevicesRecord r) + { + if (r.SystemControl is not null) + _SystemControl.Write(r.SystemControl); // must run BEFORE the attached devices + + foreach (var (ctrl, device) in r.Devices.Zip(_DcDcs)) + { + try + { + device.Write(ctrl); + } + catch (Exception e) + { + Console.WriteLine(e); + // TODO: log + } + } + } + + +} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs deleted file mode 100644 index b7d0bc201..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using InnovEnergy.Lib.Devices.Trumpf.TruConvert; -using InnovEnergy.Lib.Protocols.Modbus.Clients; -using InnovEnergy.Lib.Protocols.Modbus.Connections; -using InnovEnergy.Lib.Units.Composite; -using InnovEnergy.Lib.Utils; -using static InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.DcControlRegisters; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; - -[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] -public class TruConvertDcDevice -{ - private ModbusTcpClient ModbusTcpClient { get; } - - public TruConvertDcDevice(String hostname, UInt16 port = ModbusTcpClient.DefaultPort, Byte slaveAddress = 0) - { - var connection = new ModbusTcpConnection(hostname, port); - ModbusTcpClient = new ModbusTcpClient(connection, slaveAddress); - } - - - public void WriteControl(TruConvertDcControl c) - { - - /* - TODO: maybe later - - ModbusTcpClient.WriteRegisters(Date, new[] { dcControl.Date.ConvertTo() }); - ModbusTcpClient.WriteRegisters(Time, new[] { dcControl.Time.ConvertTo() }); - ModbusTcpClient.WriteRegisters(IpAddress, dcControl.IpAddress.ConvertTo()); - ModbusTcpClient.WriteRegisters(Subnet, dcControl.Subnet.ConvertTo()); - ModbusTcpClient.WriteRegisters(Gateway, dcControl.Gateway.ConvertTo()); - ModbusTcpClient.WriteMultipleCoils(ResetParamToDefault, dcControl.ResetParamToDefault); - ModbusTcpClient.WriteMultipleCoils(RestartFlag, dcControl.RestartFlag); - ModbusTcpClient.WriteRegisters(DcControlRegisters.TimeoutCommunication, dcControl.TimeoutForCommunication.TotalSeconds.ConvertTo()); - ModbusTcpClient.WriteRegisters(ConnectedSystemConfig, dcControl.ConnectedSystemConfig.ConvertTo()); - ModbusTcpClient.WriteRegisters(UpdateSwTrigger, dcControl.UpdateSwTrigger, dcControl.AutomaticSwUpdate, dcControl.CustomerValuesSaveReset); - ModbusTcpClient.WriteRegisters(SerialNumberSystemControl, dcControl.SerialNumberSystemControl.ConvertTo()); - ModbusTcpClient.WriteRegisters(SerialNumberDcDc, dcControl.SerialNumberDcDc.ConvertTo()); - ModbusTcpClient.WriteRegisters(MaterialNumberDcDc, dcControl.MaterialNumberDcDc.ConvertTo()); - - */ - // TODO starting from 4000, evaluate what/if needs updating below 4000 - - WriteRegs(TimeoutCommunication, c.TimeoutForCommunication.TotalSeconds.ConvertTo()); - - WriteCoils(PowerStageOperation, c.PowerStageEnable); - WriteCoils(ResetsAlarmAndWarning, c.ResetsAlarmAndWarning); - - WriteRegs (SlaveAddress, c.SlaveAddress, - c.SlaveAlarmPolicy); - - WriteRegs (SubSlaveAddress, c.SubSlaveAddress); - WriteCoils(ModbusSlaveId, c.ModbusSlaveId); - - WriteRegs(MaximumBatteryVoltage, 0.01m, c.MaximumBatteryVoltage, - c.MinimumBatteryVoltage); - - WriteRegs(MaximumBatteryChargingCurrent, 0.1m, c.MaximumBatteryChargingCurrent); - WriteRegs(MaximumBatteryDischargingCurrent, 0.1m, c.MaximumBatteryDischargingCurrent); - - WriteRegs(MaximalPowerAtDc, 1.0m, c.MaximalPowerAtDc); - WriteRegs(MaximumVoltageAlarmThreshold, 0.1m, c.MaximumVoltageAlarmThreshold); - WriteRegs(MinimumVoltageAlarmThreshold, 0.1m, c.MinimumVoltageAlarmThreshold); - - WriteRegs(BatteryCurrentSet, 1.0m, c.BatteryCurrentSet); - WriteRegs(DynamicCurrentPerMillisecond, 0.01m, c.DynamicCurrentPerMillisecond); - - WriteRegs(DcLinkControlMode, 1.0m, c.DcLinkControlMode); - WriteRegs(ReferenceVoltage, 0.1m, c.ReferenceVoltage, - c.UpperVoltageWindow, - c.LowerVoltageWindow, - c.VoltageDeadBand); - } - - private void WriteRegs (UInt16 a, Decimal res = 1.0m, params Decimal[] regs) => ModbusTcpClient.WriteRegisters(a, regs.ToUInt16(res)); - private void WriteRegs (UInt16 a, params UInt16[] regs) => ModbusTcpClient.WriteRegisters(a, regs); - private void WriteCoils(UInt16 a, params Boolean[] coils) => ModbusTcpClient.WriteMultipleCoils(a, coils); - - public TruConvertDcStatus? ReadStatus() - { - try - { - return TryReadStatus(); - } - catch (Exception) - { - ModbusTcpClient.CloseConnection(); - return null; - } - } - - - private static IEnumerable GetFlags(UInt16 input) - { - var ls = (DcCurrentLimitState)input; - - return Enum - .GetValues() - .Where(f => ls.HasFlag(f)); - } - - - private TruConvertDcStatus TryReadStatus() - { - // Console.WriteLine("Reading DC Device"); - var dcPrValMain = ModbusTcpClient.ReadInputRegisters(5001, 3); - var dcBatteryValue = ModbusTcpClient.ReadInputRegisters(5101, 1); - var dcBatteryValue2 = ModbusTcpClient.ReadInputRegisters(5111, 1); - var dcBatteryValue3 = ModbusTcpClient.ReadInputRegisters(5114, 2); - var dcBatteryValue4 = ModbusTcpClient.ReadInputRegisters(5121, 1); - var dcPrValDcDc = ModbusTcpClient.ReadInputRegisters(5124, 1); - var dcPrValDcDc2 = ModbusTcpClient.ReadInputRegisters(5127, 2); - var dcTempValue = ModbusTcpClient.ReadInputRegisters(5511, 1); - var dcWarningValues = ModbusTcpClient.ReadInputRegisters(2404, 20); - var dcAlarmValues = ModbusTcpClient.ReadInputRegisters(2811, 20); - var dcSetValues = ModbusTcpClient.ReadInputRegisters(4001, 1); - - var warnings = Enumerable - .Range(2404, 20) - .Select(n => dcWarningValues.GetUInt16((UInt16)n).ConvertTo()) - .Where(m => m != WarningMessage.NoWarning) - .ToArray(); - - var alarms = Enumerable - .Range(2811, 20) - .Select(n => dcAlarmValues.GetUInt16((UInt16)n).ConvertTo()) - .Where(m => m != AlarmMessage.NoAlarm) - .ToArray(); - - var dcCurrentLimitState = GetFlags(dcPrValDcDc.GetUInt16(5124)).ToArray(); - - var dcLinkVoltage = dcPrValDcDc2.GetUInt16(5128); - - var dcPower = dcBatteryValue4.GetInt16(5121) * 1m; - - var dcCurrent = dcLinkVoltage != 0m ? dcPower / dcLinkVoltage : 0m; - - return new TruConvertDcStatus - { - Left = new DcBus() - { - Current = dcCurrent, - Voltage = dcLinkVoltage - }, - - Right = new DcBus() - { - Current = dcBatteryValue2.GetInt16(5111), - Voltage =dcBatteryValue.GetUInt16(5101) * 0.1m, - }, - - MainState = (MainState)dcPrValMain.GetInt16(5001), - NumberOfConnectedSlaves = dcPrValMain.GetUInt16(5002), - NumberOfConnectedSubSlaves = dcPrValMain.GetUInt16(5003), - TotalDcPower = dcBatteryValue3.GetInt32(5114) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W - StatusOfCurrentLimiting = dcCurrentLimitState, - OverloadCapacity = dcPrValDcDc2.GetUInt16(5127) * 0.1m, - DcDcInletTemperature = dcTempValue.GetInt16(5511), - Warnings = warnings, - Alarms = alarms, - PowerOperation = dcSetValues.GetBoolean(4001), - - }; - } - -} \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs deleted file mode 100644 index 1937849fa..000000000 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs +++ /dev/null @@ -1,29 +0,0 @@ -using InnovEnergy.Lib.Devices.Trumpf.TruConvert; -using InnovEnergy.Lib.StatusApi; -using InnovEnergy.Lib.Units; -using InnovEnergy.Lib.Units.Composite; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; - -using AlarmMessages = IReadOnlyList; -using WarningMessages = IReadOnlyList; -using DcCurrentLimitStates = IReadOnlyList; - -public record TruConvertDcStatus : DcDcConverterStatus -{ - public MainState MainState { get; init; } - public Power TotalDcPower { get; init; } // TODO: necessary? - public DcCurrentLimitStates StatusOfCurrentLimiting { get; init; } - public Decimal OverloadCapacity { get; init; } - public Temperature DcDcInletTemperature { get; init; } - public AlarmMessages Alarms { get; init; } = Array.Empty(); - public WarningMessages Warnings { get; init; } = Array.Empty(); - public Boolean PowerOperation { get; init; } - public Decimal NumberOfConnectedSlaves { get; init; } // TODO: necessary? - public Decimal NumberOfConnectedSubSlaves { get; init; } // TODO: necessary? -} -// { -// public static TruConvertDcStatus operator |(TruConvertDcStatus left, TruConvertDcStatus right) => OpParallel(left, right); -// private static readonly Func OpParallel = Operators.Op("|"); -// } \ No newline at end of file