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

131 lines
4.4 KiB
C#
Raw Normal View History

2023-02-16 12:57:06 +00:00
using DecimalMath;
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
using InnovEnergy.Lib.StatusApi.Connections;
2023-02-16 12:57:06 +00:00
namespace InnovEnergy.Lib.Devices.AMPT;
2023-02-16 12:57:06 +00:00
public class AmptCommunicationUnit
{
private ModbusTcpClient Modbus { get; }
private const Int32 RegistersPerDevice = 16;
private const Int32 FirstDeviceOffset = 85;
public AmptCommunicationUnit(String hostname, UInt16 port = 502, Byte slaveAddress = 1)
{
var connection = new ModbusTcpConnection(hostname, port);
Modbus = new ModbusTcpClient(connection, slaveAddress);
}
public AmptStatus? ReadStatus()
{
try
{
return TryReadStatus();
}
catch (Exception)
{
Modbus.CloseConnection();
return null;
}
}
private AmptStatus TryReadStatus()
{
// Console.WriteLine("Reading Ampt Device");
var r = Modbus.ReadHoldingRegisters(1, 116);
var currentFactor = DecimalEx.Pow(10.0m, r.GetInt16(73));
var voltageFactor = DecimalEx.Pow(10.0m, r.GetInt16(74));
var energyFactor = DecimalEx.Pow(10.0m, r.GetInt16(76) + 3); // +3 => converted from Wh to kWh
var nbrOfDevices = r.GetUInt16(78);
var devices = Enumerable
.Range(0, nbrOfDevices)
.Select(ReadDeviceStatus)
.ToList();
var amptSt = new AmptStatus
(
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
// devices.d Current1 = r.GetInt16(90) * currentFactor,
// Current2 = r.GetInt16(106) * currentFactor,
// Voltage1 = r.GetUInt32(91) * voltageFactor,
// Voltage2 = r.GetUInt32(107) * voltageFactor
2023-02-16 12:57:06 +00:00
);
2023-02-16 12:57:06 +00:00
return amptSt;
Decimal ReadDevicesVoltage(Int32 numberOfDevice)
{
var avgVoltage = 0.0m;
for (var i = 0; i < numberOfDevice; i++)
{
var b = (UInt16)(FirstDeviceOffset + i * RegistersPerDevice); // base address
avgVoltage+= r.GetUInt32((UInt16)(b + 6)) * voltageFactor;
}
return avgVoltage / numberOfDevice;
}
Decimal ReadDevicesCurrent(Int32 numberOfDevice)
{
Decimal avgCurrent = 0;
for (var i = 0; i < numberOfDevice; i++)
{
var b = (UInt16)(FirstDeviceOffset + i * RegistersPerDevice); // base address
avgCurrent+= r!.GetUInt32((UInt16)(b + 5)) * voltageFactor;
}
return avgCurrent / numberOfDevice;
}
AmptDeviceStatus ReadDeviceStatus(Int32 deviceNumber)
{
var b = (UInt16)(FirstDeviceOffset + deviceNumber * RegistersPerDevice); // base address
return new AmptDeviceStatus
(
Dc : new DcConnection
(
Voltage:r.GetUInt32((UInt16)(b + 6)) * voltageFactor,
Current:r.GetUInt16((UInt16)(b + 5)) * currentFactor
),
DeviceId : r.GetInt16 (b) ,
Timestamp : r.GetUInt32((UInt16)(b + 3)),
ProductionToday : r.GetUInt32((UInt16)(b + 12))* energyFactor,
Strings : new []
2023-02-16 12:57:06 +00:00
{
new DcConnection
(
Voltage : r.GetUInt32((UInt16)(b + 8)) * voltageFactor,
Current : r.GetUInt16((UInt16)(b + 14)) * currentFactor
),
new DcConnection
(
Voltage : r.GetUInt32((UInt16)(b + 9)) * voltageFactor,
Current : r.GetUInt16((UInt16)(b + 15)) * currentFactor
)
2023-02-16 12:57:06 +00:00
}
);
2023-02-16 12:57:06 +00:00
}
}
}