2017-03-01 update 1 Change BaseMachine and AddressUnit Id.

This commit is contained in:
parallelbgls
2017-03-01 22:18:17 +08:00
parent 057ce04694
commit 4ff6e5fa80
10 changed files with 336 additions and 119 deletions

View File

@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Modbus.Net.Modbus</id>
<version>1.2.3</version>
<version>1.2.3.2</version>
<title>Modbus.Net.Modbus</title>
<authors>Chris L.(Luo Sheng)</authors>
<owners>Hangzhou Delian IoT Science Technology Co.,Ltd.</owners>
@@ -13,7 +13,7 @@
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal modbus Delian</tags>
<dependencies>
<dependency id="Modbus.Net" version="1.2.3" />
<dependency id="Modbus.Net" version="1.2.3.2" />
</dependencies>
</metadata>
<files>

View File

@@ -1,26 +1,50 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus设备
/// </summary>
public class ModbusMachine : BaseMachine
public class ModbusMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb)
IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
Endian endian = Endian.BigEndianLsb)
: base(getAddresses, keepConnect, slaveAddress, masterAddress)
{
BaseUtility = new ModbusUtility(connectionType, connectionString, slaveAddress, masterAddress, endian);
AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
AddressCombiner = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
}
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb)
IEnumerable<AddressUnit<TUnitKey>> getAddresses, byte slaveAddress, byte masterAddress,
Endian endian = Endian.BigEndianLsb)
: this(connectionType, connectionString, getAddresses, false, slaveAddress, masterAddress, endian)
{
}
}
/// <summary>
/// Modbus设备
/// </summary>
public class ModbusMachine : ModbusMachine<string, string>
{
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit<string>> getAddresses,
bool keepConnect, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb)
: base(connectionType, connectionString, getAddresses, keepConnect, slaveAddress, masterAddress, endian)
{
}
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit<string>> getAddresses,
byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb)
: base(connectionType, connectionString, getAddresses, slaveAddress, masterAddress, endian)
{
}
}
}

View File

@@ -13,7 +13,7 @@
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal OPC DA Delian</tags>
<dependencies>
<dependency id="Modbus.Net" version="1.2.3" />
<dependency id="Modbus.Net" version="1.2.3.2" />
<dependency id="H.Opc" version="0.7.0" />
</dependencies>
</metadata>

View File

@@ -1,23 +1,41 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace Modbus.Net.OPC
{
/// <summary>
/// OpcDa设备
/// </summary>
public class OpcDaMachine : BaseMachine
public class OpcDaMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses, bool keepConnect)
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
: base(getAddresses, keepConnect)
{
BaseUtility = new OpcDaUtility(connectionString);
AddressCombiner = new AddressCombinerSingle();
AddressCombinerSet = new AddressCombinerSingle();
AddressCombiner = new AddressCombinerSingle<TUnitKey>();
AddressCombinerSet = new AddressCombinerSingle<TUnitKey>();
}
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses)
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
: this(connectionString, getAddresses, false)
{
}
}
/// <summary>
/// OpcDa设备
/// </summary>
public class OpcDaMachine : OpcDaMachine<string, string>
{
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit<string>> getAddresses, bool keepConnect)
: base(connectionString, getAddresses, keepConnect)
{
}
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit<string>> getAddresses)
: base(connectionString, getAddresses)
{
}
}
}

View File

@@ -13,7 +13,7 @@
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal Siemens profinet Delian</tags>
<dependencies>
<dependency id="Modbus.Net" version="1.2.3" />
<dependency id="Modbus.Net" version="1.2.3.2" />
</dependencies>
</metadata>
<files>

View File

@@ -1,26 +1,46 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子设备
/// </summary>
public class SiemensMachine : BaseMachine
public class SiemensMachine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress)
IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress)
: base(getAddresses, keepConnect, slaveAddress, masterAddress)
{
BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress);
AddressFormater = new AddressFormaterSiemens();
AddressCombiner = new AddressCombinerContinus(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
AddressCombiner = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
}
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress)
IEnumerable<AddressUnit<TUnitKey>> getAddresses, byte slaveAddress, byte masterAddress)
: this(connectionType, connectionString, model, getAddresses, false, slaveAddress, masterAddress)
{
}
}
/// <summary>
/// 西门子设备
/// </summary>
public class SiemensMachine : SiemensMachine<string, string>
{
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit<string>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress)
: base(connectionType, connectionString, model, getAddresses, keepConnect, slaveAddress, masterAddress)
{
}
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit<string>> getAddresses, byte slaveAddress, byte masterAddress)
: base(connectionType, connectionString, model, getAddresses, slaveAddress, masterAddress)
{
}
}
}

