This commit is contained in:
parallelbgls@outlook.com
2016-08-23 15:20:33 +08:00
2 changed files with 97 additions and 30 deletions

View File

@@ -5,6 +5,21 @@ using System.Threading.Tasks;
namespace Modbus.Net namespace Modbus.Net
{ {
/// <summary>
/// 获取设备值的方式
/// </summary>
public enum MachineGetDataType
{
/// <summary>
/// 地址
/// </summary>
Address,
/// <summary>
/// 通讯标识
/// </summary>
CommunicationTag
}
/// <summary> /// <summary>
/// 向设备设置值的方式 /// 向设备设置值的方式
/// </summary> /// </summary>
@@ -28,7 +43,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 设备的Id /// 设备的Id
/// </summary> /// </summary>
public int Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 设备所在工程的名称 /// 设备所在工程的名称
@@ -113,16 +128,18 @@ namespace Modbus.Net
/// 读取数据 /// 读取数据
/// </summary> /// </summary>
/// <returns>从设备读取的数据</returns> /// <returns>从设备读取的数据</returns>
public Dictionary<string, ReturnUnit> GetDatas() public Dictionary<string, ReturnUnit> GetDatas(MachineGetDataType getDataType)
{ {
return AsyncHelper.RunSync(GetDatasAsync); return AsyncHelper.RunSync(()=>GetDatasAsync(getDataType));
} }
/// <summary> /// <summary>
/// 读取数据 /// 读取数据
/// </summary> /// </summary>
/// <returns>从设备读取的数据</returns> /// <returns>从设备读取的数据</returns>
public async Task<Dictionary<string,ReturnUnit>> GetDatasAsync() public async Task<Dictionary<string,ReturnUnit>> GetDatasAsync(MachineGetDataType getDataType)
{ {
try try
{ {
@@ -146,14 +163,26 @@ namespace Modbus.Net
Math.Ceiling(communicateAddress.GetCount* Math.Ceiling(communicateAddress.GetCount*
BigEndianValueHelper.Instance.ByteLength[ BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName])); communicateAddress.DataType.FullName]));
var datas = datasReturn.ReturnValue;
//如果没有数据,终止 byte[] datas;
if (datas == null || datas.Length == 0 || datas.Length !=
(int) //如果设备本身能获取到数据但是没有数据
Math.Ceiling(communicateAddress.GetCount * if (datasReturn == null)
BigEndianValueHelper.Instance.ByteLength[ {
communicateAddress.DataType.FullName])) return null; datas = null;
}
else
{
datas = datasReturn.ReturnValue;
//如果没有数据,终止
if (datas == null || datas.Length == 0 || datas.Length !=
(int)
Math.Ceiling(communicateAddress.GetCount *
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName])) return null;
}
int pos = 0; int pos = 0;
//解码数据 //解码数据
while (pos < communicateAddress.GetCount) while (pos < communicateAddress.GetCount)
@@ -164,17 +193,52 @@ namespace Modbus.Net
p => p.Area == communicateAddress.Area && p.Address == pos + communicateAddress.Address); p => p.Area == communicateAddress.Area && p.Address == pos + communicateAddress.Address);
if (address != null) if (address != null)
{ {
//将获取的数据和对应的通讯标识对应 string key;
ans.Add(address.CommunicationTag, switch (getDataType)
new ReturnUnit {
case MachineGetDataType.CommunicationTag:
{
key = address.CommunicationTag;
break;
}
case MachineGetDataType.Address:
{
key = AddressFormater.FormatAddress(address.Area, address.Address);
break;
}
default:
{
key = address.CommunicationTag;
break;
}
}
if (datas == null)
{
ans.Add(key, new ReturnUnit
{ {
PlcValue = PlcValue = null,
Double.Parse(
datasReturn.IsLittleEndian ? ValueHelper.Instance.GetValue(datas, ref pos, address.DataType)
.ToString() : BigEndianValueHelper.Instance.GetValue(datas, ref pos, address.DataType)
.ToString()) *address.Zoom,
UnitExtend = address.UnitExtend UnitExtend = address.UnitExtend
}); });
pos += (int)ValueHelper.Instance.ByteLength[address.DataType.ToString()];
}
else
{
//将获取的数据和对应的通讯标识对应
ans.Add(key,
new ReturnUnit
{
PlcValue =
Double.Parse(
datasReturn.IsLittleEndian
? ValueHelper.Instance.GetValue(datas, ref pos, address.DataType)
.ToString()
: BigEndianValueHelper.Instance.GetValue(datas, ref pos,
address.DataType)
.ToString())*address.Zoom,
UnitExtend = address.UnitExtend
});
}
} }
else else
{ {
@@ -361,8 +425,8 @@ namespace Modbus.Net
public static Dictionary<string, double> MapGetValuesToSetValues(Dictionary<string, ReturnUnit> getValues) public static Dictionary<string, double> MapGetValuesToSetValues(Dictionary<string, ReturnUnit> getValues)
{ {
if (getValues == null) return null; if (getValues == null) return null;
return (from getValue in getValues return (from getValue in getValues where getValue.Value.PlcValue != null
select new KeyValuePair<string, double>(getValue.Key, getValue.Value.PlcValue)).ToDictionary(p=>p.Key,p=>p.Value); select new KeyValuePair<string, double>(getValue.Key, getValue.Value.PlcValue.Value)).ToDictionary(p=>p.Key,p=>p.Value);
} }
} }
@@ -418,7 +482,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 返回的数据 /// 返回的数据
/// </summary> /// </summary>
public double PlcValue { get; set; } public double? PlcValue { get; set; }
/// <summary> /// <summary>
/// 数据的扩展 /// 数据的扩展
/// </summary> /// </summary>
@@ -430,7 +494,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 数据单元Id /// 数据单元Id
/// </summary> /// </summary>
public int Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 数据所属的区域 /// 数据所属的区域
/// </summary> /// </summary>
@@ -494,7 +558,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// Id /// Id
/// </summary> /// </summary>
int Id { get; set; } string Id { get; set; }
/// <summary> /// <summary>
/// 工程名 /// 工程名
/// </summary> /// </summary>

