mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 03:01:24 +00:00
Changed poller structure and attachment method
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using MewtocolNet;
|
using MewtocolNet;
|
||||||
|
using MewtocolNet.Responses;
|
||||||
|
|
||||||
namespace Examples {
|
namespace Examples {
|
||||||
class Program {
|
class Program {
|
||||||
@@ -16,6 +17,8 @@ namespace Examples {
|
|||||||
interf.AddRegister<short>("Cooler Status",1204);
|
interf.AddRegister<short>("Cooler Status",1204);
|
||||||
interf.AddRegister<string>(1101, 4);
|
interf.AddRegister<string>(1101, 4);
|
||||||
|
|
||||||
|
interf.WithPoller();
|
||||||
|
|
||||||
interf.RegisterChanged += (o) => {
|
interf.RegisterChanged += (o) => {
|
||||||
Console.WriteLine($"DT{o.MemoryAdress} {(o.Name != null ? $"({o.Name}) " : "")}changed to {o.GetValueString()}");
|
Console.WriteLine($"DT{o.MemoryAdress} {(o.Name != null ? $"({o.Name}) " : "")}changed to {o.GetValueString()}");
|
||||||
};
|
};
|
||||||
@@ -24,11 +27,16 @@ namespace Examples {
|
|||||||
(plcinf) => {
|
(plcinf) => {
|
||||||
|
|
||||||
Console.WriteLine("Connected to PLC:\n" + plcinf.ToString());
|
Console.WriteLine("Connected to PLC:\n" + plcinf.ToString());
|
||||||
|
|
||||||
|
//read back a register value
|
||||||
|
var statusNum = (NRegister<short>)interf.Registers[1204];
|
||||||
|
Console.WriteLine($"Status num is: {statusNum.Value}");
|
||||||
|
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
Console.WriteLine("Failed connection");
|
Console.WriteLine("Failed connection");
|
||||||
}
|
}
|
||||||
).AttachContinousReader(50);
|
);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,49 +7,129 @@ using System.Threading.Tasks;
|
|||||||
using MewtocolNet.Responses;
|
using MewtocolNet.Responses;
|
||||||
|
|
||||||
namespace MewtocolNet {
|
namespace MewtocolNet {
|
||||||
public partial class MewtocolInterface {
|
|
||||||
|
|
||||||
public event Action<Register> RegisterChanged;
|
|
||||||
|
|
||||||
internal CancellationTokenSource cTokenAutoUpdater;
|
|
||||||
protected internal bool isWriting = false;
|
|
||||||
|
|
||||||
|
|
||||||
public bool ContinousReaderRunning { get; set; }
|
|
||||||
public List<Register> Registers { get; set; } = new List<Register>();
|
|
||||||
public List<Contact> Contacts { get; set; } = new List<Contact>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Trys to connect to the PLC by the IP given in the constructor
|
/// The PLC com interface class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="OnConnected">Gets called when a connection with a PLC was established</param>
|
public partial class MewtocolInterface {
|
||||||
/// <param name="OnFailed">Gets called when an error or timeout during connection occurs</param>
|
|
||||||
/// <returns></returns>
|
internal event Action PolledCycle;
|
||||||
public async Task<MewtocolInterface> ConnectAsync (Action<PLCInfo> OnConnected = null, Action OnFailed = null) {
|
internal CancellationTokenSource cTokenAutoUpdater;
|
||||||
|
internal bool isWriting;
|
||||||
|
internal bool ContinousReaderRunning;
|
||||||
|
internal bool usePoller = false;
|
||||||
|
|
||||||
|
#region Register Polling
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attaches a continous reader that reads back the Registers and Contacts
|
||||||
|
/// </summary>
|
||||||
|
internal void AttachPoller () {
|
||||||
|
|
||||||
|
if (ContinousReaderRunning) return;
|
||||||
|
|
||||||
|
cTokenAutoUpdater = new CancellationTokenSource();
|
||||||
|
|
||||||
|
Console.WriteLine("Attaching cont reader");
|
||||||
|
|
||||||
|
Task.Factory.StartNew(async () => {
|
||||||
|
|
||||||
var plcinf = await GetPLCInfoAsync();
|
var plcinf = await GetPLCInfoAsync();
|
||||||
|
if (plcinf == null) {
|
||||||
|
Console.WriteLine("PLC is not reachable");
|
||||||
|
throw new Exception("PLC is not reachable");
|
||||||
|
}
|
||||||
|
if (!plcinf.OperationMode.RunMode) {
|
||||||
|
Console.WriteLine("PLC is not running");
|
||||||
|
throw new Exception("PLC is not running");
|
||||||
|
}
|
||||||
|
|
||||||
if(plcinf is not null) {
|
ContinousReaderRunning = true;
|
||||||
|
|
||||||
if(OnConnected != null) OnConnected(plcinf);
|
while (true) {
|
||||||
|
|
||||||
} else {
|
//dont update when currently writing a var
|
||||||
|
if (isWriting) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(OnFailed != null) OnFailed();
|
await Task.Delay(pollingDelayMs);
|
||||||
|
foreach (var registerPair in Registers) {
|
||||||
|
|
||||||
|
var reg = registerPair.Value;
|
||||||
|
|
||||||
|
if (reg is NRegister<short> shortReg) {
|
||||||
|
var lastVal = shortReg.Value;
|
||||||
|
var readout = (await ReadNumRegister(shortReg, stationNumber)).Register.Value;
|
||||||
|
if (lastVal != readout) {
|
||||||
|
shortReg.LastValue = readout;
|
||||||
|
InvokeRegisterChanged(shortReg);
|
||||||
|
shortReg.TriggerNotifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reg is NRegister<ushort> ushortReg) {
|
||||||
|
var lastVal = ushortReg.Value;
|
||||||
|
var readout = (await ReadNumRegister(ushortReg, stationNumber)).Register.Value;
|
||||||
|
if (lastVal != readout) {
|
||||||
|
ushortReg.LastValue = readout;
|
||||||
|
InvokeRegisterChanged(ushortReg);
|
||||||
|
ushortReg.TriggerNotifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reg is NRegister<int> intReg) {
|
||||||
|
var lastVal = intReg.Value;
|
||||||
|
var readout = (await ReadNumRegister(intReg, stationNumber)).Register.Value;
|
||||||
|
if (lastVal != readout) {
|
||||||
|
intReg.LastValue = readout;
|
||||||
|
InvokeRegisterChanged(intReg);
|
||||||
|
intReg.TriggerNotifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reg is NRegister<uint> uintReg) {
|
||||||
|
var lastVal = uintReg.Value;
|
||||||
|
var readout = (await ReadNumRegister(uintReg, stationNumber)).Register.Value;
|
||||||
|
if (lastVal != readout) {
|
||||||
|
uintReg.LastValue = readout;
|
||||||
|
InvokeRegisterChanged(uintReg);
|
||||||
|
uintReg.TriggerNotifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reg is NRegister<float> floatReg) {
|
||||||
|
var lastVal = floatReg.Value;
|
||||||
|
var readout = (await ReadNumRegister(floatReg, stationNumber)).Register.Value;
|
||||||
|
if (lastVal != readout) {
|
||||||
|
floatReg.LastValue = readout;
|
||||||
|
InvokeRegisterChanged(floatReg);
|
||||||
|
floatReg.TriggerNotifyChange();
|
||||||
|
}
|
||||||
|
} else if (reg is SRegister stringReg) {
|
||||||
|
var lastVal = stringReg.Value;
|
||||||
|
var readout = (await ReadStringRegister(stringReg, stationNumber)).Register.Value;
|
||||||
|
if (lastVal != readout) {
|
||||||
|
InvokeRegisterChanged(stringReg);
|
||||||
|
stringReg.TriggerNotifyChange();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
}
|
||||||
|
|
||||||
|
//invoke cycle polled event
|
||||||
|
InvokePolledCycleDone();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}, cTokenAutoUpdater.Token);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Register Adding
|
#region Register Adding
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a PLC memory register to the watchlist <para/>
|
/// Adds a PLC memory register to the watchlist <para/>
|
||||||
/// The registers can be read back by attaching <see cref="MewtocolInterfaceExtensions.AttachContinousReader(Task{MewtocolInterface}, int)"/>
|
/// The registers can be read back by attaching <see cref="WithPoller"/>
|
||||||
/// <para/>
|
|
||||||
/// to the end of a <see cref="MewtocolInterface.ConnectAsync(Action{PLCInfo}, Action)"/> method
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// The type of the register translated from C# to IEC 61131-3 types
|
/// The type of the register translated from C# to IEC 61131-3 types
|
||||||
@@ -68,17 +148,17 @@ namespace MewtocolNet {
|
|||||||
Type regType = typeof(T);
|
Type regType = typeof(T);
|
||||||
|
|
||||||
if (regType == typeof(short)) {
|
if (regType == typeof(short)) {
|
||||||
Registers.Add(new NRegister<short>(_address));
|
Registers.Add(_address, new NRegister<short>(_address));
|
||||||
} else if (regType == typeof(ushort)) {
|
} else if (regType == typeof(ushort)) {
|
||||||
Registers.Add(new NRegister<ushort>(_address));
|
Registers.Add(_address, new NRegister<ushort>(_address));
|
||||||
} else if (regType == typeof(int)) {
|
} else if (regType == typeof(int)) {
|
||||||
Registers.Add(new NRegister<int>(_address));
|
Registers.Add(_address, new NRegister<int>(_address));
|
||||||
} else if (regType == typeof(uint)) {
|
} else if (regType == typeof(uint)) {
|
||||||
Registers.Add(new NRegister<uint>(_address));
|
Registers.Add(_address, new NRegister<uint>(_address));
|
||||||
} else if (regType == typeof(float)) {
|
} else if (regType == typeof(float)) {
|
||||||
Registers.Add(new NRegister<float>(_address));
|
Registers.Add(_address, new NRegister<float>(_address));
|
||||||
} else if (regType == typeof(string)) {
|
} else if (regType == typeof(string)) {
|
||||||
Registers.Add(new SRegister(_address, _length));
|
Registers.Add(_address, new SRegister(_address, _length));
|
||||||
} else {
|
} else {
|
||||||
throw new NotSupportedException($"The type {regType} is not allowed for Registers \n" +
|
throw new NotSupportedException($"The type {regType} is not allowed for Registers \n" +
|
||||||
$"Allowed are: short, ushort, int, uint, float and string");
|
$"Allowed are: short, ushort, int, uint, float and string");
|
||||||
@@ -88,9 +168,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a PLC memory register to the watchlist <para/>
|
/// Adds a PLC memory register to the watchlist <para/>
|
||||||
/// The registers can be read back by attaching <see cref="MewtocolInterfaceExtensions.AttachContinousReader(Task{MewtocolInterface}, int)"/>
|
/// The registers can be read back by attaching <see cref="WithPoller"/>
|
||||||
/// <para/>
|
|
||||||
/// to the end of a <see cref="MewtocolInterface.ConnectAsync(Action{PLCInfo}, Action)"/> method
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// The type of the register translated from C# to IEC 61131-3 types
|
/// The type of the register translated from C# to IEC 61131-3 types
|
||||||
@@ -110,17 +188,17 @@ namespace MewtocolNet {
|
|||||||
Type regType = typeof(T);
|
Type regType = typeof(T);
|
||||||
|
|
||||||
if (regType == typeof(short)) {
|
if (regType == typeof(short)) {
|
||||||
Registers.Add(new NRegister<short>(_address, _name));
|
Registers.Add(_address, new NRegister<short>(_address, _name));
|
||||||
} else if (regType == typeof(ushort)) {
|
} else if (regType == typeof(ushort)) {
|
||||||
Registers.Add(new NRegister<ushort>(_address, _name));
|
Registers.Add(_address, new NRegister<ushort>(_address, _name));
|
||||||
} else if (regType == typeof(int)) {
|
} else if (regType == typeof(int)) {
|
||||||
Registers.Add(new NRegister<int>(_address, _name));
|
Registers.Add(_address, new NRegister<int>(_address, _name));
|
||||||
} else if (regType == typeof(uint)) {
|
} else if (regType == typeof(uint)) {
|
||||||
Registers.Add(new NRegister<uint>(_address, _name));
|
Registers.Add(_address, new NRegister<uint>(_address, _name));
|
||||||
} else if (regType == typeof(float)) {
|
} else if (regType == typeof(float)) {
|
||||||
Registers.Add(new NRegister<float>(_address, _name));
|
Registers.Add(_address, new NRegister<float>(_address, _name));
|
||||||
} else if (regType == typeof(string)) {
|
} else if (regType == typeof(string)) {
|
||||||
Registers.Add(new SRegister(_address, _length, _name));
|
Registers.Add(_address, new SRegister(_address, _length, _name));
|
||||||
} else {
|
} else {
|
||||||
throw new NotSupportedException($"The type {regType} is not allowed for Registers \n" +
|
throw new NotSupportedException($"The type {regType} is not allowed for Registers \n" +
|
||||||
$"Allowed are: short, ushort, int, uint, float and string");
|
$"Allowed are: short, ushort, int, uint, float and string");
|
||||||
@@ -132,7 +210,13 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
internal void InvokeRegisterChanged (Register reg) {
|
internal void InvokeRegisterChanged (Register reg) {
|
||||||
|
|
||||||
RegisterChanged?.Invoke (reg);
|
RegisterChanged?.Invoke(reg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InvokePolledCycleDone () {
|
||||||
|
|
||||||
|
PolledCycle?.Invoke();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,32 +10,140 @@ using MewtocolNet.Responses;
|
|||||||
|
|
||||||
namespace MewtocolNet {
|
namespace MewtocolNet {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The PLC com interface class
|
||||||
|
/// </summary>
|
||||||
public partial class MewtocolInterface {
|
public partial class MewtocolInterface {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets triggered when the PLC connection was established
|
||||||
|
/// </summary>
|
||||||
|
public event Action<PLCInfo> Connected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets triggered when a registered data register changes its value
|
||||||
|
/// </summary>
|
||||||
|
public event Action<Register> RegisterChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generic information about the connected PLC
|
/// Generic information about the connected PLC
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PLCInfo PlcInfo {get;private set;}
|
public PLCInfo PlcInfo {get;private set;}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The registered data registers of the PLC
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<int, Register> Registers { get; set; } = new();
|
||||||
|
|
||||||
private CancellationTokenSource tokenSource;
|
private CancellationTokenSource tokenSource;
|
||||||
|
|
||||||
private string ip {get;set;}
|
private string ip {get;set;}
|
||||||
private int port {get;set;}
|
private int port {get;set;}
|
||||||
public int ConnectionTimeout {get;set;} = 2000;
|
private int stationNumber {get;set;}
|
||||||
|
private int pollingDelayMs {get;set;}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current IP of the PLC connection
|
||||||
|
/// </summary>
|
||||||
|
public string IpAddress => ip;
|
||||||
|
/// <summary>
|
||||||
|
/// The current port of the PLC connection
|
||||||
|
/// </summary>
|
||||||
|
public int Port => port;
|
||||||
|
/// <summary>
|
||||||
|
/// The station number of the PLC
|
||||||
|
/// </summary>
|
||||||
|
public int StationNumber => stationNumber;
|
||||||
|
|
||||||
|
|
||||||
#region Initialization
|
#region Initialization
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds a new Interfacer for a PLC
|
/// Builds a new Interfacer for a PLC
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="_ip"></param>
|
/// <param name="_ip">IP adress of the PLC</param>
|
||||||
/// <param name="_port"></param>
|
/// <param name="_port">Port of the PLC</param>
|
||||||
public MewtocolInterface (string _ip, int _port = 9094) {
|
/// <param name="_station">Station Number of the PLC</param>
|
||||||
|
public MewtocolInterface (string _ip, int _port = 9094, int _station = 1) {
|
||||||
|
|
||||||
ip = _ip;
|
ip = _ip;
|
||||||
port = _port;
|
port = _port;
|
||||||
|
stationNumber = _station;
|
||||||
|
|
||||||
|
Connected += MewtocolInterface_Connected;
|
||||||
|
|
||||||
|
void MewtocolInterface_Connected (PLCInfo obj) {
|
||||||
|
|
||||||
|
if (usePoller)
|
||||||
|
AttachPoller();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Setup
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Trys to connect to the PLC by the IP given in the constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="OnConnected">
|
||||||
|
/// Gets called when a connection with a PLC was established
|
||||||
|
/// <para/>
|
||||||
|
/// If <see cref="WithPoller"/> is used it waits for the first data receive cycle to complete
|
||||||
|
/// </param>
|
||||||
|
/// <param name="OnFailed">Gets called when an error or timeout during connection occurs</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<MewtocolInterface> ConnectAsync (Action<PLCInfo> OnConnected = null, Action OnFailed = null) {
|
||||||
|
|
||||||
|
var plcinf = await GetPLCInfoAsync();
|
||||||
|
|
||||||
|
if (plcinf is not null) {
|
||||||
|
|
||||||
|
Connected?.Invoke(plcinf);
|
||||||
|
|
||||||
|
if (OnConnected != null) {
|
||||||
|
|
||||||
|
if (!usePoller) {
|
||||||
|
OnConnected(plcinf);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolledCycle += OnPollCycleDone;
|
||||||
|
void OnPollCycleDone () {
|
||||||
|
OnConnected(plcinf);
|
||||||
|
PolledCycle -= OnPollCycleDone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (OnFailed != null)
|
||||||
|
OnFailed();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attaches a poller to the interface that continously
|
||||||
|
/// polls the registered data registers and writes the values to them
|
||||||
|
/// </summary>
|
||||||
|
public MewtocolInterface WithPoller (int pollerDelayMs = 50) {
|
||||||
|
|
||||||
|
pollingDelayMs = pollerDelayMs;
|
||||||
|
usePoller = true;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Low level command handling
|
#region Low level command handling
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -10,110 +10,6 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
public static class MewtocolInterfaceExtensions {
|
public static class MewtocolInterfaceExtensions {
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attaches a continous reader that reads back the Registers and Contacts
|
|
||||||
/// </summary>
|
|
||||||
public static Task AttachContinousReader (this Task<MewtocolInterface> interfaceTask, int _refreshTimeMS = 200) {
|
|
||||||
|
|
||||||
interfaceTask.Wait(-1);
|
|
||||||
|
|
||||||
var interf = interfaceTask.Result;
|
|
||||||
|
|
||||||
if (interf.ContinousReaderRunning)
|
|
||||||
return Task.CompletedTask;
|
|
||||||
|
|
||||||
interf.cTokenAutoUpdater = new CancellationTokenSource();
|
|
||||||
|
|
||||||
Console.WriteLine("Attaching cont reader");
|
|
||||||
|
|
||||||
Task.Factory.StartNew(async () => {
|
|
||||||
|
|
||||||
var plcinf = await interf.GetPLCInfoAsync();
|
|
||||||
if (plcinf == null) {
|
|
||||||
Console.WriteLine("PLC is not reachable");
|
|
||||||
throw new Exception("PLC is not reachable");
|
|
||||||
}
|
|
||||||
if (!plcinf.OperationMode.RunMode) {
|
|
||||||
Console.WriteLine("PLC is not running");
|
|
||||||
throw new Exception("PLC is not running");
|
|
||||||
}
|
|
||||||
|
|
||||||
interf.ContinousReaderRunning = true;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
//dont update when currently writing a var
|
|
||||||
if (interf.isWriting) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(_refreshTimeMS);
|
|
||||||
foreach (var reg in interf.Registers) {
|
|
||||||
|
|
||||||
if (reg is NRegister<short> shortReg) {
|
|
||||||
var lastVal = shortReg.Value;
|
|
||||||
var readout = (await interf.ReadNumRegister(shortReg)).Register.Value;
|
|
||||||
if (lastVal != readout) {
|
|
||||||
shortReg.LastValue = readout;
|
|
||||||
interf.InvokeRegisterChanged(shortReg);
|
|
||||||
shortReg.TriggerNotifyChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reg is NRegister<ushort> ushortReg) {
|
|
||||||
var lastVal = ushortReg.Value;
|
|
||||||
var readout = (await interf.ReadNumRegister(ushortReg)).Register.Value;
|
|
||||||
if (lastVal != readout) {
|
|
||||||
ushortReg.LastValue = readout;
|
|
||||||
interf.InvokeRegisterChanged(ushortReg);
|
|
||||||
ushortReg.TriggerNotifyChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reg is NRegister<int> intReg) {
|
|
||||||
var lastVal = intReg.Value;
|
|
||||||
var readout = (await interf.ReadNumRegister(intReg)).Register.Value;
|
|
||||||
if (lastVal != readout) {
|
|
||||||
intReg.LastValue = readout;
|
|
||||||
interf.InvokeRegisterChanged(intReg);
|
|
||||||
intReg.TriggerNotifyChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reg is NRegister<uint> uintReg) {
|
|
||||||
var lastVal = uintReg.Value;
|
|
||||||
var readout = (await interf.ReadNumRegister(uintReg)).Register.Value;
|
|
||||||
if (lastVal != readout) {
|
|
||||||
uintReg.LastValue = readout;
|
|
||||||
interf.InvokeRegisterChanged(uintReg);
|
|
||||||
uintReg.TriggerNotifyChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reg is NRegister<float> floatReg) {
|
|
||||||
var lastVal = floatReg.Value;
|
|
||||||
var readout = (await interf.ReadNumRegister(floatReg)).Register.Value;
|
|
||||||
if (lastVal != readout) {
|
|
||||||
floatReg.LastValue = readout;
|
|
||||||
interf.InvokeRegisterChanged(floatReg);
|
|
||||||
floatReg.TriggerNotifyChange();
|
|
||||||
}
|
|
||||||
} else if (reg is SRegister stringReg) {
|
|
||||||
var lastVal = stringReg.Value;
|
|
||||||
var readout = (await interf.ReadStringRegister(stringReg)).Register.Value;
|
|
||||||
if (lastVal != readout) {
|
|
||||||
interf.InvokeRegisterChanged(stringReg);
|
|
||||||
stringReg.TriggerNotifyChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}, interf.cTokenAutoUpdater.Token);
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user