View File

@@ -7,20 +7,37 @@ namespace Modbus.Net
/// <summary>
/// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯
/// </summary>
public abstract class AddressCombiner
public abstract class AddressCombiner : AddressCombiner<string>
{
}
/// <summary>
/// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯
/// </summary>
public abstract class AddressCombiner<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 组合地址
/// </summary>
/// <param name="addresses">需要进行组合的地址</param>
/// <returns>组合完成后与设备通讯的地址</returns>
public abstract IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses);
public abstract IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses);
}
/// <summary>
/// 连续的地址将组合成一组,向设备进行通讯
/// </summary>
public class AddressCombinerContinus : AddressCombiner
public class AddressCombinerContinus : AddressCombinerContinus<string>
{
public AddressCombinerContinus(AddressTranslator addressTranslator) : base(addressTranslator)
{
}
}
/// <summary>
/// 连续的地址将组合成一组,向设备进行通讯
/// </summary>
public class AddressCombinerContinus<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
{
public AddressCombinerContinus(AddressTranslator addressTranslator)
{
@@ -29,7 +46,7 @@ namespace Modbus.Net
protected AddressTranslator AddressTranslator { get; set; }
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
//按从小到大的顺序对地址进行排序
var groupedAddresses = from address in addresses
@@ -39,7 +56,7 @@ namespace Modbus.Net
group address by address.Area
into grouped
select grouped;
var ans = new List<CommunicationUnit>();
var ans = new List<CommunicationUnit<TKey>>();
foreach (var groupedAddress in groupedAddresses)
{
var area = groupedAddress.Key;
@@ -50,7 +67,7 @@ namespace Modbus.Net
//上一个地址类型
Type preType = null;
//记录一个地址组合当中的所有原始地址
var originalAddresses = new List<AddressUnit>();
var originalAddresses = new List<AddressUnit<TKey>>();
//对组合内地址从小到大进行排序
var orderedAddresses =
groupedAddress.OrderBy(
@@ -97,7 +114,7 @@ namespace Modbus.Net
AddressTranslator.GetAreaByteLength(address.Area)))
{
//上一个地址域压入返回结果,并把当前记录的结果清空。
ans.Add(new CommunicationUnit
ans.Add(new CommunicationUnit<TKey>
{
Area = area,
Address = (int) Math.Floor(initNum),
@@ -127,7 +144,7 @@ namespace Modbus.Net
preType = address.DataType;
}
//最后一个地址域压入返回结果
ans.Add(new CommunicationUnit
ans.Add(new CommunicationUnit<TKey>
{
Area = area,
Address = (int) Math.Floor(initNum),
@@ -148,21 +165,28 @@ namespace Modbus.Net
/// <summary>
/// 单个地址变为一组,每一个地址都进行一次查询
/// </summary>
public class AddressCombinerSingle : AddressCombiner
public class AddressCombinerSingle : AddressCombinerSingle<string>
{
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
}
/// <summary>
/// 单个地址变为一组,每一个地址都进行一次查询
/// </summary>
public class AddressCombinerSingle<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
{
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
return
addresses.Select(
address =>
new CommunicationUnit
new CommunicationUnit<TKey>
{
Area = address.Area,
Address = address.Address,
SubAddress = address.SubAddress,
DataType = address.DataType,
GetCount = 1,
OriginalAddresses = new List<AddressUnit> {address}
OriginalAddresses = new List<AddressUnit<TKey>> {address}
}).ToList();
}
}
@@ -170,16 +194,27 @@ namespace Modbus.Net
/// <summary>
/// 两个CommunicationUnit之间的间隔
/// </summary>
internal class CommunicationUnitGap
internal class CommunicationUnitGap<TKey> where TKey : IEquatable<TKey>
{
public CommunicationUnit EndUnit { get; set; }
public CommunicationUnit<TKey> EndUnit { get; set; }
public int GapNumber { get; set; }
}
/// <summary>
/// 可以调过多少数量的地址,把两个地址段变为一组通讯
/// </summary>
public class AddressCombinerNumericJump : AddressCombinerContinus
public class AddressCombinerNumericJump : AddressCombinerNumericJump<string>
{
public AddressCombinerNumericJump(int jumpByteCount, AddressTranslator addressTranslator)
: base(jumpByteCount, addressTranslator)
{
}
}
/// <summary>
/// 可以调过多少数量的地址,把两个地址段变为一组通讯
/// </summary>
public class AddressCombinerNumericJump<TKey> : AddressCombinerContinus<TKey> where TKey : IEquatable<TKey>
{
public AddressCombinerNumericJump(int jumpByteCount, AddressTranslator addressTranslator)
: base(addressTranslator)
@@ -189,11 +224,11 @@ namespace Modbus.Net
private int JumpNumber { get; }
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
var continusAddresses = base.Combine(addresses).ToList();
var addressesGaps = new List<CommunicationUnitGap>();
CommunicationUnit preCommunicationUnit = null;
var addressesGaps = new List<CommunicationUnitGap<TKey>>();
CommunicationUnit<TKey> preCommunicationUnit = null;
foreach (var continusAddress in continusAddresses)
{
if (preCommunicationUnit == null)
@@ -204,7 +239,7 @@ namespace Modbus.Net
if (continusAddress.Area == preCommunicationUnit.Area)
{
//计算间隔
var gap = new CommunicationUnitGap
var gap = new CommunicationUnitGap<TKey>
{
EndUnit = continusAddress,
GapNumber =
@@ -234,7 +269,7 @@ namespace Modbus.Net
continusAddresses.RemoveAt(index);
continusAddresses.RemoveAt(index);
//合并两个已有的地址段,变为一个新的地址段
var newAddress = new CommunicationUnit
var newAddress = new CommunicationUnit<TKey>
{
Area = nowAddress.Area,
Address = preAddress.Address,
@@ -256,7 +291,18 @@ namespace Modbus.Net
/// <summary>
/// 可以调过多少百分比的地址,把两个地址段变为一个
/// </summary>
public class AddressCombinerPercentageJump : AddressCombinerContinus
public class AddressCombinerPercentageJump : AddressCombinerPercentageJump<string>
{
public AddressCombinerPercentageJump(double percentage, AddressTranslator addressTranslator)
: base(percentage, addressTranslator)
{
}
}
/// <summary>
/// 可以调过多少百分比的地址,把两个地址段变为一个
/// </summary>
public class AddressCombinerPercentageJump<TKey> : AddressCombinerContinus<TKey> where TKey : IEquatable<TKey>
{
public AddressCombinerPercentageJump(double percentage, AddressTranslator addressTranslator)
: base(addressTranslator)
@@ -267,12 +313,13 @@ namespace Modbus.Net
private double Percentage { get; }
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
public override IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses)
{
var addressUnits = addresses as IList<AddressUnit> ?? addresses.ToList();
var addressUnits = addresses as IList<AddressUnit<TKey>> ?? addresses.ToList();
var count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]);
return
new AddressCombinerNumericJump((int) (count*Percentage/100.0), AddressTranslator).Combine(addressUnits);
new AddressCombinerNumericJump<TKey>((int) (count*Percentage/100.0), AddressTranslator).Combine(
addressUnits);
}
}
}

View File

@@ -23,7 +23,12 @@ namespace Modbus.Net
/// <summary>
/// 名称
/// </summary>
Name
Name,
/// <summary>
/// Id
/// </summary>
Id
}
/// <summary>
@@ -44,10 +49,33 @@ namespace Modbus.Net
/// <summary>
/// 名称
/// </summary>
Name
Name,
/// <summary>
/// Id
/// </summary>
Id
}
public abstract class BaseMachine : IMachineProperty
public abstract class BaseMachine : BaseMachine<string, string>
{
protected BaseMachine(IEnumerable<AddressUnit<string>> getAddresses) : base(getAddresses)
{
}
protected BaseMachine(IEnumerable<AddressUnit<string>> getAddresses, bool keepConnect)
: base(getAddresses, keepConnect)
{
}
protected BaseMachine(IEnumerable<AddressUnit<string>> getAddresses, bool keepConnect, byte slaveAddress,
byte masterAddress) : base(getAddresses, keepConnect, slaveAddress, masterAddress)
{
}
}
public abstract class BaseMachine<TKey, TUnitKey> : IMachineProperty<TKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
private readonly int _maxErrorCount = 3;
@@ -55,7 +83,7 @@ namespace Modbus.Net
/// 构造器
/// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses)
protected BaseMachine(IEnumerable<AddressUnit<TUnitKey>> getAddresses)
: this(getAddresses, false)
{
}
@@ -65,7 +93,7 @@ namespace Modbus.Net
/// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect)
protected BaseMachine(IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
{
GetAddresses = getAddresses;
KeepConnect = keepConnect;
@@ -78,7 +106,7 @@ namespace Modbus.Net
/// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress,
protected BaseMachine(IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect, byte slaveAddress,
byte masterAddress) : this(getAddresses, keepConnect)
{
SlaveAddress = slaveAddress;
@@ -100,12 +128,12 @@ namespace Modbus.Net
/// <summary>
/// 获取地址组合器
/// </summary>
public AddressCombiner AddressCombiner { get; set; }
public AddressCombiner<TUnitKey> AddressCombiner { get; set; }
/// <summary>
/// 写入地址组合器
/// </summary>
public AddressCombiner AddressCombinerSet { get; set; }
public AddressCombiner<TUnitKey> AddressCombinerSet { get; set; }
/// <summary>
/// 地址转换器
@@ -119,13 +147,13 @@ namespace Modbus.Net
/// <summary>
/// 与设备实际通讯的连续地址
/// </summary>
protected IEnumerable<CommunicationUnit> CommunicateAddresses
protected IEnumerable<CommunicationUnit<TUnitKey>> CommunicateAddresses
=> GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null;
/// <summary>
/// 描述需要与设备通讯的地址
/// </summary>
public IEnumerable<AddressUnit> GetAddresses { get; set; }
public IEnumerable<AddressUnit<TUnitKey>> GetAddresses { get; set; }
/// <summary>
/// 是否保持连接
@@ -150,7 +178,7 @@ namespace Modbus.Net
/// <summary>
/// 设备的Id
/// </summary>
public string Id { get; set; }
public TKey Id { get; set; }
/// <summary>
/// 设备所在工程的名称
@@ -248,6 +276,11 @@ namespace Modbus.Net
key = address.Name;
break;
}
case MachineGetDataType.Id:
{
key = address.Id.ToString();
break;
}
default:
{
key = address.CommunicationTag;
@@ -330,12 +363,12 @@ namespace Modbus.Net
}
//如果设备无法连接,终止
if (!BaseUtility.IsConnected) return false;
var addresses = new List<AddressUnit>();
var addresses = new List<AddressUnit<TUnitKey>>();
//遍历每个要设置的值
foreach (var value in values)
{
//根据设置类型找到对应的地址描述
AddressUnit address = null;
AddressUnit<TUnitKey> address = null;
switch (setDataType)
{
case MachineSetDataType.Address:
@@ -359,6 +392,17 @@ namespace Modbus.Net
address = GetAddresses.SingleOrDefault(p => p.Name == value.Key);
break;
}
case MachineSetDataType.Id:
{
address = GetAddresses.SingleOrDefault(p => p.Id.ToString() == value.Key);
break;
}
default:
{
address =
GetAddresses.SingleOrDefault(p => p.CommunicationTag == value.Key);
break;
}
}
//地址为空报错
if (address == null)
@@ -433,38 +477,44 @@ namespace Modbus.Net
communicateAddress.Address + (int) localPos);
//获取写入类型
var dataType = addressUnit.DataType;
KeyValuePair<string, double> value;
switch (setDataType)
{
case MachineSetDataType.Address:
{
//获取要写入的值
var value =
value =
values.SingleOrDefault(
p => p.Key == address || (address2 != null && p.Key == address2));
//将要写入的值加入队列
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
return false;
break;
}
case MachineSetDataType.CommunicationTag:
{
var value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
return false;
value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
break;
}
case MachineSetDataType.Name:
{
var value = values.SingleOrDefault(p => p.Key == addressUnit.Name);
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
return false;
value = values.SingleOrDefault(p => p.Key == addressUnit.Name);
break;
}
case MachineSetDataType.Id:
{
value = values.SingleOrDefault(p => p.Key == addressUnit.Id.ToString());
break;
}
default:
{
value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
break;
}
}
//将要写入的值加入队列
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
return false;
break;
}
//写入数据
await
@@ -486,6 +536,19 @@ namespace Modbus.Net
return true;
}
public AddressUnit<TUnitKey> GetAddressUnitById(TUnitKey addressUnitId)
{
try
{
return GetAddresses.SingleOrDefault(p => p.Id.Equals(addressUnitId));
}
catch (Exception)
{
Console.WriteLine("Id重复请检查");
return null;
}
}
/// <summary>
/// 连接设备
/// </summary>
@@ -514,14 +577,15 @@ namespace Modbus.Net
}
}
public class BaseMachineEqualityComparer : IEqualityComparer<BaseMachine>
public class BaseMachineEqualityComparer<TKey, TUnitKey> : IEqualityComparer<BaseMachine<TKey, TUnitKey>>
where TKey : IEquatable<TKey> where TUnitKey : IEquatable<TUnitKey>
{
public bool Equals(BaseMachine x, BaseMachine y)
public bool Equals(BaseMachine<TKey, TUnitKey> x, BaseMachine<TKey, TUnitKey> y)
{
return x.ConnectionToken == y.ConnectionToken;
}
public int GetHashCode(BaseMachine obj)
public int GetHashCode(BaseMachine<TKey, TUnitKey> obj)
{
return obj.GetHashCode();
}
@@ -530,7 +594,14 @@ namespace Modbus.Net
/// <summary>
/// 通讯单元
/// </summary>
public class CommunicationUnit
public class CommunicationUnit : CommunicationUnit<string>
{
}
/// <summary>
/// 通讯单元
/// </summary>
public class CommunicationUnit<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 区域
@@ -560,7 +631,7 @@ namespace Modbus.Net
/// <summary>
/// 原始的地址
/// </summary>
public IEnumerable<AddressUnit> OriginalAddresses { get; set; }
public IEnumerable<AddressUnit<TKey>> OriginalAddresses { get; set; }
}
/// <summary>
@@ -586,12 +657,22 @@ namespace Modbus.Net
public UnitExtend UnitExtend { get; set; }
}
public class AddressUnit
/// <summary>
/// 地址单元
/// </summary>
public class AddressUnit : AddressUnit<string>
{
}
/// <summary>
/// 地址单元
/// </summary>
public class AddressUnit<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 数据单元Id
/// </summary>
public string Id { get; set; }
public TKey Id { get; set; }
/// <summary>
/// 数据所属的区域
@@ -652,14 +733,14 @@ namespace Modbus.Net
/// <summary>
/// AddressUnit大小比较
/// </summary>
public struct AddressUnitEqualityComparer : IEqualityComparer<AddressUnit>
public struct AddressUnitEqualityComparer<TKey> : IEqualityComparer<AddressUnit<TKey>> where TKey : IEquatable<TKey>
{
public bool Equals(AddressUnit x, AddressUnit y)
public bool Equals(AddressUnit<TKey> x, AddressUnit<TKey> y)
{
return x.Area.ToUpper() == y.Area.ToUpper() && x.Address == y.Address;
return (x.Area.ToUpper() == y.Area.ToUpper() && x.Address == y.Address) || x.Id.Equals(y.Id);
}
public int GetHashCode(AddressUnit obj)
public int GetHashCode(AddressUnit<TKey> obj)
{
return obj.GetHashCode();
}
@@ -668,12 +749,12 @@ namespace Modbus.Net
/// <summary>
/// 设备的抽象
/// </summary>
public interface IMachineProperty
public interface IMachineProperty<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Id
/// </summary>
string Id { get; set; }
TKey Id { get; set; }
/// <summary>
/// 工程名

View File

@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Modbus.Net</id>
<version>1.2.3.1</version>
<version>1.2.3.2</version>
<title>Modbus.Net</title>
<authors>Chris L.(Luo Sheng)</authors>
<owners>Hangzhou Delian IoT Science Technology Co.,Ltd.</owners>

View File

@@ -18,15 +18,16 @@ namespace Modbus.Net
{
Address,
CommunicationTag,
Name
Name,
Id
}
/// <summary>
/// 返回结果的定义类
/// </summary>
public class TaskReturnDef
public class TaskReturnDef<TMachineKey> where TMachineKey : IEquatable<TMachineKey>
{
public string MachineId { get; set; }
public TMachineKey MachineId { get; set; }
public Dictionary<string, ReturnUnit> ReturnValues { get; set; }
}
@@ -197,23 +198,41 @@ namespace Modbus.Net
}
}
public class TaskManager
/// <summary>
/// 任务调度器
/// </summary>
public class TaskManager : TaskManager<string, string>
{
public TaskManager(int maxRunningTask, int getCycle, bool keepConnect,
MachineDataType dataType = MachineDataType.CommunicationTag)
: base(maxRunningTask, getCycle, keepConnect, dataType)
{
}
}
/// <summary>
/// 任务调度器
/// </summary>
/// <typeparam name="TMachineKey"></typeparam>
/// <typeparam name="TUnitKey"></typeparam>
public class TaskManager<TMachineKey, TUnitKey> where TMachineKey : IEquatable<TMachineKey>
where TUnitKey : IEquatable<TUnitKey>
{
/// <summary>
/// 返回数据代理
/// </summary>
/// <param name="returnValue"></param>
public delegate void ReturnValuesDelegate(TaskReturnDef returnValue);
public delegate void ReturnValuesDelegate(TaskReturnDef<TMachineKey> returnValue);
/// <summary>
/// 正在运行的设备
/// </summary>
private readonly HashSet<BaseMachine> _machines;
private readonly HashSet<BaseMachine<TMachineKey, TUnitKey>> _machines;
/// <summary>
/// 不在运行的设备
/// </summary>
private readonly HashSet<BaseMachine> _unlinkedMachines;
private readonly HashSet<BaseMachine<TMachineKey, TUnitKey>> _unlinkedMachines;
private CancellationTokenSource _cts;
@@ -258,8 +277,10 @@ namespace Modbus.Net
MachineDataType dataType = MachineDataType.CommunicationTag)
{
_scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask);
_machines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer());
_unlinkedMachines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer());
_machines =
new HashSet<BaseMachine<TMachineKey, TUnitKey>>(new BaseMachineEqualityComparer<TMachineKey, TUnitKey>());
_unlinkedMachines =
new HashSet<BaseMachine<TMachineKey, TUnitKey>>(new BaseMachineEqualityComparer<TMachineKey, TUnitKey>());
_getCycle = getCycle;
KeepConnect = keepConnect;
MachineDataType = dataType;
@@ -355,6 +376,12 @@ namespace Modbus.Net
SetDataType = MachineSetDataType.Name;
break;
}
case MachineDataType.Id:
{
GetDataType = MachineGetDataType.Id;
SetDataType = MachineSetDataType.Id;
break;
}
}
}
}
@@ -384,7 +411,7 @@ namespace Modbus.Net
/// 添加一台设备
/// </summary>
/// <param name="machine">设备</param>
public void AddMachine(BaseMachine machine)
public void AddMachine(BaseMachine<TMachineKey, TUnitKey> machine)
{
machine.KeepConnect = KeepConnect;
lock (_machines)
@@ -397,7 +424,7 @@ namespace Modbus.Net
/// 添加多台设备
/// </summary>
/// <param name="machines">设备的列表</param>
public void AddMachines(IEnumerable<BaseMachine> machines)
public void AddMachines(IEnumerable<BaseMachine<TMachineKey, TUnitKey>> machines)
{
lock (_machines)
{
@@ -428,15 +455,15 @@ namespace Modbus.Net
/// 根据设备的id移除设备
/// </summary>
/// <param name="id">设备的id</param>
public void RemoveMachineWithId(string id)
public void RemoveMachineWithId(TMachineKey id)
{
lock (_machines)
{
_machines.RemoveWhere(p => p.Id == id);
_machines.RemoveWhere(p => p.Id.Equals(id));
}
lock (_unlinkedMachines)
{
_unlinkedMachines.RemoveWhere(p => p.Id == id);
_unlinkedMachines.RemoveWhere(p => p.Id.Equals(id));
}
}
@@ -444,14 +471,14 @@ namespace Modbus.Net
/// 将设备指定为未连接
/// </summary>
/// <param name="id">设备的id</param>
public void MoveMachineToUnlinked(string id)
public void MoveMachineToUnlinked(TMachineKey id)
{
IEnumerable<BaseMachine> machines;
IEnumerable<BaseMachine<TMachineKey, TUnitKey>> machines;
lock (_machines)
{
machines = _machines.Where(c => c.Id == id).ToList();
machines = _machines.Where(c => c.Id.Equals(id)).ToList();
if (!machines.Any()) return;
_machines.RemoveWhere(p => p.Id == id);
_machines.RemoveWhere(p => p.Id.Equals(id));
}
lock (_unlinkedMachines)
{
@@ -466,14 +493,14 @@ namespace Modbus.Net
/// 将设备指定为已连接
/// </summary>
/// <param name="id">设备的id</param>
public void MoveMachineToLinked(string id)
public void MoveMachineToLinked(TMachineKey id)
{
IEnumerable<BaseMachine> machines;
IEnumerable<BaseMachine<TMachineKey, TUnitKey>> machines;
lock (_unlinkedMachines)
{
machines = _unlinkedMachines.Where(c => c.Id == id).ToList();
machines = _unlinkedMachines.Where(c => c.Id.Equals(id)).ToList();
if (!machines.Any()) return;
_unlinkedMachines.RemoveWhere(p => p.Id == id);
_unlinkedMachines.RemoveWhere(p => p.Id.Equals(id));
}
lock (_machines)
{
@@ -488,7 +515,7 @@ namespace Modbus.Net
/// 移除设备
/// </summary>
/// <param name="machine">设备的实例</param>
public void RemoveMachine(BaseMachine machine)
public void RemoveMachine(BaseMachine<TMachineKey, TUnitKey> machine)
{
lock (_machines)
{
@@ -527,8 +554,8 @@ namespace Modbus.Net
try
{
var tasks = new List<Task>();
var saveMachines = new HashSet<BaseMachine>();
IEnumerable<BaseMachine> saveMachinesEnum;
var saveMachines = new HashSet<BaseMachine<TMachineKey, TUnitKey>>();
IEnumerable<BaseMachine<TMachineKey, TUnitKey>> saveMachinesEnum;
lock (_machines)
{
saveMachines.UnionWith(_machines);
@@ -543,7 +570,7 @@ namespace Modbus.Net
}
await Task.WhenAll(tasks);
}
catch(Exception)
catch (Exception)
{
//ignore
}
@@ -558,7 +585,7 @@ namespace Modbus.Net
try
{
var tasks = new List<Task>();
var saveMachines = new HashSet<BaseMachine>();
var saveMachines = new HashSet<BaseMachine<TMachineKey, TUnitKey>>();
lock (_unlinkedMachines)
{
saveMachines.UnionWith(_unlinkedMachines);
@@ -572,7 +599,7 @@ namespace Modbus.Net
}
await Task.WhenAll(tasks);
}
catch(Exception)
catch (Exception)
{
//ignore
}
@@ -587,7 +614,7 @@ namespace Modbus.Net
public async Task<bool> SetDatasAsync(string connectionToken,
Dictionary<string, double> values)
{
BaseMachine machine = null;
BaseMachine<TMachineKey, TUnitKey> machine = null;
lock (_machines)
{
machine = _machines.FirstOrDefault(p => p.ConnectionToken == connectionToken);
@@ -632,7 +659,7 @@ namespace Modbus.Net
/// </summary>
/// <param name="machine">设备的实例</param>
/// <returns></returns>
private async Task RunTask(BaseMachine machine)
private async Task RunTask(BaseMachine<TMachineKey, TUnitKey> machine)
{
try
{
@@ -652,7 +679,7 @@ namespace Modbus.Net
{
MoveMachineToLinked(machine.Id);
}
ReturnValues?.Invoke(new TaskReturnDef
ReturnValues?.Invoke(new TaskReturnDef<TMachineKey>
{
MachineId = machine.Id,
ReturnValues = ans
@@ -664,7 +691,7 @@ namespace Modbus.Net
{
MoveMachineToUnlinked(machine.Id);
}
ReturnValues?.Invoke(new TaskReturnDef
ReturnValues?.Invoke(new TaskReturnDef<TMachineKey>
{
MachineId = machine.Id,
ReturnValues = null