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;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl;
|
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes;
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
public enum AlarmMessage
|
public enum AlarmMessage : UInt16
|
||||||
{
|
{
|
||||||
NoAlarm = 0,
|
NoAlarm = 0,
|
||||||
BmsCommunicationTimeoutHasOccured = 40302, // BMS communication timeout has occured.
|
BmsCommunicationTimeoutHasOccured = 40302, // BMS communication timeout has occured.
|
||||||
Rs485CommunicationAlarm = 40303, // RS-485 communication alarm.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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,
|
PowerUp = 0,
|
||||||
Alarm = 1,
|
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
|
GridTied400V50Hz = 0, // grid-tied, 400V, 50Hz
|
||||||
GridTied480V60Hz = 1, // grid-tied, 480V, 60Hz
|
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
|
public enum SystemConfig : UInt16
|
||||||
{
|
{
|
||||||
NoConfig = 0,
|
NoConfig = 0,
|
||||||
Simulator = 1,
|
Simulator = 1,
|
||||||
DcDcOnly = 2,
|
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">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
|
||||||
<Configurations>Debug;Release;Release-Server</Configurations>
|
<Import Project="../../../InnovEnergy.Lib.props" />
|
||||||
<Platforms>AnyCPU;linux-arm</Platforms>
|
|
||||||
</PropertyGroup>
|
<!-- <Import Project="../../../../App/InnovEnergy.App.props" />-->
|
||||||
<Import Project="../../../InnovEnergy.Lib.props" />
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\Protocols\Modbus\Modbus.csproj" />
|
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
using InnovEnergy.Lib.Protocols.Modbus.Slaves;
|
||||||
using InnovEnergy.Lib.Utils;
|
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.SystemControlRegisters;
|
|
||||||
|
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl;
|
namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl;
|
||||||
|
@ -10,315 +9,21 @@ namespace InnovEnergy.Lib.Devices.Trumpf.SystemControl;
|
||||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||||
public class SystemControlDevice
|
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 SystemControlDevice(Channel channel)
|
||||||
public void WriteControl(ControlRecord c)
|
|
||||||
{
|
{
|
||||||
/*
|
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);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
var tcpClient = new ModbusTcpClient(channel, 0);
|
||||||
WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo<UInt16>());
|
_SystemControlSlave = new ModbusDevice<SystemControlRegisters>(tcpClient);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteRegs (UInt16 a, Decimal res = 1.0m, params Decimal[] regs) => ModbusTcpClient.WriteRegisters(a, regs.ToUInt16(res));
|
public void Write(SystemControlRegisters c) => _SystemControlSlave.Write(c);
|
||||||
private void WriteRegs (UInt16 a, params IConvertible[] regs) => ModbusTcpClient.WriteRegisters(a, regs.Select(v => v.ConvertTo<UInt16>()).ToArray());
|
public SystemControlRegisters Read() => _SystemControlSlave.Read();
|
||||||
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
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../../Utils/Utils.csproj" />
|
<ProjectReference Include="../../../Utils/Utils.csproj" />
|
||||||
|
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</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
|
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
|
public enum AcErrorPolicy : UInt16
|
||||||
{
|
{
|
|
@ -1,22 +1,12 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "IdentifierTypo")]
|
[SuppressMessage("ReSharper", "IdentifierTypo")]
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
[SuppressMessage("ReSharper", "CommentTypo")]
|
[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.
|
OvertemperatureIgbtBridge1 = 50000, // Overtemperature IGBT bridge 1.
|
||||||
OvertemperatureIgbtBridge2 = 50001, // Overtemperature IGBT bridge 2.
|
OvertemperatureIgbtBridge2 = 50001, // Overtemperature IGBT bridge 2.
|
||||||
OvertemperatureIgbtBridge3 = 50002, // Overtemperature IGBT bridge 3.
|
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
|
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
|
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
|
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
|
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>
|
</PropertyGroup>
|
||||||
<Import Project="../../../InnovEnergy.Lib.props" />
|
<Import Project="../../../InnovEnergy.Lib.props" />
|
||||||
|
|
||||||
|
<!-- <Import Project="../../../../App/InnovEnergy.App.props" />-->
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||||
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
||||||
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
<ProjectReference Include="../SystemControl/SystemControl.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</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;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Status;
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "IdentifierTypo")]
|
[SuppressMessage("ReSharper", "IdentifierTypo")]
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
|
@ -29,5 +29,4 @@ public enum WarningMessage
|
||||||
HveepromWrite1 = 11018, //DC-DC module warning
|
HveepromWrite1 = 11018, //DC-DC module warning
|
||||||
HveepromWrite2 = 11019, //DC-DC module warning
|
HveepromWrite2 = 11019, //DC-DC module warning
|
||||||
HveepromWrite3 = 11020 //DC-DC module warning
|
HveepromWrite3 = 11020 //DC-DC module warning
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||||
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
|
||||||
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
||||||
|
<ProjectReference Include="../SystemControl/SystemControl.csproj" />
|
||||||
</ItemGroup>
|
</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