diff --git a/Examples/ExampleScenarios.cs b/Examples/ExampleScenarios.cs
index bd2244a..df60f16 100644
--- a/Examples/ExampleScenarios.cs
+++ b/Examples/ExampleScenarios.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using System.Collections;
using MewtocolNet.RegisterBuilding;
using System.Collections.Generic;
+using MewtocolNet.Registers;
namespace Examples;
@@ -46,7 +47,7 @@ public class ExampleScenarios {
while (interf.IsConnected) {
//flip the bool register each tick and wait for it to be registered
- await interf.SetRegisterAsync(nameof(registers.TestBool1), !registers.TestBool1);
+ //await interf.SetRegisterAsync(nameof(registers.TestBool1), !registers.TestBool1);
Console.Title = $"Polling Paused: {interf.PollingPaused}, " +
$"Poller active: {interf.PollerActive}, " +
@@ -167,7 +168,7 @@ public class ExampleScenarios {
await interf.ConnectAsync();
//use the async method to make sure the cycling is stopped
- await interf.SetRegisterAsync(nameof(registers.StartCyclePLC), false);
+ //await interf.SetRegisterAsync(nameof(registers.StartCyclePLC), false);
await Task.Delay(5000);
@@ -182,4 +183,49 @@ public class ExampleScenarios {
}
+ [Scenario("Read register test")]
+ public async Task RunReadTest () {
+
+ Console.WriteLine("Starting auto enums and bitwise");
+
+ //setting up a new PLC interface and register collection
+ MewtocolInterface interf = new MewtocolInterface("192.168.115.210").WithPoller();
+
+ //auto add all built registers to the interface
+ var builder = RegBuilder.ForInterface(interf);
+ var r0reg = builder.FromPlcRegName("R0").Build();
+ builder.FromPlcRegName("R1").Build();
+ builder.FromPlcRegName("R1F").Build();
+ builder.FromPlcRegName("R101A").Build();
+
+ var shortReg = builder.FromPlcRegName("DT35").AsPlcType(PlcVarType.INT).Build();
+ builder.FromPlcRegName("DDT36").AsPlcType(PlcVarType.DINT).Build();
+
+ //builder.FromPlcRegName("DDT38").AsPlcType(PlcVarType.TIME).Build();
+ //builder.FromPlcRegName("DT40").AsPlcType(PlcVarType.STRING).Build();
+
+ //connect
+ await interf.ConnectAsync();
+
+ //var res = await interf.SendCommandAsync("%01#RCSR000F");
+
+ while(true) {
+
+ await interf.SetRegisterAsync(r0reg, !(bool)r0reg.Value);
+ await interf.SetRegisterAsync(shortReg, (short)new Random().Next(0, 100));
+
+ foreach (var reg in interf.Registers) {
+
+ Console.WriteLine($"Register {reg.GetRegisterPLCName()} val: {reg.Value}");
+
+ }
+
+ Console.WriteLine();
+
+ await Task.Delay(1000);
+
+ }
+
+ }
+
}
diff --git a/Examples/Program.cs b/Examples/Program.cs
index a868993..57c913f 100644
--- a/Examples/Program.cs
+++ b/Examples/Program.cs
@@ -14,9 +14,6 @@ class Program {
static void Main(string[] args) {
- RegBuilder.FromPlcRegName("DT303").AsPlcType(PlcVarType.INT).Build();
- var res = RegBuilder.FromPlcRegName("DT100").AsPlcType(PlcVarType.INT).Build();
-
AppDomain.CurrentDomain.UnhandledException += (s,e) => {
Console.WriteLine(e.ExceptionObject.ToString());
};
diff --git a/Examples/TestRegisters.cs b/Examples/TestRegisters.cs
index afe76f7..4b13ca1 100644
--- a/Examples/TestRegisters.cs
+++ b/Examples/TestRegisters.cs
@@ -47,10 +47,10 @@ namespace Examples {
public BitArray TestBitRegister { get; private set; }
//corresponds to a DT1204 as a 16bit word/int takes the bit at index 9 and writes it back as a boolean
- [Register(1204, 9, BitCount.B16)]
+ [Register(1204, BitCount.B16, 9)]
public bool BitValue { get; private set; }
- [Register(1204, 5, BitCount.B16)]
+ [Register(1204, BitCount.B16, 5)]
public bool FillTest { get; private set; }
//corresponds to a DT7012 - DT7013 as a 32bit time value that gets parsed as a timespan (TIME)
diff --git a/Examples/TestRegistersEnumBitwise.cs b/Examples/TestRegistersEnumBitwise.cs
index ea4954c..72f5ede 100644
--- a/Examples/TestRegistersEnumBitwise.cs
+++ b/Examples/TestRegistersEnumBitwise.cs
@@ -53,52 +53,52 @@ namespace Examples {
//you can also extract single bits from DT503
- [Register(503, 0, BitCount.B16)]
+ [Register(503, BitCount.B16, 0)]
public bool BitValue0 { get; private set; }
- [Register(503, 1, BitCount.B16)]
+ [Register(503, BitCount.B16, 1)]
public bool BitValue1 { get; private set; }
- [Register(503, 2, BitCount.B16)]
+ [Register(503, BitCount.B16, 2)]
public bool BitValue2 { get; private set; }
- [Register(503, 3, BitCount.B16)]
+ [Register(503, BitCount.B16, 3)]
public bool BitValue3 { get; private set; }
- [Register(503, 4, BitCount.B16)]
+ [Register(503, BitCount.B16, 4)]
public bool BitValue4 { get; private set; }
- [Register(503, 5, BitCount.B16)]
+ [Register(503, BitCount.B16, 5)]
public bool BitValue5 { get; private set; }
- [Register(503, 6, BitCount.B16)]
+ [Register(503, BitCount.B16, 6)]
public bool BitValue6 { get; private set; }
- [Register(503, 7, BitCount.B16)]
+ [Register(503, BitCount.B16, 7)]
public bool BitValue7 { get; private set; }
- [Register(503, 8, BitCount.B16)]
+ [Register(503, BitCount.B16, 8)]
public bool BitValue8 { get; private set; }
- [Register(503, 9, BitCount.B16)]
+ [Register(503, BitCount.B16, 9)]
public bool BitValue9 { get; private set; }
- [Register(503, 10, BitCount.B16)]
+ [Register(503, BitCount.B16, 10)]
public bool BitValue10 { get; private set; }
- [Register(503, 11, BitCount.B16)]
+ [Register(503, BitCount.B16, 11)]
public bool BitValue11 { get; private set; }
- [Register(503, 12, BitCount.B16)]
+ [Register(503, BitCount.B16, 12)]
public bool BitValue12 { get; private set; }
- [Register(503, 13, BitCount.B16)]
+ [Register(503, BitCount.B16, 13)]
public bool BitValue13 { get; private set; }
- [Register(503, 14, BitCount.B16)]
+ [Register(503, BitCount.B16, 14)]
public bool BitValue14 { get; private set; }
- [Register(503, 15, BitCount.B16)]
+ [Register(503, BitCount.B16, 15)]
public bool BitValue15 { get; private set; }
}
diff --git a/MewtocolNet/DynamicInterface.cs b/MewtocolNet/DynamicInterface.cs
index f13ceff..1bd86c6 100644
--- a/MewtocolNet/DynamicInterface.cs
+++ b/MewtocolNet/DynamicInterface.cs
@@ -1,12 +1,16 @@
-using MewtocolNet.Logging;
+using MewtocolNet.Exceptions;
+using MewtocolNet.Logging;
+using MewtocolNet.RegisterAttributes;
using MewtocolNet.Registers;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
-namespace MewtocolNet {
+namespace MewtocolNet
+{
///
/// The PLC com interface class
@@ -118,61 +122,21 @@ namespace MewtocolNet {
var reg = Registers[iteration];
- if (reg is NRegister shortReg) {
- var lastVal = shortReg.Value;
- var readout = (await ReadNumRegister(shortReg)).Register.Value;
+ if(reg.IsAllowedRegisterGenericType()) {
+
+ var lastVal = reg.Value;
+
+ var rwReg = (IRegisterInternal)reg;
+
+ var readout = await rwReg.ReadAsync(this);
+
if (lastVal != readout) {
- InvokeRegisterChanged(shortReg);
- }
- }
- if (reg is NRegister ushortReg) {
- var lastVal = ushortReg.Value;
- var readout = (await ReadNumRegister(ushortReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(ushortReg);
- }
- }
- if (reg is NRegister intReg) {
- var lastVal = intReg.Value;
- var readout = (await ReadNumRegister(intReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(intReg);
- }
- }
- if (reg is NRegister uintReg) {
- var lastVal = uintReg.Value;
- var readout = (await ReadNumRegister(uintReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(uintReg);
- }
- }
- if (reg is NRegister floatReg) {
- var lastVal = floatReg.Value;
- var readout = (await ReadNumRegister(floatReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(floatReg);
- }
- }
- if (reg is NRegister tsReg) {
- var lastVal = tsReg.Value;
- var readout = (await ReadNumRegister(tsReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(tsReg);
- }
- }
- if (reg is BRegister boolReg) {
- var lastVal = boolReg.Value;
- var readout = (await ReadBoolRegister(boolReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(boolReg);
- }
- }
- if (reg is SRegister stringReg) {
- var lastVal = stringReg.Value;
- var readout = (await ReadStringRegister(stringReg)).Register.Value;
- if (lastVal != readout) {
- InvokeRegisterChanged(stringReg);
+
+ rwReg.SetValueFromPLC(readout);
+ InvokeRegisterChanged(reg);
+
}
+
}
iteration++;
@@ -194,67 +158,218 @@ namespace MewtocolNet {
internal void PropertyRegisterWasSet(string propName, object value) {
- SetRegister(propName, value);
+ _ = SetRegisterAsync(GetRegister(propName), value);
}
#endregion
+ #region Register Colleciton adding
+
+ #region Register Collection
+
+ ///
+ /// Attaches a register collection object to
+ /// the interface that can be updated automatically.
+ ///
+ /// Just create a class inheriting from
+ /// and assert some propertys with the custom .
+ ///
+ /// A collection inherting the class
+ public MewtocolInterface WithRegisterCollection(RegisterCollectionBase collection) {
+
+ collection.PLCInterface = this;
+
+ var props = collection.GetType().GetProperties();
+
+ foreach (var prop in props) {
+
+ var attributes = prop.GetCustomAttributes(true);
+
+ string propName = prop.Name;
+ foreach (var attr in attributes) {
+
+ if (attr is RegisterAttribute cAttribute && prop.PropertyType.IsAllowedPlcCastingType()) {
+
+ var dotnetType = prop.PropertyType;
+
+ AddRegister(new RegisterBuildInfo {
+ memoryAddress = cAttribute.MemoryArea,
+ specialAddress = cAttribute.SpecialAddress,
+ memorySizeBytes = cAttribute.ByteLength,
+ registerType = cAttribute.RegisterType,
+ dotnetCastType = dotnetType,
+ collectionType = collection.GetType(),
+ name = prop.Name,
+ });
+
+ }
+
+ }
+
+ }
+
+ RegisterChanged += (reg) => {
+
+ //register is used bitwise
+ if (reg.IsUsedBitwise()) {
+
+ for (int i = 0; i < props.Length; i++) {
+
+ var prop = props[i];
+ var bitWiseFound = prop.GetCustomAttributes(true)
+ .FirstOrDefault(y => y.GetType() == typeof(RegisterAttribute) && ((RegisterAttribute)y).MemoryArea == reg.MemoryAddress);
+
+ if (bitWiseFound != null) {
+
+ var casted = (RegisterAttribute)bitWiseFound;
+ var bitIndex = casted.AssignedBitIndex;
+
+ BitArray bitAr = null;
+
+ if (reg is NumberRegister reg16) {
+ var bytes = BitConverter.GetBytes((short)reg16.Value);
+ bitAr = new BitArray(bytes);
+ } else if (reg is NumberRegister reg32) {
+ var bytes = BitConverter.GetBytes((int)reg32.Value);
+ bitAr = new BitArray(bytes);
+ }
+
+ if (bitAr != null && bitIndex < bitAr.Length && bitIndex >= 0) {
+
+ //set the specific bit index if needed
+ prop.SetValue(collection, bitAr[bitIndex]);
+ collection.TriggerPropertyChanged(prop.Name);
+
+ } else if (bitAr != null) {
+
+ //set the specific bit array if needed
+ prop.SetValue(collection, bitAr);
+ collection.TriggerPropertyChanged(prop.Name);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ //updating normal properties
+ var foundToUpdate = props.FirstOrDefault(x => x.Name == reg.Name);
+
+ if (foundToUpdate != null) {
+
+ var foundAttributes = foundToUpdate.GetCustomAttributes(true);
+ var foundAttr = foundAttributes.FirstOrDefault(x => x.GetType() == typeof(RegisterAttribute));
+
+ if (foundAttr == null)
+ return;
+
+ var registerAttr = (RegisterAttribute)foundAttr;
+
+ //check if bit parse mode
+ if (registerAttr.AssignedBitIndex == -1) {
+
+ HashSet NumericTypes = new HashSet {
+ typeof(bool),
+ typeof(short),
+ typeof(ushort),
+ typeof(int),
+ typeof(uint),
+ typeof(float),
+ typeof(TimeSpan),
+ typeof(string)
+ };
+
+ var regValue = ((IRegister)reg).Value;
+
+ if (NumericTypes.Any(x => foundToUpdate.PropertyType == x)) {
+ foundToUpdate.SetValue(collection, regValue);
+ }
+
+ if (foundToUpdate.PropertyType.IsEnum) {
+ foundToUpdate.SetValue(collection, regValue);
+ }
+
+ }
+
+ collection.TriggerPropertyChanged(foundToUpdate.Name);
+
+ }
+
+ };
+
+ if (collection != null)
+ collection.OnInterfaceLinked(this);
+
+ Connected += (i) => {
+ if (collection != null)
+ collection.OnInterfaceLinkedAndOnline(this);
+ };
+
+ return this;
+
+ }
+
+ #endregion
+
+ #endregion
+
#region Register Adding
- //Internal register adding for auto register collection building
- internal void AddRegister(Type _colType, int _address, PropertyInfo boundProp, int _length = 1, bool _isBitwise = false, Type _enumType = null) {
+ internal void AddRegister (RegisterBuildInfo buildInfo) {
- Type regType = typeof(T);
+ var builtRegister = buildInfo.Build();
- if (regType != typeof(string) && _length != 1) {
- throw new NotSupportedException($"_lenght parameter only allowed for register of type string");
- }
+ //is bitwise and the register list already contains that area register
+ if(builtRegister.IsUsedBitwise() && CheckDuplicateRegister(builtRegister, out var existing)) {
- if (Registers.Any(x => x.MemoryAddress == _address) && _isBitwise) {
return;
+
}
- IRegister reg = null;
+ if (CheckDuplicateRegister(builtRegister))
+ throw MewtocolException.DupeRegister(builtRegister);
- string propName = boundProp.Name;
+ if(CheckDuplicateNameRegister(builtRegister))
+ throw MewtocolException.DupeNameRegister(builtRegister);
- //rename the property name to prevent duplicate names in case of a bitwise prop
- if (_isBitwise && regType == typeof(short))
- propName = $"Auto_Bitwise_DT{_address}";
+ Registers.Add(builtRegister);
- if (_isBitwise && regType == typeof(int))
- propName = $"Auto_Bitwise_DDT{_address}";
+ }
- if (regType == typeof(short)) {
- reg = new NRegister(_address, propName, _isBitwise, _enumType).WithCollectionType(_colType);
- } else if (regType == typeof(ushort)) {
- reg = new NRegister(_address, propName).WithCollectionType(_colType);
- } else if (regType == typeof(int)) {
- reg = new NRegister(_address, propName, _isBitwise, _enumType).WithCollectionType(_colType);
- } else if (regType == typeof(uint)) {
- reg = new NRegister(_address, propName).WithCollectionType(_colType);
- } else if (regType == typeof(float)) {
- reg = new NRegister(_address, propName).WithCollectionType(_colType);
- } else if (regType == typeof(string)) {
- reg = new SRegister(_address, _length, propName).WithCollectionType(_colType);
- } else if (regType == typeof(TimeSpan)) {
- reg = new NRegister(_address, propName).WithCollectionType(_colType);
- } else if (regType == typeof(bool)) {
- reg = new BRegister(IOType.R, 0x0, _address, propName).WithCollectionType(_colType);
- }
+ public void AddRegister(IRegister register) {
- if (reg == null) {
- throw new NotSupportedException($"The type {regType} is not allowed for Registers \n" +
- $"Allowed are: short, ushort, int, uint, float and string");
- }
+ if (CheckDuplicateRegister(register))
+ throw MewtocolException.DupeRegister(register);
- if (Registers.Any(x => x.GetRegisterPLCName() == reg.GetRegisterPLCName()) && !_isBitwise) {
- throw new NotSupportedException($"Cannot add a register multiple times, " +
- $"make sure that all register attributes or AddRegister assignments have different adresses.");
- }
+ if (CheckDuplicateNameRegister(register))
+ throw MewtocolException.DupeNameRegister(register);
- Registers.Add(reg);
+ Registers.Add(register);
+
+ }
+
+ private bool CheckDuplicateRegister (IRegister instance, out IRegister foundDupe) {
+
+ foundDupe = Registers.FirstOrDefault(x => x.CompareIsDuplicate(instance));
+
+ return Registers.Contains(instance) || foundDupe != null;
+
+ }
+
+ private bool CheckDuplicateRegister(IRegister instance) {
+
+ var foundDupe = Registers.FirstOrDefault(x => x.CompareIsDuplicate(instance));
+
+ return Registers.Contains(instance) || foundDupe != null;
+
+ }
+
+ private bool CheckDuplicateNameRegister(IRegister instance) {
+
+ return Registers.Any(x => x.CompareIsNameDuplicate(instance));
}
diff --git a/MewtocolNet/Exceptions/MewtocolException.cs b/MewtocolNet/Exceptions/MewtocolException.cs
new file mode 100644
index 0000000..0601df4
--- /dev/null
+++ b/MewtocolNet/Exceptions/MewtocolException.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MewtocolNet.Exceptions {
+
+ [Serializable]
+ public class MewtocolException : Exception {
+
+ public MewtocolException() { }
+
+ public MewtocolException(string message) : base(message) { }
+
+ public MewtocolException(string message, Exception inner) : base(message, inner) { }
+
+ protected MewtocolException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
+
+ public static MewtocolException DupeRegister (IRegister register) {
+
+ return new MewtocolException($"The mewtocol interface already contains this register: {register.GetRegisterPLCName()}");
+
+ }
+
+ public static MewtocolException DupeNameRegister (IRegister register) {
+
+ return new MewtocolException($"The mewtocol interface registers already contains a register with the name: {register.Name}");
+
+ }
+
+ }
+
+}
diff --git a/MewtocolNet/IRegister.cs b/MewtocolNet/IRegister.cs
index f68d60d..c442584 100644
--- a/MewtocolNet/IRegister.cs
+++ b/MewtocolNet/IRegister.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
namespace MewtocolNet {
diff --git a/MewtocolNet/IRegisterInternal.cs b/MewtocolNet/IRegisterInternal.cs
new file mode 100644
index 0000000..9b9c5a4
--- /dev/null
+++ b/MewtocolNet/IRegisterInternal.cs
@@ -0,0 +1,18 @@
+using MewtocolNet.Registers;
+using System;
+using System.Threading.Tasks;
+
+namespace MewtocolNet {
+ internal interface IRegisterInternal {
+
+ void WithCollectionType(Type colType);
+
+ void SetValueFromPLC(object value);
+
+ Task
/// The area in the plcs memory
- /// The max string length in the plc
- public RegisterAttribute(int memoryArea, int stringLength = 1) {
+ public RegisterAttribute(int memoryArea) {
MemoryArea = memoryArea;
- StringLength = stringLength;
+
+ }
+
+ public RegisterAttribute(int memoryArea, int byteLength) {
+
+ MemoryArea = memoryArea;
+ ByteLength = byteLength;
+
+ }
+
+ public RegisterAttribute(int memoryArea, BitCount bitCount) {
+
+ MemoryArea = memoryArea;
+ BitCount = bitCount;
+ AssignedBitIndex = 0;
+
+ RegisterType = BitCount == BitCount.B16 ? MewtocolNet.RegisterType.DT : MewtocolNet.RegisterType.DDT;
+
+ }
+
+ public RegisterAttribute(int memoryArea, BitCount bitCount, int bitIndex) {
+
+ MemoryArea = memoryArea;
+ BitCount = bitCount;
+ AssignedBitIndex = bitIndex;
+
+ RegisterType = BitCount == BitCount.B16 ? MewtocolNet.RegisterType.DT : MewtocolNet.RegisterType.DDT;
}
@@ -49,42 +76,6 @@ namespace MewtocolNet.RegisterAttributes {
}
- ///
- /// Attribute to read numeric registers as bitwise
- ///
- /// The area in the plcs memory
- /// The number of bits to parse
- public RegisterAttribute(int memoryArea, BitCount bitcount) {
-
- MemoryArea = memoryArea;
- StringLength = 0;
- BitCount = bitcount;
-
- }
-
- ///
- /// Attribute to read numeric registers as bitwise
- ///
- /// The area in the plcs memory
- /// The number of bits to parse
- /// The index of the bit that gets linked to the bool
- public RegisterAttribute(int memoryArea, uint assignBit, BitCount bitcount) {
-
- if (assignBit > 15 && bitcount == BitCount.B16) {
- throw new NotSupportedException("The assignBit parameter cannot be greater than 15 in a 16 bit var");
- }
-
- if (assignBit > 31 && bitcount == BitCount.B32) {
- throw new NotSupportedException("The assignBit parameter cannot be greater than 31 in a 32 bit var");
- }
-
- MemoryArea = memoryArea;
- StringLength = 0;
- BitCount = bitcount;
- AssignedBitIndex = (int)assignBit;
-
- }
-
}
}
diff --git a/MewtocolNet/RegisterBuildInfo.cs b/MewtocolNet/RegisterBuildInfo.cs
new file mode 100644
index 0000000..c53074a
--- /dev/null
+++ b/MewtocolNet/RegisterBuildInfo.cs
@@ -0,0 +1,118 @@
+using MewtocolNet.Registers;
+using System;
+using System.Collections;
+using System.Reflection;
+
+namespace MewtocolNet
+{
+
+ internal struct RegisterBuildInfo {
+
+ internal string name;
+ internal int memoryAddress;
+ internal int memorySizeBytes;
+ internal byte? specialAddress;
+
+ internal RegisterType? registerType;
+ internal Type dotnetCastType;
+ internal Type collectionType;
+
+ internal IRegister Build () {
+
+ RegisterType regType = registerType ?? dotnetCastType.ToRegisterTypeDefault();
+
+ PlcVarType plcType = dotnetCastType.ToPlcVarType();
+ Type registerClassType = plcType.GetDefaultPlcVarType();
+
+ if (regType.IsNumericDTDDT() && (dotnetCastType == typeof(bool) || dotnetCastType == typeof(BitArray))) {
+
+ //-------------------------------------------
+ //as numeric register with boolean bit target
+
+ var type = typeof(NumberRegister);
+
+ var areaAddr = memoryAddress;
+
+ //create a new bregister instance
+ var flags = BindingFlags.Public | BindingFlags.Instance;
+
+ //int _adress, string _name = null, bool isBitwise = false, Type _enumType = null
+ var parameters = new object[] { areaAddr, name, true, null };
+ var instance = (IRegister)Activator.CreateInstance(type, flags, null, parameters, null);
+
+ if (collectionType != null)
+ ((IRegisterInternal)instance).WithCollectionType(collectionType);
+
+ return instance;
+
+ } else if (regType.IsNumericDTDDT()) {
+
+ //-------------------------------------------
+ //as numeric register
+
+ var type = plcType.GetDefaultPlcVarType();
+
+ var areaAddr = memoryAddress;
+
+ //create a new bregister instance
+ var flags = BindingFlags.Public | BindingFlags.Instance;
+
+ //int _adress, string _name = null, bool isBitwise = false, Type _enumType = null
+ var parameters = new object[] { areaAddr, name, false, null };
+ var instance = (IRegister)Activator.CreateInstance(type, flags, null, parameters, null);
+
+ if(collectionType != null)
+ ((IRegisterInternal)instance).WithCollectionType(collectionType);
+
+ return instance;
+
+ }
+
+ if (regType.IsBoolean()) {
+
+ //-------------------------------------------
+ //as boolean register
+
+ var io = (IOType)(int)regType;
+ var spAddr = specialAddress;
+ var areaAddr = memoryAddress;
+
+ //create a new bregister instance
+ var flags = BindingFlags.Public | BindingFlags.Instance;
+ var parameters = new object[] { io, spAddr.Value, areaAddr, name };
+ var instance = (BoolRegister)Activator.CreateInstance(typeof(BoolRegister), flags, null, parameters, null);
+
+ if (collectionType != null)
+ ((IRegisterInternal)instance).WithCollectionType(collectionType);
+
+ return instance;
+
+ }
+
+ if(regType == RegisterType.DT_RANGE) {
+
+ //-------------------------------------------
+ //as byte range register
+
+ var type = plcType.GetDefaultPlcVarType();
+
+ //create a new bregister instance
+ var flags = BindingFlags.Public | BindingFlags.Instance;
+ //int _adress, int _reservedSize, string _name = null
+ var parameters = new object[] { memoryAddress, memorySizeBytes, name };
+ var instance = (IRegister)Activator.CreateInstance(type, flags, null, parameters, null);
+
+ if (collectionType != null)
+ ((IRegisterInternal)instance).WithCollectionType(collectionType);
+
+ return instance;
+
+ }
+
+ throw new Exception("Failed to build register");
+
+ }
+
+ }
+
+}
diff --git a/MewtocolNet/RegisterBuilding/FinalizerExtensions.cs b/MewtocolNet/RegisterBuilding/FinalizerExtensions.cs
index b42a30e..a06e77b 100644
--- a/MewtocolNet/RegisterBuilding/FinalizerExtensions.cs
+++ b/MewtocolNet/RegisterBuilding/FinalizerExtensions.cs
@@ -1,8 +1,10 @@
using MewtocolNet.Registers;
using System;
+using System.Linq;
using System.Reflection;
-namespace MewtocolNet.RegisterBuilding {
+namespace MewtocolNet.RegisterBuilding
+{
public static class FinalizerExtensions {
@@ -29,7 +31,7 @@ namespace MewtocolNet.RegisterBuilding {
step.dotnetVarType = typeof(bool);
- } else if (isTypeNotDefined && step.RegType == RegisterType.DT_START) {
+ } else if (isTypeNotDefined && step.RegType == RegisterType.DT_RANGE) {
step.dotnetVarType = typeof(string);
@@ -37,58 +39,31 @@ namespace MewtocolNet.RegisterBuilding {
if(step.plcVarType != null) {
- step.dotnetVarType = step.plcVarType.Value.ToDotnetType();
+ step.dotnetVarType = step.plcVarType.Value.GetDefaultDotnetType();
}
- //as numeric register
- if (step.RegType.IsNumericDTDDT()) {
+ var builtReg = new RegisterBuildInfo {
- if(step.plcVarType == null && step.dotnetVarType != null) {
+ name = step.Name,
+ specialAddress = step.SpecialAddress,
+ memoryAddress = step.MemAddress,
+ registerType = step.RegType,
+ dotnetCastType = step.dotnetVarType,
- step.plcVarType = step.dotnetVarType.ToPlcVarType();
+ }.Build();
- }
+ step.AddToRegisterList(builtReg);
- var type = step.plcVarType.Value.ToRegisterType();
+ return builtReg;
- var areaAddr = step.MemAddress;
- var name = step.Name;
+ }
- //create a new bregister instance
- var flags = BindingFlags.Public | BindingFlags.Instance;
+ private static void AddToRegisterList (this RegisterBuilderStep step, IRegister instance) {
- //int _adress, string _name = null, bool isBitwise = false, Type _enumType = null
- var parameters = new object[] { areaAddr, name, false, null };
- var instance = (IRegister)Activator.CreateInstance(type, flags, null, parameters, null);
+ if (step.forInterface == null) return;
- return instance;
-
- }
-
- if (step.RegType.IsBoolean()) {
-
- var io = (IOType)(int)step.RegType;
- var spAddr = step.SpecialAddress;
- var areaAddr = step.MemAddress;
- var name = step.Name;
-
- //create a new bregister instance
- var flags = BindingFlags.Public | BindingFlags.Instance;
- var parameters = new object[] { io, spAddr.Value, areaAddr, name };
- var instance = (BRegister)Activator.CreateInstance(typeof(BRegister), flags, null, parameters, null);
-
- return instance;
-
- }
-
- if (step.dotnetVarType != null) {
-
-
-
- }
-
- throw new Exception("Failed to build register");
+ step.forInterface.AddRegister(instance);
}
diff --git a/MewtocolNet/RegisterBuilding/RegBuilder.cs b/MewtocolNet/RegisterBuilding/RegBuilder.cs
index ce91a17..4ca8416 100644
--- a/MewtocolNet/RegisterBuilding/RegBuilder.cs
+++ b/MewtocolNet/RegisterBuilding/RegBuilder.cs
@@ -9,7 +9,9 @@ namespace MewtocolNet.RegisterBuilding {
///
/// Contains useful tools for register creation
///
- public static class RegBuilder {
+ public class RegBuilder {
+
+ internal MewtocolInterface forInterface = null;
//methods to test the input string on
private static List> parseMethods = new List>() {
@@ -19,7 +21,18 @@ namespace MewtocolNet.RegisterBuilding {
};
- public static RegisterBuilderStep FromPlcRegName (string plcAddrName, string name = null) {
+ public static RegBuilder ForInterface (MewtocolInterface interf) {
+
+ var rb = new RegBuilder();
+ rb.forInterface = interf;
+ return rb;
+
+ }
+
+ public static RegBuilder Factory { get; private set; } = new RegBuilder();
+
+
+ public RegisterBuilderStep FromPlcRegName (string plcAddrName, string name = null) {
foreach (var method in parseMethods) {
@@ -30,8 +43,8 @@ namespace MewtocolNet.RegisterBuilding {
if (!string.IsNullOrEmpty(name))
res.stepData.Name = name;
- res.stepData.OriginalInput = plcAddrName;
-
+ res.stepData.OriginalInput = plcAddrName;
+ res.stepData.forInterface = forInterface;
return res.stepData;
} else if(res.state == ParseResultState.FailedHard) {
diff --git a/MewtocolNet/RegisterBuilding/RegisterBuilderStep.cs b/MewtocolNet/RegisterBuilding/RegisterBuilderStep.cs
index e1c2103..04883be 100644
--- a/MewtocolNet/RegisterBuilding/RegisterBuilderStep.cs
+++ b/MewtocolNet/RegisterBuilding/RegisterBuilderStep.cs
@@ -1,8 +1,11 @@
using System;
namespace MewtocolNet.RegisterBuilding {
+
public class RegisterBuilderStep {
+ internal MewtocolInterface forInterface;
+
internal bool wasCasted = false;
internal string OriginalInput;
@@ -15,12 +18,12 @@ namespace MewtocolNet.RegisterBuilding {
internal PlcVarType? plcVarType;
internal Type dotnetVarType;
- public RegisterBuilderStep () => throw new NotSupportedException("Cant make a new instance of RegisterBuilderStep, use the builder pattern");
-
- internal RegisterBuilderStep (RegisterType regType, int memAddr) {
-
- RegType = regType;
- MemAddress = memAddr;
+ public RegisterBuilderStep() => throw new NotSupportedException("Cant make a new instance of RegisterBuilderStep, use the builder pattern");
+
+ internal RegisterBuilderStep(RegisterType regType, int memAddr) {
+
+ RegType = regType;
+ MemAddress = memAddr;
}
@@ -28,11 +31,11 @@ namespace MewtocolNet.RegisterBuilding {
RegType = regType;
MemAddress = memAddr;
- SpecialAddress = specialAddr;
+ SpecialAddress = specialAddr;
}
- public RegisterBuilderStep AsPlcType (PlcVarType varType) {
+ public RegisterBuilderStep AsPlcType(PlcVarType varType) {
dotnetVarType = null;
plcVarType = varType;
@@ -43,9 +46,9 @@ namespace MewtocolNet.RegisterBuilding {
}
- public RegisterBuilderStep AsType () {
+ public RegisterBuilderStep AsType() {
- if(!typeof(T).IsAllowedPlcCastingType()) {
+ if (!typeof(T).IsAllowedPlcCastingType()) {
throw new NotSupportedException($"The dotnet type {typeof(T)}, is not supported for PLC type casting");
@@ -60,7 +63,7 @@ namespace MewtocolNet.RegisterBuilding {
}
- internal RegisterBuilderStep AutoType () {
+ internal RegisterBuilderStep AutoType() {
switch (RegType) {
case RegisterType.X:
@@ -74,7 +77,7 @@ namespace MewtocolNet.RegisterBuilding {
case RegisterType.DDT:
dotnetVarType = typeof(int);
break;
- case RegisterType.DT_START:
+ case RegisterType.DT_RANGE:
dotnetVarType = typeof(string);
break;
}
diff --git a/MewtocolNet/RegisterEnums.cs b/MewtocolNet/RegisterEnums.cs
index 1195f35..e23e89f 100644
--- a/MewtocolNet/RegisterEnums.cs
+++ b/MewtocolNet/RegisterEnums.cs
@@ -1,4 +1,6 @@
-namespace MewtocolNet {
+using System;
+
+namespace MewtocolNet {
///
/// The register prefixed type
@@ -26,9 +28,9 @@
///
DDT = 4,
///
- /// Start area of a byte sequence longer than 2 words
+ /// Area of a byte sequence longer than 2 words
///
- DT_START = 5,
+ DT_RANGE = 5,
}
diff --git a/MewtocolNet/Registers/BRegister.cs b/MewtocolNet/Registers/BoolRegister.cs
similarity index 81%
rename from MewtocolNet/Registers/BRegister.cs
rename to MewtocolNet/Registers/BoolRegister.cs
index 3e83adb..2ec09f4 100644
--- a/MewtocolNet/Registers/BRegister.cs
+++ b/MewtocolNet/Registers/BoolRegister.cs
@@ -1,13 +1,14 @@
using System;
using System.ComponentModel;
using System.Text;
+using System.Threading.Tasks;
namespace MewtocolNet.Registers {
///
/// Defines a register containing a boolean
///
- public class BRegister : IRegister, INotifyPropertyChanged {
+ public class BoolRegister : IRegister, IRegisterInternal, INotifyPropertyChanged {
///
/// Gets called whenever the value was changed
@@ -62,7 +63,7 @@ namespace MewtocolNet.Registers {
/// The custom name
///
///
- public BRegister(IOType _io, byte _spAddress = 0x0, int _areaAdress = 0, string _name = null) {
+ public BoolRegister(IOType _io, byte _spAddress = 0x0, int _areaAdress = 0, string _name = null) {
if (_areaAdress < 0)
throw new NotSupportedException("The area address cant be negative");
@@ -84,36 +85,33 @@ namespace MewtocolNet.Registers {
}
- internal BRegister WithCollectionType(Type colType) {
-
- collectionType = colType;
- return this;
-
- }
+ public void WithCollectionType (Type colType) => collectionType = colType;
public byte? GetSpecialAddress() => SpecialAddress;
///
- /// Builds the register area name
+ /// Builds the register area name for the mewtocol protocol
///
public string BuildMewtocolQuery() {
- //build area code from register type
- StringBuilder asciistring = new StringBuilder(RegisterType.ToString());
+ //(R|X|Y)(area add [3] + special add [1])
+ StringBuilder asciistring = new StringBuilder();
- string memPadded = MemoryAddress.ToString().PadLeft(4, '0');
+ string prefix = RegisterType.ToString();
+ string mem = MemoryAddress.ToString();
string sp = SpecialAddress.ToString("X1");
- asciistring.Append(memPadded);
+ asciistring.Append(prefix);
+ asciistring.Append(mem.PadLeft(3, '0'));
asciistring.Append(sp);
return asciistring.ToString();
}
- internal void SetValueFromPLC(bool val) {
+ public void SetValueFromPLC(object val) {
- lastValue = val;
+ lastValue = (bool)val;
TriggerChangedEvnt(this);
TriggerNotifyChange();
@@ -183,6 +181,19 @@ namespace MewtocolNet.Registers {
}
+ public async Task