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
|
||||
{
|
||||
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 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;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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; }
|
||||
/// <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();
|
||||
}
|
||||
|
||||
public bool DisConnect()
|
||||
public bool Disconnect()
|
||||
{
|
||||
return Wrapper.Disconnect();
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AddressCombiner.cs" />
|
||||
<Compile Include="AddressFormater.cs" />
|
||||
<Compile Include="AddressTranslator.cs" />
|
||||
<Compile Include="AsyncHelper.cs" />
|
||||
<Compile Include="BaseProtocal.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<BaseMachine> _machines;
|
||||
private TaskFactory<IEnumerable<IEnumerable<object>>> _tasks;
|
||||
private TaskFactory<Dictionary<string,string>> _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<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;
|
||||
|
||||
@@ -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<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;
|
||||
}
|
||||
|
||||
@@ -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<string, IEnumerable<IEnumerable<object>>>(machine.BaseUtility.ConnectionToken, ans));
|
||||
ReturnValues(new KeyValuePair<string, Dictionary<string,string>>(machine.ConnectionToken, ans));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -305,7 +326,7 @@ namespace ModBus.Net
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// 将byte数组中相应的位置转换为byte数字
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user