diff --git a/csharp/InnovEnergy.sln b/csharp/InnovEnergy.sln index 64acaf80f..beaac246d 100644 --- a/csharp/InnovEnergy.sln +++ b/csharp/InnovEnergy.sln @@ -75,6 +75,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "Lib\Logging\Logg EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adam6360D", "Lib\Devices\Adam6360D\Adam6360D.csproj", "{A3C79247-4CAA-44BE-921E-7285AB39E71F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IEM3kGridMeter", "Lib\Devices\IEM3kGridMeter\IEM3kGridMeter.csproj", "{1391165D-51F1-45B4-8B7F-042A20AA0277}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -190,6 +192,10 @@ Global {A3C79247-4CAA-44BE-921E-7285AB39E71F}.Debug|Any CPU.Build.0 = Debug|Any CPU {A3C79247-4CAA-44BE-921E-7285AB39E71F}.Release|Any CPU.ActiveCfg = Release|Any CPU {A3C79247-4CAA-44BE-921E-7285AB39E71F}.Release|Any CPU.Build.0 = Release|Any CPU + {1391165D-51F1-45B4-8B7F-042A20AA0277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1391165D-51F1-45B4-8B7F-042A20AA0277}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1391165D-51F1-45B4-8B7F-042A20AA0277}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1391165D-51F1-45B4-8B7F-042A20AA0277}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {CF4834CB-91B7-4172-AC13-ECDA8613CD17} = {145597B4-3E30-45E6-9F72-4DD43194539A} @@ -223,5 +229,6 @@ Global {B816BB44-E97E-4E02-B80A-BEDB5B923A96} = {DDDBEFD0-5DEA-4C7C-A9F2-FDB4636CF092} {1A56992B-CB72-490F-99A4-DF1186BA3A18} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {A3C79247-4CAA-44BE-921E-7285AB39E71F} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} + {1391165D-51F1-45B4-8B7F-042A20AA0277} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} EndGlobalSection EndGlobal diff --git a/csharp/Lib/Devices/IEM3kGridMeter/Doc/Acti 9 iEM3000_A9MEM3255.pdf b/csharp/Lib/Devices/IEM3kGridMeter/Doc/Acti 9 iEM3000_A9MEM3255.pdf new file mode 100644 index 000000000..fc758ccd2 Binary files /dev/null and b/csharp/Lib/Devices/IEM3kGridMeter/Doc/Acti 9 iEM3000_A9MEM3255.pdf differ diff --git a/csharp/Lib/Devices/IEM3kGridMeter/Doc/DOCA0005EN-13.pdf b/csharp/Lib/Devices/IEM3kGridMeter/Doc/DOCA0005EN-13.pdf new file mode 100644 index 000000000..3d954f8cd Binary files /dev/null and b/csharp/Lib/Devices/IEM3kGridMeter/Doc/DOCA0005EN-13.pdf differ diff --git a/csharp/Lib/Devices/IEM3kGridMeter/Doc/NHA15801-06.pdf b/csharp/Lib/Devices/IEM3kGridMeter/Doc/NHA15801-06.pdf new file mode 100644 index 000000000..9da2ba2a5 Binary files /dev/null and b/csharp/Lib/Devices/IEM3kGridMeter/Doc/NHA15801-06.pdf differ diff --git a/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeter.csproj b/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeter.csproj new file mode 100644 index 000000000..622823c62 --- /dev/null +++ b/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeter.csproj @@ -0,0 +1,14 @@ + + + + + InnovEnergy.Lib.Devices.IEM3kGridMeter + + + + + + + + + diff --git a/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeterDevice.cs b/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeterDevice.cs new file mode 100644 index 000000000..de9e04b62 --- /dev/null +++ b/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeterDevice.cs @@ -0,0 +1,50 @@ +using InnovEnergy.Lib.Protocols.Modbus.Channels; +using InnovEnergy.Lib.Protocols.Modbus.Clients; +using InnovEnergy.Lib.Protocols.Modbus.Slaves; +using InnovEnergy.Lib.Utils; + +namespace InnovEnergy.Lib.Devices.IEM3kGridMeter; + +public class Iem3KGridMeterDevice: ModbusDevice +{ + public Iem3KGridMeterDevice(String hostname, UInt16 port = 502, Byte slaveId = 1) : this(new TcpChannel(hostname, port), slaveId) + { + } + + public Iem3KGridMeterDevice(Channel channel, Byte slaveId = 1) : base(new ModbusTcpClient(channel, slaveId)) + { + } + + public Iem3KGridMeterDevice(ModbusClient client) : base(client) + { + } + + + public new Iem3KGridMeterRegisters? Read() + { + try + { + return base.Read(); + } + catch + { + // TODO: Log + $"Failed to read data from {nameof(Iem3KGridMeterDevice)}".WriteLine(); + return null; + } + } + + + public new void Write(Iem3KGridMeterRegisters registers) + { + try + { + base.Write(registers); + } + catch + { + // TODO: Log + $"Failed to write data to {nameof(Iem3KGridMeterDevice)}".WriteLine(); + } + } +} \ No newline at end of file diff --git a/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeterRegisters.cs b/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeterRegisters.cs new file mode 100644 index 000000000..19fe9907a --- /dev/null +++ b/csharp/Lib/Devices/IEM3kGridMeter/IEM3kGridMeterRegisters.cs @@ -0,0 +1,73 @@ +using InnovEnergy.Lib.Protocols.Modbus.Reflection.Attributes; +using InnovEnergy.Lib.StatusApi.DeviceTypes; +using InnovEnergy.Lib.Units.Composite; + +#pragma warning disable CS0649 + +namespace InnovEnergy.Lib.Devices.IEM3kGridMeter; + +using Float32 = Single; + + +[AddressOffset(-2)] // why? +public class Iem3KGridMeterRegisters : IAc3Meter +{ + + // TODO + // The registers below are kept as example (from EmuMeter) + // replace with actual registers from datasheet + + [HoldingRegister(9002)] private Float32 _ActivePowerL1; + [HoldingRegister(9004)] private Float32 _ActivePowerL2; + [HoldingRegister(9006)] private Float32 _ActivePowerL3; + + [HoldingRegister(9012)] private Float32 _ReactivePowerL1; + [HoldingRegister(9014)] private Float32 _ReactivePowerL2; + [HoldingRegister(9016)] private Float32 _ReactivePowerL3; + + [HoldingRegister(9022)] private Float32 _ApparentPowerL1; + [HoldingRegister(9024)] private Float32 _ApparentPowerL2; + [HoldingRegister(9026)] private Float32 _ApparentPowerL3; + + [HoldingRegister(9102)] private Float32 _CurrentL1; + [HoldingRegister(9104)] private Float32 _CurrentL2; + [HoldingRegister(9106)] private Float32 _CurrentL3; + + [HoldingRegister(9200)] private Float32 _VoltageL1N; + [HoldingRegister(9202)] private Float32 _VoltageL2N; + [HoldingRegister(9204)] private Float32 _VoltageL3N; + + [HoldingRegister(9310)] private Float32 _Frequency; + + public Ac3Bus Ac => Ac3Bus.FromPhasesAndFrequency + ( + l1: AcPhase.FromVoltageCurrentActiveReactiveApparent + ( + _VoltageL1N, + _CurrentL1, + _ActivePowerL1, + _ReactivePowerL1, + _ApparentPowerL1 + ), + l2: AcPhase.FromVoltageCurrentActiveReactiveApparent + ( + _VoltageL2N, + _CurrentL2, + _ActivePowerL2, + _ReactivePowerL2, + _ApparentPowerL2 + ), + l3: AcPhase.FromVoltageCurrentActiveReactiveApparent + ( + _VoltageL3N, + _CurrentL3, + _ActivePowerL3, + _ReactivePowerL3, + _ApparentPowerL3 + ), + frequency: _Frequency + ); +} + + +