Trumpf V2
This commit is contained in:
parent
a2f5286e45
commit
9c2a8d0966
|
@ -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;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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.
|
||||
}
|
|
@ -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,
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes;
|
||||
|
||||
public enum PowerSetPointActivation : UInt16
|
||||
{
|
||||
Immediate = 0,
|
||||
Trigger = 1,
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes;
|
||||
|
||||
public enum PowerSetPointTrigger : UInt16
|
||||
{
|
||||
Wait = 0,
|
||||
Trigger = 1,
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes;
|
||||
|
||||
public enum ReferenceFrame : UInt16
|
||||
{
|
||||
Producer = 0,
|
||||
Consumer = 1,
|
||||
}
|
|
@ -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.
|
||||
}
|
|
@ -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.
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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: ???
|
||||
}
|
|
@ -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.)
|
||||
}
|
|
@ -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);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -1,43 +0,0 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl;
|
||||
|
||||
using AlarmMessages = IReadOnlyList<AlarmMessage>;
|
||||
using WarningMessages = IReadOnlyList<WarningMessage>;
|
||||
|
||||
|
||||
// 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; }
|
||||
}
|
|
@ -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.
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configurations>Debug;Release;Release-Server</Configurations>
|
||||
<Platforms>AnyCPU;linux-arm</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../../../InnovEnergy.Lib.props" />
|
||||
|
||||
<!-- <Import Project="../../../../App/InnovEnergy.App.props" />-->
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Protocols\Modbus\Modbus.csproj" />
|
||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -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<SystemControlRegisters> _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)
|
||||
public SystemControlDevice(Channel channel)
|
||||
{
|
||||
/*
|
||||
WriteRegs(AcControlRegisters.Date, new List<UInt16> { c.Date.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.Time, new List<UInt16> { c.Time.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.IpAddress, new List<UInt16> { c.IpAddress.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.Subnet, new List<UInt16> { c.Subnet.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.Gateway, new List<UInt16> { c.Gateway.ConvertTo<UInt16>()});
|
||||
WriteCoils(AcControlRegisters.ResetParamToDefault, c.ResetParamToDefault);
|
||||
WriteCoils(AcControlRegisters.FactoryResetParameters, c.FactoryResetParameters);
|
||||
ModbusTcpClient.WriteRegisters(AcControlRegisters.UpdateSwTrigger, c.UpdateSwTrigger, c.AutomaticSwUpdate, c.CustomerValuesSaveReset);
|
||||
*/
|
||||
Channel = channel;
|
||||
|
||||
|
||||
WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo<UInt16>());
|
||||
|
||||
WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig);
|
||||
|
||||
|
||||
WriteCoils(PowerStageConfig, c.PowerStageEnable,
|
||||
c.SetValueConfig.ConvertTo<Boolean>(),
|
||||
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<UInt16>(),
|
||||
c.SetPointSinPhi.ConvertTo<UInt16>(),
|
||||
c.SetPointSinPhiL1.ConvertTo<UInt16>(),
|
||||
c.SetPointSinPhiL2.ConvertTo<UInt16>(),
|
||||
c.SetPointSinPhiL3.ConvertTo<UInt16>(),
|
||||
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);
|
||||
var tcpClient = new ModbusTcpClient(channel, 0);
|
||||
_SystemControlSlave = new ModbusDevice<SystemControlRegisters>(tcpClient);
|
||||
}
|
||||
|
||||
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<UInt16>()).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()
|
||||
{
|
||||
try
|
||||
{
|
||||
return TryReadStatus();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ModbusTcpClient.CloseConnection();
|
||||
Console.WriteLine("Failed to read inverter status");
|
||||
e.Message.WriteLine();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
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<WarningMessage>())
|
||||
.ToArray();
|
||||
|
||||
var alarms = Enumerable
|
||||
.Range(2811, 20)
|
||||
.Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo<AlarmMessage>())
|
||||
.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<MainState>(),
|
||||
Alarms = alarms,
|
||||
Warnings = warnings,
|
||||
GridType = acActualAcDc.GetUInt16(5024).ConvertTo<AcDcGridType>(),
|
||||
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<MainState>(),
|
||||
// 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<AcDcGridType>(),
|
||||
// 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();
|
||||
}
|
|
@ -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<AlarmMessage> 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<AlarmMessage> Alarms => GetAlarms()
|
||||
.Take(NumberOfAlarms)
|
||||
.Where(IsSystemControlAlarm)
|
||||
.ToList();
|
||||
|
||||
private static Boolean IsSystemControlAlarm(AlarmMessage alarm) => (UInt16)alarm is >= 40000 and < 50000;
|
||||
}
|
|
@ -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<UInt16>()
|
||||
: NoTimeout;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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<WarningMessage> 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<WarningMessage> Warnings => GetWarnings()
|
||||
.Take(NumberOfWarnings)
|
||||
.Where(w => w != WarningMessage.NoWarning)
|
||||
.ToList();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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,
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
||||
|
||||
public static class Slave
|
||||
{
|
||||
public const UInt16 Broadcast = 0;
|
||||
}
|
||||
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../Utils/Utils.csproj" />
|
||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
public static UInt16[] ToUInt16(this IEnumerable<Decimal> regs, Decimal resolution)
|
||||
{
|
||||
// LINQ
|
||||
return regs
|
||||
.Select(v => (Int16)(v / resolution))
|
||||
.Select(v => unchecked((UInt16)v))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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<AcDcRecord> devices)
|
||||
{
|
||||
SystemControl = systemControl;
|
||||
Devices = devices;
|
||||
}
|
||||
|
||||
public SystemControlRegisters? SystemControl { get; }
|
||||
public IReadOnlyList<AcDcRecord> Devices { get; init; }
|
||||
|
||||
public IEnumerable<AlarmMessage> Alarms => Devices.SelectMany(d => d.Status.Alarms).Distinct();
|
||||
public IEnumerable<WarningMessage> 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)
|
||||
);
|
||||
}
|
|
@ -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<Int16>(4206)] internal Double CosPhiSetpointL1;
|
||||
[HoldingRegister<Int16>(4207)] internal Double CosPhiSetpointL2;
|
||||
[HoldingRegister<Int16>(4208)] internal Double CosPhiSetpointL3;
|
||||
|
||||
[HoldingRegister<Int16>(4219)] internal Double SinPhiSetpointL1;
|
||||
[HoldingRegister<Int16>(4220)] internal Double SinPhiSetpointL2;
|
||||
[HoldingRegister<Int16>(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<Int16>(5140)] internal readonly Double ActivePowerL1;
|
||||
[InputRegister<Int16>(5141)] internal readonly Double ActivePowerL2;
|
||||
[InputRegister<Int16>(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<Int16>(5170, Scale = .01)] internal readonly Double CosPhiL1;// TODO: check that those agree with computed ones in AC
|
||||
[InputRegister<Int16>(5171, Scale = .01)] internal readonly Double CosPhiL2;// TODO: remove
|
||||
[InputRegister<Int16>(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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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<AcPower> GetEnumerator()
|
||||
// {
|
||||
// yield return L1;
|
||||
// yield return L2;
|
||||
// yield return L3;
|
||||
// }
|
||||
//
|
||||
// IEnumerator IEnumerable.GetEnumerator()
|
||||
// {
|
||||
// return GetEnumerator();
|
||||
// }
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
// }
|
||||
//
|
||||
//
|
|
@ -1,4 +1,4 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums;
|
||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum AcDcDistributionMode : UInt16
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums;
|
||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum AcErrorPolicy : UInt16
|
||||
{
|
|
@ -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.
|
|
@ -0,0 +1,9 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum DcPrechargeConfig : UInt16
|
||||
{
|
||||
WaitForExternalPrecharge = 0,
|
||||
PrechargeDcWithSystemCtl = 1,
|
||||
PrechargeDcWithDcDcs = 2,
|
||||
PrechargeDcWithSystemCtlAndWait = 3,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums;
|
||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum DcStageConfiguration : UInt16
|
||||
{
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum GridMode
|
||||
{
|
||||
GridTied = 0,
|
||||
Island = 1
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum PhaseControl : Byte
|
||||
{
|
||||
Asymmetric = 0,
|
||||
Symmetric = 1,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums;
|
||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum PowerFactorConvention : UInt16
|
||||
{
|
|
@ -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,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums;
|
||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum PreChargeDcLinkConfig : UInt16
|
||||
{
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum ReactivePowerKind
|
||||
{
|
||||
Inductive = 0,
|
||||
Capacitive = 1
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.Enums;
|
||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||
|
||||
public enum SymmetricAcOperationMode : UInt16
|
||||
{
|
|
@ -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
|
||||
|
||||
*/
|
||||
}
|
|
@ -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.
|
||||
}
|
|
@ -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 });
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
|
@ -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<AlarmMessage> Alarms => GetAlarms ().Take(_Self.NumberOfAlarms ).Where(IsAcDcAlarm ).ToList();
|
||||
public IReadOnlyList<WarningMessage> Warnings => GetWarnings().Take(_Self.NumberOfWarnings).Where(IsAcDcWarning).ToList();
|
||||
|
||||
private IEnumerable<AlarmMessage> 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<WarningMessage> 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;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -5,10 +5,12 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="../../../InnovEnergy.Lib.props" />
|
||||
|
||||
<!-- <Import Project="../../../../App/InnovEnergy.App.props" />-->
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
||||
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
||||
<ProjectReference Include="../SystemControl/SystemControl.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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<SystemControlRegisters> _SystemControl;
|
||||
private readonly IEnumerable<ModbusDevice<AcDcRecord>> _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<SystemControlRegisters>(modbusClient);
|
||||
|
||||
_AcDcs = Enumerable
|
||||
.Range(1, Byte.MaxValue - 1)
|
||||
.Memoize(CreateAcDc);
|
||||
|
||||
ModbusDevice<AcDcRecord> CreateAcDc(Int32 i)
|
||||
{
|
||||
var mb = new ModbusTcpClient(transport, (Byte)i);
|
||||
return new ModbusDevice<AcDcRecord>(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<AcDcRecord>());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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<UInt16>;
|
||||
|
||||
[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<UInt16> { c.Date.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.Time, new List<UInt16> { c.Time.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.IpAddress, new List<UInt16> { c.IpAddress.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.Subnet, new List<UInt16> { c.Subnet.ConvertTo<UInt16>()});
|
||||
WriteRegs(AcControlRegisters.Gateway, new List<UInt16> { c.Gateway.ConvertTo<UInt16>()});
|
||||
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<UInt16>());
|
||||
|
||||
WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig);
|
||||
|
||||
|
||||
WriteCoils(PowerStageConfig, c.PowerStageEnable,
|
||||
c.SetValueConfig.ConvertTo<Boolean>(),
|
||||
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<UInt16>(),
|
||||
c.SetPointSinPhi.ConvertTo<UInt16>(),
|
||||
c.SetPointSinPhiL1.ConvertTo<UInt16>(),
|
||||
c.SetPointSinPhiL2.ConvertTo<UInt16>(),
|
||||
c.SetPointSinPhiL3.ConvertTo<UInt16>(),
|
||||
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<UInt16>()).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<WarningMessage>())
|
||||
.ToArray();
|
||||
|
||||
var alarms = Enumerable
|
||||
.Range(2811, 20)
|
||||
.Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo<AlarmMessage>())
|
||||
.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<MainState>(),
|
||||
Alarms = alarms,
|
||||
Warnings = warnings,
|
||||
GridType = acActualAcDc.GetUInt16(5024).ConvertTo<AcDcGridType>(),
|
||||
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<MainState>(),
|
||||
// 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<AcDcGridType>(),
|
||||
// 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
|
||||
// );
|
||||
}
|
||||
}
|
|
@ -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<AlarmMessage>;
|
||||
using WarningMessages = IReadOnlyList<WarningMessage>;
|
||||
|
||||
|
||||
// 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; }
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control;
|
||||
|
||||
public enum DcControlMode : UInt16
|
||||
{
|
||||
CurrentSetpoint = 0,
|
||||
VoltageDroop = 1
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
@ -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<DcDcRecord> 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<DcDcRecord> Devices { get; }
|
||||
|
||||
public IEnumerable<AlarmMessage> Alarms => Devices.SelectMany(d => d.Status.Alarms ).Distinct();
|
||||
public IEnumerable<WarningMessage> Warnings => Devices.SelectMany(d => d.Status.Warnings).Distinct();
|
||||
|
||||
public static DcDcDevicesRecord Null { get; } = new DcDcDevicesRecord(null, Array.Empty<DcDcRecord>());
|
||||
}
|
|
@ -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<AlarmMessage> 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<AlarmMessage> Alarms => GetAlarms()
|
||||
.Take(NumberOfAlarms)
|
||||
.Where(IsDcDcAlarm)
|
||||
.ToList();
|
||||
|
||||
private static Boolean IsDcDcAlarm(AlarmMessage alarm) => (UInt16)alarm >= 60000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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<WarningMessage> 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<WarningMessage> Warnings => GetWarnings()
|
||||
.Take(NumberOfWarnings)
|
||||
.Where(IsDcDcWarning)
|
||||
.ToList();
|
||||
|
||||
private static Boolean IsDcDcWarning(WarningMessage warning) => (UInt16)warning is >= 11000 and < 12000;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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.
|
||||
|
||||
}
|
|
@ -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,
|
||||
}
|
|
@ -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<BatteryPowerLimit> PowerLimitedBy => ListActivePowerLimits();
|
||||
public IReadOnlyList<AlarmMessage> Alarms => ListAlarms();
|
||||
public IReadOnlyList<WarningMessage> Warnings => ListWarnings();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private AlarmMessage[] ListAlarms() => EnumerateAlarms()
|
||||
.Take(_Self.NumberOfAlarms)
|
||||
.ToArray(_Self.NumberOfAlarms);
|
||||
|
||||
private WarningMessage[] ListWarnings() => EnumerateWarnings()
|
||||
.Take(_Self.NumberOfWarnings)
|
||||
.ToArray(_Self.NumberOfWarnings);
|
||||
|
||||
private IEnumerable<WarningMessage> 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<AlarmMessage> 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<BatteryPowerLimit> ListActivePowerLimits()
|
||||
{
|
||||
return Utils
|
||||
.Utils
|
||||
.GetEnumValues<BatteryPowerLimit>()
|
||||
.Where(t => _Self.BatteryPowerLimit.HasFlag(t))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private readonly DcDcRecord _Self;
|
||||
internal DcDcStatus(DcDcRecord self) => _Self = self;
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
||||
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
||||
<ProjectReference Include="../SystemControl/SystemControl.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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<SystemControlRegisters> _SystemControl;
|
||||
private readonly IEnumerable<ModbusDevice<DcDcRecord>> _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<SystemControlRegisters>(modbusClient);
|
||||
|
||||
_DcDcs = Enumerable
|
||||
.Range(1, Byte.MaxValue - 1)
|
||||
.Memoize(CreateDcDc);
|
||||
|
||||
ModbusDevice<DcDcRecord> CreateDcDc(Int32 i)
|
||||
{
|
||||
var mb = new ModbusTcpClient(transport, (Byte)i);
|
||||
return new ModbusDevice<DcDcRecord>(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<DcDcRecord>());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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<UInt16>() });
|
||||
ModbusTcpClient.WriteRegisters(Time, new[] { dcControl.Time.ConvertTo<UInt16>() });
|
||||
ModbusTcpClient.WriteRegisters(IpAddress, dcControl.IpAddress.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteRegisters(Subnet, dcControl.Subnet.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteRegisters(Gateway, dcControl.Gateway.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteMultipleCoils(ResetParamToDefault, dcControl.ResetParamToDefault);
|
||||
ModbusTcpClient.WriteMultipleCoils(RestartFlag, dcControl.RestartFlag);
|
||||
ModbusTcpClient.WriteRegisters(DcControlRegisters.TimeoutCommunication, dcControl.TimeoutForCommunication.TotalSeconds.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteRegisters(ConnectedSystemConfig, dcControl.ConnectedSystemConfig.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteRegisters(UpdateSwTrigger, dcControl.UpdateSwTrigger, dcControl.AutomaticSwUpdate, dcControl.CustomerValuesSaveReset);
|
||||
ModbusTcpClient.WriteRegisters(SerialNumberSystemControl, dcControl.SerialNumberSystemControl.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteRegisters(SerialNumberDcDc, dcControl.SerialNumberDcDc.ConvertTo<UInt16>());
|
||||
ModbusTcpClient.WriteRegisters(MaterialNumberDcDc, dcControl.MaterialNumberDcDc.ConvertTo<UInt16>());
|
||||
|
||||
*/
|
||||
// TODO starting from 4000, evaluate what/if needs updating below 4000
|
||||
|
||||
WriteRegs(TimeoutCommunication, c.TimeoutForCommunication.TotalSeconds.ConvertTo<UInt16>());
|
||||
|
||||
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<DcCurrentLimitState> GetFlags(UInt16 input)
|
||||
{
|
||||
var ls = (DcCurrentLimitState)input;
|
||||
|
||||
return Enum
|
||||
.GetValues<DcCurrentLimitState>()
|
||||
.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<WarningMessage>())
|
||||
.Where(m => m != WarningMessage.NoWarning)
|
||||
.ToArray();
|
||||
|
||||
var alarms = Enumerable
|
||||
.Range(2811, 20)
|
||||
.Select(n => dcAlarmValues.GetUInt16((UInt16)n).ConvertTo<AlarmMessage>())
|
||||
.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),
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -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<AlarmMessage>;
|
||||
using WarningMessages = IReadOnlyList<WarningMessage>;
|
||||
using DcCurrentLimitStates = IReadOnlyList<DcCurrentLimitState>;
|
||||
|
||||
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<AlarmMessage>();
|
||||
public WarningMessages Warnings { get; init; } = Array.Empty<WarningMessage>();
|
||||
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<TruConvertDcStatus, TruConvertDcStatus, TruConvertDcStatus> OpParallel = Operators.Op<TruConvertDcStatus>("|");
|
||||
// }
|
Loading…
Reference in New Issue