diff --git a/Modbus.Net/ModBus.Net/AddressFormater.cs b/Modbus.Net/ModBus.Net/AddressFormater.cs new file mode 100644 index 0000000..8ca6c1c --- /dev/null +++ b/Modbus.Net/ModBus.Net/AddressFormater.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModBus.Net +{ + public abstract class AddressFormater + { + public abstract string FormatAddress(string area, int address); + } + + public class AddressFormaterSimense : AddressFormater + { + public override string FormatAddress(string area, int address) + { + if (area.ToUpper() == "DB") + { + return area.ToUpper() + "." + "DB" + address; + } + else + { + return area.ToUpper() + address; + } + } + } + + public class AddressFormaterBase : AddressFormater + { + public override string FormatAddress(string area, int address) + { + return area + "." + address; + } + } + + public class AddressFormaterNA200H : AddressFormater + { + public override string FormatAddress(string area, int address) + { + return area + address; + } + } +} diff --git a/Modbus.Net/ModBus.Net/BaseMachine.cs b/Modbus.Net/ModBus.Net/BaseMachine.cs index d124ed1..5c6f7e5 100644 --- a/Modbus.Net/ModBus.Net/BaseMachine.cs +++ b/Modbus.Net/ModBus.Net/BaseMachine.cs @@ -8,47 +8,129 @@ using System.Threading.Tasks; namespace ModBus.Net { - public abstract class BaseMachine + public abstract class BaseMachine : IMachineProperty { - public IEnumerable GetAddresses { get; set; } + public string ProjectName { get; set; } + + public string MachineName { get; set; } + + public string ConnectionToken { get { return BaseUtility.ConnectionToken; } } + + protected AddressFormater AddressFormater { get; set; } + + protected AddressCombiner AddressCombiner { get; set; } + + protected IEnumerable CommunicateAddresses + { + get { return AddressCombiner.Combine(GetAddresses); } + } + + public IEnumerable GetAddresses { get; set; } public bool KeepConnect { get; set; } - public BaseUtility BaseUtility { get; protected set; } + protected BaseUtility BaseUtility { get; set; } - protected BaseMachine(IEnumerable getAddresses) : this(getAddresses, false) + protected BaseMachine(IEnumerable getAddresses) + : this(getAddresses, false) { } - protected BaseMachine(IEnumerable getAddresses, bool keepConnect) + protected BaseMachine(IEnumerable getAddresses, bool keepConnect) { GetAddresses = getAddresses; KeepConnect = keepConnect; } - public IEnumerable> GetDatas() + public Dictionary GetDatas() { - List ans = new List(); + Dictionary ans = new Dictionary(); if (!BaseUtility.IsConnected) { BaseUtility.Connect(); } - foreach (var getAddress in GetAddresses) + foreach (var communicateAddress in CommunicateAddresses) { - ans.Add(BaseUtility.GetDatas(2, 0, getAddress.StartAddress, new KeyValuePair(getAddress.DataType, getAddress.GetCount))); + var datas = BaseUtility.GetDatas(2, 0, AddressFormater.FormatAddress(communicateAddress.Area,communicateAddress.Address), communicateAddress.GetCount); + int pos = 0; + while (pos < communicateAddress.GetCount) + { + var address = + GetAddresses.SingleOrDefault( + p => p.Area == communicateAddress.Area && p.Address == pos + communicateAddress.Address); + if (address != null) + { + ans.Add(address.CommunicationTag, (String.Format("{0:#0.000}", Double.Parse(ValueHelper.Instance.GetValue(datas, ref pos, address.DataType).ToString()) * address.Zoom))); + } + else + { + pos++; + } + } } if (!KeepConnect) { - BaseUtility.DisConnect(); + BaseUtility.Disconnect(); } return ans; } + + public bool Connect() + { + return BaseUtility.Connect(); + } + + public bool Disconnect() + { + return BaseUtility.Disconnect(); + } } public struct CommunicationUnit { - public string StartAddress { get; set; } + public string Area { get; set; } + public int Address { get; set; } public int GetCount { get; set; } public Type DataType { get; set; } } + + public class AddressUnit + { + public int Id { get; set; } + /// + /// 数据所属的区域,Modbus指通讯码,PROFINET指数据块 + /// + public string Area { get; set; } + public int Address { get; set; } + public Type DataType { get; set; } + /// + /// 放缩比例 + /// + public double Zoom { get; set; } + /// + /// 通讯标识名称 + /// + public string CommunicationTag { get; set; } + public string Name { get; set; } + } + + public struct AddressUnitEqualityComparer : IEqualityComparer + { + public bool Equals(AddressUnit x, AddressUnit y) + { + return x.Area.ToUpper() == y.Area.ToUpper() && x.Address == y.Address; + } + + public int GetHashCode(AddressUnit obj) + { + return obj.GetHashCode(); + } + } + + public interface IMachineProperty + { + string ProjectName { get; set; } + string MachineName { get; set; } + string ConnectionToken { get; } + } } diff --git a/Modbus.Net/ModBus.Net/BaseUtility.cs b/Modbus.Net/ModBus.Net/BaseUtility.cs index 297c368..8c24bde 100644 --- a/Modbus.Net/ModBus.Net/BaseUtility.cs +++ b/Modbus.Net/ModBus.Net/BaseUtility.cs @@ -109,7 +109,7 @@ namespace ModBus.Net return Wrapper.Connect(); } - public bool DisConnect() + public bool Disconnect() { return Wrapper.Disconnect(); } diff --git a/Modbus.Net/ModBus.Net/ModBus.Net.csproj b/Modbus.Net/ModBus.Net/ModBus.Net.csproj index c878027..7ac7073 100644 --- a/Modbus.Net/ModBus.Net/ModBus.Net.csproj +++ b/Modbus.Net/ModBus.Net/ModBus.Net.csproj @@ -47,6 +47,8 @@ + + diff --git a/Modbus.Net/ModBus.Net/TaskManager.cs b/Modbus.Net/ModBus.Net/TaskManager.cs index da33e15..47d4637 100644 --- a/Modbus.Net/ModBus.Net/TaskManager.cs +++ b/Modbus.Net/ModBus.Net/TaskManager.cs @@ -170,7 +170,7 @@ namespace ModBus.Net { public bool Equals(BaseMachine x, BaseMachine y) { - return x.BaseUtility.ConnectionToken == y.BaseUtility.ConnectionToken; + return x.ConnectionToken == y.ConnectionToken; } public int GetHashCode(BaseMachine obj) @@ -182,20 +182,31 @@ namespace ModBus.Net public class TaskManager { private HashSet _machines; - private TaskFactory>> _tasks; + private TaskFactory> _tasks; private TaskScheduler _scheduler; private CancellationTokenSource _cts; private Timer _timer; private bool _keepConnect; - public bool KeepConnect { get { return _keepConnect; } set { TaskStop(); _keepConnect = value; - foreach (var machine in _machines) - { - machine.KeepConnect = _keepConnect; - } - } } - public delegate void ReturnValuesDelegate(KeyValuePair>> returnValue); + public bool KeepConnect + { + get { return _keepConnect; } + set + { + TaskStop(); + _keepConnect = value; + lock (_machines) + { + foreach (var machine in _machines) + { + machine.KeepConnect = _keepConnect; + } + } + } + } + + public delegate void ReturnValuesDelegate(KeyValuePair> returnValue); public event ReturnValuesDelegate ReturnValues; @@ -226,9 +237,10 @@ namespace ModBus.Net else { _timer = new Timer(_getCycle*1000); - _timer.Elapsed += MaintainTasks; + _timer.Elapsed += MaintainTasks; } _timer.Start(); + MaintainTasks(null,null); } } } @@ -253,15 +265,21 @@ namespace ModBus.Net public void AddMachine(BaseMachine machine) { - _machines.Add(machine); machine.KeepConnect = KeepConnect; + lock (_machines) + { + _machines.Add(machine); + } } private void MaintainTasks(object sender, System.Timers.ElapsedEventArgs e) { - foreach (var machine in _machines) + lock (_machines) { - RunTask(machine); + foreach (var machine in _machines) + { + RunTask(machine); + } } } @@ -269,7 +287,7 @@ namespace ModBus.Net { TaskStop(); _cts = new CancellationTokenSource(); - _tasks = new TaskFactory>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler); + _tasks = new TaskFactory>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler); GetCycle = TimeRestore.Restore; } @@ -282,9 +300,12 @@ namespace ModBus.Net } if (_machines != null) { - foreach (var machine in _machines) + lock (_machines) { - machine.BaseUtility.DisConnect(); + foreach (var machine in _machines) + { + machine.Disconnect(); + } } } } @@ -297,7 +318,7 @@ namespace ModBus.Net var ans = _tasks.StartNew(machine.GetDatas).Result; if (ReturnValues != null) { - ReturnValues(new KeyValuePair>>(machine.BaseUtility.ConnectionToken, ans)); + ReturnValues(new KeyValuePair>(machine.ConnectionToken, ans)); } } catch (Exception e) @@ -305,7 +326,7 @@ namespace ModBus.Net if (ReturnValues != null) { - ReturnValues(new KeyValuePair>>(machine.BaseUtility.ConnectionToken, null)); + ReturnValues(new KeyValuePair>(machine.ConnectionToken, null)); } } } diff --git a/Modbus.Net/ModBus.Net/ValueHelper.cs b/Modbus.Net/ModBus.Net/ValueHelper.cs index 8fdf975..7277f48 100644 --- a/Modbus.Net/ModBus.Net/ValueHelper.cs +++ b/Modbus.Net/ModBus.Net/ValueHelper.cs @@ -155,6 +155,69 @@ namespace ModBus.Net return BitConverter.GetBytes(value); } + /// + /// 将byte数组中相应的位置转换为对应类型的数字 + /// + /// + /// + /// + /// + public virtual object GetValue(byte[] data, ref int pos, Type t) + { + switch (t.FullName) + { + case "System.Int16": + { + short value = Instance.GetShort(data, ref pos); + return value; + } + case "System.Int32": + { + int value = Instance.GetInt(data, ref pos); + return value; + } + case "System.Int64": + { + long value = Instance.GetLong(data, ref pos); + return value; + } + case "System.UInt16": + { + ushort value = Instance.GetUShort(data, ref pos); + return value; + } + case "System.UInt32": + { + uint value = Instance.GetUInt(data, ref pos); + return value; + } + case "System.UInt64": + { + ulong value = Instance.GetULong(data, ref pos); + return value; + } + case "System.Single": + { + float value = Instance.GetFloat(data, ref pos); + return value; + } + case "System.Double": + { + double value = Instance.GetDouble(data, ref pos); + return value; + } + case "System.Byte": + { + byte value = Instance.GetByte(data, ref pos); + return value; + } + default: + { + throw new NotImplementedException("没有实现除整数以外的其它转换方式"); + } + } + } + /// /// 将byte数组中相应的位置转换为byte数字 ///