mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 03:01:24 +00:00
Changed boolean register usage and attributes
This commit is contained in:
@@ -7,7 +7,7 @@ namespace Examples {
|
||||
public class TestRegisters : RegisterCollectionBase {
|
||||
|
||||
//corresponds to a R100 boolean register in the PLC
|
||||
[Register(1000, RegisterType.R)]
|
||||
[Register(IOType.R, 1000)]
|
||||
public bool TestBool1 { get; private set; }
|
||||
|
||||
private int testDuplicate;
|
||||
@@ -19,7 +19,7 @@ namespace Examples {
|
||||
}
|
||||
|
||||
//corresponds to a XD input of the PLC
|
||||
[Register(RegisterType.X, SpecialAddress.D)]
|
||||
[Register(IOType.X, (byte)0xD)]
|
||||
public bool TestBoolInputXD { get; private set; }
|
||||
|
||||
//corresponds to a DT1101 - DT1104 string register in the PLC with (STRING[4])
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Examples {
|
||||
|
||||
private bool startCyclePLC;
|
||||
|
||||
[Register(50, RegisterType.R)]
|
||||
[Register(IOType.R, 50)]
|
||||
public bool StartCyclePLC {
|
||||
get => startCyclePLC;
|
||||
set => AutoSetter(value, ref startCyclePLC);
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
|
||||
namespace MewtocolNet.Links {
|
||||
|
||||
internal class LinkedData {
|
||||
internal class CodeDescriptions {
|
||||
|
||||
internal static Dictionary<int, string> ErrorCodes = new Dictionary<int, string> {
|
||||
internal static Dictionary<int, string> Error = new Dictionary<int, string> {
|
||||
|
||||
{21, "NACK error"},
|
||||
{22, "WACK error"},
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -205,167 +206,6 @@ namespace MewtocolNet {
|
||||
|
||||
#region Register Adding
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a PLC memory register to the watchlist <para/>
|
||||
/// The registers can be read back by attaching <see cref="WithPoller"/>
|
||||
/// </summary>
|
||||
/// <param name="_address">The address of the register in the PLCs memory</param>
|
||||
/// <param name="_type">
|
||||
/// The memory area type
|
||||
/// <para>X = Physical input area (bool)</para>
|
||||
/// <para>Y = Physical input area (bool)</para>
|
||||
/// <para>R = Internal relay area (bool)</para>
|
||||
/// <para>DT = Internal data area (short/ushort)</para>
|
||||
/// <para>DDT = Internal relay area (int/uint)</para>
|
||||
/// </param>
|
||||
/// <param name="_name">A naming definition for QOL, doesn't effect PLC and is optional</param>
|
||||
public void AddRegister (int _address, RegisterType _type, string _name = null) {
|
||||
|
||||
IRegister toAdd = null;
|
||||
|
||||
//as number registers
|
||||
if (_type == RegisterType.DT_short) {
|
||||
toAdd = new NRegister<short>(_address, _name);
|
||||
}
|
||||
if (_type == RegisterType.DT_ushort) {
|
||||
toAdd = new NRegister<ushort>(_address, _name);
|
||||
}
|
||||
if (_type == RegisterType.DDT_int) {
|
||||
toAdd = new NRegister<int>(_address, _name);
|
||||
}
|
||||
if (_type == RegisterType.DDT_uint) {
|
||||
toAdd = new NRegister<uint>(_address, _name);
|
||||
}
|
||||
if (_type == RegisterType.DDT_float) {
|
||||
toAdd = new NRegister<float>(_address, _name);
|
||||
}
|
||||
|
||||
if(toAdd == null) {
|
||||
toAdd = new BRegister(_address, _type, _name);
|
||||
}
|
||||
|
||||
Registers.Add(toAdd);
|
||||
|
||||
}
|
||||
|
||||
internal void AddRegister (Type _colType, int _address, RegisterType _type, string _name = null) {
|
||||
|
||||
IRegister toAdd = null;
|
||||
|
||||
//as number registers
|
||||
if (_type == RegisterType.DT_short) {
|
||||
toAdd = new NRegister<short>(_address, _name).WithCollectionType(_colType);
|
||||
}
|
||||
if (_type == RegisterType.DT_ushort) {
|
||||
toAdd = new NRegister<ushort>(_address, _name).WithCollectionType(_colType);
|
||||
}
|
||||
if (_type == RegisterType.DDT_int) {
|
||||
toAdd = new NRegister<int>(_address, _name).WithCollectionType(_colType);
|
||||
}
|
||||
if (_type == RegisterType.DDT_uint) {
|
||||
toAdd = new NRegister<uint>(_address, _name).WithCollectionType(_colType);
|
||||
}
|
||||
if (_type == RegisterType.DDT_float) {
|
||||
toAdd = new NRegister<float>(_address, _name).WithCollectionType(_colType);
|
||||
}
|
||||
|
||||
if (toAdd == null) {
|
||||
toAdd = new BRegister(_address, _type, _name).WithCollectionType(_colType);
|
||||
}
|
||||
|
||||
Registers.Add(toAdd);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a PLC memory register to the watchlist <para/>
|
||||
/// The registers can be read back by attaching <see cref="WithPoller"/>
|
||||
/// </summary>
|
||||
/// <param name="_spAddress">The special address of the register in the PLCs memory</param>
|
||||
/// <param name="_type">
|
||||
/// The memory area type
|
||||
/// <para>X = Physical input area (bool)</para>
|
||||
/// <para>Y = Physical input area (bool)</para>
|
||||
/// <para>R = Internal relay area (bool)</para>
|
||||
/// <para>DT = Internal data area (short/ushort)</para>
|
||||
/// <para>DDT = Internal relay area (int/uint)</para>
|
||||
/// </param>
|
||||
/// <param name="_name">A naming definition for QOL, doesn't effect PLC and is optional</param>
|
||||
public void AddRegister (SpecialAddress _spAddress, RegisterType _type, string _name = null) {
|
||||
|
||||
//as bool registers
|
||||
Registers.Add(new BRegister(_spAddress, _type, _name));
|
||||
|
||||
}
|
||||
|
||||
internal void AddRegister (Type _colType, SpecialAddress _spAddress, RegisterType _type, string _name = null) {
|
||||
|
||||
var reg = new BRegister(_spAddress, _type, _name);
|
||||
|
||||
reg.collectionType = _colType;
|
||||
|
||||
//as bool registers
|
||||
Registers.Add(reg);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a PLC memory register to the watchlist <para/>
|
||||
/// The registers can be read back by attaching <see cref="WithPoller"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of the register translated from C# to IEC 61131-3 types
|
||||
/// <para>C# ------ IEC</para>
|
||||
/// <para>short => INT/WORD</para>
|
||||
/// <para>ushort => UINT</para>
|
||||
/// <para>int => DOUBLE</para>
|
||||
/// <para>uint => UDOUBLE</para>
|
||||
/// <para>float => REAL</para>
|
||||
/// <para>string => STRING</para>
|
||||
/// </typeparam>
|
||||
/// <param name="_name">A naming definition for QOL, doesn't effect PLC and is optional</param>
|
||||
/// <param name="_address">The address of the register in the PLCs memory</param>
|
||||
/// <param name="_length">The length of the string (Can be ignored for other types)</param>
|
||||
public void AddRegister<T>(int _address, int _length = 1, string _name = null) {
|
||||
|
||||
Type regType = typeof(T);
|
||||
|
||||
if (regType != typeof(string) && _length != 1) {
|
||||
throw new NotSupportedException($"_lenght parameter only allowed for register of type string");
|
||||
}
|
||||
|
||||
IRegister toAdd;
|
||||
|
||||
if (regType == typeof(short)) {
|
||||
toAdd = new NRegister<short>(_address, _name);
|
||||
} else if (regType == typeof(ushort)) {
|
||||
toAdd = new NRegister<ushort>(_address, _name);
|
||||
} else if (regType == typeof(int)) {
|
||||
toAdd = new NRegister<int>(_address, _name);
|
||||
} else if (regType == typeof(uint)) {
|
||||
toAdd = new NRegister<uint>(_address, _name);
|
||||
} else if (regType == typeof(float)) {
|
||||
toAdd = new NRegister<float>(_address, _name);
|
||||
} else if (regType == typeof(string)) {
|
||||
toAdd = new SRegister(_address, _length, _name);
|
||||
} else if (regType == typeof(TimeSpan)) {
|
||||
toAdd = new NRegister<TimeSpan>(_address, _name);
|
||||
} else if (regType == typeof(bool)) {
|
||||
toAdd = new BRegister(_address, RegisterType.R, _name);
|
||||
} else {
|
||||
throw new NotSupportedException($"The type {regType} is not allowed for Registers \n" +
|
||||
$"Allowed are: short, ushort, int, uint, float and string");
|
||||
}
|
||||
|
||||
|
||||
if (Registers.Any(x => x.GetRegisterPLCName() == toAdd.GetRegisterPLCName())) {
|
||||
throw new NotSupportedException($"Cannot add a register multiple times, " +
|
||||
$"make sure that all register attributes or AddRegister assignments have different adresses.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Internal register adding for auto register collection building
|
||||
internal void AddRegister<T> (Type _colType, int _address, PropertyInfo boundProp, int _length = 1, bool _isBitwise = false, Type _enumType = null) {
|
||||
|
||||
@@ -405,7 +245,7 @@ namespace MewtocolNet {
|
||||
} else if (regType == typeof(TimeSpan)) {
|
||||
reg = new NRegister<TimeSpan>(_address, propName).WithCollectionType(_colType);
|
||||
} else if (regType == typeof(bool)) {
|
||||
reg = new BRegister(_address, RegisterType.R, propName).WithCollectionType(_colType);
|
||||
reg = new BRegister(IOType.R, 0x0, _address,propName).WithCollectionType(_colType);
|
||||
}
|
||||
|
||||
if (reg == null) {
|
||||
|
||||
@@ -239,6 +239,24 @@ namespace MewtocolNet {
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the register type is non numeric
|
||||
/// </summary>
|
||||
internal static bool IsBoolean (this RegisterType type) {
|
||||
|
||||
return type == RegisterType.X || type == RegisterType.Y || type == RegisterType.R;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the register type is an physical in or output of the plc
|
||||
/// </summary>
|
||||
internal static bool IsPhysicalInOutType (this RegisterType type) {
|
||||
|
||||
return type == RegisterType.X || type == RegisterType.Y;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,8 @@ using System.Threading;
|
||||
using MewtocolNet.Queue;
|
||||
using System.Reflection;
|
||||
using System.Timers;
|
||||
using System.Data;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace MewtocolNet
|
||||
{
|
||||
@@ -437,11 +439,10 @@ namespace MewtocolNet
|
||||
if (attr is RegisterAttribute cAttribute) {
|
||||
|
||||
if (prop.PropertyType == typeof(bool) && cAttribute.AssignedBitIndex == -1) {
|
||||
if (cAttribute.SpecialAddress == SpecialAddress.None) {
|
||||
AddRegister(collection.GetType(), cAttribute.MemoryArea, cAttribute.RegisterType, _name: propName);
|
||||
} else {
|
||||
AddRegister(collection.GetType(), cAttribute.SpecialAddress, cAttribute.RegisterType, _name: propName);
|
||||
}
|
||||
|
||||
//add bool register non bit assgined
|
||||
Registers.Add(new BRegister((IOType)(int)cAttribute.RegisterType, cAttribute.SpecialAddress, cAttribute.MemoryArea, _name: propName).WithCollectionType(collection.GetType()));
|
||||
|
||||
}
|
||||
|
||||
if (prop.PropertyType == typeof(short)) {
|
||||
@@ -738,7 +739,7 @@ namespace MewtocolNet
|
||||
Match m = errorcheck.Match(response.ToString());
|
||||
if (m.Success) {
|
||||
string eCode = m.Groups[1].Value;
|
||||
string eDes = Links.LinkedData.ErrorCodes[Convert.ToInt32(eCode)];
|
||||
string eDes = Links.CodeDescriptions.Error[Convert.ToInt32(eCode)];
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"Response is: {response}");
|
||||
Logger.Log($"Error on command {_msg.Replace("\r", "")} the PLC returned error code: {eCode}, {eDes}", LogLevel.Error);
|
||||
|
||||
@@ -23,17 +23,16 @@ namespace MewtocolNet.RegisterAttributes {
|
||||
/// <summary>
|
||||
/// Defines the behavior of a register property
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class RegisterAttribute : Attribute {
|
||||
|
||||
internal int MemoryArea;
|
||||
internal int StringLength;
|
||||
internal RegisterType RegisterType;
|
||||
internal SpecialAddress SpecialAddress = SpecialAddress.None;
|
||||
internal byte SpecialAddress = 0x0;
|
||||
internal BitCount BitCount;
|
||||
internal int AssignedBitIndex = -1;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for string type or numeric registers
|
||||
/// </summary>
|
||||
@@ -49,30 +48,21 @@ namespace MewtocolNet.RegisterAttributes {
|
||||
/// <summary>
|
||||
/// Attribute for boolean registers
|
||||
/// </summary>
|
||||
/// <param name="memoryArea">The area in the plcs memory</param>
|
||||
/// <param name="type">The type of boolean register</param>
|
||||
public RegisterAttribute (int memoryArea, RegisterType type) {
|
||||
public RegisterAttribute(IOType type, byte spAdress = 0x0) {
|
||||
|
||||
if (type.ToString().StartsWith("DT"))
|
||||
throw new NotSupportedException("DT types are not supported for attribute register setups because the number type is casted automatically");
|
||||
|
||||
MemoryArea = memoryArea;
|
||||
RegisterType = type;
|
||||
SpecialAddress = SpecialAddress.None;
|
||||
MemoryArea = 0;
|
||||
RegisterType = (RegisterType)(int)type;
|
||||
SpecialAddress = spAdress;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for boolean registers
|
||||
/// </summary>
|
||||
/// <param name="spAdress">The special area in the plcs memory</param>
|
||||
/// <param name="type">The type of boolean register</param>
|
||||
public RegisterAttribute (RegisterType type, SpecialAddress spAdress) {
|
||||
public RegisterAttribute (IOType type, int memoryArea, byte spAdress = 0x0) {
|
||||
|
||||
if (type.ToString().StartsWith("DT"))
|
||||
throw new NotSupportedException("DT types are not supported for attribute register setups because the number type is casted automatically");
|
||||
|
||||
RegisterType = type;
|
||||
MemoryArea = memoryArea;
|
||||
RegisterType = (RegisterType)(int)type;
|
||||
SpecialAddress = spAdress;
|
||||
|
||||
}
|
||||
|
||||
26
MewtocolNet/Mewtocol/RegisterBuilder.cs
Normal file
26
MewtocolNet/Mewtocol/RegisterBuilder.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MewtocolNet.Mewtocol {
|
||||
|
||||
/// <summary>
|
||||
/// Contains useful tools for register creation
|
||||
/// </summary>
|
||||
public static class RegisterBuilder {
|
||||
|
||||
/// <summary>
|
||||
/// Parses a register from its PLC name
|
||||
/// </summary>
|
||||
/// <param name="name">The name, fe. DT100</param>
|
||||
/// <param name="reg">An <see cref="IRegister"/> or null if </param>
|
||||
/// <returns>True if successfully parsed</returns>
|
||||
//public static bool TryBuildFromName (string name, out IRegister reg) {
|
||||
|
||||
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,64 +7,62 @@ using System.Threading.Tasks;
|
||||
namespace MewtocolNet {
|
||||
|
||||
/// <summary>
|
||||
/// The special register type
|
||||
/// The register prefixed type
|
||||
/// </summary>
|
||||
public enum RegisterType {
|
||||
|
||||
/// <summary>
|
||||
/// Physical input as a bool (Relay)
|
||||
/// </summary>
|
||||
X,
|
||||
X = 0,
|
||||
/// <summary>
|
||||
/// Physical output as a bool (Relay)
|
||||
/// </summary>
|
||||
Y,
|
||||
Y = 1,
|
||||
/// <summary>
|
||||
/// Internal as a bool (Relay)
|
||||
/// </summary>
|
||||
R,
|
||||
R = 2,
|
||||
/// <summary>
|
||||
/// Data area as a short (Register)
|
||||
/// </summary>
|
||||
DT_short,
|
||||
DT_short = 3,
|
||||
/// <summary>
|
||||
/// Data area as an unsigned short (Register)
|
||||
/// </summary>
|
||||
DT_ushort,
|
||||
DT_ushort = 4,
|
||||
/// <summary>
|
||||
/// Double data area as an integer (Register)
|
||||
/// </summary>
|
||||
DDT_int,
|
||||
DDT_int = 5,
|
||||
/// <summary>
|
||||
/// Double data area as an unsigned integer (Register)
|
||||
/// </summary>
|
||||
DDT_uint,
|
||||
DDT_uint = 6,
|
||||
/// <summary>
|
||||
/// Double data area as an floating point number (Register)
|
||||
/// </summary>
|
||||
DDT_float,
|
||||
DDT_float = 7,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The special input / output channel address
|
||||
/// The type of an input/output register
|
||||
/// </summary>
|
||||
public enum SpecialAddress {
|
||||
|
||||
#pragma warning disable CS1591
|
||||
public enum IOType {
|
||||
|
||||
/// <summary>
|
||||
/// No defined
|
||||
/// Physical input as a bool (Relay)
|
||||
/// </summary>
|
||||
None,
|
||||
A = -10,
|
||||
B = -11,
|
||||
C = -12,
|
||||
D = -13,
|
||||
E = -14,
|
||||
F = -15,
|
||||
|
||||
#pragma warning restore
|
||||
X = 0,
|
||||
/// <summary>
|
||||
/// Physical output as a bool (Relay)
|
||||
/// </summary>
|
||||
Y = 1,
|
||||
/// <summary>
|
||||
/// Internal relay
|
||||
/// </summary>
|
||||
R = 2,
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using MewtocolNet;
|
||||
|
||||
@@ -22,8 +23,6 @@ namespace MewtocolNet.Registers {
|
||||
|
||||
internal RegisterType RegType { get; private set; }
|
||||
|
||||
internal SpecialAddress SpecialAddress { get; private set; }
|
||||
|
||||
internal Type collectionType;
|
||||
|
||||
/// <summary>
|
||||
@@ -44,50 +43,46 @@ namespace MewtocolNet.Registers {
|
||||
/// </summary>
|
||||
public string Name => name;
|
||||
|
||||
internal int memoryAdress;
|
||||
internal int memoryAddress;
|
||||
/// <summary>
|
||||
/// The registers memory adress if not a special register
|
||||
/// </summary>
|
||||
public int MemoryAddress => memoryAdress;
|
||||
public int MemoryAddress => memoryAddress;
|
||||
|
||||
internal byte specialAddress;
|
||||
/// <summary>
|
||||
/// The registers memory adress if not a special register
|
||||
/// </summary>
|
||||
public byte SpecialAddress => specialAddress;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a register containing a number
|
||||
/// Creates a new boolean register
|
||||
/// </summary>
|
||||
/// <param name="_address">Memory start adress max 99999</param>
|
||||
/// <param name="_type">Type of boolean register</param>
|
||||
/// <param name="_name">Name of the register</param>
|
||||
public BRegister (int _address, RegisterType _type = RegisterType.R, string _name = null) {
|
||||
/// <param name="_io">The io type prefix</param>
|
||||
/// <param name="_spAddress">The special address</param>
|
||||
/// <param name="_areaAdress">The area special address</param>
|
||||
/// <param name="_name">The custom name</param>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public BRegister (IOType _io, byte _spAddress = 0x0, int _areaAdress = 0, string _name = null) {
|
||||
|
||||
if (_address > 99999) throw new NotSupportedException("Memory addresses cant be greater than 99999");
|
||||
if (_areaAdress < 0)
|
||||
throw new NotSupportedException("The area address cant be negative");
|
||||
|
||||
if (_type != RegisterType.X && _type != RegisterType.Y && _type != RegisterType.R)
|
||||
throw new NotSupportedException("The register type cant be numeric, use X, Y or R");
|
||||
if(_io == IOType.R && _areaAdress >= 512)
|
||||
throw new NotSupportedException("R area addresses cant be greater than 511");
|
||||
|
||||
memoryAdress = _address;
|
||||
if ((_io == IOType.X || _io == IOType.Y) && _areaAdress >= 110)
|
||||
throw new NotSupportedException("XY area addresses cant be greater than 110");
|
||||
|
||||
if (_spAddress > 0xF)
|
||||
throw new NotSupportedException("Special address cant be greater 15 or 0xF");
|
||||
|
||||
memoryAddress = (int)_areaAdress;
|
||||
specialAddress = _spAddress;
|
||||
name = _name;
|
||||
|
||||
RegType = _type;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a register containing a number
|
||||
/// </summary>
|
||||
/// <param name="_address">Memory start adress max 99999</param>
|
||||
/// <param name="_type">Type of boolean register</param>
|
||||
/// <param name="_name">Name of the register</param>
|
||||
public BRegister (SpecialAddress _address, RegisterType _type = RegisterType.R, string _name = null) {
|
||||
|
||||
if (_address == SpecialAddress.None)
|
||||
throw new NotSupportedException("Special address cant be none");
|
||||
|
||||
if (_type != RegisterType.X && _type != RegisterType.Y && _type != RegisterType.R)
|
||||
throw new NotSupportedException("The register type cant be numeric, use X, Y or R");
|
||||
|
||||
SpecialAddress = _address;
|
||||
name = _name;
|
||||
|
||||
RegType = _type;
|
||||
RegType = (RegisterType)(int)_io;
|
||||
|
||||
}
|
||||
|
||||
@@ -105,11 +100,12 @@ namespace MewtocolNet.Registers {
|
||||
|
||||
//build area code from register type
|
||||
StringBuilder asciistring = new StringBuilder(RegType.ToString());
|
||||
if(SpecialAddress == SpecialAddress.None) {
|
||||
asciistring.Append(MemoryAddress.ToString().PadLeft(4, '0'));
|
||||
} else {
|
||||
asciistring.Append(SpecialAddress.ToString().PadLeft(4, '0'));
|
||||
}
|
||||
|
||||
string memPadded = MemoryAddress.ToString().PadLeft(4, '0');
|
||||
string sp = SpecialAddress.ToString("X1");
|
||||
|
||||
asciistring.Append(memPadded);
|
||||
asciistring.Append(sp);
|
||||
|
||||
return asciistring.ToString();
|
||||
|
||||
@@ -125,9 +121,6 @@ namespace MewtocolNet.Registers {
|
||||
|
||||
public string GetStartingMemoryArea() {
|
||||
|
||||
if (SpecialAddress != SpecialAddress.None)
|
||||
return SpecialAddress.ToString();
|
||||
|
||||
return MemoryAddress.ToString();
|
||||
|
||||
}
|
||||
@@ -148,8 +141,18 @@ namespace MewtocolNet.Registers {
|
||||
|
||||
public string GetRegisterPLCName() {
|
||||
|
||||
if (SpecialAddress != SpecialAddress.None) {
|
||||
return $"{GetRegisterString()}{SpecialAddress}";
|
||||
var spAdressEnd = SpecialAddress.ToString("X1");
|
||||
|
||||
if (MemoryAddress == 0) {
|
||||
|
||||
return $"{GetRegisterString()}{spAdressEnd}";
|
||||
|
||||
}
|
||||
|
||||
if(MemoryAddress > 0 && SpecialAddress != 0) {
|
||||
|
||||
return $"{GetRegisterString()}{MemoryAddress}{spAdressEnd}";
|
||||
|
||||
}
|
||||
|
||||
return $"{GetRegisterString()}{MemoryAddress}";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageId>Mewtocol.NET</PackageId>
|
||||
<Version>0.7.0</Version>
|
||||
<Version>0.7.1</Version>
|
||||
<Authors>Felix Weiss</Authors>
|
||||
<Company>Womed</Company>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
|
||||
@@ -21,11 +21,12 @@ namespace MewtocolTests {
|
||||
public class TestRegisterCollection : RegisterCollectionBase {
|
||||
|
||||
//corresponds to a R100 boolean register in the PLC
|
||||
[Register(1000, RegisterType.R)]
|
||||
//can also be written as R1000 because the last one is a special address
|
||||
[Register(IOType.R, 100, spAdress: 0)]
|
||||
public bool TestBool1 { get; private set; }
|
||||
|
||||
//corresponds to a XD input of the PLC
|
||||
[Register(RegisterType.X, SpecialAddress.D)]
|
||||
[Register(IOType.X, (byte)0xD)]
|
||||
public bool TestBoolInputXD { get; private set; }
|
||||
|
||||
//corresponds to a DT1101 - DT1104 string register in the PLC with (STRING[4])
|
||||
@@ -117,7 +118,7 @@ namespace MewtocolTests {
|
||||
var register = interf.GetRegister(nameof(TestRegisterCollection.TestBool1));
|
||||
|
||||
//test generic properties
|
||||
TestBasicGeneration(register, nameof(TestRegisterCollection.TestBool1), false, 1000, "R1000");
|
||||
TestBasicGeneration(register, nameof(TestRegisterCollection.TestBool1), false, 100, "R100");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace MewtocolTests {
|
||||
|
||||
};
|
||||
|
||||
Assert.Equal(expectedData, LinkedData.ErrorCodes);
|
||||
Assert.Equal(expectedData, CodeDescriptions.Error);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace MewtocolTests {
|
||||
new NRegister<TimeSpan>(50, _name : null),
|
||||
};
|
||||
|
||||
List<string> expcectedIdents = new List<string> {
|
||||
List<string> expectedIdents = new List<string> {
|
||||
"D0005000050", //single word register
|
||||
"D0005000050", //single word register
|
||||
"D0005000051", //double word register
|
||||
@@ -39,7 +39,7 @@ namespace MewtocolTests {
|
||||
for (int i = 0; i < registers.Count; i++) {
|
||||
|
||||
IRegister? reg = registers[i];
|
||||
string expect = expcectedIdents[i];
|
||||
string expect = expectedIdents[i];
|
||||
|
||||
Assert.Equal(expect, reg.BuildMewtocolQuery());
|
||||
|
||||
@@ -58,25 +58,38 @@ namespace MewtocolTests {
|
||||
new NRegister<uint>(80, _name : null),
|
||||
new NRegister<float>(90, _name : null),
|
||||
new NRegister<TimeSpan>(100, _name : null),
|
||||
|
||||
//boolean
|
||||
new BRegister(100),
|
||||
new BRegister(5, RegisterType.X),
|
||||
new BRegister(SpecialAddress.A, RegisterType.X),
|
||||
new BRegister(IOType.R, 0, 100),
|
||||
new BRegister(IOType.X, 5),
|
||||
new BRegister(IOType.X, 0xA),
|
||||
new BRegister(IOType.X, 0xF, 109),
|
||||
new BRegister(IOType.Y, 0xC, 75),
|
||||
|
||||
//string
|
||||
new SRegister(999, 5),
|
||||
};
|
||||
|
||||
List<string> expcectedIdents = new List<string> {
|
||||
|
||||
//numeric ones
|
||||
"DT50",
|
||||
"DT60",
|
||||
"DDT70",
|
||||
"DDT80",
|
||||
"DDT90",
|
||||
"DDT100",
|
||||
|
||||
//boolean
|
||||
"R100",
|
||||
"X5",
|
||||
"XA",
|
||||
"X109F",
|
||||
"Y75C",
|
||||
|
||||
//string
|
||||
"DT999"
|
||||
|
||||
};
|
||||
|
||||
//test mewtocol idents
|
||||
@@ -104,7 +117,7 @@ namespace MewtocolTests {
|
||||
|
||||
var ex1 = Assert.Throws<NotSupportedException>(() => {
|
||||
|
||||
new BRegister(100000);
|
||||
new BRegister(IOType.R, _areaAdress: 512);
|
||||
|
||||
});
|
||||
|
||||
@@ -112,12 +125,20 @@ namespace MewtocolTests {
|
||||
|
||||
var ex2 = Assert.Throws<NotSupportedException>(() => {
|
||||
|
||||
new SRegister(100000, 5);
|
||||
new BRegister(IOType.X, _areaAdress: 110);
|
||||
|
||||
});
|
||||
|
||||
output.WriteLine(ex2.Message.ToString());
|
||||
|
||||
var ex3 = Assert.Throws<NotSupportedException>(() => {
|
||||
|
||||
new SRegister(100000, 5);
|
||||
|
||||
});
|
||||
|
||||
output.WriteLine(ex3.Message.ToString());
|
||||
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Non allowed (Wrong data type)")]
|
||||
@@ -133,32 +154,6 @@ namespace MewtocolTests {
|
||||
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Non allowed (Wrong bool type address)")]
|
||||
public void WrongDataTypeRegisterBool1 () {
|
||||
|
||||
var ex = Assert.Throws<NotSupportedException>(() => {
|
||||
|
||||
new BRegister(100, RegisterType.DDT_int);
|
||||
|
||||
});
|
||||
|
||||
output.WriteLine(ex.Message.ToString());
|
||||
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Non allowed (Wrong bool special address)")]
|
||||
public void WrongDataTypeRegisterBool2 () {
|
||||
|
||||
var ex = Assert.Throws<NotSupportedException>(() => {
|
||||
|
||||
new BRegister(SpecialAddress.None, RegisterType.X);
|
||||
|
||||
});
|
||||
|
||||
output.WriteLine(ex.Message.ToString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
84
MewtocolTests/TestRegisterParsing.cs
Normal file
84
MewtocolTests/TestRegisterParsing.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using MewtocolNet;
|
||||
using MewtocolNet.Mewtocol;
|
||||
using MewtocolNet.Registers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace MewtocolTests;
|
||||
|
||||
public class TestRegisterParsing {
|
||||
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public TestRegisterParsing (ITestOutputHelper output) {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Parsing as BRegister (Phyiscal Outputs)")]
|
||||
public void TestParsingBRegisterY () {
|
||||
|
||||
var tests = new Dictionary<string, IRegister>() {
|
||||
|
||||
{"Y0", new BRegister(IOType.Y)},
|
||||
{"Y1", new BRegister(IOType.Y, 0x1)},
|
||||
{"Y2", new BRegister(IOType.Y, 0x2)},
|
||||
{"Y3", new BRegister(IOType.Y, 0x3)},
|
||||
{"Y4", new BRegister(IOType.Y, 0x4)},
|
||||
{"Y5", new BRegister(IOType.Y, 0x5)},
|
||||
{"Y6", new BRegister(IOType.Y, 0x6)},
|
||||
{"Y7", new BRegister(IOType.Y, 0x7)},
|
||||
{"Y8", new BRegister(IOType.Y, 0x8)},
|
||||
{"Y9", new BRegister(IOType.Y, 0x9)},
|
||||
|
||||
{"YA", new BRegister(IOType.Y, 0xA)},
|
||||
{"YB", new BRegister(IOType.Y, 0xB)},
|
||||
{"YC", new BRegister(IOType.Y, 0xC)},
|
||||
{"YD", new BRegister(IOType.Y, 0xD)},
|
||||
{"YE", new BRegister(IOType.Y, 0xE)},
|
||||
{"YF", new BRegister(IOType.Y, 0xF)},
|
||||
|
||||
{"Y1A", new BRegister(IOType.Y, 0xA, 1)},
|
||||
{"Y10B", new BRegister(IOType.Y, 0xB, 10)},
|
||||
{"Y109C", new BRegister(IOType.Y, 0xC, 109)},
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Parsing as BRegister (Phyiscal Inputs)")]
|
||||
public void TestParsingBRegisterX () {
|
||||
|
||||
var tests = new Dictionary<string, IRegister>() {
|
||||
|
||||
{"X0", new BRegister(IOType.X)},
|
||||
{"X1", new BRegister(IOType.X, 0x1)},
|
||||
{"X2", new BRegister(IOType.X, 0x2)},
|
||||
{"X3", new BRegister(IOType.X, 0x3)},
|
||||
{"X4", new BRegister(IOType.X, 0x4)},
|
||||
{"X5", new BRegister(IOType.X, 0x5)},
|
||||
{"X6", new BRegister(IOType.X, 0x6)},
|
||||
{"X7", new BRegister(IOType.X, 0x7)},
|
||||
{"X8", new BRegister(IOType.X, 0x8)},
|
||||
{"X9", new BRegister(IOType.X, 0x9)},
|
||||
|
||||
{"XA", new BRegister(IOType.X, 0xA)},
|
||||
{"XB", new BRegister(IOType.X, 0xB)},
|
||||
{"XC", new BRegister(IOType.X, 0xC)},
|
||||
{"XD", new BRegister(IOType.X, 0xD)},
|
||||
{"XE", new BRegister(IOType.X, 0xE)},
|
||||
{"XF", new BRegister(IOType.X, 0xF)},
|
||||
|
||||
{"X1A", new BRegister(IOType.X, 0xA, 1)},
|
||||
{"X10B", new BRegister(IOType.X, 0xB, 10)},
|
||||
{"X109C", new BRegister(IOType.X, 0xC, 109)},
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user