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

View File

@@ -1,26 +1,50 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace Modbus.Net.Modbus namespace Modbus.Net.Modbus
{ {
/// <summary> /// <summary>
/// Modbus设备 /// Modbus设备
/// </summary> /// </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, 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) : base(getAddresses, keepConnect, slaveAddress, masterAddress)
{ {
BaseUtility = new ModbusUtility(connectionType, connectionString, slaveAddress, masterAddress, endian); BaseUtility = new ModbusUtility(connectionType, connectionString, slaveAddress, masterAddress, endian);
AddressFormater = new AddressFormaterModbus(); AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus(AddressTranslator); AddressCombiner = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator); AddressCombinerSet = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
} }
public ModbusMachine(ModbusType connectionType, string connectionString, 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) : 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> <copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal OPC DA Delian</tags> <tags>hardware communicate protocal OPC DA Delian</tags>
<dependencies> <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" /> <dependency id="H.Opc" version="0.7.0" />
</dependencies> </dependencies>
</metadata> </metadata>

View File

@@ -1,23 +1,41 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace Modbus.Net.OPC namespace Modbus.Net.OPC
{ {
/// <summary> /// <summary>
/// OpcDa设备 /// OpcDa设备
/// </summary> /// </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) : base(getAddresses, keepConnect)
{ {
BaseUtility = new OpcDaUtility(connectionString); BaseUtility = new OpcDaUtility(connectionString);
AddressCombiner = new AddressCombinerSingle(); AddressCombiner = new AddressCombinerSingle<TUnitKey>();
AddressCombinerSet = new AddressCombinerSingle(); AddressCombinerSet = new AddressCombinerSingle<TUnitKey>();
} }
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses) public OpcDaMachine(string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
: this(connectionString, getAddresses, false) : 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> <copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal Siemens profinet Delian</tags> <tags>hardware communicate protocal Siemens profinet Delian</tags>
<dependencies> <dependencies>
<dependency id="Modbus.Net" version="1.2.3" /> <dependency id="Modbus.Net" version="1.2.3.2" />
</dependencies> </dependencies>
</metadata> </metadata>
<files> <files>

View File

@@ -1,26 +1,46 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace Modbus.Net.Siemens namespace Modbus.Net.Siemens
{ {
/// <summary> /// <summary>
/// 西门子设备 /// 西门子设备
/// </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, 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) : base(getAddresses, keepConnect, slaveAddress, masterAddress)
{ {
BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress); BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress);
AddressFormater = new AddressFormaterSiemens(); AddressFormater = new AddressFormaterSiemens();
AddressCombiner = new AddressCombinerContinus(AddressTranslator); AddressCombiner = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator); AddressCombinerSet = new AddressCombinerContinus<TUnitKey>(AddressTranslator);
} }
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model, 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) : 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>
/// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯 /// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯
/// </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>
/// 组合地址 /// 组合地址
/// </summary> /// </summary>
/// <param name="addresses">需要进行组合的地址</param> /// <param name="addresses">需要进行组合的地址</param>
/// <returns>组合完成后与设备通讯的地址</returns> /// <returns>组合完成后与设备通讯的地址</returns>
public abstract IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses); public abstract IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses);
} }
/// <summary> /// <summary>
/// 连续的地址将组合成一组,向设备进行通讯 /// 连续的地址将组合成一组,向设备进行通讯
/// </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) public AddressCombinerContinus(AddressTranslator addressTranslator)
{ {
@@ -29,7 +46,7 @@ namespace Modbus.Net
protected AddressTranslator AddressTranslator { get; set; } 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 var groupedAddresses = from address in addresses
@@ -39,7 +56,7 @@ namespace Modbus.Net
group address by address.Area group address by address.Area
into grouped into grouped
select grouped; select grouped;
var ans = new List<CommunicationUnit>(); var ans = new List<CommunicationUnit<TKey>>();
foreach (var groupedAddress in groupedAddresses) foreach (var groupedAddress in groupedAddresses)
{ {
var area = groupedAddress.Key; var area = groupedAddress.Key;
@@ -50,7 +67,7 @@ namespace Modbus.Net
//上一个地址类型 //上一个地址类型
Type preType = null; Type preType = null;
//记录一个地址组合当中的所有原始地址 //记录一个地址组合当中的所有原始地址
var originalAddresses = new List<AddressUnit>(); var originalAddresses = new List<AddressUnit<TKey>>();
//对组合内地址从小到大进行排序 //对组合内地址从小到大进行排序
var orderedAddresses = var orderedAddresses =
groupedAddress.OrderBy( groupedAddress.OrderBy(
@@ -97,7 +114,7 @@ namespace Modbus.Net
AddressTranslator.GetAreaByteLength(address.Area))) AddressTranslator.GetAreaByteLength(address.Area)))
{ {
//上一个地址域压入返回结果,并把当前记录的结果清空。 //上一个地址域压入返回结果,并把当前记录的结果清空。
ans.Add(new CommunicationUnit ans.Add(new CommunicationUnit<TKey>
{ {
Area = area, Area = area,
Address = (int) Math.Floor(initNum), Address = (int) Math.Floor(initNum),
@@ -127,7 +144,7 @@ namespace Modbus.Net
preType = address.DataType; preType = address.DataType;
} }
//最后一个地址域压入返回结果 //最后一个地址域压入返回结果
ans.Add(new CommunicationUnit ans.Add(new CommunicationUnit<TKey>
{ {
Area = area, Area = area,
Address = (int) Math.Floor(initNum), Address = (int) Math.Floor(initNum),
@@ -148,21 +165,28 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 单个地址变为一组,每一个地址都进行一次查询 /// 单个地址变为一组,每一个地址都进行一次查询
/// </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 return
addresses.Select( addresses.Select(
address => address =>
new CommunicationUnit new CommunicationUnit<TKey>
{ {
Area = address.Area, Area = address.Area,
Address = address.Address, Address = address.Address,
SubAddress = address.SubAddress, SubAddress = address.SubAddress,
DataType = address.DataType, DataType = address.DataType,
GetCount = 1, GetCount = 1,
OriginalAddresses = new List<AddressUnit> {address} OriginalAddresses = new List<AddressUnit<TKey>> {address}
}).ToList(); }).ToList();
} }
} }
@@ -170,16 +194,27 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 两个CommunicationUnit之间的间隔 /// 两个CommunicationUnit之间的间隔
/// </summary> /// </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; } public int GapNumber { get; set; }
} }
/// <summary> /// <summary>
/// 可以调过多少数量的地址,把两个地址段变为一组通讯 /// 可以调过多少数量的地址,把两个地址段变为一组通讯
/// </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) public AddressCombinerNumericJump(int jumpByteCount, AddressTranslator addressTranslator)
: base(addressTranslator) : base(addressTranslator)
@@ -189,11 +224,11 @@ namespace Modbus.Net
private int JumpNumber { get; } 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 continusAddresses = base.Combine(addresses).ToList();
var addressesGaps = new List<CommunicationUnitGap>(); var addressesGaps = new List<CommunicationUnitGap<TKey>>();
CommunicationUnit preCommunicationUnit = null; CommunicationUnit<TKey> preCommunicationUnit = null;
foreach (var continusAddress in continusAddresses) foreach (var continusAddress in continusAddresses)
{ {
if (preCommunicationUnit == null) if (preCommunicationUnit == null)
@@ -204,7 +239,7 @@ namespace Modbus.Net
if (continusAddress.Area == preCommunicationUnit.Area) if (continusAddress.Area == preCommunicationUnit.Area)
{ {
//计算间隔 //计算间隔
var gap = new CommunicationUnitGap var gap = new CommunicationUnitGap<TKey>
{ {
EndUnit = continusAddress, EndUnit = continusAddress,
GapNumber = GapNumber =
@@ -234,7 +269,7 @@ namespace Modbus.Net
continusAddresses.RemoveAt(index); continusAddresses.RemoveAt(index);
continusAddresses.RemoveAt(index); continusAddresses.RemoveAt(index);
//合并两个已有的地址段,变为一个新的地址段 //合并两个已有的地址段,变为一个新的地址段
var newAddress = new CommunicationUnit var newAddress = new CommunicationUnit<TKey>
{ {
Area = nowAddress.Area, Area = nowAddress.Area,
Address = preAddress.Address, Address = preAddress.Address,
@@ -256,7 +291,18 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 可以调过多少百分比的地址,把两个地址段变为一个 /// 可以调过多少百分比的地址,把两个地址段变为一个
/// </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) public AddressCombinerPercentageJump(double percentage, AddressTranslator addressTranslator)
: base(addressTranslator) : base(addressTranslator)
@@ -267,12 +313,13 @@ namespace Modbus.Net
private double Percentage { get; } 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]); var count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]);
return 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>
/// 名称 /// 名称
/// </summary> /// </summary>
Name Name,
/// <summary>
/// Id
/// </summary>
Id
} }
/// <summary> /// <summary>
@@ -44,10 +49,33 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 名称 /// 名称
/// </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; private readonly int _maxErrorCount = 3;
@@ -55,7 +83,7 @@ namespace Modbus.Net
/// 构造器 /// 构造器
/// </summary> /// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param> /// <param name="getAddresses">需要与设备通讯的地址</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses) protected BaseMachine(IEnumerable<AddressUnit<TUnitKey>> getAddresses)
: this(getAddresses, false) : this(getAddresses, false)
{ {
} }
@@ -65,7 +93,7 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param> /// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param> /// <param name="keepConnect">是否保持连接</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect) protected BaseMachine(IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
{ {
GetAddresses = getAddresses; GetAddresses = getAddresses;
KeepConnect = keepConnect; KeepConnect = keepConnect;
@@ -78,7 +106,7 @@ namespace Modbus.Net
/// <param name="keepConnect">是否保持连接</param> /// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站地址</param> /// <param name="slaveAddress">从站地址</param>
/// <param name="masterAddress">主站地址</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) byte masterAddress) : this(getAddresses, keepConnect)
{ {
SlaveAddress = slaveAddress; SlaveAddress = slaveAddress;
@@ -100,12 +128,12 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 获取地址组合器 /// 获取地址组合器
/// </summary> /// </summary>
public AddressCombiner AddressCombiner { get; set; } public AddressCombiner<TUnitKey> AddressCombiner { get; set; }
/// <summary> /// <summary>
/// 写入地址组合器 /// 写入地址组合器
/// </summary> /// </summary>
public AddressCombiner AddressCombinerSet { get; set; } public AddressCombiner<TUnitKey> AddressCombinerSet { get; set; }
/// <summary> /// <summary>
/// 地址转换器 /// 地址转换器
@@ -119,13 +147,13 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 与设备实际通讯的连续地址 /// 与设备实际通讯的连续地址
/// </summary> /// </summary>
protected IEnumerable<CommunicationUnit> CommunicateAddresses protected IEnumerable<CommunicationUnit<TUnitKey>> CommunicateAddresses
=> GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null; => GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null;
/// <summary> /// <summary>
/// 描述需要与设备通讯的地址 /// 描述需要与设备通讯的地址
/// </summary> /// </summary>
public IEnumerable<AddressUnit> GetAddresses { get; set; } public IEnumerable<AddressUnit<TUnitKey>> GetAddresses { get; set; }
/// <summary> /// <summary>
/// 是否保持连接 /// 是否保持连接
@@ -150,7 +178,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 设备的Id /// 设备的Id
/// </summary> /// </summary>
public string Id { get; set; } public TKey Id { get; set; }
/// <summary> /// <summary>
/// 设备所在工程的名称 /// 设备所在工程的名称
@@ -248,6 +276,11 @@ namespace Modbus.Net
key = address.Name; key = address.Name;
break; break;
} }
case MachineGetDataType.Id:
{
key = address.Id.ToString();
break;
}
default: default:
{ {
key = address.CommunicationTag; key = address.CommunicationTag;
@@ -330,12 +363,12 @@ namespace Modbus.Net
} }
//如果设备无法连接,终止 //如果设备无法连接,终止
if (!BaseUtility.IsConnected) return false; if (!BaseUtility.IsConnected) return false;
var addresses = new List<AddressUnit>(); var addresses = new List<AddressUnit<TUnitKey>>();
//遍历每个要设置的值 //遍历每个要设置的值
foreach (var value in values) foreach (var value in values)
{ {
//根据设置类型找到对应的地址描述 //根据设置类型找到对应的地址描述
AddressUnit address = null; AddressUnit<TUnitKey> address = null;
switch (setDataType) switch (setDataType)
{ {
case MachineSetDataType.Address: case MachineSetDataType.Address:
@@ -359,6 +392,17 @@ namespace Modbus.Net
address = GetAddresses.SingleOrDefault(p => p.Name == value.Key); address = GetAddresses.SingleOrDefault(p => p.Name == value.Key);
break; 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) if (address == null)
@@ -433,38 +477,44 @@ namespace Modbus.Net
communicateAddress.Address + (int) localPos); communicateAddress.Address + (int) localPos);
//获取写入类型 //获取写入类型
var dataType = addressUnit.DataType; var dataType = addressUnit.DataType;
KeyValuePair<string, double> value;
switch (setDataType) switch (setDataType)
{ {
case MachineSetDataType.Address: case MachineSetDataType.Address:
{ {
//获取要写入的值 //获取要写入的值
var value = value =
values.SingleOrDefault( values.SingleOrDefault(
p => p.Key == address || (address2 != null && p.Key == address2)); 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; break;
} }
case MachineSetDataType.CommunicationTag: case MachineSetDataType.CommunicationTag:
{ {
var value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag); 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;
break; break;
} }
case MachineSetDataType.Name: case MachineSetDataType.Name:
{ {
var value = values.SingleOrDefault(p => p.Key == addressUnit.Name); value = values.SingleOrDefault(p => p.Key == addressUnit.Name);
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType); break;
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data)) }
return false; case MachineSetDataType.Id:
{
value = values.SingleOrDefault(p => p.Key == addressUnit.Id.ToString());
break;
}
default:
{
value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
break; break;
} }
} }
//将要写入的值加入队列
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
return false;
break;
} }
//写入数据 //写入数据
await await
@@ -486,6 +536,19 @@ namespace Modbus.Net
return true; 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>
/// 连接设备 /// 连接设备
/// </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; return x.ConnectionToken == y.ConnectionToken;
} }
public int GetHashCode(BaseMachine obj) public int GetHashCode(BaseMachine<TKey, TUnitKey> obj)
{ {
return obj.GetHashCode(); return obj.GetHashCode();
} }
@@ -530,7 +594,14 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 通讯单元 /// 通讯单元
/// </summary> /// </summary>
public class CommunicationUnit public class CommunicationUnit : CommunicationUnit<string>
{
}
/// <summary>
/// 通讯单元
/// </summary>
public class CommunicationUnit<TKey> where TKey : IEquatable<TKey>
{ {
/// <summary> /// <summary>
/// 区域 /// 区域
@@ -560,7 +631,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 原始的地址 /// 原始的地址
/// </summary> /// </summary>
public IEnumerable<AddressUnit> OriginalAddresses { get; set; } public IEnumerable<AddressUnit<TKey>> OriginalAddresses { get; set; }
} }
/// <summary> /// <summary>
@@ -586,12 +657,22 @@ namespace Modbus.Net
public UnitExtend UnitExtend { get; set; } 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> /// <summary>
/// 数据单元Id /// 数据单元Id
/// </summary> /// </summary>
public string Id { get; set; } public TKey Id { get; set; }
/// <summary> /// <summary>
/// 数据所属的区域 /// 数据所属的区域
@@ -652,14 +733,14 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// AddressUnit大小比较 /// AddressUnit大小比较
/// </summary> /// </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(); return obj.GetHashCode();
} }
@@ -668,12 +749,12 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 设备的抽象 /// 设备的抽象
/// </summary> /// </summary>
public interface IMachineProperty public interface IMachineProperty<TKey> where TKey : IEquatable<TKey>
{ {
/// <summary> /// <summary>
/// Id /// Id
/// </summary> /// </summary>
string Id { get; set; } TKey Id { get; set; }
/// <summary> /// <summary>
/// 工程名 /// 工程名

View File

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

View File

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