diff --git a/csharp/App/Backend/Controllers/Controller.cs b/csharp/App/Backend/Controllers/Controller.cs index 345ac4e58..1aac55752 100644 --- a/csharp/App/Backend/Controllers/Controller.cs +++ b/csharp/App/Backend/Controllers/Controller.cs @@ -4,6 +4,7 @@ using Innovenergy.Backend.Database; using Innovenergy.Backend.Model; using Innovenergy.Backend.Model.Relations; using Innovenergy.Backend.Utils; +using InnovEnergy.Lib.Utils; using Microsoft.AspNetCore.Mvc; using HttpContextAccessor = Microsoft.AspNetCore.Http.HttpContextAccessor; @@ -173,7 +174,8 @@ public class Controller using var db = Db.Connect(); var folders = db - .GetDirectlyAccessibleFolders(caller) // ReSharper disable once AccessToDisposedClosure + .GetDirectlyAccessibleFolders(caller) + .Do(f => f.ParentId = 0) // ReSharper disable once AccessToDisposedClosure .Select(f => PopulateChildren(db, f)); var installations = db.GetDirectlyAccessibleInstallations(caller); diff --git a/csharp/Lib/Devices/EmuMeter/doc/ModbusRegisters.pdf b/csharp/Lib/Devices/EmuMeter/doc/ModbusRegisters.pdf new file mode 100644 index 000000000..77bd4acf6 Binary files /dev/null and b/csharp/Lib/Devices/EmuMeter/doc/ModbusRegisters.pdf differ diff --git a/csharp/Lib/Protocols/Modbus/Clients/Endianness.cs b/csharp/Lib/Protocols/Modbus/Clients/Endianness.cs new file mode 100644 index 000000000..d53103dec --- /dev/null +++ b/csharp/Lib/Protocols/Modbus/Clients/Endianness.cs @@ -0,0 +1,10 @@ +namespace InnovEnergy.Lib.Protocols.Modbus.Clients; + +[Flags] +public enum Endianness +{ + LittleEndian32BitIntegers = 0, + LittleEndian32Floats = 0, + BigEndian32BitIntegers = 1, + BigEndian32Floats = 2, +} \ No newline at end of file diff --git a/csharp/Lib/Protocols/Modbus/Clients/ModbusClient.cs b/csharp/Lib/Protocols/Modbus/Clients/ModbusClient.cs index 66576d9d1..1bc736622 100644 --- a/csharp/Lib/Protocols/Modbus/Clients/ModbusClient.cs +++ b/csharp/Lib/Protocols/Modbus/Clients/ModbusClient.cs @@ -1,6 +1,6 @@ -using System.Threading.Channels; using InnovEnergy.Lib.Protocols.Modbus.Connections; using InnovEnergy.Lib.Protocols.Modbus.Conversions; +using static InnovEnergy.Lib.Protocols.Modbus.Clients.Endianness; namespace InnovEnergy.Lib.Protocols.Modbus.Clients; @@ -13,8 +13,9 @@ public abstract class ModbusClient { protected ModbusConnection Connection { get; } protected Byte SlaveId { get; } - - + protected Endianness Endianness { get; } + + // TODO: add additional functions: coils... public abstract Coils ReadDiscreteInputs (UInt16 readAddress, UInt16 nValues); @@ -40,11 +41,11 @@ public abstract class ModbusClient return WriteRegisters(writeAddress, (IReadOnlyList)values); } - - protected ModbusClient(ModbusConnection connection, Byte slaveId) + protected ModbusClient(ModbusConnection connection, Byte slaveId, Endianness endianness = LittleEndian32BitIntegers | LittleEndian32Floats) { Connection = connection; SlaveId = slaveId; + Endianness = endianness; } public void CloseConnection() => Connection.Close(); diff --git a/csharp/Lib/Protocols/Modbus/Clients/ModbusTcpClient.cs b/csharp/Lib/Protocols/Modbus/Clients/ModbusTcpClient.cs index 89824106c..c0506cbf3 100644 --- a/csharp/Lib/Protocols/Modbus/Clients/ModbusTcpClient.cs +++ b/csharp/Lib/Protocols/Modbus/Clients/ModbusTcpClient.cs @@ -4,13 +4,13 @@ using InnovEnergy.Lib.Protocols.Modbus.Conversions; using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Commands; using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Replies; using InnovEnergy.Lib.Protocols.Modbus.Tcp; +using static InnovEnergy.Lib.Protocols.Modbus.Clients.Endianness; namespace InnovEnergy.Lib.Protocols.Modbus.Clients; using UInt16s = IReadOnlyList; using Coils = IReadOnlyList; - public class ModbusTcpClient : ModbusClient { public const UInt16 DefaultPort = 502; @@ -20,7 +20,7 @@ public class ModbusTcpClient : ModbusClient private UInt16 NextId() => unchecked(++_Id); - public ModbusTcpClient(ModbusConnection connection, Byte slaveId) : base(connection, slaveId) + public ModbusTcpClient(ModbusConnection connection, Byte slaveId, Endianness endianness = LittleEndian32BitIntegers | LittleEndian32Floats) : base(connection, slaveId, endianness) { } diff --git a/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Bit.cs b/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Bit.cs index e2e02ed7e..2ab1061dc 100644 --- a/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Bit.cs +++ b/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Bit.cs @@ -1,4 +1,5 @@ using System.Collections; +using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Protocols.Modbus.Conversions; @@ -8,7 +9,7 @@ public partial class ModbusRegisters { var offset = index - StartRegister; - var byteArray = BitConverter.GetBytes(Registers[offset]).Reverse().ToArray(); + var byteArray = Registers[offset].Apply(BitConverter.GetBytes).Reverse().ToArray(); var bitArray = new BitArray(byteArray); return bitArray.Get(bitIndex); @@ -18,7 +19,7 @@ public partial class ModbusRegisters { var offset = index - StartRegister; - var byteArray = BitConverter.GetBytes(Registers[offset]).Reverse().ToArray(); + var byteArray = Registers[offset].Apply(BitConverter.GetBytes).Reverse().ToArray(); var bitArray = new BitArray(byteArray); bitArray.Set(bitIndex, value); diff --git a/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Single.cs b/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Single.cs index a6408185e..26f5776e6 100644 --- a/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Single.cs +++ b/csharp/Lib/Protocols/Modbus/Conversions/ModbusRegisters.Single.cs @@ -9,7 +9,7 @@ public partial class ModbusRegisters var bytearray = BitConverter.GetBytes(value).Reverse().ToArray(); var value32 = BitConverter.ToUInt32(bytearray); - Registers[index - StartRegister] = (UInt16)(value32 >> 16); + Registers[index - StartRegister ] = (UInt16)(value32 >> 16); Registers[index - StartRegister + 1] = (UInt16)(value32 & 0xFFFF); } diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs index 583ad6979..92282070e 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs @@ -9,8 +9,8 @@ public static class Accessors public static MbWord WordAt (this ArraySegment data, Byte i) => new MbWord(data, i); public static MbAddress AddressAt(this ArraySegment data, Byte i) => new MbAddress(data, i); - public static MbWords WordsAt(this ArraySegment data, Byte i) => new MbWords(data, i); - public static MbBits BitsAt (this ArraySegment data, Byte i) => new MbBits(data, i); + public static MbRegisters RegistersAt(this ArraySegment data, Byte i) => new MbRegisters(data, i); + public static MbBits BitsAt (this ArraySegment data, Byte i) => new MbBits(data, i); public static MbByte ByteAt(this ArraySegment data,Byte i) where T : struct, IConvertible => new MbByte(data, i); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbRegisters.cs similarity index 79% rename from csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs rename to csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbRegisters.cs index 30876dceb..a2124a9fa 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbRegisters.cs @@ -3,30 +3,30 @@ using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; -public readonly struct MbWords : IReadOnlyList +public readonly struct MbRegisters : IReadOnlyList { private readonly ArraySegment _Data; - internal MbWords(ArraySegment data, Byte startIndex) : this(data, startIndex, CountWords(data, startIndex)) + internal MbRegisters(ArraySegment data, Byte startIndex) : this(data, startIndex, CountWords(data, startIndex)) { } + + + internal MbRegisters(ArraySegment data, Byte startIndex, UInt16 wordCount) : this(data.Array!, startIndex, wordCount) + { + } + + internal MbRegisters(Byte[] data, Byte startIndex, UInt16 wordCount) + { + _Data = new ArraySegment(data, startIndex, wordCount * 2); + } + private static UInt16 CountWords(ArraySegment data, Byte startIndex) { var wordCount = (data.Count - startIndex) / 2; return wordCount.ConvertTo(); } - internal MbWords(ArraySegment data, Byte startIndex, UInt16 wordCount) : this(data.Array!, startIndex, wordCount) - { - - } - - - internal MbWords(Byte[] data, Byte startIndex, UInt16 wordCount) - { - _Data = new ArraySegment(data, startIndex, wordCount * 2); - } - internal IReadOnlyCollection Set(IReadOnlyCollection values) { if (values.Count != _Data.Count / 2) diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs index 1e4c8366f..57f86d379 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs @@ -16,7 +16,7 @@ internal class ReadWriteRegistersCommandFrame : ModbusFrame public MbAddress WriteAddress => Data.AddressAt(6); public MbWord NbToWrite => Data.WordAt(8); public MbByte ByteCount => Data.ByteAt(10); - public MbWords RegistersToWrite => Data.WordsAt(11); + public MbRegisters RegistersToWrite => Data.RegistersAt(11); public Int32 ExpectedResponseSize => ReadWriteRegistersResponseFrame.ExpectedSize(NbToRead); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs index af925ff9e..8eb4ca915 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs @@ -14,7 +14,7 @@ internal class WriteRegistersCommandFrame : ModbusFrame public MbAddress WriteAddress => Data.AddressAt(2); public MbWord NbOfRegisters => Data.WordAt(4); public MbByte ByteCount => Data.ByteAt(6); - public MbWords RegistersToWrite => Data.WordsAt(7); + public MbRegisters RegistersToWrite => Data.RegistersAt(7); public Int32 ExpectedResponseSize => WriteRegistersResponseFrame.ExpectedSize(); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs index 7fcd77983..ba8b3e707 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs @@ -11,7 +11,7 @@ internal class ReadHoldingRegistersResponseFrame : ModbusFrame internal new const Int32 MinSize = 3; public MbByte ByteCount => Data.ByteAt(2); - public MbWords RegistersRead => Data.WordsAt(3); + public MbRegisters RegistersRead => Data.RegistersAt(3); public ReadHoldingRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count)) diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs index 29cebda39..bb301e638 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs @@ -12,7 +12,7 @@ internal class ReadInputRegistersResponseFrame : ModbusFrame internal new const Int32 MinSize = 3; public MbByte ByteCount => Data.ByteAt(2); - public MbWords RegistersRead => Data.WordsAt(3); + public MbRegisters RegistersRead => Data.RegistersAt(3); public ReadInputRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count)) { diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs index 43eed5e21..ce7ecf2da 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs @@ -12,7 +12,7 @@ internal class ReadWriteRegistersResponseFrame : ModbusFrame internal new const Int32 MinSize = 3; public MbByte ByteCount => Data.ByteAt(2); - public MbWords RegistersRead => Data.WordsAt(3); + public MbRegisters RegistersRead => Data.RegistersAt(3); public ReadWriteRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count)) { diff --git a/csharp/Lib/StatusApi/DeviceStatus.cs b/csharp/Lib/StatusApi/DeviceStatus.cs index ef92280ab..380007d85 100644 --- a/csharp/Lib/StatusApi/DeviceStatus.cs +++ b/csharp/Lib/StatusApi/DeviceStatus.cs @@ -1,26 +1,14 @@ -using System.Text.Json; using InnovEnergy.Lib.Utils; -using static InnovEnergy.Lib.Units.Units; namespace InnovEnergy.Lib.StatusApi; public abstract record DeviceStatus { - private static readonly JsonSerializerOptions JsonSerializerOptions; - - static DeviceStatus() - { - JsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; - JsonConverters.ForEach(JsonSerializerOptions.Converters.Add); // how stupid is that?!! - } - public String DeviceType => GetType() - .Generate(t => t.BaseType!) + .Unfold(t => t.BaseType) .First(t => t.IsAbstract) .Name .Replace("Status", ""); - - public String ToJson() => JsonSerializer.Serialize(this, GetType(), JsonSerializerOptions); } diff --git a/csharp/Lib/SysTools/SysTools.csproj b/csharp/Lib/SysTools/SysTools.csproj index 629608dc6..72e17cc9b 100644 --- a/csharp/Lib/SysTools/SysTools.csproj +++ b/csharp/Lib/SysTools/SysTools.csproj @@ -6,7 +6,7 @@ - + diff --git a/csharp/Lib/Units/Angle.generated.cs b/csharp/Lib/Units/Angle.generated.cs index 0c1abd7e5..837f0b2a2 100644 --- a/csharp/Lib/Units/Angle.generated.cs +++ b/csharp/Lib/Units/Angle.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Angle; +[JsonConverter(typeof(AngleConverter))] public readonly partial struct Angle { public Decimal Value { get; } diff --git a/csharp/Lib/Units/ApparentPower.generated.cs b/csharp/Lib/Units/ApparentPower.generated.cs index ae632e889..a72053726 100644 --- a/csharp/Lib/Units/ApparentPower.generated.cs +++ b/csharp/Lib/Units/ApparentPower.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = ApparentPower; +[JsonConverter(typeof(ApparentPowerConverter))] public readonly partial struct ApparentPower { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Current.generated.cs b/csharp/Lib/Units/Current.generated.cs index 1bb733666..c06cb3ff0 100644 --- a/csharp/Lib/Units/Current.generated.cs +++ b/csharp/Lib/Units/Current.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Current; +[JsonConverter(typeof(CurrentConverter))] public readonly partial struct Current { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Frequency.generated.cs b/csharp/Lib/Units/Frequency.generated.cs index b1e8c6e65..576e7b1a4 100644 --- a/csharp/Lib/Units/Frequency.generated.cs +++ b/csharp/Lib/Units/Frequency.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Frequency; +[JsonConverter(typeof(FrequencyConverter))] public readonly partial struct Frequency { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Generator/Template.txt b/csharp/Lib/Units/Generator/Template.txt index 857ecad58..38e30aa04 100644 --- a/csharp/Lib/Units/Generator/Template.txt +++ b/csharp/Lib/Units/Generator/Template.txt @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Template; +[JsonConverter(typeof(TemplateConverter))] public readonly partial struct Template { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Number.generated.cs b/csharp/Lib/Units/Number.generated.cs index 4e533f664..4c6eb5693 100644 --- a/csharp/Lib/Units/Number.generated.cs +++ b/csharp/Lib/Units/Number.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Number; +[JsonConverter(typeof(NumberConverter))] public readonly partial struct Number { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Power.generated.cs b/csharp/Lib/Units/Power.generated.cs index 923275e3b..1e68ec3a8 100644 --- a/csharp/Lib/Units/Power.generated.cs +++ b/csharp/Lib/Units/Power.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Power; +[JsonConverter(typeof(PowerConverter))] public readonly partial struct Power { public Decimal Value { get; } diff --git a/csharp/Lib/Units/ReactivePower.generated.cs b/csharp/Lib/Units/ReactivePower.generated.cs index 252438ae1..f6b694b7a 100644 --- a/csharp/Lib/Units/ReactivePower.generated.cs +++ b/csharp/Lib/Units/ReactivePower.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = ReactivePower; +[JsonConverter(typeof(ReactivePowerConverter))] public readonly partial struct ReactivePower { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Resistance.generated.cs b/csharp/Lib/Units/Resistance.generated.cs index d81ace678..6918e60dd 100644 --- a/csharp/Lib/Units/Resistance.generated.cs +++ b/csharp/Lib/Units/Resistance.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Resistance; +[JsonConverter(typeof(ResistanceConverter))] public readonly partial struct Resistance { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Temperature.generated.cs b/csharp/Lib/Units/Temperature.generated.cs index e0ff31eaa..c182f6737 100644 --- a/csharp/Lib/Units/Temperature.generated.cs +++ b/csharp/Lib/Units/Temperature.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Temperature; +[JsonConverter(typeof(TemperatureConverter))] public readonly partial struct Temperature { public Decimal Value { get; } diff --git a/csharp/Lib/Units/Units.csproj b/csharp/Lib/Units/Units.csproj index 4cedc809f..f750ccf47 100644 --- a/csharp/Lib/Units/Units.csproj +++ b/csharp/Lib/Units/Units.csproj @@ -6,7 +6,7 @@ - + diff --git a/csharp/Lib/Units/Voltage.cs b/csharp/Lib/Units/Voltage.cs index 2c65129e4..9d9df166c 100644 --- a/csharp/Lib/Units/Voltage.cs +++ b/csharp/Lib/Units/Voltage.cs @@ -16,4 +16,5 @@ public readonly partial struct Voltage // P=UI public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value); -} \ No newline at end of file +} + diff --git a/csharp/Lib/Units/Voltage.generated.cs b/csharp/Lib/Units/Voltage.generated.cs index 44c32da19..4f5c57f91 100644 --- a/csharp/Lib/Units/Voltage.generated.cs +++ b/csharp/Lib/Units/Voltage.generated.cs @@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units; using T = Voltage; +[JsonConverter(typeof(VoltageConverter))] public readonly partial struct Voltage { public Decimal Value { get; } diff --git a/csharp/Lib/Utils/EnumerableUtils.cs b/csharp/Lib/Utils/EnumerableUtils.cs index dd0243ef8..af9cc1998 100644 --- a/csharp/Lib/Utils/EnumerableUtils.cs +++ b/csharp/Lib/Utils/EnumerableUtils.cs @@ -243,7 +243,7 @@ public static class EnumerableUtils return ts.ElementAtOrDefault(index) ?? defaultValue; } - public static IEnumerable Generate(this T seed, Func next) + public static IEnumerable Unfold(this T seed, Func next) { var value = seed; while (value is not null)