Merge branch 'main' of https://git.innov.energy/Innovenergy/git_trunk
This commit is contained in:
commit
40f5c8c391
|
@ -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.
|
@ -0,0 +1,10 @@
|
|||
namespace InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||
|
||||
[Flags]
|
||||
public enum Endianness
|
||||
{
|
||||
LittleEndian32BitIntegers = 0,
|
||||
LittleEndian32Floats = 0,
|
||||
BigEndian32BitIntegers = 1,
|
||||
BigEndian32Floats = 2,
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ 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 MbBits BitsAt (this ArraySegment<Byte> data, Byte i) => new MbBits(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);
|
||||
|
||||
|
||||
public static MbByte<T> ByteAt<T>(this ArraySegment<Byte> data,Byte i) where T : struct, IConvertible => new MbByte<T>(data, i);
|
||||
|
|
|
@ -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)
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Utils\Utils.csproj" />
|
||||
<ProjectReference Include="../Utils/Utils.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Angle;
|
||||
|
||||
[JsonConverter(typeof(AngleConverter))]
|
||||
public readonly partial struct Angle
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = ApparentPower;
|
||||
|
||||
[JsonConverter(typeof(ApparentPowerConverter))]
|
||||
public readonly partial struct ApparentPower
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Current;
|
||||
|
||||
[JsonConverter(typeof(CurrentConverter))]
|
||||
public readonly partial struct Current
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Frequency;
|
||||
|
||||
[JsonConverter(typeof(FrequencyConverter))]
|
||||
public readonly partial struct Frequency
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Template;
|
||||
|
||||
[JsonConverter(typeof(TemplateConverter))]
|
||||
public readonly partial struct Template
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Number;
|
||||
|
||||
[JsonConverter(typeof(NumberConverter))]
|
||||
public readonly partial struct Number
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Power;
|
||||
|
||||
[JsonConverter(typeof(PowerConverter))]
|
||||
public readonly partial struct Power
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = ReactivePower;
|
||||
|
||||
[JsonConverter(typeof(ReactivePowerConverter))]
|
||||
public readonly partial struct ReactivePower
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Resistance;
|
||||
|
||||
[JsonConverter(typeof(ResistanceConverter))]
|
||||
public readonly partial struct Resistance
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Temperature;
|
||||
|
||||
[JsonConverter(typeof(TemperatureConverter))]
|
||||
public readonly partial struct Temperature
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Utils\Utils.csproj" />
|
||||
<ProjectReference Include="../Utils/Utils.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace InnovEnergy.Lib.Units;
|
|||
|
||||
using T = Voltage;
|
||||
|
||||
[JsonConverter(typeof(VoltageConverter))]
|
||||
public readonly partial struct Voltage
|
||||
{
|
||||
public Decimal Value { get; }
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue