2015-04-15 update 1 Update about TaskManager
This commit is contained in:
44
Modbus.Net/ModBus.Net/AddressFormater.cs
Normal file
44
Modbus.Net/ModBus.Net/AddressFormater.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,47 +8,129 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
public abstract class BaseMachine
|
public abstract class BaseMachine : IMachineProperty
|
||||||
{
|
{
|
||||||
public IEnumerable<CommunicationUnit> 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<CommunicationUnit> CommunicateAddresses
|
||||||
|
{
|
||||||
|
get { return AddressCombiner.Combine(GetAddresses); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<AddressUnit> GetAddresses { get; set; }
|
||||||
|
|
||||||
public bool KeepConnect { get; set; }
|
public bool KeepConnect { get; set; }
|
||||||
|
|
||||||
public BaseUtility BaseUtility { get; protected set; }
|
protected BaseUtility BaseUtility { get; set; }
|
||||||
|
|
||||||
protected BaseMachine(IEnumerable<CommunicationUnit> getAddresses) : this(getAddresses, false)
|
protected BaseMachine(IEnumerable<AddressUnit> getAddresses)
|
||||||
|
: this(getAddresses, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BaseMachine(IEnumerable<CommunicationUnit> getAddresses, bool keepConnect)
|
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect)
|
||||||
{
|
{
|
||||||
GetAddresses = getAddresses;
|
GetAddresses = getAddresses;
|
||||||
KeepConnect = keepConnect;
|
KeepConnect = keepConnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IEnumerable<object>> GetDatas()
|
public Dictionary<string,string> GetDatas()
|
||||||
{
|
{
|
||||||
List<object[]> ans = new List<object[]>();
|
Dictionary<string, string> ans = new Dictionary<string, string>();
|
||||||
if (!BaseUtility.IsConnected)
|
if (!BaseUtility.IsConnected)
|
||||||
{
|
{
|
||||||
BaseUtility.Connect();
|
BaseUtility.Connect();
|
||||||
}
|
}
|
||||||
foreach (var getAddress in GetAddresses)
|
foreach (var communicateAddress in CommunicateAddresses)
|
||||||
{
|
{
|
||||||
ans.Add(BaseUtility.GetDatas(2, 0, getAddress.StartAddress, new KeyValuePair<Type, int>(getAddress.DataType, getAddress.GetCount)));
|
var datas = BaseUtility.GetDatas<byte>(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)
|
if (!KeepConnect)
|
||||||
{
|
{
|
||||||
BaseUtility.DisConnect();
|
BaseUtility.Disconnect();
|
||||||
}
|
}
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Connect()
|
||||||
|
{
|
||||||
|
return BaseUtility.Connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Disconnect()
|
||||||
|
{
|
||||||
|
return BaseUtility.Disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct CommunicationUnit
|
public struct CommunicationUnit
|
||||||
{
|
{
|
||||||
public string StartAddress { get; set; }
|
public string Area { get; set; }
|
||||||
|
public int Address { get; set; }
|
||||||
public int GetCount { get; set; }
|
public int GetCount { get; set; }
|
||||||
public Type DataType { get; set; }
|
public Type DataType { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AddressUnit
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 数据所属的区域,Modbus指通讯码,PROFINET指数据块
|
||||||
|
/// </summary>
|
||||||
|
public string Area { get; set; }
|
||||||
|
public int Address { get; set; }
|
||||||
|
public Type DataType { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 放缩比例
|
||||||
|
/// </summary>
|
||||||
|
public double Zoom { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 通讯标识名称
|
||||||
|
/// </summary>
|
||||||
|
public string CommunicationTag { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AddressUnitEqualityComparer : IEqualityComparer<AddressUnit>
|
||||||
|
{
|
||||||
|
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; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ namespace ModBus.Net
|
|||||||
return Wrapper.Connect();
|
return Wrapper.Connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DisConnect()
|
public bool Disconnect()
|
||||||
{
|
{
|
||||||
return Wrapper.Disconnect();
|
return Wrapper.Disconnect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,8 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="AddressCombiner.cs" />
|
||||||
|
<Compile Include="AddressFormater.cs" />
|
||||||
<Compile Include="AddressTranslator.cs" />
|
<Compile Include="AddressTranslator.cs" />
|
||||||
<Compile Include="AsyncHelper.cs" />
|
<Compile Include="AsyncHelper.cs" />
|
||||||
<Compile Include="BaseProtocal.cs" />
|
<Compile Include="BaseProtocal.cs" />
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ namespace ModBus.Net
|
|||||||
{
|
{
|
||||||
public bool Equals(BaseMachine x, BaseMachine y)
|
public bool Equals(BaseMachine x, BaseMachine y)
|
||||||
{
|
{
|
||||||
return x.BaseUtility.ConnectionToken == y.BaseUtility.ConnectionToken;
|
return x.ConnectionToken == y.ConnectionToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetHashCode(BaseMachine obj)
|
public int GetHashCode(BaseMachine obj)
|
||||||
@@ -182,20 +182,31 @@ namespace ModBus.Net
|
|||||||
public class TaskManager
|
public class TaskManager
|
||||||
{
|
{
|
||||||
private HashSet<BaseMachine> _machines;
|
private HashSet<BaseMachine> _machines;
|
||||||
private TaskFactory<IEnumerable<IEnumerable<object>>> _tasks;
|
private TaskFactory<Dictionary<string,string>> _tasks;
|
||||||
private TaskScheduler _scheduler;
|
private TaskScheduler _scheduler;
|
||||||
private CancellationTokenSource _cts;
|
private CancellationTokenSource _cts;
|
||||||
private Timer _timer;
|
private Timer _timer;
|
||||||
|
|
||||||
private bool _keepConnect;
|
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<string, IEnumerable<IEnumerable<object>>> 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<string, Dictionary<string,string>> returnValue);
|
||||||
|
|
||||||
public event ReturnValuesDelegate ReturnValues;
|
public event ReturnValuesDelegate ReturnValues;
|
||||||
|
|
||||||
@@ -226,9 +237,10 @@ namespace ModBus.Net
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_timer = new Timer(_getCycle*1000);
|
_timer = new Timer(_getCycle*1000);
|
||||||
_timer.Elapsed += MaintainTasks;
|
_timer.Elapsed += MaintainTasks;
|
||||||
}
|
}
|
||||||
_timer.Start();
|
_timer.Start();
|
||||||
|
MaintainTasks(null,null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,15 +265,21 @@ namespace ModBus.Net
|
|||||||
|
|
||||||
public void AddMachine(BaseMachine machine)
|
public void AddMachine(BaseMachine machine)
|
||||||
{
|
{
|
||||||
_machines.Add(machine);
|
|
||||||
machine.KeepConnect = KeepConnect;
|
machine.KeepConnect = KeepConnect;
|
||||||
|
lock (_machines)
|
||||||
|
{
|
||||||
|
_machines.Add(machine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MaintainTasks(object sender, System.Timers.ElapsedEventArgs e)
|
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();
|
TaskStop();
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
_tasks = new TaskFactory<IEnumerable<IEnumerable<object>>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
|
_tasks = new TaskFactory<Dictionary<string,string>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
|
||||||
GetCycle = TimeRestore.Restore;
|
GetCycle = TimeRestore.Restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,9 +300,12 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
if (_machines != null)
|
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;
|
var ans = _tasks.StartNew(machine.GetDatas).Result;
|
||||||
if (ReturnValues != null)
|
if (ReturnValues != null)
|
||||||
{
|
{
|
||||||
ReturnValues(new KeyValuePair<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, ans));
|
ReturnValues(new KeyValuePair<string, Dictionary<string,string>>(machine.ConnectionToken, ans));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -305,7 +326,7 @@ namespace ModBus.Net
|
|||||||
|
|
||||||
if (ReturnValues != null)
|
if (ReturnValues != null)
|
||||||
{
|
{
|
||||||
ReturnValues(new KeyValuePair<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, null));
|
ReturnValues(new KeyValuePair<string, Dictionary<string,string>>(machine.ConnectionToken, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,69 @@ namespace ModBus.Net
|
|||||||
return BitConverter.GetBytes(value);
|
return BitConverter.GetBytes(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将byte数组中相应的位置转换为对应类型的数字
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <param name="t"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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("没有实现除整数以外的其它转换方式");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 将byte数组中相应的位置转换为byte数字
|
/// 将byte数组中相应的位置转换为byte数字
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user