2023-02-16 12:57:06 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
2023-04-04 11:43:23 +00:00
|
|
|
using InnovEnergy.Lib.Units.Composite;
|
2023-02-16 12:57:06 +00:00
|
|
|
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
|
|
|
|
|
2023-02-23 12:45:09 +00:00
|
|
|
WriteRegs(TimeoutCommunication, c.TimeoutForCommunication.TotalSeconds.ConvertTo<UInt16>());
|
2023-02-16 12:57:06 +00:00
|
|
|
|
|
|
|
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);
|
2023-02-23 12:45:09 +00:00
|
|
|
var dcBatteryValue4 = ModbusTcpClient.ReadInputRegisters(5121, 1);
|
2023-02-16 12:57:06 +00:00
|
|
|
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();
|
|
|
|
|
2023-02-23 12:45:09 +00:00
|
|
|
var dcLinkVoltage = dcPrValDcDc2.GetUInt16(5128);
|
|
|
|
|
|
|
|
var dcPower = dcBatteryValue4.GetInt16(5121) * 1m;
|
|
|
|
|
|
|
|
var dcCurrent = dcLinkVoltage != 0m ? dcPower / dcLinkVoltage : 0m;
|
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
return new TruConvertDcStatus
|
2023-04-04 11:43:23 +00:00
|
|
|
{
|
|
|
|
Left = new DcBus()
|
|
|
|
{
|
|
|
|
Current = dcCurrent,
|
|
|
|
Voltage = dcLinkVoltage
|
|
|
|
},
|
|
|
|
|
|
|
|
Right = new DcBus()
|
|
|
|
{
|
|
|
|
Current = dcBatteryValue2.GetInt16(5111),
|
|
|
|
Voltage =dcBatteryValue.GetUInt16(5101) * 0.1m,
|
|
|
|
},
|
2023-02-16 12:57:06 +00:00
|
|
|
|
2023-04-04 11:43:23 +00:00
|
|
|
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),
|
|
|
|
|
|
|
|
};
|
2023-02-16 12:57:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|