Innovenergy_trunk/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs

168 lines
7.9 KiB
C#

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),
};
}
}