View File

@@ -9,7 +9,7 @@ namespace Modbus.Net
{ {
public class TaskReturnDef public class TaskReturnDef
{ {
public int MachineId { get; set; } public string MachineId { get; set; }
public Dictionary<string, ReturnUnit> ReturnValues { get; set; } public Dictionary<string, ReturnUnit> ReturnValues { get; set; }
} }
@@ -279,6 +279,8 @@ namespace Modbus.Net
} }
} }
public MachineGetDataType GetDataType { get; set; }
/*public int MaxRunningTasks /*public int MaxRunningTasks
{ {
get { return _scheduler.MaximumConcurrencyLevel; } get { return _scheduler.MaximumConcurrencyLevel; }
@@ -295,13 +297,14 @@ namespace Modbus.Net
/// <param name="maxRunningTask">同时可以运行的任务数</param> /// <param name="maxRunningTask">同时可以运行的任务数</param>
/// <param name="getCycle">读取数据的时间间隔(秒)</param> /// <param name="getCycle">读取数据的时间间隔(秒)</param>
/// <param name="keepConnect">读取数据后是否保持连接</param> /// <param name="keepConnect">读取数据后是否保持连接</param>
public TaskManager(/*int maxRunningTask,*/ int getCycle, bool keepConnect) public TaskManager(/*int maxRunningTask,*/ int getCycle, bool keepConnect, MachineGetDataType getDataType = MachineGetDataType.CommunicationTag)
{ {
//_scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask); //_scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask);
_machines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer()); _machines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer());
_unlinkedMachines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer()); _unlinkedMachines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer());
_getCycle = getCycle; _getCycle = getCycle;
KeepConnect = keepConnect; KeepConnect = keepConnect;
GetDataType = getDataType;
} }
/// <summary> /// <summary>
@@ -352,7 +355,7 @@ namespace Modbus.Net
/// 根据设备的id移除设备 /// 根据设备的id移除设备
/// </summary> /// </summary>
/// <param name="id">设备的id</param> /// <param name="id">设备的id</param>
public void RemoveMachineWithId(int id) public void RemoveMachineWithId(string id)
{ {
lock (_machines) lock (_machines)
{ {
@@ -368,7 +371,7 @@ namespace Modbus.Net
/// 将设备指定为未连接 /// 将设备指定为未连接
/// </summary> /// </summary>
/// <param name="id">设备的id</param> /// <param name="id">设备的id</param>
public void MoveMachineToUnlinked(int id) public void MoveMachineToUnlinked(string id)
{ {
IEnumerable<BaseMachine> machines; IEnumerable<BaseMachine> machines;
lock(_machines) lock(_machines)
@@ -390,7 +393,7 @@ namespace Modbus.Net
/// 将设备指定为已连接 /// 将设备指定为已连接
/// </summary> /// </summary>
/// <param name="id">设备的id</param> /// <param name="id">设备的id</param>
public void MoveMachineToLinked(int id) public void MoveMachineToLinked(string id)
{ {
IEnumerable<BaseMachine> machines; IEnumerable<BaseMachine> machines;
lock (_unlinkedMachines) lock (_unlinkedMachines)
@@ -556,7 +559,7 @@ namespace Modbus.Net
//超时后取消任务 //超时后取消任务
cts.CancelAfter(TimeSpan.FromSeconds(_getCycle)); cts.CancelAfter(TimeSpan.FromSeconds(_getCycle));
//读取数据 //读取数据
var ans = await machine.GetDatasAsync().WithCancellation(cts.Token); var ans = await machine.GetDatasAsync(GetDataType).WithCancellation(cts.Token);
if (!machine.IsConnected) if (!machine.IsConnected)
{ {
MoveMachineToUnlinked(machine.Id); MoveMachineToUnlinked(machine.Id);