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 () {
|
public void SetupLogger () {
|
||||||
|
|
||||||
//attaching the logger
|
//attaching the logger
|
||||||
Logger.LogLevel = LogLevel.Verbose;
|
Logger.LogLevel = LogLevel.Info;
|
||||||
Logger.OnNewLogMessage((date, level, msg) => {
|
Logger.OnNewLogMessage((date, level, msg) => {
|
||||||
|
|
||||||
if (level == LogLevel.Error) Console.ForegroundColor = ConsoleColor.Red;
|
if (level == LogLevel.Error) Console.ForegroundColor = ConsoleColor.Red;
|
||||||
@@ -74,12 +74,28 @@ public class ExampleScenarios {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Scenario("Read all kinds of example registers")]
|
[Scenario("Read all kinds of example registers over ethernet")]
|
||||||
public async Task RunReadTest () {
|
public async Task RunReadTestEth () {
|
||||||
|
|
||||||
//setting up a new PLC interface and register collection
|
//setting up a new PLC interface and register collection
|
||||||
var interf = Mewtocol.Ethernet("192.168.115.210").WithPoller();
|
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
|
//auto add all built registers to the interface
|
||||||
var builder = RegBuilder.ForInterface(interf);
|
var builder = RegBuilder.ForInterface(interf);
|
||||||
var r0reg = builder.FromPlcRegName("R0").Build();
|
var r0reg = builder.FromPlcRegName("R0").Build();
|
||||||
@@ -95,14 +111,26 @@ public class ExampleScenarios {
|
|||||||
var stringReg = builder.FromPlcRegName("DT40").AsPlcType(PlcVarType.STRING).Build();
|
var stringReg = builder.FromPlcRegName("DT40").AsPlcType(PlcVarType.STRING).Build();
|
||||||
|
|
||||||
//connect
|
//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 first register data
|
||||||
await interf.AwaitFirstDataAsync();
|
await interf.AwaitFirstDataAsync();
|
||||||
|
|
||||||
_ = Task.Factory.StartNew(async () => {
|
_ = Task.Factory.StartNew(async () => {
|
||||||
|
|
||||||
void setTitle () {
|
void setTitle() {
|
||||||
|
|
||||||
Console.Title =
|
Console.Title =
|
||||||
$"Speed UP: {interf.BytesPerSecondUpstream} B/s, " +
|
$"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;
|
using System.Collections;
|
||||||
|
|
||||||
namespace Examples {
|
namespace Examples {
|
||||||
public class TestRegisters : RegisterCollectionBase {
|
public class TestRegisters : RegisterCollection {
|
||||||
|
|
||||||
//corresponds to a R100 boolean register in the PLC
|
//corresponds to a R100 boolean register in the PLC
|
||||||
[Register(IOType.R, 1000)]
|
[Register(IOType.R, 1000)]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Collections;
|
|||||||
|
|
||||||
namespace Examples {
|
namespace Examples {
|
||||||
|
|
||||||
public class TestRegistersEnumBitwise : RegisterCollectionBase {
|
public class TestRegistersEnumBitwise : RegisterCollection {
|
||||||
|
|
||||||
private bool startCyclePLC;
|
private bool startCyclePLC;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
|
||||||
<PropertyGroup>
|
<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>
|
<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 -->
|
<!-- 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> -->
|
<!-- <TargetFrameworks>$(TargetFrameworks);net7.0-tizen</TargetFrameworks> -->
|
||||||
@@ -23,12 +23,10 @@
|
|||||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||||
<ApplicationVersion>1</ApplicationVersion>
|
<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)')) == 'android'">24.0</SupportedOSPlatformVersion>
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using MewtocolNet.Registers;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -49,6 +50,11 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
int StationNumber { get; }
|
int StationNumber { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A connection info string
|
||||||
|
/// </summary>
|
||||||
|
string ConnectionInfo { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The initial connection timeout in milliseconds
|
/// The initial connection timeout in milliseconds
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -91,6 +97,26 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
string GetConnectionInfo();
|
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>
|
/// <summary>
|
||||||
/// Provides a interface for Panasonic PLCs over a ethernet connection
|
/// Provides a interface for Panasonic PLCs over a ethernet connection
|
||||||
@@ -16,9 +21,14 @@
|
|||||||
int Port { get; }
|
int Port { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attaches a poller to the interface
|
/// The host ip endpoint, leave it null to use an automatic interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IPlcEthernet WithPoller();
|
IPEndPoint HostEndpoint { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to establish a connection with the device asynchronously
|
||||||
|
/// </summary>
|
||||||
|
Task ConnectAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configures the serial interface
|
/// Configures the serial interface
|
||||||
@@ -28,6 +38,18 @@
|
|||||||
/// <param name="_station">Station Number of the PLC</param>
|
/// <param name="_station">Station Number of the PLC</param>
|
||||||
void ConfigureConnection(string _ip, int _port = 9094, int _station = 1);
|
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.Collections.Generic;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -36,11 +37,6 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
StopBits SerialStopBits { get; }
|
StopBits SerialStopBits { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attaches a poller to the interface
|
|
||||||
/// </summary>
|
|
||||||
public IPlcSerial WithPoller();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets up the connection settings for the device
|
/// Sets up the connection settings for the device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -50,7 +46,29 @@ namespace MewtocolNet {
|
|||||||
/// <param name="_parity">The serial connection parity</param>
|
/// <param name="_parity">The serial connection parity</param>
|
||||||
/// <param name="_stopBits">The serial connection stop bits</param>
|
/// <param name="_stopBits">The serial connection stop bits</param>
|
||||||
/// <param name="_station">The station number of the PLC</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.Collections.Generic;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace MewtocolNet {
|
namespace MewtocolNet {
|
||||||
@@ -13,14 +16,29 @@ namespace MewtocolNet {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds a ethernet based Mewtocol Interface
|
/// Builds a ethernet based Mewtocol Interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="_ip"></param>
|
/// <param name="ip"></param>
|
||||||
/// <param name="_port"></param>
|
/// <param name="port"></param>
|
||||||
/// <param name="_station"></param>
|
/// <param name="station">Plc station number</param>
|
||||||
/// <returns></returns>
|
/// <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();
|
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;
|
return instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -28,16 +46,19 @@ namespace MewtocolNet {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds a serial port based Mewtocol Interface
|
/// Builds a serial port based Mewtocol Interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="_portName"></param>
|
/// <param name="portName"></param>
|
||||||
/// <param name="_baudRate"></param>
|
/// <param name="baudRate"></param>
|
||||||
/// <param name="_dataBits"></param>
|
/// <param name="dataBits"></param>
|
||||||
/// <param name="_parity"></param>
|
/// <param name="parity"></param>
|
||||||
/// <param name="_stopBits"></param>
|
/// <param name="stopBits"></param>
|
||||||
|
/// <param name="station"></param>
|
||||||
/// <returns></returns>
|
/// <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();
|
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;
|
return instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -45,18 +66,29 @@ namespace MewtocolNet {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds a serial mewtocol interface that finds the correct settings for the given port name automatically
|
/// Builds a serial mewtocol interface that finds the correct settings for the given port name automatically
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="_portName"></param>
|
/// <param name="portName"></param>
|
||||||
/// <param name="_station"></param>
|
/// <param name="station"></param>
|
||||||
/// <returns></returns>
|
/// <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();
|
var instance = new MewtocolInterfaceSerial();
|
||||||
instance.ConfigureConnection(_portName, _station);
|
instance.ConfigureConnection(portName, station);
|
||||||
instance.ConfigureConnectionAuto();
|
instance.ConfigureConnectionAuto();
|
||||||
return instance;
|
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
|
#endregion
|
||||||
|
|
||||||
#region Public read/write Properties / Fields
|
#region Public read/write Properties / Fields
|
||||||
@@ -153,7 +156,7 @@ namespace MewtocolNet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual Task ConnectAsync () => throw new NotImplementedException();
|
public virtual async Task ConnectAsync() => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task AwaitFirstDataAsync() => await firstPollTask;
|
public async Task AwaitFirstDataAsync() => await firstPollTask;
|
||||||
@@ -163,7 +166,8 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
if (!IsConnected) return;
|
if (!IsConnected) return;
|
||||||
|
|
||||||
pollCycleTask.Wait();
|
if(pollCycleTask != null && !pollCycleTask.IsCompleted)
|
||||||
|
pollCycleTask.Wait();
|
||||||
|
|
||||||
OnMajorSocketExceptionWhileConnected();
|
OnMajorSocketExceptionWhileConnected();
|
||||||
|
|
||||||
@@ -212,10 +216,16 @@ namespace MewtocolNet {
|
|||||||
if (useCr)
|
if (useCr)
|
||||||
frame = $"{frame}\r";
|
frame = $"{frame}\r";
|
||||||
|
|
||||||
|
|
||||||
|
SetUpstreamStopWatchStart();
|
||||||
|
|
||||||
//write inital command
|
//write inital command
|
||||||
byte[] writeBuffer = Encoding.UTF8.GetBytes(frame);
|
byte[] writeBuffer = Encoding.UTF8.GetBytes(frame);
|
||||||
stream.Write(writeBuffer, 0, writeBuffer.Length);
|
stream.Write(writeBuffer, 0, writeBuffer.Length);
|
||||||
|
|
||||||
|
//calc upstream speed
|
||||||
|
CalcUpstreamSpeed(writeBuffer.Length);
|
||||||
|
|
||||||
Logger.Log($"[---------CMD START--------]", LogLevel.Critical, this);
|
Logger.Log($"[---------CMD START--------]", LogLevel.Critical, this);
|
||||||
Logger.Log($"--> OUT MSG: {frame.Replace("\r", "(CR)")}", LogLevel.Critical, this);
|
Logger.Log($"--> OUT MSG: {frame.Replace("\r", "(CR)")}", LogLevel.Critical, this);
|
||||||
|
|
||||||
@@ -235,7 +245,9 @@ namespace MewtocolNet {
|
|||||||
//error response
|
//error response
|
||||||
var gotErrorcode = CheckForErrorMsg(resString);
|
var gotErrorcode = CheckForErrorMsg(resString);
|
||||||
if (gotErrorcode != 0) {
|
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
|
//was multiframed response
|
||||||
@@ -281,9 +293,13 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
SetDownstreamStopWatchStart();
|
||||||
|
|
||||||
byte[] buffer = new byte[128];
|
byte[] buffer = new byte[128];
|
||||||
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
|
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
|
CalcDownstreamSpeed(bytesRead);
|
||||||
|
|
||||||
byte[] received = new byte[bytesRead];
|
byte[] received = new byte[bytesRead];
|
||||||
Buffer.BlockCopy(buffer, 0, received, 0, bytesRead);
|
Buffer.BlockCopy(buffer, 0, received, 0, bytesRead);
|
||||||
|
|
||||||
@@ -338,7 +354,7 @@ namespace MewtocolNet {
|
|||||||
private protected int CheckForErrorMsg (string msg) {
|
private protected int CheckForErrorMsg (string msg) {
|
||||||
|
|
||||||
//error catching
|
//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);
|
Match m = errorcheck.Match(msg);
|
||||||
|
|
||||||
if (m.Success) {
|
if (m.Success) {
|
||||||
@@ -401,7 +417,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
BytesPerSecondDownstream = 0;
|
BytesPerSecondDownstream = 0;
|
||||||
BytesPerSecondUpstream = 0;
|
BytesPerSecondUpstream = 0;
|
||||||
CycleTimeMs = 0;
|
PollerCycleDurationMs = 0;
|
||||||
|
|
||||||
IsConnected = false;
|
IsConnected = false;
|
||||||
ClearRegisterVals();
|
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) {
|
private protected void OnPropChange([CallerMemberName] string propertyName = null) {
|
||||||
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
|||||||
@@ -205,15 +205,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
#region Register Colleciton adding
|
#region Register Colleciton adding
|
||||||
|
|
||||||
/// <summary>
|
internal MewtocolInterface WithRegisterCollection (RegisterCollection collection) {
|
||||||
/// 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) {
|
|
||||||
|
|
||||||
collection.PLCInterface = this;
|
collection.PLCInterface = this;
|
||||||
|
|
||||||
@@ -353,6 +345,23 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
#region Register Adding
|
#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) {
|
internal void AddRegister (RegisterBuildInfo buildInfo) {
|
||||||
|
|
||||||
var builtRegister = buildInfo.Build();
|
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) {
|
private bool CheckDuplicateRegister (IRegisterInternal instance, out IRegisterInternal foundDupe) {
|
||||||
|
|
||||||
foundDupe = RegistersInternal.FirstOrDefault(x => x.CompareIsDuplicate(instance));
|
foundDupe = RegistersInternal.FirstOrDefault(x => x.CompareIsDuplicate(instance));
|
||||||
@@ -414,24 +410,15 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
#region Register accessing
|
#region Register accessing
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>>
|
||||||
/// Gets a register that was added by its name
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IRegister GetRegister(string name) {
|
public IRegister GetRegister(string name) {
|
||||||
|
|
||||||
return RegistersUnderlying.FirstOrDefault(x => x.Name == name);
|
return RegistersUnderlying.FirstOrDefault(x => x.Name == name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
/// <inheritdoc/>
|
||||||
|
public IEnumerable<IRegister> GetAllRegisters () {
|
||||||
#region Register Reading
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a list of all added registers
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<IRegister> GetAllRegisters() {
|
|
||||||
|
|
||||||
return RegistersUnderlying.Cast<IRegister>();
|
return RegistersUnderlying.Cast<IRegister>();
|
||||||
|
|
||||||
|
|||||||
@@ -289,6 +289,86 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
#endregion
|
#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
|
#region Helpers
|
||||||
|
|
||||||
internal string GetStationNumber() {
|
internal string GetStationNumber() {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Net;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using MewtocolNet.RegisterAttributes;
|
||||||
|
|
||||||
namespace MewtocolNet {
|
namespace MewtocolNet {
|
||||||
|
|
||||||
@@ -17,11 +18,23 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
private bool autoSerial;
|
private bool autoSerial;
|
||||||
|
|
||||||
|
private event Action tryingSerialConfig;
|
||||||
|
|
||||||
//serial config
|
//serial config
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public string PortName { get; private set; }
|
public string PortName { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public int SerialBaudRate { get; private set; }
|
public int SerialBaudRate { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public int SerialDataBits { get; private set; }
|
public int SerialDataBits { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public Parity SerialParity { get; private set; }
|
public Parity SerialParity { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public StopBits SerialStopBits { get; private set; }
|
public StopBits SerialStopBits { get; private set; }
|
||||||
|
|
||||||
//Serial
|
//Serial
|
||||||
@@ -29,7 +42,6 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
internal MewtocolInterfaceSerial () : base() { }
|
internal MewtocolInterfaceSerial () : base() { }
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IPlcSerial WithPoller () {
|
public IPlcSerial WithPoller () {
|
||||||
|
|
||||||
@@ -38,6 +50,13 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IPlcSerial AddRegisterCollection (RegisterCollection collection) {
|
||||||
|
|
||||||
|
WithRegisterCollection(collection);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string GetConnectionInfo() {
|
public override string GetConnectionInfo() {
|
||||||
|
|
||||||
@@ -89,8 +108,17 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task ConnectAsync() => await ConnectAsync(null);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override async Task ConnectAsync () {
|
public async Task ConnectAsync (Action onTryingConfig = null) {
|
||||||
|
|
||||||
|
void OnTryConfig() {
|
||||||
|
onTryingConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onTryingConfig != null)
|
||||||
|
tryingSerialConfig += OnTryConfig;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -98,10 +126,12 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
if(autoSerial) {
|
if(autoSerial) {
|
||||||
|
|
||||||
|
Logger.Log($"Connecting [AUTO CONFIGURE]: {PortName}", LogLevel.Info, this);
|
||||||
gotInfo = await TryConnectAsyncMulti();
|
gotInfo = await TryConnectAsyncMulti();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
Logger.Log($"Connecting [MAN]: {PortName}", LogLevel.Info, this);
|
||||||
gotInfo = await TryConnectAsyncSingle(PortName, SerialBaudRate, SerialDataBits, SerialParity, SerialStopBits);
|
gotInfo = await TryConnectAsyncSingle(PortName, SerialBaudRate, SerialDataBits, SerialParity, SerialStopBits);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -112,7 +142,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Logger.Log("Initial connection failed", LogLevel.Info, this);
|
Logger.Log("Initial connection failed", LogLevel.Error, this);
|
||||||
OnMajorSocketExceptionWhileConnecting();
|
OnMajorSocketExceptionWhileConnecting();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -125,6 +155,8 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tryingSerialConfig -= OnTryConfig;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<PLCInfo> TryConnectAsyncMulti () {
|
private async Task<PLCInfo> TryConnectAsyncMulti () {
|
||||||
@@ -193,19 +225,20 @@ namespace MewtocolNet {
|
|||||||
SerialParity = par;
|
SerialParity = par;
|
||||||
SerialStopBits = sbits;
|
SerialStopBits = sbits;
|
||||||
OnSerialPropsChanged();
|
OnSerialPropsChanged();
|
||||||
|
tryingSerialConfig?.Invoke();
|
||||||
|
|
||||||
serialClient.Open();
|
serialClient.Open();
|
||||||
|
|
||||||
if (!serialClient.IsOpen) {
|
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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stream = serialClient.BaseStream;
|
stream = serialClient.BaseStream;
|
||||||
|
|
||||||
Logger.Log($"Opened [SERIAL]: {GetConnectionInfo()}", LogLevel.Verbose, this);
|
Logger.Log($"Opened [SERIAL]: {GetConnectionInfo()}", LogLevel.Critical, this);
|
||||||
|
|
||||||
var plcinf = await GetPLCInfoAsync(100);
|
var plcinf = await GetPLCInfoAsync(100);
|
||||||
|
|
||||||
|
|||||||
@@ -26,23 +26,19 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MewtocolInterfaceTcp : MewtocolInterface, IPlcEthernet {
|
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
|
//TCP
|
||||||
internal TcpClient client;
|
internal TcpClient client;
|
||||||
|
|
||||||
//tcp/ip config
|
private IPAddress ipAddr;
|
||||||
private string ip;
|
|
||||||
private int port;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string IpAddress => ip;
|
public string IpAddress => ipAddr.ToString();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int Port => port;
|
public int Port { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IPEndPoint HostEndpoint { get; set; }
|
||||||
|
|
||||||
internal MewtocolInterfaceTcp () : base() { }
|
internal MewtocolInterfaceTcp () : base() { }
|
||||||
|
|
||||||
@@ -54,14 +50,35 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IPlcEthernet AddRegisterCollection (RegisterCollection collection) {
|
||||||
|
|
||||||
|
WithRegisterCollection(collection);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#region TCP connection state handling
|
#region TCP connection state handling
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <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;
|
if (!IPAddress.TryParse(ip, out ipAddr))
|
||||||
port = _port;
|
throw new MewtocolException($"The ip: {ip} is no valid ip address");
|
||||||
stationNumber = _station;
|
|
||||||
|
Port = port;
|
||||||
|
stationNumber = station;
|
||||||
|
|
||||||
|
Disconnect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void ConfigureConnection(IPAddress ip, int port = 9094, int station = 1) {
|
||||||
|
|
||||||
|
ipAddr = ip;
|
||||||
|
Port = port;
|
||||||
|
stationNumber = station;
|
||||||
|
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
|
||||||
@@ -70,10 +87,6 @@ namespace MewtocolNet {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override async Task ConnectAsync () {
|
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 {
|
try {
|
||||||
|
|
||||||
if (HostEndpoint != null) {
|
if (HostEndpoint != null) {
|
||||||
@@ -83,29 +96,31 @@ namespace MewtocolNet {
|
|||||||
NoDelay = false,
|
NoDelay = false,
|
||||||
};
|
};
|
||||||
var ep = (IPEndPoint)client.Client.LocalEndPoint;
|
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 {
|
} else {
|
||||||
|
|
||||||
client = new TcpClient() {
|
client = new TcpClient() {
|
||||||
ReceiveBufferSize = RecBufferSize,
|
ReceiveBufferSize = RecBufferSize,
|
||||||
NoDelay = false,
|
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));
|
var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(ConnectTimeout));
|
||||||
|
|
||||||
if (!success || !client.Connected) {
|
if (!success || !client.Connected) {
|
||||||
|
|
||||||
|
Logger.Log("The PLC connection timed out", LogLevel.Error, this);
|
||||||
OnMajorSocketExceptionWhileConnecting();
|
OnMajorSocketExceptionWhileConnecting();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HostEndpoint == null) {
|
if (HostEndpoint == null) {
|
||||||
var ep = (IPEndPoint)client.Client.LocalEndPoint;
|
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
|
//get the stream
|
||||||
@@ -121,7 +136,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Logger.Log("Initial connection failed", LogLevel.Info, this);
|
Logger.Log("Initial connection failed", LogLevel.Error, this);
|
||||||
OnDisconnect();
|
OnDisconnect();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace MewtocolNet.RegisterAttributes {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A register collection base with full auto read and notification support built in
|
/// A register collection base with full auto read and notification support built in
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RegisterCollectionBase : INotifyPropertyChanged {
|
public class RegisterCollection : INotifyPropertyChanged {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reference to its bound interface
|
/// 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();
|
var rb = new RegBuilder();
|
||||||
rb.forInterface = interf as MewtocolInterface;
|
rb.forInterface = interf as MewtocolInterface;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace MewtocolTests {
|
|||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestRegisterCollection : RegisterCollectionBase {
|
public class TestRegisterCollection : RegisterCollection {
|
||||||
|
|
||||||
//corresponds to a R100 boolean register in the PLC
|
//corresponds to a R100 boolean register in the PLC
|
||||||
//can also be written as R1000 because the last one is a special address
|
//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")]
|
[Fact(DisplayName = "Boolean R generation")]
|
||||||
public void BooleanGen() {
|
public void BooleanGen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBool1));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBool1));
|
||||||
|
|
||||||
@@ -122,8 +122,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "Boolean input XD generation")]
|
[Fact(DisplayName = "Boolean input XD generation")]
|
||||||
public void BooleanInputGen() {
|
public void BooleanInputGen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBoolInputXD));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBoolInputXD));
|
||||||
|
|
||||||
@@ -135,8 +135,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "Int16 generation")]
|
[Fact(DisplayName = "Int16 generation")]
|
||||||
public void Int16Gen() {
|
public void Int16Gen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestInt16));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestInt16));
|
||||||
|
|
||||||
@@ -148,8 +148,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "UInt16 generation")]
|
[Fact(DisplayName = "UInt16 generation")]
|
||||||
public void UInt16Gen() {
|
public void UInt16Gen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestUInt16));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestUInt16));
|
||||||
|
|
||||||
@@ -161,8 +161,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "Int32 generation")]
|
[Fact(DisplayName = "Int32 generation")]
|
||||||
public void Int32Gen() {
|
public void Int32Gen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestInt32));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestInt32));
|
||||||
|
|
||||||
@@ -174,8 +174,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "UInt32 generation")]
|
[Fact(DisplayName = "UInt32 generation")]
|
||||||
public void UInt32Gen() {
|
public void UInt32Gen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestUInt32));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestUInt32));
|
||||||
|
|
||||||
@@ -187,8 +187,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "Float32 generation")]
|
[Fact(DisplayName = "Float32 generation")]
|
||||||
public void Float32Gen() {
|
public void Float32Gen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestFloat32));
|
var register = interf.GetRegister(nameof(TestRegisterCollection.TestFloat32));
|
||||||
|
|
||||||
@@ -200,8 +200,8 @@ namespace MewtocolTests {
|
|||||||
[Fact(DisplayName = "TimeSpan generation")]
|
[Fact(DisplayName = "TimeSpan generation")]
|
||||||
public void TimespanGen() {
|
public void TimespanGen() {
|
||||||
|
|
||||||
var interf = new MewtocolInterfaceShared("192.168.0.1");
|
var interf = Mewtocol.Ethernet("192.168.0.1");
|
||||||
interf.WithRegisterCollection(new TestRegisterCollection()).WithPoller();
|
interf.AddRegisterCollection(new TestRegisterCollection()).WithPoller();
|
||||||
|
|
||||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestTime));
|
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,
|
AfterWriteValue = true,
|
||||||
},
|
},
|
||||||
new RegisterReadWriteTest {
|
new RegisterReadWriteTest {
|
||||||
TargetRegister = new NumberRegister<int>(3000),
|
TargetRegister = new NumberRegister<short>(3000),
|
||||||
RegisterPlcAddressName = "DT3000",
|
RegisterPlcAddressName = "DT3000",
|
||||||
IntialValue = (int)0,
|
IntialValue = (short)0,
|
||||||
AfterWriteValue = (int)-513,
|
AfterWriteValue = (short)-513,
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -73,9 +73,9 @@ namespace MewtocolTests
|
|||||||
|
|
||||||
output.WriteLine($"Testing: {plc.PLCName}");
|
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);
|
Assert.True(cycleClient.IsConnected);
|
||||||
|
|
||||||
@@ -94,9 +94,9 @@ namespace MewtocolTests
|
|||||||
|
|
||||||
output.WriteLine($"Testing: {plc.PLCName}\n");
|
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");
|
output.WriteLine($"{client.PlcInfo}\n");
|
||||||
|
|
||||||
@@ -111,38 +111,43 @@ namespace MewtocolTests
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Fact(DisplayName = "Reading basic information from PLC")]
|
[Fact(DisplayName = "Reading basic information from PLC")]
|
||||||
//public async void TestRegisterReadWriteAsync () {
|
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();
|
await client.ConnectAsync();
|
||||||
// Assert.True(client.IsConnected);
|
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);
|
await testRegister.WriteAsync(testRW.AfterWriteValue);
|
||||||
// Assert.Equal(client.PlcInfo.CpuInformation.ProgramCapacity, plc.ProgCapacity);
|
|
||||||
|
|
||||||
// client.Disconnect();
|
//test after write val
|
||||||
|
Assert.Equal(testRW.AfterWriteValue, testRegister.Value);
|
||||||
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
//}
|
client.Disconnect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user