Add Valerio Meter library
This commit is contained in:
parent
5fd533419b
commit
07ede85347
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>InnovEnergy.Lib.Devices.PLVario2Meter</RootNamespace>
|
||||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Protocols\Modbus\Modbus.csproj" />
|
||||
<ProjectReference Include="..\..\StatusApi\StatusApi.csproj" />
|
||||
<ProjectReference Include="..\..\Units\Units.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
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.PLVario2Meter;
|
||||
|
||||
public class PlVarioMeterDevice: ModbusDevice<PlVarioMeterRegisters>
|
||||
{
|
||||
public PlVarioMeterDevice(String hostname, UInt16 port = 502, Byte slaveId = 2) : this(new TcpChannel(hostname, port), slaveId)
|
||||
{
|
||||
}
|
||||
|
||||
public PlVarioMeterDevice(Channel channel, Byte slaveId = 2) : base(new ModbusTcpClient(channel, slaveId))
|
||||
{
|
||||
}
|
||||
|
||||
public PlVarioMeterDevice(ModbusClient client) : base(client)
|
||||
{
|
||||
}
|
||||
|
||||
public new PlVarioMeterRegisters? Read()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.Read();
|
||||
}
|
||||
catch
|
||||
{
|
||||
"Failed to read data from PLVario-II meter".WriteLine();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public new void Write(PlVarioMeterRegisters registers)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.Write(registers);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO: Log
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
using InnovEnergy.Lib.Units;
|
||||
using InnovEnergy.Lib.Units.Power;
|
||||
|
||||
namespace InnovEnergy.Lib.Devices.PLVario2Meter;
|
||||
|
||||
public class PlVarioMeterRecord
|
||||
{
|
||||
private readonly PlVarioMeterRegisters _raw;
|
||||
|
||||
public PlVarioMeterRecord(PlVarioMeterRegisters raw)
|
||||
{
|
||||
_raw = raw ?? throw new ArgumentNullException(nameof(raw));
|
||||
}
|
||||
|
||||
|
||||
static ushort SwapBytes16(ushort x)
|
||||
=> (ushort)((x << 8) | (x >> 8));
|
||||
|
||||
static float DecodeFloat_BADC(ushort w0, ushort w1)
|
||||
{
|
||||
// Build bytes: [B A D C] = swap bytes in each word, and use W1 then W0
|
||||
ushort w0s = SwapBytes16(w0); // F1AA
|
||||
ushort w1s = SwapBytes16(w1); // 4247
|
||||
uint raw = ((uint)w1s << 16) | w0s; // 0x4247F1AA
|
||||
return BitConverter.Int32BitsToSingle(unchecked((int)raw));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Decoders (DCBA) from raw UInt16 pairs
|
||||
// -------------------------------------------------------------------------
|
||||
private static uint DecodeUInt32DCBA(ushort lowWord, ushort highWord)
|
||||
=> ((uint)highWord << 16) | (uint)lowWord;
|
||||
|
||||
private static float DecodeFloatDCBA(ushort lowWord, ushort highWord)
|
||||
{
|
||||
uint raw = ((uint)highWord << 16) | (uint)lowWord;
|
||||
return BitConverter.Int32BitsToSingle(unchecked((int)raw));
|
||||
}
|
||||
|
||||
private static Double F(ushort w0, ushort w1) => DecodeFloat_BADC(w0, w1);
|
||||
private static UInt32 U32(ushort w0, ushort w1) => DecodeUInt32DCBA(w0, w1);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Time
|
||||
// -------------------------------------------------------------------------
|
||||
/// <summary>Timestamp in seconds (as provided by the device).</summary>
|
||||
public uint TimestampSeconds => U32(_raw.Timestamp_W0, _raw.Timestamp_W1);
|
||||
|
||||
/// <summary>Timestamp interpreted as Unix epoch seconds (UTC).</summary>
|
||||
public DateTimeOffset TimestampUtc => DateTimeOffset.FromUnixTimeSeconds(TimestampSeconds);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Voltages (phase-neutral and line-line)
|
||||
// -------------------------------------------------------------------------
|
||||
public VoltageRms VoltageU1 => new(F(_raw.VoltageU1_W0, _raw.VoltageU1_W1)); // U-1
|
||||
public VoltageRms VoltageU2 => new(F(_raw.VoltageU2_W0, _raw.VoltageU2_W1)); // U-2
|
||||
public VoltageRms VoltageU3 => new(F(_raw.VoltageU3_W0, _raw.VoltageU3_W1)); // U-3
|
||||
|
||||
// Friendly aliases (match your naming style)
|
||||
public VoltageRms GridAbLineVoltage => (VoltageRms)new(F(_raw.VoltageUL1_W0, _raw.VoltageUL1_W1));
|
||||
public VoltageRms GridBcLineVoltage => (VoltageRms)new(F(_raw.VoltageUL2_W0, _raw.VoltageUL2_W1));
|
||||
public VoltageRms GridCaLineVoltage => (VoltageRms)new(F(_raw.VoltageUL3_W0, _raw.VoltageUL3_W1));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Frequency
|
||||
// -------------------------------------------------------------------------
|
||||
public Double Frequency => (F(_raw.Frequency_W0, _raw.Frequency_W1));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Currents
|
||||
// -------------------------------------------------------------------------
|
||||
public CurrentRms CurrentI1 => new(F(_raw.CurrentI1_W0, _raw.CurrentI1_W1));
|
||||
public CurrentRms CurrentI2 => new(F(_raw.CurrentI2_W0, _raw.CurrentI2_W1));
|
||||
public CurrentRms CurrentI3 => new(F(_raw.CurrentI3_W0, _raw.CurrentI3_W1));
|
||||
public CurrentRms CurrentI4 => new(F(_raw.CurrentI4_W0, _raw.CurrentI4_W1)); // optional channel
|
||||
public CurrentRms CurrentTotal => new(F(_raw.CurrentTotal_W0, _raw.CurrentTotal_W1));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Active Power (kW)
|
||||
// -------------------------------------------------------------------------
|
||||
public ActivePower ActivePowerL1 => new(F(_raw.ActivePowerP1_W0, _raw.ActivePowerP1_W1) * 1000);
|
||||
public ActivePower ActivePowerL2 => new(F(_raw.ActivePowerP2_W0, _raw.ActivePowerP2_W1) * 1000);
|
||||
public ActivePower ActivePowerL3 => new(F(_raw.ActivePowerP3_W0, _raw.ActivePowerP3_W1) * 1000);
|
||||
public ActivePower ActivePowerCh4 => new(F(_raw.ActivePowerP4_W0, _raw.ActivePowerP4_W1) * 1000); // optional channel
|
||||
public ActivePower ActivePowerTotal => new(F(_raw.ActivePowerTotal_W0, _raw.ActivePowerTotal_W1) * 1000);
|
||||
|
||||
// If you later map import/export separately, you can redefine these.
|
||||
// For now, the table provides only total P (signed), so we expose it as "GridPower".
|
||||
public ActivePower GridPower => ActivePowerTotal;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Reactive Power (kVAr)
|
||||
// -------------------------------------------------------------------------
|
||||
public ReactivePower ReactivePowerL1 => new(F(_raw.ReactivePowerQ1_W0, _raw.ReactivePowerQ1_W1));
|
||||
public ReactivePower ReactivePowerL2 => new(F(_raw.ReactivePowerQ2_W0, _raw.ReactivePowerQ2_W1));
|
||||
public ReactivePower ReactivePowerL3 => new(F(_raw.ReactivePowerQ3_W0, _raw.ReactivePowerQ3_W1));
|
||||
public ReactivePower ReactivePowerCh4 => new(F(_raw.ReactivePowerQ4_W0, _raw.ReactivePowerQ4_W1));
|
||||
public ReactivePower ReactivePowerTotal => new(F(_raw.ReactivePowerTotal_W0, _raw.ReactivePowerTotal_W1));
|
||||
|
||||
// Friendly alias
|
||||
public ReactivePower GridReactivePower => ReactivePowerTotal;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Apparent Power (kVA)
|
||||
// -------------------------------------------------------------------------
|
||||
public ApparentPower ApparentPowerL1 => new(F(_raw.ApparentPowerS1_W0, _raw.ApparentPowerS1_W1));
|
||||
public ApparentPower ApparentPowerL2 => new(F(_raw.ApparentPowerS2_W0, _raw.ApparentPowerS2_W1));
|
||||
public ApparentPower ApparentPowerL3 => new(F(_raw.ApparentPowerS3_W0, _raw.ApparentPowerS3_W1));
|
||||
public ApparentPower ApparentPowerCh4 => new(F(_raw.ApparentPowerS4_W0, _raw.ApparentPowerS4_W1));
|
||||
public ApparentPower ApparentPowerTotal => new(F(_raw.ApparentPowerTotal_W0, _raw.ApparentPowerTotal_W1));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Power Factor
|
||||
// -------------------------------------------------------------------------
|
||||
public Double PowerFactorL1 => (F(_raw.PowerFactorPF1_W0, _raw.PowerFactorPF1_W1));
|
||||
public Double PowerFactorL2 => (F(_raw.PowerFactorPF2_W0, _raw.PowerFactorPF2_W1));
|
||||
public Double PowerFactorL3 => (F(_raw.PowerFactorPF3_W0, _raw.PowerFactorPF3_W1));
|
||||
public Double PowerFactorCh4 => (F(_raw.PowerFactorPF4_W0, _raw.PowerFactorPF4_W1));
|
||||
public Double PowerFactorTotal => (F(_raw.PowerFactorTotal_W0, _raw.PowerFactorTotal_W1));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Repeated totals (table shows duplicates at offsets 66..74)
|
||||
// Keep them exposed in case your installation populates them differently.
|
||||
// -------------------------------------------------------------------------
|
||||
public CurrentRms CurrentTotalRepeat => new(F(_raw.CurrentTotalRepeat_W0, _raw.CurrentTotalRepeat_W1));
|
||||
public ActivePower ActivePowerTotalRepeat => new(F(_raw.ActivePowerTotalRepeat_W0, _raw.ActivePowerTotalRepeat_W1));
|
||||
public ReactivePower ReactivePowerTotalRepeat => new(F(_raw.ReactivePowerTotalRepeat_W0, _raw.ReactivePowerTotalRepeat_W1));
|
||||
public ApparentPower ApparentPowerTotalRepeat => new(F(_raw.ApparentPowerTotalRepeat_W0, _raw.ApparentPowerTotalRepeat_W1));
|
||||
public Double PowerFactorTotalRepeat => (F(_raw.PowerFactorTotalRepeat_W0, _raw.PowerFactorTotalRepeat_W1));
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
using InnovEnergy.Lib.Protocols.Modbus.Reflection.Attributes;
|
||||
using InnovEnergy.Lib.StatusApi.DeviceTypes;
|
||||
using InnovEnergy.Lib.Units.Composite;
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace InnovEnergy.Lib.Devices.PLVario2Meter;
|
||||
|
||||
using Float32 = Single;
|
||||
|
||||
// If your project already defines Float32 as an alias/struct, keep that.
|
||||
// Otherwise, you can just use float. Here we use float for simplicity.
|
||||
public class PlVarioMeterRegisters : IAc3Meter
|
||||
{
|
||||
// -------------------------------------------------------------------------
|
||||
// Timestamp (UINT32) -> 2 x UInt16
|
||||
// Offset 0: Timestamp [s]
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1000, writable: false)] public UInt16 Timestamp_W0; // low word
|
||||
[HoldingRegister<UInt16>(1001, writable: false)] public UInt16 Timestamp_W1; // high word
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Voltages phase-neutral (FLOAT32) -> 2 x UInt16 each
|
||||
// Offsets 2,4,6
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1002, writable: false)] public UInt16 VoltageU1_W0;
|
||||
[HoldingRegister<UInt16>(1003, writable: false)] public UInt16 VoltageU1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1004, writable: false)] public UInt16 VoltageU2_W0;
|
||||
[HoldingRegister<UInt16>(1005, writable: false)] public UInt16 VoltageU2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1006, writable: false)] public UInt16 VoltageU3_W0;
|
||||
[HoldingRegister<UInt16>(1007, writable: false)] public UInt16 VoltageU3_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Voltages line-line (FLOAT32) -> 2 x UInt16 each
|
||||
// Offsets 8,10,12
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1008, writable: false)] public UInt16 VoltageUL1_W0;
|
||||
[HoldingRegister<UInt16>(1009, writable: false)] public UInt16 VoltageUL1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1010, writable: false)] public UInt16 VoltageUL2_W0;
|
||||
[HoldingRegister<UInt16>(1011, writable: false)] public UInt16 VoltageUL2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1012, writable: false)] public UInt16 VoltageUL3_W0;
|
||||
[HoldingRegister<UInt16>(1013, writable: false)] public UInt16 VoltageUL3_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Frequency (FLOAT32) -> 2 x UInt16
|
||||
// Offset 14
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1014, writable: false)] public UInt16 Frequency_W0;
|
||||
[HoldingRegister<UInt16>(1015, writable: false)] public UInt16 Frequency_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Currents (FLOAT32) -> 2 x UInt16 each
|
||||
// Offsets 16..24
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1016, writable: false)] public UInt16 CurrentI1_W0;
|
||||
[HoldingRegister<UInt16>(1017, writable: false)] public UInt16 CurrentI1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1018, writable: false)] public UInt16 CurrentI2_W0;
|
||||
[HoldingRegister<UInt16>(1019, writable: false)] public UInt16 CurrentI2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1020, writable: false)] public UInt16 CurrentI3_W0;
|
||||
[HoldingRegister<UInt16>(1021, writable: false)] public UInt16 CurrentI3_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1022, writable: false)] public UInt16 CurrentI4_W0;
|
||||
[HoldingRegister<UInt16>(1023, writable: false)] public UInt16 CurrentI4_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1024, writable: false)] public UInt16 CurrentTotal_W0;
|
||||
[HoldingRegister<UInt16>(1025, writable: false)] public UInt16 CurrentTotal_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Active power P (FLOAT32, kW) -> 2 x UInt16 each
|
||||
// Offsets 26..34
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1026, writable: false)] public UInt16 ActivePowerP1_W0;
|
||||
[HoldingRegister<UInt16>(1027, writable: false)] public UInt16 ActivePowerP1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1028, writable: false)] public UInt16 ActivePowerP2_W0;
|
||||
[HoldingRegister<UInt16>(1029, writable: false)] public UInt16 ActivePowerP2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1030, writable: false)] public UInt16 ActivePowerP3_W0;
|
||||
[HoldingRegister<UInt16>(1031, writable: false)] public UInt16 ActivePowerP3_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1032, writable: false)] public UInt16 ActivePowerP4_W0;
|
||||
[HoldingRegister<UInt16>(1033, writable: false)] public UInt16 ActivePowerP4_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1034, writable: false)] public UInt16 ActivePowerTotal_W0;
|
||||
[HoldingRegister<UInt16>(1035, writable: false)] public UInt16 ActivePowerTotal_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Reactive power Q (FLOAT32, kVAr) -> 2 x UInt16 each
|
||||
// Offsets 36..44
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1036, writable: false)] public UInt16 ReactivePowerQ1_W0;
|
||||
[HoldingRegister<UInt16>(1037, writable: false)] public UInt16 ReactivePowerQ1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1038, writable: false)] public UInt16 ReactivePowerQ2_W0;
|
||||
[HoldingRegister<UInt16>(1039, writable: false)] public UInt16 ReactivePowerQ2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1040, writable: false)] public UInt16 ReactivePowerQ3_W0;
|
||||
[HoldingRegister<UInt16>(1041, writable: false)] public UInt16 ReactivePowerQ3_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1042, writable: false)] public UInt16 ReactivePowerQ4_W0;
|
||||
[HoldingRegister<UInt16>(1043, writable: false)] public UInt16 ReactivePowerQ4_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1044, writable: false)] public UInt16 ReactivePowerTotal_W0;
|
||||
[HoldingRegister<UInt16>(1045, writable: false)] public UInt16 ReactivePowerTotal_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Apparent power S (FLOAT32, kVA) -> 2 x UInt16 each
|
||||
// Offsets 46..54
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1046, writable: false)] public UInt16 ApparentPowerS1_W0;
|
||||
[HoldingRegister<UInt16>(1047, writable: false)] public UInt16 ApparentPowerS1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1048, writable: false)] public UInt16 ApparentPowerS2_W0;
|
||||
[HoldingRegister<UInt16>(1049, writable: false)] public UInt16 ApparentPowerS2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1050, writable: false)] public UInt16 ApparentPowerS3_W0;
|
||||
[HoldingRegister<UInt16>(1051, writable: false)] public UInt16 ApparentPowerS3_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1052, writable: false)] public UInt16 ApparentPowerS4_W0;
|
||||
[HoldingRegister<UInt16>(1053, writable: false)] public UInt16 ApparentPowerS4_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1054, writable: false)] public UInt16 ApparentPowerTotal_W0;
|
||||
[HoldingRegister<UInt16>(1055, writable: false)] public UInt16 ApparentPowerTotal_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Power factor PF (FLOAT32) -> 2 x UInt16 each
|
||||
// Offsets 56..64
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1056, writable: false)] public UInt16 PowerFactorPF1_W0;
|
||||
[HoldingRegister<UInt16>(1057, writable: false)] public UInt16 PowerFactorPF1_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1058, writable: false)] public UInt16 PowerFactorPF2_W0;
|
||||
[HoldingRegister<UInt16>(1059, writable: false)] public UInt16 PowerFactorPF2_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1060, writable: false)] public UInt16 PowerFactorPF3_W0;
|
||||
[HoldingRegister<UInt16>(1061, writable: false)] public UInt16 PowerFactorPF3_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1062, writable: false)] public UInt16 PowerFactorPF4_W0;
|
||||
[HoldingRegister<UInt16>(1063, writable: false)] public UInt16 PowerFactorPF4_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1064, writable: false)] public UInt16 PowerFactorTotal_W0;
|
||||
[HoldingRegister<UInt16>(1065, writable: false)] public UInt16 PowerFactorTotal_W1;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Repeated totals (as shown in the table) at offsets 66..74
|
||||
// -------------------------------------------------------------------------
|
||||
[HoldingRegister<UInt16>(1066, writable: false)] public UInt16 CurrentTotalRepeat_W0;
|
||||
[HoldingRegister<UInt16>(1067, writable: false)] public UInt16 CurrentTotalRepeat_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1068, writable: false)] public UInt16 ActivePowerTotalRepeat_W0;
|
||||
[HoldingRegister<UInt16>(1069, writable: false)] public UInt16 ActivePowerTotalRepeat_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1070, writable: false)] public UInt16 ReactivePowerTotalRepeat_W0;
|
||||
[HoldingRegister<UInt16>(1071, writable: false)] public UInt16 ReactivePowerTotalRepeat_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1072, writable: false)] public UInt16 ApparentPowerTotalRepeat_W0;
|
||||
[HoldingRegister<UInt16>(1073, writable: false)] public UInt16 ApparentPowerTotalRepeat_W1;
|
||||
|
||||
[HoldingRegister<UInt16>(1074, writable: false)] public UInt16 PowerFactorTotalRepeat_W0;
|
||||
[HoldingRegister<UInt16>(1075, writable: false)] public UInt16 PowerFactorTotalRepeat_W1;
|
||||
|
||||
public Ac3Bus Ac { get; }
|
||||
}
|
||||
Loading…
Reference in New Issue