Added missing async write methods

- refactoring
This commit is contained in:
Felix Weiß
2022-06-20 17:09:48 +02:00
parent d0519f2409
commit ba48d97c2b
19 changed files with 314 additions and 180 deletions

View File

@@ -34,8 +34,12 @@ namespace Examples {
Task.Factory.StartNew(async () => { Task.Factory.StartNew(async () => {
await Task.Delay(2000); await Task.Delay(2000);
//inverts the boolean register //inverts the boolean register
interf.SetRegister(nameof(registers.TestBool1), !registers.TestBool1); await interf.SetRegisterAsync(nameof(registers.TestBool1), !registers.TestBool1);
Console.WriteLine("Testregister was toggled");
//adds 10 each time the plc connects to the PLCs INT regíster //adds 10 each time the plc connects to the PLCs INT regíster
interf.SetRegister(nameof(registers.TestInt16), (short)(registers.TestInt16 + 10)); interf.SetRegister(nameof(registers.TestInt16), (short)(registers.TestInt16 + 10));
//adds 1 each time the plc connects to the PLCs DINT regíster //adds 1 each time the plc connects to the PLCs DINT regíster

View File

@@ -10,7 +10,7 @@ namespace Examples {
[Register(100, RegisterType.R)] [Register(100, RegisterType.R)]
public bool TestBool1 { get; private set; } public bool TestBool1 { get; private set; }
//corresponds to a R100 boolean register in the PLC //corresponds to a XD input of the PLC
[Register(RegisterType.X, SpecialAddress.D)] [Register(RegisterType.X, SpecialAddress.D)]
public bool TestBoolInputXD { get; private set; } public bool TestBoolInputXD { get; private set; }

View File

@@ -0,0 +1,96 @@
using System;
namespace MewtocolNet.Registers {
public class CpuInfo {
/// <summary>
/// CPU type of the PLC
/// </summary>
public enum CpuType {
/// <summary>
/// FP 0 / FP 2.7K
/// </summary>
FP0_FP1_2_7K,
/// <summary>
/// FP0 / FP1, 5K / 10K
/// </summary>
FP0_FP1_5K_10K,
/// <summary>
/// FP1 M 0.9K
/// </summary>
FP1_M_0_9K,
/// <summary>
/// FP2 16k / 32k
/// </summary>
FP2_16K_32K,
/// <summary>
/// FP3 C 10K
/// </summary>
FP3_C_10K,
/// <summary>
/// FP3 C 16K
/// </summary>
FP3_C_16K,
/// <summary>
/// FP5 16K
/// </summary>
FP5_16K,
/// <summary>
/// FP 5 24K
/// </summary>
FP5_24K,
/// <summary>
/// Includes panasonic FPX, FPX-H, Sigma
/// </summary>
FP_Sigma_X_H_30K_60K_120K
}
public CpuType Cputype { get; set; }
public int ProgramCapacity { get; set; }
public string CpuVersion { get; set; }
public static CpuInfo BuildFromHexString (string _cpuType, string _cpuVersion, string _progCapacity) {
CpuInfo retInf = new CpuInfo();
switch (_cpuType) {
case "02":
retInf.Cputype = CpuType.FP5_16K;
break;
case "03":
retInf.Cputype = CpuType.FP3_C_10K;
break;
case "04":
retInf.Cputype = CpuType.FP1_M_0_9K;
break;
case "05":
retInf.Cputype = CpuType.FP0_FP1_2_7K;
break;
case "06":
retInf.Cputype = CpuType.FP0_FP1_5K_10K;
break;
case "12":
retInf.Cputype = CpuType.FP5_24K;
break;
case "13":
retInf.Cputype = CpuType.FP3_C_16K;
break;
case "20":
retInf.Cputype = CpuType.FP_Sigma_X_H_30K_60K_120K;
break;
case "50":
retInf.Cputype = CpuType.FP2_16K_32K;
break;
}
retInf.ProgramCapacity = Convert.ToInt32(_progCapacity);
retInf.CpuVersion = _cpuVersion.Insert(1, ".");
return retInf;
}
}
}

View File

@@ -5,7 +5,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MewtocolNet.Logging; using MewtocolNet.Logging;
using MewtocolNet.Responses; using MewtocolNet.Registers;
namespace MewtocolNet { namespace MewtocolNet {
@@ -296,6 +296,34 @@ namespace MewtocolNet {
#endregion #endregion
#region Register accessing
/// <summary>
/// Gets a register that was added by its name
/// </summary>
/// <returns></returns>
public Register GetRegister (string name) {
return Registers.FirstOrDefault(x => x.Value.Name == name).Value;
}
/// <summary>
/// Gets a register that was added by its name
/// </summary>
/// <typeparam name="T">The type of register</typeparam>
/// <returns>A casted register or the <code>default</code> value</returns>
public T GetRegister<T> (string name) where T : Register {
try {
var reg = Registers.FirstOrDefault(x => x.Value.Name == name);
return reg.Value as T;
} catch (InvalidCastException) {
return default(T);
}
}
#endregion
#region Register Reading #region Register Reading
/// <summary> /// <summary>

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
namespace MewtocolNet.Links { namespace MewtocolNet.Links {
public class LinkedData { internal class LinkedData {
public static Dictionary<int, string> ErrorCodes = new System.Collections.Generic.Dictionary<int, string> { internal static Dictionary<int, string> ErrorCodes = new System.Collections.Generic.Dictionary<int, string> {
{21, "NACK error"}, {21, "NACK error"},
{22, "WACK error"}, {22, "WACK error"},

View File

@@ -3,10 +3,14 @@ using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Collections.Generic; using System.Collections.Generic;
using MewtocolNet.Responses; using MewtocolNet.Registers;
using System.Collections; using System.Collections;
namespace MewtocolNet { namespace MewtocolNet {
/// <summary>
/// Contains helper methods
/// </summary>
public static class MewtocolHelpers { public static class MewtocolHelpers {
/// <summary> /// <summary>
@@ -20,7 +24,7 @@ namespace MewtocolNet {
} }
public static byte[] ToHexASCIIBytes (this string _str) { internal static byte[] ToHexASCIIBytes (this string _str) {
ASCIIEncoding ascii = new ASCIIEncoding(); ASCIIEncoding ascii = new ASCIIEncoding();
byte[] bytes = ascii.GetBytes(_str.ToUpper()); byte[] bytes = ascii.GetBytes(_str.ToUpper());
return bytes; return bytes;

View File

@@ -4,15 +4,12 @@ using System.Net.Sockets;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq; using System.Linq;
using MewtocolNet.Responses; using MewtocolNet.Registers;
using MewtocolNet.RegisterAttributes; using MewtocolNet.RegisterAttributes;
using MewtocolNet.Logging; using MewtocolNet.Logging;
using System.Collections; using System.Collections;
using System.Reflection;
using MewtocolNet.Logging;
using System.Diagnostics; using System.Diagnostics;
namespace MewtocolNet { namespace MewtocolNet {
@@ -372,6 +369,22 @@ namespace MewtocolNet {
/// <param name="value">The value to write to the register</param> /// <param name="value">The value to write to the register</param>
public void SetRegister (string registerName, object value) { public void SetRegister (string registerName, object value) {
var foundRegister = GetAllRegisters().FirstOrDefault(x => x.Name == registerName);
if (foundRegister == null) {
throw new Exception($"Register with the name {registerName} was not found");
}
_ = SetRegisterAsync(registerName, value);
}
/// <summary>
/// Sets a register in the PLCs memory asynchronously, returns the result status from the PLC
/// </summary>
/// <param name="registerName">The name the register was given to or a property name from the RegisterCollection class</param>
/// <param name="value">The value to write to the register</param>
public async Task<bool> SetRegisterAsync (string registerName, object value) {
var foundRegister = GetAllRegisters().FirstOrDefault(x => x.Name == registerName); var foundRegister = GetAllRegisters().FirstOrDefault(x => x.Name == registerName);
@@ -381,52 +394,54 @@ namespace MewtocolNet {
if (foundRegister.GetType() == typeof(BRegister)) { if (foundRegister.GetType() == typeof(BRegister)) {
_ = WriteBoolRegister((BRegister)foundRegister, (bool)value, StationNumber); return await WriteBoolRegister((BRegister)foundRegister, (bool)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(NRegister<short>)) { if (foundRegister.GetType() == typeof(NRegister<short>)) {
_ = WriteNumRegister((NRegister<short>)foundRegister, (short)value, StationNumber); return await WriteNumRegister((NRegister<short>)foundRegister, (short)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(NRegister<ushort>)) { if (foundRegister.GetType() == typeof(NRegister<ushort>)) {
_ = WriteNumRegister((NRegister<ushort>)foundRegister, (ushort)value, StationNumber); return await WriteNumRegister((NRegister<ushort>)foundRegister, (ushort)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(NRegister<int>)) { if (foundRegister.GetType() == typeof(NRegister<int>)) {
_ = WriteNumRegister((NRegister<int>)foundRegister, (int)value, StationNumber); return await WriteNumRegister((NRegister<int>)foundRegister, (int)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(NRegister<uint>)) { if (foundRegister.GetType() == typeof(NRegister<uint>)) {
_ = WriteNumRegister((NRegister<uint>)foundRegister, (uint)value, StationNumber); return await WriteNumRegister((NRegister<uint>)foundRegister, (uint)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(NRegister<float>)) { if (foundRegister.GetType() == typeof(NRegister<float>)) {
_ = WriteNumRegister((NRegister<float>)foundRegister, (float)value, StationNumber); return await WriteNumRegister((NRegister<float>)foundRegister, (float)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(NRegister<TimeSpan>)) { if (foundRegister.GetType() == typeof(NRegister<TimeSpan>)) {
_ = WriteNumRegister((NRegister<TimeSpan>)foundRegister, (TimeSpan)value, StationNumber); return await WriteNumRegister((NRegister<TimeSpan>)foundRegister, (TimeSpan)value, StationNumber);
} }
if (foundRegister.GetType() == typeof(SRegister)) { if (foundRegister.GetType() == typeof(SRegister)) {
_ = WriteStringRegister((SRegister)foundRegister, (string)value, StationNumber); return await WriteStringRegister((SRegister)foundRegister, (string)value, StationNumber);
} }
return false;
} }
#endregion #endregion

View File

@@ -5,7 +5,7 @@ using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using MewtocolNet.Responses; using MewtocolNet.Registers;
using System.Linq; using System.Linq;
using System.Globalization; using System.Globalization;

View File

@@ -0,0 +1,43 @@
namespace MewtocolNet.Registers {
/// <summary>
/// Contains generic information about the plc
/// </summary>
public class PLCInfo {
/// <summary>
/// Contains information about the PLCs cpu
/// </summary>
public CpuInfo CpuInformation {get;set;}
/// <summary>
/// Contains information about the PLCs operation modes
/// </summary>
public PLCMode OperationMode {get;set;}
/// <summary>
/// Current error code of the PLC
/// </summary>
public string ErrorCode {get;set;}
/// <summary>
/// Current station number of the PLC
/// </summary>
public int StationNumber { get;set;}
/// <summary>
/// Generates a string containing some of the most important informations
/// </summary>
/// <returns></returns>
public override string ToString () {
return $"Type: {CpuInformation.Cputype},\n" +
$"Capacity: {CpuInformation.ProgramCapacity}k\n" +
$"CPU v: {CpuInformation.CpuVersion}\n" +
$"Station Num: {StationNumber}\n" +
$"--------------------------------\n" +
$"OP Mode: {(OperationMode.RunMode ? "Run" : "Prog")}\n" +
$"Error Code: {ErrorCode}";
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
namespace MewtocolNet.Registers {
/// <summary>
/// All modes
/// </summary>
public class PLCMode {
public bool RunMode { get; set; }
public bool TestRunMode { get; set; }
public bool BreakExcecuting { get; set; }
public bool BreakValid { get; set; }
public bool OutputEnabled { get; set; }
public bool StepRunMode { get; set; }
public bool MessageExecuting { get; set; }
public bool RemoteMode { get; set; }
/// <summary>
/// Gets operation mode from 2 digit hex number
/// </summary>
internal static PLCMode BuildFromHex (string _hexString) {
string lower = Convert.ToString(Convert.ToInt32(_hexString.Substring(0, 1)), 2).PadLeft(4, '0');
string higher = Convert.ToString(Convert.ToInt32(_hexString.Substring(1, 1)), 2).PadLeft(4, '0');
string combined = lower + higher;
var retMode = new PLCMode();
for (int i = 0; i < 8; i++) {
char digit = combined[i];
bool state = false;
if (digit.ToString() == "1")
state = true;
switch (i) {
case 0:
retMode.RunMode = state;
break;
case 1:
retMode.TestRunMode = state;
break;
case 2:
retMode.BreakExcecuting = state;
break;
case 3:
retMode.BreakValid = state;
break;
case 4:
retMode.OutputEnabled = state;
break;
case 5:
retMode.StepRunMode = state;
break;
case 6:
retMode.MessageExecuting = state;
break;
case 7:
retMode.RemoteMode = state;
break;
}
}
return retMode;
}
}
}

View File

@@ -5,6 +5,10 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MewtocolNet { namespace MewtocolNet {
/// <summary>
/// The special register type
/// </summary>
public enum RegisterType { public enum RegisterType {
/// <summary> /// <summary>
@@ -42,8 +46,16 @@ namespace MewtocolNet {
} }
/// <summary>
/// The special input / output channel address
/// </summary>
public enum SpecialAddress { public enum SpecialAddress {
#pragma warning disable CS1591
/// <summary>
/// No defined
/// </summary>
None, None,
A = -10, A = -10,
B = -11, B = -11,
@@ -52,6 +64,8 @@ namespace MewtocolNet {
E = -14, E = -14,
F = -15, F = -15,
#pragma warning restore
} }
} }

View File

@@ -1,170 +1,33 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.ComponentModel; using System.ComponentModel;
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
/// <summary> /// <summary>
/// The formatted result of a ascii command /// The formatted result of a ascii command
/// </summary> /// </summary>
public struct CommandResult { public struct CommandResult {
/// <summary>
/// Success state of the message
/// </summary>
public bool Success {get;set;} public bool Success {get;set;}
/// <summary>
/// Response text of the message
/// </summary>
public string Response {get;set;} public string Response {get;set;}
/// <summary>
/// Error code of the message
/// </summary>
public string Error {get;set;} public string Error {get;set;}
/// <summary>
/// Error text of the message
/// </summary>
public string ErrorDescription {get;set;} public string ErrorDescription {get;set;}
public override string ToString() {
string errmsg = Success ? "" : ErrorDescription;
return $"Success: {Success}, Response: {Response} {errmsg}";
} }
}
/// <summary>
/// Contains generic information about the plc
/// </summary>
public class PLCInfo {
public class PLCMode {
public bool RunMode {get;set;}
public bool TestRunMode {get;set;}
public bool BreakExcecuting {get;set;}
public bool BreakValid {get;set;}
public bool OutputEnabled {get;set;}
public bool StepRunMode {get;set;}
public bool MessageExecuting {get;set;}
public bool RemoteMode {get;set;}
/// <summary>
/// Gets operation mode from 2 digit hex number
/// </summary>
public static PLCMode BuildFromHex (string _hexString) {
string lower = Convert.ToString(Convert.ToInt32(_hexString.Substring(0, 1)), 2).PadLeft(4, '0');
string higher = Convert.ToString(Convert.ToInt32(_hexString.Substring(1, 1)), 2).PadLeft(4, '0');
string combined = lower + higher;
var retMode = new PLCMode();
for (int i = 0; i < 8; i++) {
char digit = combined[i];
bool state = false;
if(digit.ToString() == "1") state = true;
switch (i) {
case 0 :
retMode.RunMode = state;
break;
case 1 :
retMode.TestRunMode = state;
break;
case 2 :
retMode.BreakExcecuting = state;
break;
case 3 :
retMode.BreakValid = state;
break;
case 4 :
retMode.OutputEnabled = state;
break;
case 5 :
retMode.StepRunMode = state;
break;
case 6 :
retMode.MessageExecuting = state;
break;
case 7 :
retMode.RemoteMode = state;
break;
}
}
return retMode;
}
}
public class CpuInfo {
public enum CpuType {
FP0_FP1_2_7K,
FP0_FP1_5K_10K,
FP1_M_0_9K,
FP2_16K_32K,
FP3_C_10K,
FP3_C_16K,
FP5_16K,
FP5_24K,
FP_Sigma_X_H_30K_60K_120K
}
public CpuType Cputype {get;set;}
public int ProgramCapacity {get;set;}
public string CpuVersion {get;set;}
public static CpuInfo BuildFromHexString (string _cpuType, string _cpuVersion, string _progCapacity) {
CpuInfo retInf = new CpuInfo();
switch (_cpuType) {
case "02":
retInf.Cputype = CpuType.FP5_16K;
break;
case "03":
retInf.Cputype = CpuType.FP3_C_10K;
break;
case "04":
retInf.Cputype = CpuType.FP1_M_0_9K;
break;
case "05":
retInf.Cputype = CpuType.FP0_FP1_2_7K;
break;
case "06":
retInf.Cputype = CpuType.FP0_FP1_5K_10K;
break;
case "12":
retInf.Cputype = CpuType.FP5_24K;
break;
case "13":
retInf.Cputype = CpuType.FP3_C_16K;
break;
case "20":
retInf.Cputype = CpuType.FP_Sigma_X_H_30K_60K_120K;
break;
case "50":
retInf.Cputype = CpuType.FP2_16K_32K;
break;
}
retInf.ProgramCapacity = Convert.ToInt32(_progCapacity);
retInf.CpuVersion = _cpuVersion.Insert(1, ".");
return retInf;
}
}
public CpuInfo CpuInformation {get;set;}
public PLCMode OperationMode {get;set;}
public string ErrorCode {get;set;}
public int StationNumber { get;set;}
public override string ToString () {
return $"Type: {CpuInformation.Cputype},\n" +
$"Capacity: {CpuInformation.ProgramCapacity}k\n" +
$"CPU v: {CpuInformation.CpuVersion}\n" +
$"Station Num: {StationNumber}\n" +
$"--------------------------------\n" +
$"OP Mode: {(OperationMode.RunMode ? "Run" : "Prog")}\n" +
$"Error Code: {ErrorCode}";
}
}
} }

View File

@@ -2,7 +2,7 @@
using System.Text; using System.Text;
using MewtocolNet; using MewtocolNet;
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
/// <summary> /// <summary>
/// Defines a register containing a boolean /// Defines a register containing a boolean

View File

@@ -1,4 +1,4 @@
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
public class BRegisterResult { public class BRegisterResult {
public CommandResult Result { get; set; } public CommandResult Result { get; set; }

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
/// <summary> /// <summary>
/// Defines a register containing a number /// Defines a register containing a number
/// </summary> /// </summary>

View File

@@ -1,4 +1,4 @@
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
/// <summary> /// <summary>
/// Result for a read/write operation /// Result for a read/write operation
/// </summary> /// </summary>

View File

@@ -6,7 +6,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
/// <summary> /// <summary>
/// A class describing a register /// A class describing a register

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Text; using System.Text;
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
/// <summary> /// <summary>
/// Defines a register containing a string /// Defines a register containing a string
/// </summary> /// </summary>

View File

@@ -1,4 +1,4 @@
namespace MewtocolNet.Responses { namespace MewtocolNet.Registers {
public class SRegisterResult { public class SRegisterResult {
public CommandResult Result { get; set; } public CommandResult Result { get; set; }
public SRegister Register { get; set; } public SRegister Register { get; set; }