Innovenergy_trunk/csharp/Lib/Devices/AMPT/AmptCommunicationUnit.cs

118 lines
3.5 KiB
C#
Raw Normal View History

2023-02-16 12:57:06 +00:00
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
2023-03-09 11:40:47 +00:00
using InnovEnergy.Lib.Units.Composite;
using static DecimalMath.DecimalEx;
2023-02-16 12:57:06 +00:00
namespace InnovEnergy.Lib.Devices.AMPT;
2023-02-16 12:57:06 +00:00
public class AmptCommunicationUnit
{
2023-03-09 11:40:47 +00:00
private ModbusTcpClient? Modbus { get; set; }
2023-02-16 12:57:06 +00:00
2023-03-09 11:40:47 +00:00
private const UInt16 RegistersPerDevice = 16;
private const UInt16 FirstDeviceOffset = 85;
public String Hostname { get; }
public UInt16 Port { get; }
public Byte SlaveAddress { get; }
2023-02-16 12:57:06 +00:00
public AmptCommunicationUnit(String hostname, UInt16 port = 502, Byte slaveAddress = 1)
{
2023-03-09 11:40:47 +00:00
Hostname = hostname;
Port = port;
SlaveAddress = slaveAddress;
2023-02-16 12:57:06 +00:00
}
2023-03-09 11:40:47 +00:00
public AmptCommunicationUnitStatus? ReadStatus()
2023-02-16 12:57:06 +00:00
{
try
{
OpenConnection();
return TryReadStatus();
2023-02-16 12:57:06 +00:00
}
catch
2023-02-16 12:57:06 +00:00
{
CloseConnection();
2023-02-16 12:57:06 +00:00
return null;
}
}
2023-03-09 11:40:47 +00:00
private void CloseConnection()
{
try
{
Modbus?.CloseConnection();
}
catch
{
// ignored
}
Modbus = null;
}
private void OpenConnection()
2023-02-16 12:57:06 +00:00
{
2023-03-09 11:40:47 +00:00
if (Modbus is null)
{
var connection = new ModbusTcpConnection(Hostname, Port);
Modbus = new ModbusTcpClient(connection, SlaveAddress);
}
}
private AmptCommunicationUnitStatus TryReadStatus()
2023-03-09 11:40:47 +00:00
{
var r = Modbus!.ReadHoldingRegisters(1, 116);
2023-03-09 11:40:47 +00:00
var currentFactor = Pow(10.0m, r.GetInt16(73));
var voltageFactor = Pow(10.0m, r.GetInt16(74));
var energyFactor = Pow(10.0m, r.GetInt16(76) + 3); // +3 => converted from Wh to kWh
2023-02-16 12:57:06 +00:00
var nbrOfDevices = r.GetUInt16(78);
var devices = Enumerable
.Range(0, nbrOfDevices)
.Select(ReadDeviceStatus)
.ToList();
2023-03-09 11:40:47 +00:00
return new AmptCommunicationUnitStatus
2023-02-16 12:57:06 +00:00
{
2023-03-09 11:40:47 +00:00
Sid = r.GetUInt32(1),
IdSunSpec = r.GetUInt16(3),
Manufacturer = r.GetString(5, 16),
Model = r.GetString(21, 16),
Version = r.GetString(45, 8),
SerialNumber = r.GetString(53, 16),
DeviceAddress = r.GetInt16(69),
IdVendor = r.GetUInt16(71),
Devices = devices
};
2023-02-16 12:57:06 +00:00
2023-03-09 11:40:47 +00:00
AmptStatus ReadDeviceStatus(Int32 deviceNumber)
2023-02-16 12:57:06 +00:00
{
2023-03-09 11:40:47 +00:00
var baseAddress = (UInt16)(FirstDeviceOffset + deviceNumber * RegistersPerDevice); // base address
2023-02-16 12:57:06 +00:00
2023-03-09 11:40:47 +00:00
return new AmptStatus
{
Dc = new DcBus
{
Voltage = r.GetUInt32((UInt16)(baseAddress + 6)) * voltageFactor,
Current = r.GetUInt16((UInt16)(baseAddress + 5)) * currentFactor
},
Strings = new DcBus[]
2023-02-16 12:57:06 +00:00
{
2023-03-09 11:40:47 +00:00
new()
{
Voltage = r.GetUInt32((UInt16)(baseAddress + 8)) * voltageFactor,
Current = r.GetUInt16((UInt16)(baseAddress + 14)) * currentFactor
},
new()
{
Voltage = r.GetUInt32((UInt16)(baseAddress + 9)) * voltageFactor,
Current = r.GetUInt16((UInt16)(baseAddress + 15)) * currentFactor
}
},
ProductionToday = r.GetUInt32((UInt16)(baseAddress + 12)) * energyFactor,
};
2023-02-16 12:57:06 +00:00
}
}
}