This commit is contained in:
Sina Blattmann 2023-03-08 13:01:56 +01:00
commit 40f5c8c391
30 changed files with 62 additions and 48 deletions

View File

@ -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);

Binary file not shown.

View File

@ -0,0 +1,10 @@
namespace InnovEnergy.Lib.Protocols.Modbus.Clients;
[Flags]
public enum Endianness
{
LittleEndian32BitIntegers = 0,
LittleEndian32Floats = 0,
BigEndian32BitIntegers = 1,
BigEndian32Floats = 2,
}

View File

@ -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,6 +13,7 @@ public abstract class ModbusClient
{
protected ModbusConnection Connection { get; }
protected Byte SlaveId { get; }
protected Endianness Endianness { get; }
// TODO: add additional functions: coils...
@ -40,11 +41,11 @@ public abstract class ModbusClient
return WriteRegisters(writeAddress, (IReadOnlyList<UInt16>)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();

View File

@ -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<UInt16>;
using Coils = IReadOnlyList<Boolean>;
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)
{
}

View File

@ -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);

View File

@ -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);
}

View File

@ -9,7 +9,7 @@ public static class Accessors
public static MbWord WordAt (this ArraySegment<Byte> data, Byte i) => new MbWord(data, i);
public static MbAddress AddressAt(this ArraySegment<Byte> data, Byte i) => new MbAddress(data, i);
public static MbWords WordsAt(this ArraySegment<Byte> data, Byte i) => new MbWords(data, i);
public static MbRegisters RegistersAt(this ArraySegment<Byte> data, Byte i) => new MbRegisters(data, i);
public static MbBits BitsAt (this ArraySegment<Byte> data, Byte i) => new MbBits(data, i);

View File

@ -3,30 +3,30 @@ using InnovEnergy.Lib.Utils;
namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors;
public readonly struct MbWords : IReadOnlyList<UInt16>
public readonly struct MbRegisters : IReadOnlyList<UInt16>
{
private readonly ArraySegment<Byte> _Data;
internal MbWords(ArraySegment<Byte> data, Byte startIndex) : this(data, startIndex, CountWords(data, startIndex))
internal MbRegisters(ArraySegment<Byte> data, Byte startIndex) : this(data, startIndex, CountWords(data, startIndex))
{ }
internal MbRegisters(ArraySegment<Byte> data, Byte startIndex, UInt16 wordCount) : this(data.Array!, startIndex, wordCount)
{
}
internal MbRegisters(Byte[] data, Byte startIndex, UInt16 wordCount)
{
_Data = new ArraySegment<Byte>(data, startIndex, wordCount * 2);
}
private static UInt16 CountWords(ArraySegment<Byte> data, Byte startIndex)
{
var wordCount = (data.Count - startIndex) / 2;
return wordCount.ConvertTo<UInt16>();
}
internal MbWords(ArraySegment<Byte> data, Byte startIndex, UInt16 wordCount) : this(data.Array!, startIndex, wordCount)
{
}
internal MbWords(Byte[] data, Byte startIndex, UInt16 wordCount)
{
_Data = new ArraySegment<Byte>(data, startIndex, wordCount * 2);
}
internal IReadOnlyCollection<UInt16> Set(IReadOnlyCollection<UInt16> values)
{
if (values.Count != _Data.Count / 2)

View File

@ -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);

View File

@ -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();

View File

@ -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))

View File

@ -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))
{

View File

@ -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))
{

View File

@ -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);
}

View File

@ -6,7 +6,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Utils\Utils.csproj" />
<ProjectReference Include="../Utils/Utils.csproj" />
</ItemGroup>
</Project>

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Angle;
[JsonConverter(typeof(AngleConverter))]
public readonly partial struct Angle
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = ApparentPower;
[JsonConverter(typeof(ApparentPowerConverter))]
public readonly partial struct ApparentPower
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Current;
[JsonConverter(typeof(CurrentConverter))]
public readonly partial struct Current
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Frequency;
[JsonConverter(typeof(FrequencyConverter))]
public readonly partial struct Frequency
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Template;
[JsonConverter(typeof(TemplateConverter))]
public readonly partial struct Template
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Number;
[JsonConverter(typeof(NumberConverter))]
public readonly partial struct Number
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Power;
[JsonConverter(typeof(PowerConverter))]
public readonly partial struct Power
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = ReactivePower;
[JsonConverter(typeof(ReactivePowerConverter))]
public readonly partial struct ReactivePower
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Resistance;
[JsonConverter(typeof(ResistanceConverter))]
public readonly partial struct Resistance
{
public Decimal Value { get; }

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Temperature;
[JsonConverter(typeof(TemperatureConverter))]
public readonly partial struct Temperature
{
public Decimal Value { get; }

View File

@ -6,7 +6,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Utils\Utils.csproj" />
<ProjectReference Include="../Utils/Utils.csproj" />
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">

View File

@ -17,3 +17,4 @@ public readonly partial struct Voltage
// P=UI
public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value);
}

View File

@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
using T = Voltage;
[JsonConverter(typeof(VoltageConverter))]
public readonly partial struct Voltage
{
public Decimal Value { get; }

View File

@ -243,7 +243,7 @@ public static class EnumerableUtils
return ts.ElementAtOrDefault(index) ?? defaultValue;
}
public static IEnumerable<T> Generate<T>(this T seed, Func<T, T> next)
public static IEnumerable<T> Unfold<T>(this T seed, Func<T, T?> next)
{
var value = seed;
while (value is not null)