using DecimalMath; using InnovEnergy.Lib.Protocols.Modbus.Clients; using InnovEnergy.Lib.Protocols.Modbus.Connections; using InnovEnergy.Lib.StatusApi.Connections; using InnovEnergy.Lib.Units.Composite; using InnovEnergy.Lib.Utils; using static DecimalMath.DecimalEx; namespace InnovEnergy.Lib.Devices.EmuMeter; public class EmuMeterDevice { private ModbusTcpClient Modbus { get; } public EmuMeterDevice(String hostname, UInt16 port = 502, Byte slaveId = 1) { var connection = new ModbusTcpConnection(hostname, port); Modbus = new ModbusTcpClient(connection, slaveId); } public EmuMeterStatus? ReadStatus() { try { return TryReadStatus(); } catch (Exception) { Modbus.CloseConnection(); return null; } } //private static Decimal GetPhi(Decimal cosPhi) => cosPhi.Clamp(-1m, 1m).Apply(ACos); private EmuMeterStatus TryReadStatus() { // Console.WriteLine("Reading Emu Meter Data"); var powerCurrent = Modbus.ReadHoldingRegisters(9000, 108).ToDecimals(); // TODO "ModbusRegisters" var voltageFreq = Modbus.ReadHoldingRegisters(9200, 112).ToDecimals(); // To check with Ivo var energyTotal = Modbus.ReadHoldingRegisters(6000, 24) .ToUInt64s(); var energyPhases = Modbus.ReadHoldingRegisters(6100, 104).ToUInt64s(); var activePowerL123 = powerCurrent[0]; var activePowerL1 = powerCurrent[1]; var activePowerL2 = powerCurrent[2]; var activePowerL3 = powerCurrent[3]; var reactivePowerL123 = powerCurrent[5]; var reactivePowerL1 = powerCurrent[6]; var reactivePowerL2 = powerCurrent[7]; var reactivePowerL3 = powerCurrent[8]; var apparentPowerL123 = powerCurrent[10]; var apparentPowerL1 = powerCurrent[11]; var apparentPowerL2 = powerCurrent[12]; var apparentPowerL3 = powerCurrent[13]; var currentL123 = powerCurrent[50]; var currentL1 = powerCurrent[51]; var currentL2 = powerCurrent[52]; var currentL3 = powerCurrent[53]; var voltageL1N = voltageFreq[0]; var voltageL2N = voltageFreq[1]; var voltageL3N = voltageFreq[2]; var voltageL1L2 = voltageFreq[3]; var voltageL2L3 = voltageFreq[4]; var voltageL3L1 = voltageFreq[5]; var powerFactorL1 = voltageFreq[50]; var powerFactorL2 = voltageFreq[51]; var powerFactorL3 = voltageFreq[52]; var frequency = voltageFreq[55]; var energyImportL123 = energyTotal[0 / 4] / 1000.0m; var energyExportL123 = energyTotal[20 / 4] / 1000.0m; var energyImportL1 = energyPhases[0 / 4] / 1000.0m; var energyExportL1 = energyPhases[20 / 4] / 1000.0m; var energyImportL2 = energyPhases[40 / 4] / 1000.0m; var energyExportL2 = energyPhases[60 / 4] / 1000.0m; var energyImportL3 = energyPhases[80 / 4] / 1000.0m; var energyExportL3 = energyPhases[100 / 4] / 1000.0m; // Ac: new Ac3Bus // ( // new AcPhase( // voltageL1N, // currentL1, // GetPhi(powerFactorL1) // ), // // new AcPhase( // voltageL2N, // currentL2, // GetPhi(powerFactorL2) // ), // // new AcPhase( // voltageL3N, // currentL3, // GetPhi(powerFactorL3) // ), // frequency // ), // activePowerL123, // reactivePowerL123, // apparentPowerL123, // currentL123, // voltageL1L2, // voltageL2L3, // voltageL3L1, // energyImportL123, // energyImportL1, // energyImportL2, // energyImportL3, // energyExportL123, // energyExportL1, // energyExportL2, // energyExportL3 // ); return new EmuMeterStatus { Ac = new Ac3Bus { Frequency = frequency, L1 = new AcPhase { Current = currentL1, Voltage = voltageL1N, Phi = ATan2(reactivePowerL1, activePowerL1) // TODO: check that this works }, L2 = new AcPhase { Current = currentL2, Voltage = voltageL2N, Phi = ATan2(reactivePowerL2, activePowerL2) }, L3 = new AcPhase { Current = currentL3, Voltage = voltageL3N, Phi = ATan2(reactivePowerL3, activePowerL3) } } }; } }