mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 11:11:23 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18d5118b43 | ||
|
|
48b04dfb7f | ||
|
|
9ca31fe748 | ||
|
|
3bc790238e | ||
|
|
df0de8830e | ||
|
|
19db0a9daa | ||
|
|
6dd2a1688a |
14
.github/workflows/test-pipeline.yml
vendored
14
.github/workflows/test-pipeline.yml
vendored
@@ -22,12 +22,6 @@ jobs:
|
|||||||
name: 'Run tests and documentation'
|
name: 'Run tests and documentation'
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: 'Extract branch name'
|
|
||||||
shell: bash
|
|
||||||
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
|
||||||
id: extract_branch
|
|
||||||
|
|
||||||
- name: 'Setup dotnet'
|
- name: 'Setup dotnet'
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v2
|
||||||
@@ -35,6 +29,14 @@ jobs:
|
|||||||
dotnet-version: |
|
dotnet-version: |
|
||||||
6.0.x
|
6.0.x
|
||||||
7.0.x
|
7.0.x
|
||||||
|
|
||||||
|
- name: 'Checkout'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: 'Extract branch name'
|
||||||
|
shell: bash
|
||||||
|
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||||
|
id: extract_branch
|
||||||
|
|
||||||
- name: 'Run tests'
|
- name: 'Run tests'
|
||||||
run: dotnet test "./MewtocolTests" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../Builds/TestResults/coverage.opencover.xml
|
run: dotnet test "./MewtocolTests" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../Builds/TestResults/coverage.opencover.xml
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ internal class Program {
|
|||||||
|
|
||||||
//the library provides a logging tool, comment this out if needed
|
//the library provides a logging tool, comment this out if needed
|
||||||
Logger.LogLevel = LogLevel.Critical;
|
Logger.LogLevel = LogLevel.Critical;
|
||||||
|
Logger.OnNewLogMessage((t, l, m) => { Console.WriteLine(m); });
|
||||||
|
|
||||||
//create a new interface to the plc using ethernet / tcp ip
|
//create a new interface to the plc using ethernet / tcp ip
|
||||||
//the using keyword is optional, if you want to use your PLC instance
|
//the using keyword is optional, if you want to use your PLC instance
|
||||||
|
|||||||
@@ -198,6 +198,17 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
IEnumerable<IRegister> GetAllRegisters();
|
IEnumerable<IRegister> GetAllRegisters();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds and adds registers to the device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder"></param>
|
||||||
|
void BuildRegisters(Action<RBuildMulti> builder);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all registers atached to the interface
|
||||||
|
/// </summary>
|
||||||
|
void ClearAllRegisters();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explains the register internal layout at this moment in time
|
/// Explains the register internal layout at this moment in time
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
StopBits SerialStopBits { get; }
|
StopBits SerialStopBits { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is RTS (Request to send) enabled?
|
||||||
|
/// </summary>
|
||||||
|
bool RtsEnabled { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets up the connection settings for the device
|
/// Sets up the connection settings for the device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -42,8 +47,9 @@ namespace MewtocolNet {
|
|||||||
/// <param name="_dataBits">The serial connection data bits</param>
|
/// <param name="_dataBits">The serial connection data bits</param>
|
||||||
/// <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="_rtsEnable">Is RTS (Request to send) enabled?</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, bool _rtsEnable = true, int _station = 1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to establish a connection with the device asynchronously
|
/// Tries to establish a connection with the device asynchronously
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace MewtocolNet.Logging {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the default output logger targets
|
/// Defines the default output logger targets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LoggerTargets DefaultTargets { get; set; } = LoggerTargets.None;
|
public static LoggerTargets DefaultTargets { get; set; } = LoggerTargets.Console;
|
||||||
|
|
||||||
internal static Action<DateTime, LogLevel, string> LogInvoked;
|
internal static Action<DateTime, LogLevel, string> LogInvoked;
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ namespace MewtocolNet.Logging {
|
|||||||
|
|
||||||
OnNewLogMessage((d, l, m) => {
|
OnNewLogMessage((d, l, m) => {
|
||||||
|
|
||||||
if(isConsoleApplication || DefaultTargets.HasFlag(LoggerTargets.Console)) {
|
if(isConsoleApplication && DefaultTargets.HasFlag(LoggerTargets.Console)) {
|
||||||
|
|
||||||
switch (l) {
|
switch (l) {
|
||||||
case LogLevel.Error:
|
case LogLevel.Error:
|
||||||
|
|||||||
@@ -128,12 +128,13 @@ namespace MewtocolNet {
|
|||||||
/// <param name="dataBits">DataBits of the plc toolport</param>
|
/// <param name="dataBits">DataBits of the plc toolport</param>
|
||||||
/// <param name="parity">Parity rate of the plc toolport</param>
|
/// <param name="parity">Parity rate of the plc toolport</param>
|
||||||
/// <param name="stopBits">Stop bits of the plc toolport</param>
|
/// <param name="stopBits">Stop bits of the plc toolport</param>
|
||||||
|
/// <param name="rtsEnabled">Is RTS (Request to send) enabled?</param>
|
||||||
/// <param name="station">Plc station number 0xEE for direct communication</param>
|
/// <param name="station">Plc station number 0xEE for direct communication</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static PostInit<IPlcSerial> Serial(string portName, BaudRate baudRate = BaudRate._19200, DataBits dataBits = DataBits.Eight, Parity parity = Parity.Odd, StopBits stopBits = StopBits.One, int station = 0xEE) {
|
public static PostInit<IPlcSerial> Serial(string portName, BaudRate baudRate = BaudRate._19200, DataBits dataBits = DataBits.Eight, Parity parity = Parity.Odd, StopBits stopBits = StopBits.One, bool rtsEnabled = true, int station = 0xEE) {
|
||||||
|
|
||||||
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, rtsEnabled, station);
|
||||||
return new PostInit<IPlcSerial> {
|
return new PostInit<IPlcSerial> {
|
||||||
intf = instance
|
intf = instance
|
||||||
};
|
};
|
||||||
@@ -144,12 +145,13 @@ namespace MewtocolNet {
|
|||||||
/// 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="rtsEnabled">Is RTS (Request to send) enabled?</param>
|
||||||
/// <param name="station">Plc station number 0xEE for direct communication</param>
|
/// <param name="station">Plc station number 0xEE for direct communication</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static PostInit<IPlcSerial> SerialAuto(string portName, int station = 0xEE) {
|
public static PostInit<IPlcSerial> SerialAuto(string portName, bool rtsEnabled = true, int station = 0xEE) {
|
||||||
|
|
||||||
var instance = new MewtocolInterfaceSerial();
|
var instance = new MewtocolInterfaceSerial();
|
||||||
instance.ConfigureConnection(portName, station);
|
instance.ConfigureConnection(portName, station, rtsEnable: rtsEnabled);
|
||||||
instance.ConfigureConnectionAuto();
|
instance.ConfigureConnectionAuto();
|
||||||
return new PostInit<IPlcSerial> {
|
return new PostInit<IPlcSerial> {
|
||||||
intf = instance
|
intf = instance
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace MewtocolNet {
|
|||||||
internal int tryReconnectDelayMs = 1000;
|
internal int tryReconnectDelayMs = 1000;
|
||||||
|
|
||||||
internal bool usePoller = false;
|
internal bool usePoller = false;
|
||||||
internal bool alwaysGetMetadata = true;
|
internal bool alwaysGetMetadata = false;
|
||||||
|
|
||||||
internal Func<int, Task> onBeforeReconnectTryTask;
|
internal Func<int, Task> onBeforeReconnectTryTask;
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ namespace MewtocolNet {
|
|||||||
#region Message sending and queuing
|
#region Message sending and queuing
|
||||||
|
|
||||||
//internally used send task
|
//internally used send task
|
||||||
internal async Task<MewtocolFrameResponse> SendCommandInternalAsync(string _msg, Action<double> onReceiveProgress = null) {
|
internal async Task<MewtocolFrameResponse> SendCommandInternalAsync(string _msg, Action<double> onReceiveProgress = null, int? overrideTimeout = null) {
|
||||||
|
|
||||||
if (tSourceMessageCancel.Token.IsCancellationRequested) return MewtocolFrameResponse.Canceled;
|
if (tSourceMessageCancel.Token.IsCancellationRequested) return MewtocolFrameResponse.Canceled;
|
||||||
|
|
||||||
@@ -484,7 +484,7 @@ namespace MewtocolNet {
|
|||||||
//send request
|
//send request
|
||||||
regularSendTask = SendTwoDirectionalFrameAsync(_msg, onReceiveProgress);
|
regularSendTask = SendTwoDirectionalFrameAsync(_msg, onReceiveProgress);
|
||||||
|
|
||||||
var timeoutAwaiter = await Task.WhenAny(regularSendTask, Task.Delay(sendReceiveTimeoutMs, tSourceMessageCancel.Token));
|
var timeoutAwaiter = await Task.WhenAny(regularSendTask, Task.Delay(overrideTimeout ?? sendReceiveTimeoutMs, tSourceMessageCancel.Token));
|
||||||
|
|
||||||
if (timeoutAwaiter != regularSendTask) {
|
if (timeoutAwaiter != regularSendTask) {
|
||||||
|
|
||||||
@@ -530,43 +530,6 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private protected async Task<MewtocolFrameResponse> SendOneDirectionalFrameAsync (string frame) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (stream == null) return MewtocolFrameResponse.NotIntialized;
|
|
||||||
|
|
||||||
frame = $"{frame.BCC_Mew()}\r";
|
|
||||||
|
|
||||||
SetUpstreamStopWatchStart();
|
|
||||||
|
|
||||||
IsSending = true;
|
|
||||||
|
|
||||||
if (tSourceMessageCancel.Token.IsCancellationRequested) return MewtocolFrameResponse.Canceled;
|
|
||||||
|
|
||||||
//write inital command
|
|
||||||
byte[] writeBuffer = Encoding.UTF8.GetBytes(frame);
|
|
||||||
await stream.WriteAsync(writeBuffer, 0, writeBuffer.Length, tSourceMessageCancel.Token);
|
|
||||||
|
|
||||||
IsSending = false;
|
|
||||||
|
|
||||||
//calc upstream speed
|
|
||||||
CalcUpstreamSpeed(writeBuffer.Length);
|
|
||||||
|
|
||||||
OnOutMsg(frame);
|
|
||||||
OnEndMsg();
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
|
|
||||||
IsSending = false;
|
|
||||||
return new MewtocolFrameResponse(400, ex.Message.ToString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return MewtocolFrameResponse.EmptySuccess;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private protected async Task<MewtocolFrameResponse> SendTwoDirectionalFrameAsync(string frame, Action<double> onReceiveProgress = null) {
|
private protected async Task<MewtocolFrameResponse> SendTwoDirectionalFrameAsync(string frame, Action<double> onReceiveProgress = null) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -899,8 +862,6 @@ namespace MewtocolNet {
|
|||||||
ClearRegisterVals();
|
ClearRegisterVals();
|
||||||
KillPoller();
|
KillPoller();
|
||||||
|
|
||||||
//GetAllRegisters().Cast<Register>().ToList().ForEach(x => x.OnPlcDisconnected());
|
|
||||||
|
|
||||||
//generate a new cancellation token source
|
//generate a new cancellation token source
|
||||||
tSourceMessageCancel = new CancellationTokenSource();
|
tSourceMessageCancel = new CancellationTokenSource();
|
||||||
|
|
||||||
|
|||||||
@@ -327,66 +327,30 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
#region Register Adding
|
#region Register Adding
|
||||||
|
|
||||||
|
/// <inheritdoc/>>
|
||||||
|
public void BuildRegisters (Action<RBuildMulti> builder) {
|
||||||
|
|
||||||
|
var regBuilder = new RBuildMulti(this);
|
||||||
|
|
||||||
|
builder.Invoke(regBuilder);
|
||||||
|
|
||||||
|
this.AddRegisters(regBuilder.assembler.assembled.ToArray());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>>
|
||||||
|
public void ClearAllRegisters () {
|
||||||
|
|
||||||
|
memoryManager.ClearAllRegisters();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
internal void AddRegisters(params Register[] registers) {
|
internal void AddRegisters(params Register[] registers) {
|
||||||
|
|
||||||
memoryManager.LinkAndMergeRegisters(registers.ToList());
|
memoryManager.LinkAndMergeRegisters(registers.ToList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckDuplicateRegister(Register instance, out Register foundDupe) {
|
|
||||||
|
|
||||||
foundDupe = RegistersInternal.FirstOrDefault(x => x.CompareIsDuplicate(instance));
|
|
||||||
|
|
||||||
return RegistersInternal.Contains(instance) || foundDupe != null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckDuplicateRegister(Register instance) {
|
|
||||||
|
|
||||||
var foundDupe = RegistersInternal.FirstOrDefault(x => x.CompareIsDuplicate(instance));
|
|
||||||
|
|
||||||
return RegistersInternal.Contains(instance) || foundDupe != null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckDuplicateNameRegister(Register instance) {
|
|
||||||
|
|
||||||
return RegistersInternal.Any(x => x.CompareIsNameDuplicate(instance));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckOverlappingRegister(Register instance, out Register regB) {
|
|
||||||
|
|
||||||
//ignore bool registers, they have their own address spectrum
|
|
||||||
regB = null;
|
|
||||||
if (instance is BoolRegister) return false;
|
|
||||||
|
|
||||||
uint addressFrom = instance.MemoryAddress;
|
|
||||||
uint addressTo = addressFrom + instance.GetRegisterAddressLen();
|
|
||||||
|
|
||||||
var foundOverlapping = RegistersInternal.FirstOrDefault(x => {
|
|
||||||
|
|
||||||
//ignore bool registers, they have their own address spectrum
|
|
||||||
if (x is BoolRegister) return false;
|
|
||||||
|
|
||||||
uint addressF = x.MemoryAddress;
|
|
||||||
uint addressT = addressF + x.GetRegisterAddressLen();
|
|
||||||
|
|
||||||
bool matchingBaseAddress = addressFrom < addressT && addressF < addressTo;
|
|
||||||
|
|
||||||
return matchingBaseAddress;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (foundOverlapping != null) {
|
|
||||||
regB = foundOverlapping;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Register accessing
|
#region Register accessing
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace MewtocolNet {
|
|||||||
/// <returns>A PLCInfo class</returns>
|
/// <returns>A PLCInfo class</returns>
|
||||||
public async Task<PLCInfo> GetInfoAsync(bool detailed = true) {
|
public async Task<PLCInfo> GetInfoAsync(bool detailed = true) {
|
||||||
|
|
||||||
MewtocolFrameResponse resRT = await SendCommandInternalAsync("%EE#RT");
|
MewtocolFrameResponse resRT = await SendCommandInternalAsync($"%{GetStationNumber()}#RT");
|
||||||
|
|
||||||
if (!resRT.Success || tSourceMessageCancel.Token.IsCancellationRequested) return null;
|
if (!resRT.Success || tSourceMessageCancel.Token.IsCancellationRequested) return null;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
if (isConnectingStage && detailed) {
|
if (isConnectingStage && detailed) {
|
||||||
|
|
||||||
resEXRT = await SendCommandInternalAsync("%EE#EX00RT00");
|
resEXRT = await SendCommandInternalAsync($"%{GetStationNumber()}#EX00RT00");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace MewtocolNet {
|
namespace MewtocolNet {
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public sealed class MewtocolInterfaceSerial : MewtocolInterface, IPlcSerial {
|
public sealed class MewtocolInterfaceSerial : MewtocolInterface, IPlcSerial {
|
||||||
|
|
||||||
private bool autoSerial;
|
private bool autoSerial;
|
||||||
@@ -32,6 +33,9 @@ namespace MewtocolNet {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public StopBits SerialStopBits { get; private set; }
|
public StopBits SerialStopBits { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool RtsEnabled { get; private set; }
|
||||||
|
|
||||||
//Serial
|
//Serial
|
||||||
internal SerialPort serialClient;
|
internal SerialPort serialClient;
|
||||||
|
|
||||||
@@ -76,7 +80,7 @@ namespace MewtocolNet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void ConfigureConnection(string _portName, int _baudRate = 19200, int _dataBits = 8, Parity _parity = Parity.Odd, StopBits _stopBits = StopBits.One, int _station = 0xEE) {
|
public void ConfigureConnection(string _portName, int _baudRate = 19200, int _dataBits = 8, Parity _parity = Parity.Odd, StopBits _stopBits = StopBits.One, bool rtsEnable = true, int _station = 0xEE) {
|
||||||
|
|
||||||
if (IsConnected)
|
if (IsConnected)
|
||||||
throw new NotSupportedException("Can't change the connection settings while the PLC is connected");
|
throw new NotSupportedException("Can't change the connection settings while the PLC is connected");
|
||||||
@@ -87,6 +91,7 @@ namespace MewtocolNet {
|
|||||||
SerialParity = _parity;
|
SerialParity = _parity;
|
||||||
SerialStopBits = _stopBits;
|
SerialStopBits = _stopBits;
|
||||||
stationNumber = _station;
|
stationNumber = _station;
|
||||||
|
RtsEnabled = rtsEnable;
|
||||||
|
|
||||||
if (stationNumber != 0xEE && stationNumber > 99)
|
if (stationNumber != 0xEE && stationNumber > 99)
|
||||||
throw new NotSupportedException("Station number can't be greater than 99");
|
throw new NotSupportedException("Station number can't be greater than 99");
|
||||||
@@ -231,7 +236,8 @@ namespace MewtocolNet {
|
|||||||
Parity = par,
|
Parity = par,
|
||||||
StopBits = sbits,
|
StopBits = sbits,
|
||||||
ReadTimeout = 100,
|
ReadTimeout = 100,
|
||||||
Handshake = Handshake.None
|
Handshake = Handshake.None,
|
||||||
|
RtsEnable = RtsEnabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
PortName = port;
|
PortName = port;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace MewtocolNet {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override async Task<ConnectResult> ConnectAsync(Func<Task> callBack = null) => await ConnectAsyncPriv(callBack);
|
public override async Task<ConnectResult> ConnectAsync(Func<Task> callBack = null) => await ConnectAsyncPriv(callBack);
|
||||||
|
|
||||||
private void BuildTcpClient () {
|
protected internal void BuildTcpClient () {
|
||||||
|
|
||||||
if (HostEndpoint != null) {
|
if (HostEndpoint != null) {
|
||||||
|
|
||||||
@@ -87,9 +87,6 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
client = new TcpClient(HostEndpoint) {
|
client = new TcpClient(HostEndpoint) {
|
||||||
ReceiveBufferSize = RecBufferSize,
|
ReceiveBufferSize = RecBufferSize,
|
||||||
NoDelay = false,
|
|
||||||
ReceiveTimeout = sendReceiveTimeoutMs,
|
|
||||||
SendTimeout = sendReceiveTimeoutMs,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var ep = (IPEndPoint)client.Client.LocalEndPoint;
|
var ep = (IPEndPoint)client.Client.LocalEndPoint;
|
||||||
@@ -99,9 +96,6 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
client = new TcpClient() {
|
client = new TcpClient() {
|
||||||
ReceiveBufferSize = RecBufferSize,
|
ReceiveBufferSize = RecBufferSize,
|
||||||
NoDelay = false,
|
|
||||||
ReceiveTimeout = sendReceiveTimeoutMs,
|
|
||||||
SendTimeout = sendReceiveTimeoutMs,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
internal bool TryExtendFromEXRT(string msg) {
|
internal bool TryExtendFromEXRT(string msg) {
|
||||||
|
|
||||||
var regexEXRT = new Regex(@"\%EE\$EX00RT00(?<icnt>..)(?<mc>..)..(?<cap>..)(?<op>..)..(?<flg>..)(?<sdiag>....)(?<ver>..)(?<hwif>..)(?<nprog>.)(?<csumpz>...)(?<psize>...).*", RegexOptions.IgnoreCase);
|
var regexEXRT = new Regex(@"\%..\$EX00RT00(?<icnt>..)(?<mc>..)..(?<cap>..)(?<op>..)..(?<flg>..)(?<sdiag>....)(?<ver>..)(?<hwif>..)(?<nprog>.)(?<csumpz>...)(?<psize>...).*", RegexOptions.IgnoreCase);
|
||||||
var match = regexEXRT.Match(msg);
|
var match = regexEXRT.Match(msg);
|
||||||
if (match.Success) {
|
if (match.Success) {
|
||||||
|
|
||||||
@@ -160,9 +160,11 @@ namespace MewtocolNet {
|
|||||||
this.TypeCode = (PlcType)tempTypeCode;
|
this.TypeCode = (PlcType)tempTypeCode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cpuVerStr = match.Groups["ver"].Value;
|
||||||
|
|
||||||
//overwrite the other vals that are also contained in EXRT
|
//overwrite the other vals that are also contained in EXRT
|
||||||
this.CpuVersion = match.Groups["ver"].Value.Insert(1, ".");
|
this.CpuVersion = string.Join(".", cpuVerStr.Select(x => byte.Parse($"{x}", NumberStyles.HexNumber).ToString()));
|
||||||
this.HardwareInformation = (HWInformation)byte.Parse(match.Groups["hwif"].Value, NumberStyles.HexNumber);
|
this.HardwareInformation = (HWInformation)byte.Parse(match.Groups["hwif"].Value, NumberStyles.HexNumber);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -175,7 +177,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
internal static bool TryFromRT(string msg, MewtocolInterface onInterface, out PLCInfo inf) {
|
internal static bool TryFromRT(string msg, MewtocolInterface onInterface, out PLCInfo inf) {
|
||||||
|
|
||||||
var regexRT = new Regex(@"\%EE\$RT(?<cputype>..)(?<cpuver>..)(?<cap>..)(?<op>..)..(?<flg>..)(?<sdiag>....).*", RegexOptions.IgnoreCase);
|
var regexRT = new Regex(@"\%..\$RT(?<cputype>..)(?<cpuver>..)(?<cap>..)(?<op>..)..(?<flg>..)(?<sdiag>....).*", RegexOptions.IgnoreCase);
|
||||||
var match = regexRT.Match(msg);
|
var match = regexRT.Match(msg);
|
||||||
if (match.Success) {
|
if (match.Success) {
|
||||||
|
|
||||||
@@ -206,9 +208,12 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cpuVerStr = match.Groups["cpuver"].Value;
|
||||||
|
var cpuVer = string.Join(".", cpuVerStr.Select(x => byte.Parse($"{x}").ToString("X1")));
|
||||||
|
|
||||||
inf = new PLCInfo (onInterface) {
|
inf = new PLCInfo (onInterface) {
|
||||||
TypeCode = typeCodeFull,
|
TypeCode = typeCodeFull,
|
||||||
CpuVersion = match.Groups["cpuver"].Value.Insert(1, "."),
|
CpuVersion = cpuVer,
|
||||||
ProgramCapacity = definedProgCapacity,
|
ProgramCapacity = definedProgCapacity,
|
||||||
SelfDiagnosticError = match.Groups["sdiag"].Value,
|
SelfDiagnosticError = match.Groups["sdiag"].Value,
|
||||||
OperationMode = (OPMode)byte.Parse(match.Groups["op"].Value, NumberStyles.HexNumber),
|
OperationMode = (OPMode)byte.Parse(match.Groups["op"].Value, NumberStyles.HexNumber),
|
||||||
|
|||||||
@@ -23,15 +23,17 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
public async Task WriteAsync(T value) {
|
public async Task WriteAsync(T value) {
|
||||||
|
|
||||||
var reg = (IRegister<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
await reg.WriteAsync(value);
|
reg.isAnonymous = true;
|
||||||
|
await ((IRegister<T>)reg).WriteAsync(value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> ReadAsync() {
|
public async Task<T> ReadAsync() {
|
||||||
|
|
||||||
var reg = (IRegister<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
return await reg.ReadAsync();
|
reg.isAnonymous = true;
|
||||||
|
return await ((IRegister<T>)reg).ReadAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +43,17 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
public async Task WriteAsync(string value) {
|
public async Task WriteAsync(string value) {
|
||||||
|
|
||||||
var reg = (IStringRegister)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
await reg.WriteAsync(value);
|
reg.isAnonymous = true;
|
||||||
|
await ((IStringRegister)reg).WriteAsync(value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> ReadAsync() {
|
public async Task<string> ReadAsync() {
|
||||||
|
|
||||||
var reg = (IStringRegister)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
return await reg.ReadAsync();
|
reg.isAnonymous = true;
|
||||||
|
return await ((IStringRegister)reg).ReadAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,15 +75,19 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
public async Task WriteAsync(T[] value) {
|
public async Task WriteAsync(T[] value) {
|
||||||
|
|
||||||
var reg = (IArrayRegister<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
await reg.WriteAsync(value);
|
reg.isAnonymous = true;
|
||||||
|
var tReg = (IArrayRegister<T>)reg;
|
||||||
|
await tReg.WriteAsync(value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T[]> ReadAsync() {
|
public async Task<T[]> ReadAsync() {
|
||||||
|
|
||||||
var reg = (IArrayRegister<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
return await reg.ReadAsync();
|
reg.isAnonymous = true;
|
||||||
|
var tReg = (IArrayRegister<T>)reg;
|
||||||
|
return await tReg.ReadAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,15 +99,17 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
public async Task WriteAsync(T[,] value) {
|
public async Task WriteAsync(T[,] value) {
|
||||||
|
|
||||||
var reg = (IArrayRegister2D<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
await reg.WriteAsync(value);
|
reg.isAnonymous = true;
|
||||||
|
await ((IArrayRegister2D<T>)reg).WriteAsync(value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T[,]> ReadAsync() {
|
public async Task<T[,]> ReadAsync() {
|
||||||
|
|
||||||
var reg = (IArrayRegister2D<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
return await reg.ReadAsync();
|
reg.isAnonymous = true;
|
||||||
|
return await ((IArrayRegister2D<T>)reg).ReadAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,15 +121,17 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
public async Task WriteAsync(T[,,] value) {
|
public async Task WriteAsync(T[,,] value) {
|
||||||
|
|
||||||
var reg = (IArrayRegister3D<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
await reg.WriteAsync(value);
|
reg.isAnonymous = true;
|
||||||
|
await ((IArrayRegister3D<T>)reg).WriteAsync(value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T[,,]> ReadAsync() {
|
public async Task<T[,,]> ReadAsync() {
|
||||||
|
|
||||||
var reg = (IArrayRegister3D<T>)builder.Assemble(this);
|
var reg = builder.Assemble(this);
|
||||||
return await reg.ReadAsync();
|
reg.isAnonymous = true;
|
||||||
|
return await ((IArrayRegister3D<T>)reg).ReadAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace MewtocolNet.SetupClasses {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets wether or not the interface should always retrieve metadata on connection start
|
/// Sets wether or not the interface should always retrieve metadata on connection start
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AlwaysGetMetadata { get; set; } = true;
|
public bool AlwaysGetMetadata { get; set; } = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user