mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 03:01:24 +00:00
Fixes
This commit is contained in:
@@ -22,7 +22,7 @@ public class ExampleScenarios {
|
||||
public void SetupLogger () {
|
||||
|
||||
//attaching the logger
|
||||
Logger.LogLevel = LogLevel.Verbose;
|
||||
Logger.LogLevel = LogLevel.Info;
|
||||
Logger.OnNewLogMessage((date, level, msg) => {
|
||||
|
||||
if (level == LogLevel.Error) Console.ForegroundColor = ConsoleColor.Red;
|
||||
@@ -74,12 +74,28 @@ public class ExampleScenarios {
|
||||
|
||||
}
|
||||
|
||||
[Scenario("Read all kinds of example registers")]
|
||||
public async Task RunReadTest () {
|
||||
[Scenario("Read all kinds of example registers over ethernet")]
|
||||
public async Task RunReadTestEth () {
|
||||
|
||||
//setting up a new PLC interface and register collection
|
||||
var interf = Mewtocol.Ethernet("192.168.115.210").WithPoller();
|
||||
|
||||
await RunCyclicReadTest(interf);
|
||||
|
||||
}
|
||||
|
||||
[Scenario("Read all kinds of example registers over serial")]
|
||||
public async Task RunReadTestSer () {
|
||||
|
||||
//setting up a new PLC interface and register collection
|
||||
var interf = Mewtocol.SerialAuto("COM4").WithPoller();
|
||||
|
||||
await RunCyclicReadTest(interf);
|
||||
|
||||
}
|
||||
|
||||
private async Task RunCyclicReadTest (IPlc interf) {
|
||||
|
||||
//auto add all built registers to the interface
|
||||
var builder = RegBuilder.ForInterface(interf);
|
||||
var r0reg = builder.FromPlcRegName("R0").Build();
|
||||
@@ -95,14 +111,26 @@ public class ExampleScenarios {
|
||||
var stringReg = builder.FromPlcRegName("DT40").AsPlcType(PlcVarType.STRING).Build();
|
||||
|
||||
//connect
|
||||
await interf.ConnectAsync();
|
||||
if(interf is IPlcSerial serialPlc) {
|
||||
|
||||
await serialPlc.ConnectAsync(() => {
|
||||
|
||||
Console.WriteLine($"Trying config: {serialPlc.ConnectionInfo}");
|
||||
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
await interf.ConnectAsync();
|
||||
|
||||
}
|
||||
|
||||
//await first register data
|
||||
await interf.AwaitFirstDataAsync();
|
||||
|
||||
_ = Task.Factory.StartNew(async () => {
|
||||
|
||||
void setTitle () {
|
||||
void setTitle() {
|
||||
|
||||
Console.Title =
|
||||
$"Speed UP: {interf.BytesPerSecondUpstream} B/s, " +
|
||||
@@ -287,4 +315,33 @@ public class ExampleScenarios {
|
||||
|
||||
}
|
||||
|
||||
[Scenario("Test")]
|
||||
public async Task Test () {
|
||||
|
||||
Logger.LogLevel = LogLevel.Critical;
|
||||
|
||||
//fpx c14 r
|
||||
var plxFpx = Mewtocol.Ethernet("192.168.178.55");
|
||||
await plxFpx.ConnectAsync();
|
||||
await ((MewtocolInterface)plxFpx).GetSystemRegister();
|
||||
|
||||
//fpx-h c30 t
|
||||
var plcFpxH = Mewtocol.Ethernet("192.168.115.210");
|
||||
await plcFpxH.ConnectAsync();
|
||||
await ((MewtocolInterface)plcFpxH).GetSystemRegister();
|
||||
|
||||
//fpx-h c14 r
|
||||
var plcFpxHc14 = Mewtocol.Ethernet("192.168.115.212");
|
||||
await plcFpxHc14.ConnectAsync();
|
||||
await ((MewtocolInterface)plcFpxHc14).GetSystemRegister();
|
||||
|
||||
//fpx c30 t
|
||||
var plcFpxc30T = Mewtocol.Ethernet("192.168.115.213");
|
||||
await plcFpxc30T.ConnectAsync();
|
||||
await ((MewtocolInterface)plcFpxc30T).GetSystemRegister();
|
||||
|
||||
await Task.Delay(-1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Examples {
|
||||
public class TestRegisters : RegisterCollectionBase {
|
||||
public class TestRegisters : RegisterCollection {
|
||||
|
||||
//corresponds to a R100 boolean register in the PLC
|
||||
[Register(IOType.R, 1000)]
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Collections;
|
||||
|
||||
namespace Examples {
|
||||
|
||||
public class TestRegistersEnumBitwise : RegisterCollectionBase {
|
||||
public class TestRegistersEnumBitwise : RegisterCollection {
|
||||
|
||||
private bool startCyclePLC;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0-android;</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net7.0-tizen</TargetFrameworks> -->
|
||||
@@ -23,12 +23,10 @@
|
||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">24.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using MewtocolNet.Registers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -49,6 +50,11 @@ namespace MewtocolNet {
|
||||
/// </summary>
|
||||
int StationNumber { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A connection info string
|
||||
/// </summary>
|
||||
string ConnectionInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The initial connection timeout in milliseconds
|
||||
/// </summary>
|
||||
@@ -91,6 +97,26 @@ namespace MewtocolNet {
|
||||
/// </summary>
|
||||
string GetConnectionInfo();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a register to the plc
|
||||
/// </summary>
|
||||
void AddRegister(BaseRegister register);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a register to the plc
|
||||
/// </summary>
|
||||
void AddRegister(IRegister register);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a register from the plc by name
|
||||
/// </summary>
|
||||
IRegister GetRegister(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registers from the plc
|
||||
/// </summary>
|
||||
IEnumerable<IRegister> GetAllRegisters();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
namespace MewtocolNet {
|
||||
using MewtocolNet.RegisterAttributes;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MewtocolNet {
|
||||
|
||||
/// <summary>
|
||||
/// Provides a interface for Panasonic PLCs over a ethernet connection
|
||||
@@ -16,9 +21,14 @@
|
||||
int Port { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a poller to the interface
|
||||
/// The host ip endpoint, leave it null to use an automatic interface
|
||||
/// </summary>
|
||||
public IPlcEthernet WithPoller();
|
||||
IPEndPoint HostEndpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tries to establish a connection with the device asynchronously
|
||||
/// </summary>
|
||||
Task ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Configures the serial interface
|
||||
@@ -28,6 +38,18 @@
|
||||
/// <param name="_station">Station Number of the PLC</param>
|
||||
void ConfigureConnection(string _ip, int _port = 9094, int _station = 1);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a poller to the interface
|
||||
/// </summary>
|
||||
IPlcEthernet WithPoller();
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a register collection object to
|
||||
/// the interface that can be updated automatically.
|
||||
/// </summary>
|
||||
/// <param name="collection">The type of the collection base class</param>
|
||||
IPlcEthernet AddRegisterCollection(RegisterCollection collection);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using MewtocolNet.RegisterAttributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Text;
|
||||
@@ -36,11 +37,6 @@ namespace MewtocolNet {
|
||||
/// </summary>
|
||||
StopBits SerialStopBits { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a poller to the interface
|
||||
/// </summary>
|
||||
public IPlcSerial WithPoller();
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the connection settings for the device
|
||||
/// </summary>
|
||||
@@ -50,7 +46,29 @@ namespace MewtocolNet {
|
||||
/// <param name="_parity">The serial connection parity</param>
|
||||
/// <param name="_stopBits">The serial connection stop bits</param>
|
||||
/// <param name="_station">The station number of the PLC</param>
|
||||
void ConfigureConnection(string _portName, int _baudRate = 19200, int _dataBits = 8, Parity _parity = Parity.Odd, StopBits _stopBits = StopBits.One, int _station = 1)
|
||||
void ConfigureConnection(string _portName, int _baudRate = 19200, int _dataBits = 8, Parity _parity = Parity.Odd, StopBits _stopBits = StopBits.One, int _station = 1);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to establish a connection with the device asynchronously
|
||||
/// </summary>
|
||||
Task ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Tries to establish a connection with the device asynchronously
|
||||
/// </summary>
|
||||
Task ConnectAsync(Action onTryingConfig);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a poller to the interface
|
||||
/// </summary>
|
||||
IPlcSerial WithPoller();
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a register collection object to
|
||||
/// the interface that can be updated automatically.
|
||||
/// </summary>
|
||||
/// <param name="collection">The type of the collection base class</param>
|
||||
IPlcSerial AddRegisterCollection(RegisterCollection collection);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using MewtocolNet.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace MewtocolNet {
|
||||
@@ -13,14 +16,29 @@ namespace MewtocolNet {
|
||||
/// <summary>
|
||||
/// Builds a ethernet based Mewtocol Interface
|
||||
/// </summary>
|
||||
/// <param name="_ip"></param>
|
||||
/// <param name="_port"></param>
|
||||
/// <param name="_station"></param>
|
||||
/// <param name="ip"></param>
|
||||
/// <param name="port"></param>
|
||||
/// <param name="station">Plc station number</param>
|
||||
/// <returns></returns>
|
||||
public static IPlcEthernet Ethernet (string _ip, int _port = 9094, int _station = 1) {
|
||||
public static IPlcEthernet Ethernet (string ip, int port = 9094, int station = 1) {
|
||||
|
||||
var instance = new MewtocolInterfaceTcp();
|
||||
instance.ConfigureConnection(_ip, _port, _station);
|
||||
instance.ConfigureConnection(ip, port, station);
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a ethernet based Mewtocol Interface
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <param name="port"></param>
|
||||
/// <param name="station">Plc station number</param>
|
||||
/// <returns></returns>
|
||||
public static IPlcEthernet Ethernet(IPAddress ip, int port = 9094, int station = 1) {
|
||||
|
||||
var instance = new MewtocolInterfaceTcp();
|
||||
instance.ConfigureConnection(ip, port, station);
|
||||
return instance;
|
||||
|
||||
}
|
||||
@@ -28,16 +46,19 @@ namespace MewtocolNet {
|
||||
/// <summary>
|
||||
/// Builds a serial port based Mewtocol Interface
|
||||
/// </summary>
|
||||
/// <param name="_portName"></param>
|
||||
/// <param name="_baudRate"></param>
|
||||
/// <param name="_dataBits"></param>
|
||||
/// <param name="_parity"></param>
|
||||
/// <param name="_stopBits"></param>
|
||||
/// <param name="portName"></param>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="dataBits"></param>
|
||||
/// <param name="parity"></param>
|
||||
/// <param name="stopBits"></param>
|
||||
/// <param name="station"></param>
|
||||
/// <returns></returns>
|
||||
public static IPlcSerial Serial (string _portName, BaudRate _baudRate = BaudRate._19200, DataBits _dataBits = DataBits.Eight, Parity _parity = Parity.Odd, StopBits _stopBits = StopBits.One, int _station = 1) {
|
||||
public static IPlcSerial Serial (string portName, BaudRate baudRate = BaudRate._19200, DataBits dataBits = DataBits.Eight, Parity parity = Parity.Odd, StopBits stopBits = StopBits.One, int station = 1) {
|
||||
|
||||
TestPortName(portName);
|
||||
|
||||
var instance = new MewtocolInterfaceSerial();
|
||||
instance.ConfigureConnection(_portName, (int)_baudRate, (int)_dataBits, _parity, _stopBits, _station);
|
||||
instance.ConfigureConnection(portName, (int)baudRate, (int)dataBits, parity, stopBits, station);
|
||||
return instance;
|
||||
|
||||
}
|
||||
@@ -45,18 +66,29 @@ namespace MewtocolNet {
|
||||
/// <summary>
|
||||
/// Builds a serial mewtocol interface that finds the correct settings for the given port name automatically
|
||||
/// </summary>
|
||||
/// <param name="_portName"></param>
|
||||
/// <param name="_station"></param>
|
||||
/// <param name="portName"></param>
|
||||
/// <param name="station"></param>
|
||||
/// <returns></returns>
|
||||
public static IPlcSerial SerialAuto (string _portName, int _station = 1) {
|
||||
public static IPlcSerial SerialAuto (string portName, int station = 1) {
|
||||
|
||||
TestPortName(portName);
|
||||
|
||||
var instance = new MewtocolInterfaceSerial();
|
||||
instance.ConfigureConnection(_portName, _station);
|
||||
instance.ConfigureConnection(portName, station);
|
||||
instance.ConfigureConnectionAuto();
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
private static void TestPortName (string portName) {
|
||||
|
||||
var portnames = SerialPort.GetPortNames();
|
||||
|
||||
if (!portnames.Any(x => x == portName))
|
||||
throw new MewtocolException($"The port {portName} is no valid port");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -115,6 +115,9 @@ namespace MewtocolNet {
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ConnectionInfo => GetConnectionInfo();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public read/write Properties / Fields
|
||||
@@ -153,7 +156,7 @@ namespace MewtocolNet {
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Task ConnectAsync () => throw new NotImplementedException();
|
||||
public virtual async Task ConnectAsync() => throw new NotImplementedException();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task AwaitFirstDataAsync() => await firstPollTask;
|
||||
@@ -163,7 +166,8 @@ namespace MewtocolNet {
|
||||
|
||||
if (!IsConnected) return;
|
||||
|
||||
pollCycleTask.Wait();
|
||||
if(pollCycleTask != null && !pollCycleTask.IsCompleted)
|
||||
pollCycleTask.Wait();
|
||||
|
||||
OnMajorSocketExceptionWhileConnected();
|
||||
|
||||
@@ -212,10 +216,16 @@ namespace MewtocolNet {
|
||||
if (useCr)
|
||||
frame = $"{frame}\r";
|
||||
|
||||
|
||||
SetUpstreamStopWatchStart();
|
||||
|
||||
//write inital command
|
||||
byte[] writeBuffer = Encoding.UTF8.GetBytes(frame);
|
||||
stream.Write(writeBuffer, 0, writeBuffer.Length);
|
||||
|
||||
//calc upstream speed
|
||||
CalcUpstreamSpeed(writeBuffer.Length);
|
||||
|
||||
Logger.Log($"[---------CMD START--------]", LogLevel.Critical, this);
|
||||
Logger.Log($"--> OUT MSG: {frame.Replace("\r", "(CR)")}", LogLevel.Critical, this);
|
||||
|
||||
@@ -235,7 +245,9 @@ namespace MewtocolNet {
|
||||
//error response
|
||||
var gotErrorcode = CheckForErrorMsg(resString);
|
||||
if (gotErrorcode != 0) {
|
||||
return new MewtocolFrameResponse(gotErrorcode);
|
||||
var errResponse = new MewtocolFrameResponse(gotErrorcode);
|
||||
Logger.Log($"Command error: {errResponse.Error}", LogLevel.Error, this);
|
||||
return errResponse;
|
||||
}
|
||||
|
||||
//was multiframed response
|
||||
@@ -281,9 +293,13 @@ namespace MewtocolNet {
|
||||
|
||||
do {
|
||||
|
||||
SetDownstreamStopWatchStart();
|
||||
|
||||
byte[] buffer = new byte[128];
|
||||
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
|
||||
|
||||
CalcDownstreamSpeed(bytesRead);
|
||||
|
||||
byte[] received = new byte[bytesRead];
|
||||
Buffer.BlockCopy(buffer, 0, received, 0, bytesRead);
|
||||
|
||||
@@ -338,7 +354,7 @@ namespace MewtocolNet {
|
||||
private protected int CheckForErrorMsg (string msg) {
|
||||
|
||||
//error catching
|
||||
Regex errorcheck = new Regex(@"\%[0-9]{2}\!([0-9]{2})", RegexOptions.IgnoreCase);
|
||||
Regex errorcheck = new Regex(@"\%..\!([0-9]{2})", RegexOptions.IgnoreCase);
|
||||
Match m = errorcheck.Match(msg);
|
||||
|
||||
if (m.Success) {
|
||||
@@ -401,7 +417,7 @@ namespace MewtocolNet {
|
||||
|
||||
BytesPerSecondDownstream = 0;
|
||||
BytesPerSecondUpstream = 0;
|
||||
CycleTimeMs = 0;
|
||||
PollerCycleDurationMs = 0;
|
||||
|
||||
IsConnected = false;
|
||||
ClearRegisterVals();
|
||||
@@ -422,6 +438,53 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
private void SetUpstreamStopWatchStart () {
|
||||
|
||||
if (speedStopwatchUpstr == null) {
|
||||
speedStopwatchUpstr = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
if (speedStopwatchUpstr.Elapsed.TotalSeconds >= 1) {
|
||||
speedStopwatchUpstr.Restart();
|
||||
bytesTotalCountedUpstream = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void SetDownstreamStopWatchStart () {
|
||||
|
||||
if (speedStopwatchDownstr == null) {
|
||||
speedStopwatchDownstr = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
if (speedStopwatchDownstr.Elapsed.TotalSeconds >= 1) {
|
||||
speedStopwatchDownstr.Restart();
|
||||
bytesTotalCountedDownstream = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void CalcUpstreamSpeed (int byteCount) {
|
||||
|
||||
bytesTotalCountedUpstream += byteCount;
|
||||
|
||||
var perSecUpstream = (double)((bytesTotalCountedUpstream / speedStopwatchUpstr.Elapsed.TotalMilliseconds) * 1000);
|
||||
if (perSecUpstream <= 10000)
|
||||
BytesPerSecondUpstream = (int)Math.Round(perSecUpstream, MidpointRounding.AwayFromZero);
|
||||
|
||||
}
|
||||
|
||||
private void CalcDownstreamSpeed (int byteCount) {
|
||||
|
||||
bytesTotalCountedDownstream += byteCount;
|
||||
|
||||
var perSecDownstream = (double)((bytesTotalCountedDownstream / speedStopwatchDownstr.Elapsed.TotalMilliseconds) * 1000);
|
||||
|
||||
if (perSecDownstream <= 10000)
|
||||
BytesPerSecondDownstream = (int)Math.Round(perSecDownstream, MidpointRounding.AwayFromZero);
|
||||
|
||||
}
|
||||
|
||||
private protected void OnPropChange([CallerMemberName] string propertyName = null) {
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
|
||||
@@ -205,15 +205,7 @@ namespace MewtocolNet {
|
||||
|
||||
#region Register Colleciton adding
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a register collection object to
|
||||
/// the interface that can be updated automatically.
|
||||
/// <para/>
|
||||
/// Just create a class inheriting from <see cref="RegisterCollectionBase"/>
|
||||
/// and assert some propertys with the custom <see cref="RegisterAttribute"/>.
|
||||
/// </summary>
|
||||
/// <param name="collection">A collection inherting the <see cref="RegisterCollectionBase"/> class</param>
|
||||
public MewtocolInterface WithRegisterCollection(RegisterCollectionBase collection) {
|
||||
internal MewtocolInterface WithRegisterCollection (RegisterCollection collection) {
|
||||
|
||||
collection.PLCInterface = this;
|
||||
|
||||
@@ -353,6 +345,23 @@ namespace MewtocolNet {
|
||||
|
||||
#region Register Adding
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void AddRegister(BaseRegister register) {
|
||||
|
||||
if (CheckDuplicateRegister(register))
|
||||
throw MewtocolException.DupeRegister(register);
|
||||
|
||||
if (CheckDuplicateNameRegister(register))
|
||||
throw MewtocolException.DupeNameRegister(register);
|
||||
|
||||
register.attachedInterface = this;
|
||||
RegistersUnderlying.Add(register);
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void AddRegister(IRegister register) => AddRegister(register as BaseRegister);
|
||||
|
||||
internal void AddRegister (RegisterBuildInfo buildInfo) {
|
||||
|
||||
var builtRegister = buildInfo.Build();
|
||||
@@ -375,19 +384,6 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
public void AddRegister (BaseRegister register) {
|
||||
|
||||
if (CheckDuplicateRegister(register))
|
||||
throw MewtocolException.DupeRegister(register);
|
||||
|
||||
if (CheckDuplicateNameRegister(register))
|
||||
throw MewtocolException.DupeNameRegister(register);
|
||||
|
||||
register.attachedInterface = this;
|
||||
RegistersUnderlying.Add(register);
|
||||
|
||||
}
|
||||
|
||||
private bool CheckDuplicateRegister (IRegisterInternal instance, out IRegisterInternal foundDupe) {
|
||||
|
||||
foundDupe = RegistersInternal.FirstOrDefault(x => x.CompareIsDuplicate(instance));
|
||||
@@ -414,24 +410,15 @@ namespace MewtocolNet {
|
||||
|
||||
#region Register accessing
|
||||
|
||||
/// <summary>
|
||||
/// Gets a register that was added by its name
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc/>>
|
||||
public IRegister GetRegister(string name) {
|
||||
|
||||
return RegistersUnderlying.FirstOrDefault(x => x.Name == name);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Register Reading
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all added registers
|
||||
/// </summary>
|
||||
public IEnumerable<IRegister> GetAllRegisters() {
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<IRegister> GetAllRegisters () {
|
||||
|
||||
return RegistersUnderlying.Cast<IRegister>();
|
||||
|
||||
|
||||
@@ -289,6 +289,86 @@ namespace MewtocolNet {
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reading / Writing Plc program
|
||||
|
||||
public async Task ReadPLCProgramAsync () {
|
||||
|
||||
var cmd = SendCommandAsync($"");
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task GetSystemRegister () {
|
||||
|
||||
//the "." means CR or \r
|
||||
|
||||
await SendCommandAsync("%EE#RT");
|
||||
|
||||
//then get plc status extended? gets polled all time
|
||||
// %EE#EX00RT00
|
||||
await SendCommandAsync("%EE#EX00RT00");
|
||||
|
||||
//fpx C14 r
|
||||
|
||||
//%EE$EX00 RT
|
||||
//00 Extended mode
|
||||
//32 Data item count
|
||||
//70 Machine type
|
||||
//00 Version (Fixed to 00)
|
||||
//16 Prog capacity in K
|
||||
//81 Operation mode / status
|
||||
//00 Link unit
|
||||
//60 Error flag
|
||||
//0000 Self diag error
|
||||
//50 Version
|
||||
//02 Hardware information
|
||||
//0 Number of programs
|
||||
//4100 Program size BCD
|
||||
//1600 Header size (no. of words) bcd
|
||||
//1604 System register size
|
||||
//96230000001480004 ??
|
||||
//
|
||||
|
||||
// PLC TYPE | Machine Code | HW Information
|
||||
// FPX C14 R | 70 | 02
|
||||
// FPX C30 T | 77 | 02
|
||||
|
||||
// FPX-H C14 R | A0 | 01
|
||||
// FPX-H C30 T | A5 | 01
|
||||
|
||||
|
||||
//then a sequence of these is sent
|
||||
|
||||
// Specifiy register for monitoring
|
||||
// %EE#MDFFFFFF
|
||||
//await SendCommandAsync("%EE#MDFFFFFF");
|
||||
|
||||
// reset monitor registers
|
||||
// %EE#MCFFFFF -> gets ackn
|
||||
//await SendCommandAsync("%EE#MCFFFFF");
|
||||
|
||||
// maybe some special registers?
|
||||
// %EE#MCR9029R0000R0000R0000R0000R0000R0000R0000 -> gets ackn
|
||||
//await SendCommandAsync("%EE#MCR9029R0000R0000R0000R0000R0000R0000R0000");
|
||||
|
||||
// gets requested when opening plc status
|
||||
// %EE#MG
|
||||
// has a response like:
|
||||
|
||||
//await SendCommandAsync("%EE#MG");
|
||||
|
||||
|
||||
//var res = cmd.Response.Replace("%01$RR", "");
|
||||
|
||||
//var parts = res.SplitInParts(4);
|
||||
|
||||
//foreach (var part in parts)
|
||||
// Console.WriteLine(part);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
internal string GetStationNumber() {
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using MewtocolNet.RegisterAttributes;
|
||||
|
||||
namespace MewtocolNet {
|
||||
|
||||
@@ -17,11 +18,23 @@ namespace MewtocolNet {
|
||||
|
||||
private bool autoSerial;
|
||||
|
||||
private event Action tryingSerialConfig;
|
||||
|
||||
//serial config
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string PortName { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int SerialBaudRate { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int SerialDataBits { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Parity SerialParity { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public StopBits SerialStopBits { get; private set; }
|
||||
|
||||
//Serial
|
||||
@@ -29,7 +42,6 @@ namespace MewtocolNet {
|
||||
|
||||
internal MewtocolInterfaceSerial () : base() { }
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPlcSerial WithPoller () {
|
||||
|
||||
@@ -38,6 +50,13 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
public IPlcSerial AddRegisterCollection (RegisterCollection collection) {
|
||||
|
||||
WithRegisterCollection(collection);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetConnectionInfo() {
|
||||
|
||||
@@ -89,8 +108,17 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
public override async Task ConnectAsync() => await ConnectAsync(null);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task ConnectAsync () {
|
||||
public async Task ConnectAsync (Action onTryingConfig = null) {
|
||||
|
||||
void OnTryConfig() {
|
||||
onTryingConfig();
|
||||
}
|
||||
|
||||
if (onTryingConfig != null)
|
||||
tryingSerialConfig += OnTryConfig;
|
||||
|
||||
try {
|
||||
|
||||
@@ -98,10 +126,12 @@ namespace MewtocolNet {
|
||||
|
||||
if(autoSerial) {
|
||||
|
||||
Logger.Log($"Connecting [AUTO CONFIGURE]: {PortName}", LogLevel.Info, this);
|
||||
gotInfo = await TryConnectAsyncMulti();
|
||||
|
||||
} else {
|
||||
|
||||
Logger.Log($"Connecting [MAN]: {PortName}", LogLevel.Info, this);
|
||||
gotInfo = await TryConnectAsyncSingle(PortName, SerialBaudRate, SerialDataBits, SerialParity, SerialStopBits);
|
||||
|
||||
}
|
||||
@@ -112,7 +142,7 @@ namespace MewtocolNet {
|
||||
|
||||
} else {
|
||||
|
||||
Logger.Log("Initial connection failed", LogLevel.Info, this);
|
||||
Logger.Log("Initial connection failed", LogLevel.Error, this);
|
||||
OnMajorSocketExceptionWhileConnecting();
|
||||
|
||||
}
|
||||
@@ -125,6 +155,8 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
tryingSerialConfig -= OnTryConfig;
|
||||
|
||||
}
|
||||
|
||||
private async Task<PLCInfo> TryConnectAsyncMulti () {
|
||||
@@ -193,19 +225,20 @@ namespace MewtocolNet {
|
||||
SerialParity = par;
|
||||
SerialStopBits = sbits;
|
||||
OnSerialPropsChanged();
|
||||
tryingSerialConfig?.Invoke();
|
||||
|
||||
serialClient.Open();
|
||||
|
||||
if (!serialClient.IsOpen) {
|
||||
|
||||
Logger.Log($"Failed to open [SERIAL]: {GetConnectionInfo()}", LogLevel.Verbose, this);
|
||||
Logger.Log($"Failed to open [SERIAL]: {GetConnectionInfo()}", LogLevel.Critical, this);
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
stream = serialClient.BaseStream;
|
||||
|
||||
Logger.Log($"Opened [SERIAL]: {GetConnectionInfo()}", LogLevel.Verbose, this);
|
||||
Logger.Log($"Opened [SERIAL]: {GetConnectionInfo()}", LogLevel.Critical, this);
|
||||
|
||||
var plcinf = await GetPLCInfoAsync(100);
|
||||
|
||||
|
||||
@@ -26,23 +26,19 @@ namespace MewtocolNet {
|
||||
/// </summary>
|
||||
public class MewtocolInterfaceTcp : MewtocolInterface, IPlcEthernet {
|
||||
|
||||
/// <summary>
|
||||
/// The host ip endpoint, leave it null to use an automatic interface
|
||||
/// </summary>
|
||||
public IPEndPoint HostEndpoint { get; set; }
|
||||
|
||||
//TCP
|
||||
internal TcpClient client;
|
||||
|
||||
//tcp/ip config
|
||||
private string ip;
|
||||
private int port;
|
||||
private IPAddress ipAddr;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string IpAddress => ip;
|
||||
public string IpAddress => ipAddr.ToString();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Port => port;
|
||||
public int Port { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPEndPoint HostEndpoint { get; set; }
|
||||
|
||||
internal MewtocolInterfaceTcp () : base() { }
|
||||
|
||||
@@ -54,14 +50,35 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPlcEthernet AddRegisterCollection (RegisterCollection collection) {
|
||||
|
||||
WithRegisterCollection(collection);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
#region TCP connection state handling
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ConfigureConnection (string _ip, int _port = 9094, int _station = 1) {
|
||||
public void ConfigureConnection (string ip, int port = 9094, int station = 1) {
|
||||
|
||||
ip = _ip;
|
||||
port = _port;
|
||||
stationNumber = _station;
|
||||
if (!IPAddress.TryParse(ip, out ipAddr))
|
||||
throw new MewtocolException($"The ip: {ip} is no valid ip address");
|
||||
|
||||
Port = port;
|
||||
stationNumber = station;
|
||||
|
||||
Disconnect();
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ConfigureConnection(IPAddress ip, int port = 9094, int station = 1) {
|
||||
|
||||
ipAddr = ip;
|
||||
Port = port;
|
||||
stationNumber = station;
|
||||
|
||||
Disconnect();
|
||||
|
||||
@@ -70,10 +87,6 @@ namespace MewtocolNet {
|
||||
/// <inheritdoc/>
|
||||
public override async Task ConnectAsync () {
|
||||
|
||||
if (!IPAddress.TryParse(ip, out var targetIP)) {
|
||||
throw new ArgumentException("The IP adress of the PLC was no valid format");
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (HostEndpoint != null) {
|
||||
@@ -83,29 +96,31 @@ namespace MewtocolNet {
|
||||
NoDelay = false,
|
||||
};
|
||||
var ep = (IPEndPoint)client.Client.LocalEndPoint;
|
||||
Logger.Log($"Connecting [MAN] endpoint: {ep.Address}:{ep.Port}", LogLevel.Verbose, this);
|
||||
Logger.Log($"Connecting [MAN] endpoint: {ep.Address}:{ep.Port}", LogLevel.Info, this);
|
||||
|
||||
} else {
|
||||
|
||||
client = new TcpClient() {
|
||||
ReceiveBufferSize = RecBufferSize,
|
||||
NoDelay = false,
|
||||
ExclusiveAddressUse = true,
|
||||
//ExclusiveAddressUse = true,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
var result = client.BeginConnect(targetIP, port, null, null);
|
||||
var result = client.BeginConnect(ipAddr, Port, null, null);
|
||||
var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(ConnectTimeout));
|
||||
|
||||
if (!success || !client.Connected) {
|
||||
|
||||
Logger.Log("The PLC connection timed out", LogLevel.Error, this);
|
||||
OnMajorSocketExceptionWhileConnecting();
|
||||
return;
|
||||
}
|
||||
|
||||
if (HostEndpoint == null) {
|
||||
var ep = (IPEndPoint)client.Client.LocalEndPoint;
|
||||
Logger.Log($"Connecting [AUTO] endpoint: {ep.Address.MapToIPv4()}:{ep.Port}", LogLevel.Verbose, this);
|
||||
Logger.Log($"Connecting [AUTO] endpoint: {ep.Address.MapToIPv4()}:{ep.Port}", LogLevel.Info, this);
|
||||
}
|
||||
|
||||
//get the stream
|
||||
@@ -121,7 +136,7 @@ namespace MewtocolNet {
|
||||
|
||||
} else {
|
||||
|
||||
Logger.Log("Initial connection failed", LogLevel.Info, this);
|
||||
Logger.Log("Initial connection failed", LogLevel.Error, this);
|
||||
OnDisconnect();
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace MewtocolNet.RegisterAttributes {
|
||||
/// <summary>
|
||||
/// A register collection base with full auto read and notification support built in
|
||||
/// </summary>
|
||||
public class RegisterCollectionBase : INotifyPropertyChanged {
|
||||
public class RegisterCollection : INotifyPropertyChanged {
|
||||
|
||||
/// <summary>
|
||||
/// Reference to its bound interface
|
||||
@@ -21,7 +21,7 @@ namespace MewtocolNet.RegisterBuilding {
|
||||
|
||||
};
|
||||
|
||||
public static RegBuilder ForInterface (IPlcEthernet interf) {
|
||||
public static RegBuilder ForInterface (IPlc interf) {
|
||||
|
||||
var rb = new RegBuilder();
|
||||
rb.forInterface = interf as MewtocolInterface;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace MewtocolTests {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public class TestRegisterCollection : RegisterCollectionBase {
|
||||
public class TestRegisterCollection : RegisterCollection {
|
||||
|
||||
//corresponds to a R100 boolean register in the PLC
|
||||
//can also be written as R1000 because the last one is a special address
|
||||
@@ -109,8 +109,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "Boolean R generation")]
|
||||
public void BooleanGen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBool1));
|
||||
|
||||
@@ -122,8 +122,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "Boolean input XD generation")]
|
||||
public void BooleanInputGen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBoolInputXD));
|
||||
|
||||
@@ -135,8 +135,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "Int16 generation")]
|
||||
public void Int16Gen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestInt16));
|
||||
|
||||
@@ -148,8 +148,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "UInt16 generation")]
|
||||
public void UInt16Gen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestUInt16));
|
||||
|
||||
@@ -161,8 +161,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "Int32 generation")]
|
||||
public void Int32Gen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestInt32));
|
||||
|
||||
@@ -174,8 +174,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "UInt32 generation")]
|
||||
public void UInt32Gen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestUInt32));
|
||||
|
||||
@@ -187,8 +187,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "Float32 generation")]
|
||||
public void Float32Gen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestFloat32));
|
||||
|
||||
@@ -200,8 +200,8 @@ namespace MewtocolTests {
|
||||
[Fact(DisplayName = "TimeSpan generation")]
|
||||
public void TimespanGen() {
|
||||
|
||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestTime));
|
||||
|
||||
@@ -210,22 +210,6 @@ namespace MewtocolTests {
|
||||
|
||||
}
|
||||
|
||||
//[Fact(DisplayName = "String generation")]
|
||||
//public void StringGen() {
|
||||
|
||||
// var interf = new MewtocolInterface("192.168.0.1");
|
||||
// interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||
|
||||
// var register = interf.GetRegister(nameof(TestRegisterCollection.TestString2));
|
||||
|
||||
// //test generic properties
|
||||
// TestBasicGeneration(register, nameof(TestRegisterCollection.TestString2), null!, 7005, "DT7005");
|
||||
|
||||
// Assert.Equal(5, ((BytesRegister<string>)register).ReservedSize);
|
||||
// Assert.Equal(4, ((BytesRegister<string>)register).MemoryLength);
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,10 +45,10 @@ namespace MewtocolTests
|
||||
AfterWriteValue = true,
|
||||
},
|
||||
new RegisterReadWriteTest {
|
||||
TargetRegister = new NumberRegister<int>(3000),
|
||||
TargetRegister = new NumberRegister<short>(3000),
|
||||
RegisterPlcAddressName = "DT3000",
|
||||
IntialValue = (int)0,
|
||||
AfterWriteValue = (int)-513,
|
||||
IntialValue = (short)0,
|
||||
AfterWriteValue = (short)-513,
|
||||
},
|
||||
|
||||
};
|
||||
@@ -73,9 +73,9 @@ namespace MewtocolTests
|
||||
|
||||
output.WriteLine($"Testing: {plc.PLCName}");
|
||||
|
||||
var cycleClient = new MewtocolInterfaceShared(plc.PLCIP, plc.PLCPort);
|
||||
var cycleClient = Mewtocol.Ethernet(plc.PLCIP, plc.PLCPort);
|
||||
|
||||
await cycleClient.ConnectAsyncOld();
|
||||
await cycleClient.ConnectAsync();
|
||||
|
||||
Assert.True(cycleClient.IsConnected);
|
||||
|
||||
@@ -94,9 +94,9 @@ namespace MewtocolTests
|
||||
|
||||
output.WriteLine($"Testing: {plc.PLCName}\n");
|
||||
|
||||
var client = new MewtocolInterfaceShared(plc.PLCIP, plc.PLCPort);
|
||||
var client = Mewtocol.Ethernet(plc.PLCIP, plc.PLCPort);
|
||||
|
||||
await client.ConnectAsyncOld();
|
||||
await client.ConnectAsync();
|
||||
|
||||
output.WriteLine($"{client.PlcInfo}\n");
|
||||
|
||||
@@ -111,38 +111,43 @@ namespace MewtocolTests
|
||||
|
||||
}
|
||||
|
||||
//[Fact(DisplayName = "Reading basic information from PLC")]
|
||||
//public async void TestRegisterReadWriteAsync () {
|
||||
[Fact(DisplayName = "Reading basic information from PLC")]
|
||||
public async void TestRegisterReadWriteAsync() {
|
||||
|
||||
// foreach (var plc in testPlcInformationData) {
|
||||
foreach (var plc in testPlcInformationData) {
|
||||
|
||||
// output.WriteLine($"Testing: {plc.PLCName}\n");
|
||||
output.WriteLine($"Testing: {plc.PLCName}\n");
|
||||
|
||||
// var client = new MewtocolInterface(plc.PLCIP, plc.PLCPort);
|
||||
var client = Mewtocol.Ethernet(plc.PLCIP, plc.PLCPort);
|
||||
|
||||
// foreach (var testRW in testRegisterRW) {
|
||||
foreach (var testRW in testRegisterRW) {
|
||||
|
||||
// client.AddRegister(testRW.TargetRegister);
|
||||
client.AddRegister(testRW.TargetRegister);
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
// await client.ConnectAsync();
|
||||
// Assert.True(client.IsConnected);
|
||||
await client.ConnectAsync();
|
||||
Assert.True(client.IsConnected);
|
||||
|
||||
// foreach (var testRW in testRegisterRW) {
|
||||
foreach (var testRW in testRegisterRW) {
|
||||
|
||||
// client.AddRegister(testRW.TargetRegister);
|
||||
var testRegister = client.Registers.First(x => x.PLCAddressName == testRW.RegisterPlcAddressName);
|
||||
|
||||
// }
|
||||
//test inital val
|
||||
Assert.Equal(testRW.IntialValue, testRegister.Value);
|
||||
|
||||
// Assert.Equal(client.PlcInfo.CpuInformation.Cputype, plc.Type);
|
||||
// Assert.Equal(client.PlcInfo.CpuInformation.ProgramCapacity, plc.ProgCapacity);
|
||||
await testRegister.WriteAsync(testRW.AfterWriteValue);
|
||||
|
||||
// client.Disconnect();
|
||||
//test after write val
|
||||
Assert.Equal(testRW.AfterWriteValue, testRegister.Value);
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
//}
|
||||
client.Disconnect();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user