2017-05-17 update 1 Add Comments and Reformat code.

This commit is contained in:
parallelbgls
2017-05-17 11:18:21 +08:00
parent 779b7d3fa4
commit 2f238780a7
113 changed files with 2490 additions and 1557 deletions

View File

@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="COM" value="COM1"/>
<add key="FBoxOpcDaHost" value="opcda://localhost/FBoxOpcServer"/>
<add key="IP" value="192.168.1.1"/>
<add key="IPConnectionTimeout" value="5000"/>
<add key="ModbusPort" value="502"/>
<add key="OpcDaHost" value="opcda://localhost/..."/>
<add key="OpcUaHost" value="opc.tcp://localhost/..."/>
<add key="SiemensPort" value="102"/>
<add key="COM" value="COM1" />
<add key="FBoxOpcDaHost" value="opcda://localhost/FBoxOpcServer" />
<add key="IP" value="192.168.1.1" />
<add key="IPConnectionTimeout" value="5000" />
<add key="ModbusPort" value="502" />
<add key="OpcDaHost" value="opcda://localhost/..." />
<add key="OpcUaHost" value="opc.tcp://localhost/..." />
<add key="SiemensPort" value="102" />
</appSettings>
</configuration>

View File

@@ -1,20 +1,39 @@
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Configuration;
namespace Modbus.Net
{
/// <summary>
/// Simulate ConfigurationManager in System.Configuration
/// </summary>
public static class ConfigurationManager
{
private static IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
/// <summary>
/// Configuration Builder
/// </summary>
private static readonly IConfigurationBuilder Builder = new ConfigurationBuilder()
.SetBasePath(RootPath ?? Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddXmlFile("App.config");
private static IConfigurationRoot Configuration => builder.Build();
/// <summary>
/// RootPath of App.config and appsettings.json
/// </summary>
public static string RootPath { get; set; } = null;
/// <summary>
/// Configuration Root
/// </summary>
private static IConfigurationRoot Configuration => Builder.Build();
/// <summary>
/// AppSettings
/// </summary>
public static IConfigurationSection AppSettings => Configuration.GetSection("AppSettings");
/// <summary>
/// ConnectionStrings
/// </summary>
public static IConfigurationSection ConnectionStrings => Configuration.GetSection("ConnectionStrings");
}
}

View File

@@ -12,10 +12,12 @@ namespace Modbus.Net.Modbus
/// 读功能码
/// </summary>
protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
/// <summary>
/// 功能码翻译至标准Modbus地址位置
/// </summary>
protected Dictionary<string, int> TransDictionary;
/// <summary>
/// 写功能码
/// </summary>
@@ -201,6 +203,7 @@ namespace Modbus.Net.Modbus
/// 读功能码
/// </summary>
protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
/// <summary>
/// 写功能码
/// </summary>

View File

@@ -8,7 +8,8 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusAsciiProtocalLinker : ComProtocalLinker
{
public ModbusAsciiProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
public ModbusAsciiProtocalLinker(string com, int slaveAddress)
: base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
{
}
@@ -18,14 +19,10 @@ namespace Modbus.Net.Modbus
//CRC校验失败
var contentString = Encoding.ASCII.GetString(content);
if (!Crc16.GetInstance().LrcEfficacy(contentString))
{
throw new ModbusProtocalErrorException(501);
}
//Modbus协议错误
if (byte.Parse(contentString.Substring(3, 2)) > 127)
{
throw new ModbusProtocalErrorException(byte.Parse(contentString.Substring(5, 2)));
}
return true;
}
}

View File

@@ -47,7 +47,8 @@ namespace Modbus.Net.Modbus
/// </summary>
public abstract class ModbusProtocal : BaseProtocal
{
protected ModbusProtocal(byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian)
protected ModbusProtocal(byte slaveAddress, byte masterAddress, Endian endian)
: base(slaveAddress, masterAddress, endian)
{
}
@@ -73,7 +74,8 @@ namespace Modbus.Net.Modbus
var translateAddress = addressTranslator.AddressTranslate(startAddress, true);
FunctionCode = (byte) translateAddress.Area;
StartAddress = (ushort) translateAddress.Address;
GetCount = (ushort) Math.Ceiling(getCount/addressTranslator.GetAreaByteLength(translateAddress.AreaString));
GetCount =
(ushort) Math.Ceiling(getCount / addressTranslator.GetAreaByteLength(translateAddress.AreaString));
}
public byte SlaveAddress { get; }
@@ -140,7 +142,7 @@ namespace Modbus.Net.Modbus
StartAddress = (ushort) translateAddress.Address;
var writeByteValue = ValueHelper.GetInstance(endian).ObjectArrayToByteArray(writeValue);
WriteCount =
(ushort) (writeByteValue.Length/addressTranslator.GetAreaByteLength(translateAddress.AreaString));
(ushort) (writeByteValue.Length / addressTranslator.GetAreaByteLength(translateAddress.AreaString));
WriteByteCount = (byte) writeByteValue.Length;
WriteValue = writeByteValue;
}

View File

@@ -61,9 +61,7 @@ namespace Modbus.Net.Modbus
var newContent = new List<byte>();
newContent.AddRange(Encoding.ASCII.GetBytes(":"));
foreach (var number in content)
{
newContent.AddRange(Encoding.ASCII.GetBytes(number.ToString("X2")));
}
newContent.AddRange(Encoding.ASCII.GetBytes(Crc16.GetInstance().GetLRC(content)));
newContent.Add(0x0d);
newContent.Add(0x0a);

View File

@@ -7,7 +7,8 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusRtuProtocalLinker : ComProtocalLinker
{
public ModbusRtuProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
public ModbusRtuProtocalLinker(string com, int slaveAddress)
: base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
{
}
@@ -16,14 +17,10 @@ namespace Modbus.Net.Modbus
if (!base.CheckRight(content).Value) return false;
//CRC校验失败
if (!Crc16.GetInstance().CrcEfficacy(content))
{
throw new ModbusProtocalErrorException(501);
}
//Modbus协议错误
if (content[1] > 127)
{
throw new ModbusProtocalErrorException(content[2]);
}
return true;
}
}

View File

@@ -12,7 +12,8 @@ namespace Modbus.Net.Modbus
{
}
public ModbusTcpProtocal(string ip, byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian)
public ModbusTcpProtocal(string ip, byte slaveAddress, byte masterAddress, Endian endian)
: base(slaveAddress, masterAddress, endian)
{
ProtocalLinker = new ModbusTcpProtocalLinker(ip);
}

View File

@@ -7,7 +7,8 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusTcpProtocalLinker : TcpProtocalLinker
{
public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.AppSettings["ModbusPort"] ?? "502"))
public ModbusTcpProtocalLinker(string ip)
: base(ip, int.Parse(ConfigurationManager.AppSettings["ModbusPort"] ?? "502"))
{
}
@@ -20,14 +21,10 @@ namespace Modbus.Net.Modbus
if (!base.CheckRight(content).Value) return false;
//长度校验失败
if (content[5] != content.Length - 6)
{
throw new ModbusProtocalErrorException(500);
}
//Modbus协议错误
if (content[7] > 127)
{
throw new ModbusProtocalErrorException(content[2] > 0 ? content[2] : content[8]);
}
return true;
}
}

View File

@@ -27,14 +27,15 @@ namespace Modbus.Net.Modbus
/// <summary>
/// Modbus基础Api入口
/// </summary>
public class ModbusUtility : BaseUtility, IUtilityMethodTime
public class ModbusUtility : BaseUtility, IIUtilityMethodTime
{
/// <summary>
/// Modbus协议类型
/// </summary>
private ModbusType _modbusType;
public ModbusUtility(int connectionType, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb)
public ModbusUtility(int connectionType, byte slaveAddress, byte masterAddress,
Endian endian = Endian.BigEndianLsb)
: base(slaveAddress, masterAddress)
{
Endian = endian;
@@ -43,7 +44,8 @@ namespace Modbus.Net.Modbus
AddressTranslator = new AddressTranslatorModbus();
}
public ModbusUtility(ModbusType connectionType, string connectionString, byte slaveAddress, byte masterAddress, Endian endian = Endian.BigEndianLsb)
public ModbusUtility(ModbusType connectionType, string connectionString, byte slaveAddress, byte masterAddress,
Endian endian = Endian.BigEndianLsb)
: base(slaveAddress, masterAddress)
{
Endian = endian;
@@ -120,6 +122,47 @@ namespace Modbus.Net.Modbus
}
}
/// <summary>
/// 读时间
/// </summary>
/// <returns>设备的时间</returns>
public async Task<DateTime> GetTimeAsync()
{
try
{
var inputStruct = new GetSystemTimeModbusInputStruct(SlaveAddress);
var outputStruct =
await Wrapper.SendReceiveAsync<GetSystemTimeModbusOutputStruct>(
Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct);
return outputStruct?.Time ?? DateTime.MinValue;
}
catch (Exception)
{
return DateTime.MinValue;
}
}
/// <summary>
/// 写时间
/// </summary>
/// <param name="setTime">需要写入的时间</param>
/// <returns>写入是否成功</returns>
public async Task<bool> SetTimeAsync(DateTime setTime)
{
try
{
var inputStruct = new SetSystemTimeModbusInputStruct(SlaveAddress, setTime);
var outputStruct =
await Wrapper.SendReceiveAsync<SetSystemTimeModbusOutputStruct>(
Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct);
return outputStruct?.WriteCount > 0;
}
catch (Exception)
{
return false;
}
}
public override void SetConnectionType(int connectionType)
{
ModbusType = (ModbusType) connectionType;
@@ -138,7 +181,8 @@ namespace Modbus.Net.Modbus
var inputStruct = new ReadDataModbusInputStruct(SlaveAddress, startAddress,
(ushort) getByteCount, AddressTranslator);
var outputStruct = await
Wrapper.SendReceiveAsync<ReadDataModbusOutputStruct>(Wrapper[typeof (ReadDataModbusProtocal)], inputStruct);
Wrapper.SendReceiveAsync<ReadDataModbusOutputStruct>(Wrapper[typeof(ReadDataModbusProtocal)],
inputStruct);
return outputStruct?.DataValue;
}
catch
@@ -160,7 +204,8 @@ namespace Modbus.Net.Modbus
var inputStruct = new WriteDataModbusInputStruct(SlaveAddress, startAddress, setContents,
AddressTranslator, Endian);
var outputStruct = await
Wrapper.SendReceiveAsync<WriteDataModbusOutputStruct>(Wrapper[typeof (WriteDataModbusProtocal)], inputStruct);
Wrapper.SendReceiveAsync<WriteDataModbusOutputStruct>(Wrapper[typeof(WriteDataModbusProtocal)],
inputStruct);
return outputStruct?.WriteCount == setContents.Length;
}
catch
@@ -168,44 +213,5 @@ namespace Modbus.Net.Modbus
return false;
}
}
/// <summary>
/// 读时间
/// </summary>
/// <returns>设备的时间</returns>
public async Task<DateTime> GetTimeAsync()
{
try
{
var inputStruct = new GetSystemTimeModbusInputStruct(SlaveAddress);
var outputStruct =
await Wrapper.SendReceiveAsync<GetSystemTimeModbusOutputStruct>(Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct);
return outputStruct?.Time ?? DateTime.MinValue;
}
catch (Exception)
{
return DateTime.MinValue;
}
}
/// <summary>
/// 写时间
/// </summary>
/// <param name="setTime">需要写入的时间</param>
/// <returns>写入是否成功</returns>
public async Task<bool> SetTimeAsync(DateTime setTime)
{
try
{
var inputStruct = new SetSystemTimeModbusInputStruct(SlaveAddress, setTime);
var outputStruct =
await Wrapper.SendReceiveAsync<SetSystemTimeModbusOutputStruct>(Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct);
return outputStruct?.WriteCount > 0;
}
catch (Exception)
{
return false;
}
}
}
}

View File

@@ -6,7 +6,8 @@ namespace Modbus.Net.OPC
/// <summary>
/// Opc地址编码器
/// </summary>
public class AddressFormaterOpc<TMachineKey,TUnitKey> : AddressFormater where TMachineKey : IEquatable<TMachineKey> where TUnitKey : IEquatable<TUnitKey>
public class AddressFormaterOpc<TMachineKey, TUnitKey> : AddressFormater where TMachineKey : IEquatable<TMachineKey>
where TUnitKey : IEquatable<TUnitKey>
{
/// <summary>
/// 协议构造器
@@ -14,7 +15,8 @@ namespace Modbus.Net.OPC
/// <param name="tagGeter">如何通过BaseMachine和AddressUnit构造Opc的标签</param>
/// <param name="machine">调用这个编码器的设备</param>
/// <param name="seperator">每两个标签之间用什么符号隔开,默认为/</param>
public AddressFormaterOpc(Func<BaseMachine<TMachineKey, TUnitKey>, AddressUnit<TUnitKey>, string[]> tagGeter, BaseMachine<TMachineKey, TUnitKey> machine,
public AddressFormaterOpc(Func<BaseMachine<TMachineKey, TUnitKey>, AddressUnit<TUnitKey>, string[]> tagGeter,
BaseMachine<TMachineKey, TUnitKey> machine,
char seperator = '/')
{
Machine = machine;
@@ -35,9 +37,7 @@ namespace Modbus.Net.OPC
var strings = TagGeter(Machine, findAddress);
var ans = "";
for (var i = 0; i < strings.Length; i++)
{
ans += strings[i].Trim().Replace(" ", "") + Seperator;
}
ans = ans.Substring(0, ans.Length - 1);
return ans;
}

View File

@@ -1,16 +1,16 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Hylasoft.Opc.Common;
using Hylasoft.Opc.Da;
using Opc;
using Opc.Da;
using System.Collections.Generic;
using Hylasoft.Opc.Ua;
namespace Modbus.Net.OPC
{
public interface IClientExtend : IDisposable
{
Node RootNodeBase { get; }
void Connect();
T Read<T>(string tag);
@@ -24,8 +24,6 @@ namespace Modbus.Net.OPC
Task<Node> FindNodeAsync(string tag);
Task<IEnumerable<Node>> ExploreFolderAsync(string tag);
Node RootNodeBase { get; }
}
public class MyDaClient : DaClient, IClientExtend

View File

@@ -1,27 +1,20 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.OPC.FBox
{
public class FBoxOpcDaMachine : OpcDaMachine
{
public string LocalSequence { get; set; }
public string LinkerName { get; set; }
public FBoxOpcDaMachine(string localSequence, string linkerName,
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(ConfigurationManager.AppSettings["FBoxOpcDaHost"], getAddresses, keepConnect)
IEnumerable<AddressUnit> getAddresses, bool keepConnect)
: base(ConfigurationManager.AppSettings["FBoxOpcDaHost"], getAddresses, keepConnect)
{
LocalSequence = localSequence;
LinkerName = linkerName;
AddressFormater =
new AddressFormaterOpc<string,string>(
new AddressFormaterOpc<string, string>(
(machine, unit) =>
new string[]
new[]
{
"(.*)", ((FBoxOpcDaMachine) machine).LinkerName, ((FBoxOpcDaMachine) machine).LocalSequence,
unit.Name
@@ -33,5 +26,9 @@ namespace Modbus.Net.OPC.FBox
: this(localSequence, linkerName, getAddresses, false)
{
}
public string LocalSequence { get; set; }
public string LinkerName { get; set; }
}
}
}

View File

@@ -1,25 +1,25 @@
using Hylasoft.Opc.Common;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Hylasoft.Opc.Common;
namespace Modbus.Net.OPC
{
public abstract class OpcConnector : BaseConnector<OpcParamIn, OpcParamOut>
{
protected IClientExtend Client;
protected bool _connect;
public override string ConnectionToken { get; }
public override bool IsConnected => _connect;
protected IClientExtend Client;
protected OpcConnector(string host)
{
ConnectionToken = host;
}
}
public override string ConnectionToken { get; }
public override bool IsConnected => _connect;
public override bool Disconnect()
{
@@ -56,15 +56,12 @@ namespace Modbus.Net.OPC
private void FoldWith(List<string> tagSplitList, char splitChar, char startChar, char endChar)
{
for (int i = 0; i < tagSplitList.Count; i++)
{
if (tagSplitList[i].Count(ch=>ch == startChar) > tagSplitList[i].Count(ch=>ch == endChar))
{
for (int j = i + 1; j < tagSplitList.Count; j++)
{
for (var i = 0; i < tagSplitList.Count; i++)
if (tagSplitList[i].Count(ch => ch == startChar) > tagSplitList[i].Count(ch => ch == endChar))
for (var j = i + 1; j < tagSplitList.Count; j++)
if (tagSplitList[j].Contains(endChar))
{
for (int k = i + 1; k <= j; k++)
for (var k = i + 1; k <= j; k++)
{
tagSplitList[i] += splitChar + tagSplitList[i + 1];
tagSplitList.RemoveAt(i + 1);
@@ -72,9 +69,6 @@ namespace Modbus.Net.OPC
i--;
break;
}
}
}
}
}
private string[] SplitTag(string tag, char split)
@@ -108,7 +102,7 @@ namespace Modbus.Net.OPC
Value = BigEndianValueHelper.Instance.GetBytes(result, result.GetType())
};
}
return new OpcParamOut()
return new OpcParamOut
{
Success = false,
Value = Encoding.ASCII.GetBytes("NoData")
@@ -132,17 +126,17 @@ namespace Modbus.Net.OPC
catch (Exception e)
{
AddInfo("opc write exception:" + e.Message);
return new OpcParamOut()
return new OpcParamOut
{
Success = false
};
}
return new OpcParamOut()
return new OpcParamOut
{
Success = true
};
}
return new OpcParamOut()
return new OpcParamOut
{
Success = false
};
@@ -151,7 +145,7 @@ namespace Modbus.Net.OPC
catch (Exception e)
{
AddInfo("opc client exception:" + e.Message);
return new OpcParamOut()
return new OpcParamOut
{
Success = false,
Value = Encoding.ASCII.GetBytes("NoData")
@@ -203,4 +197,4 @@ namespace Modbus.Net.OPC
return Task.FromResult(Connect());
}
}
}
}

View File

@@ -1,9 +1,5 @@
using Hylasoft.Opc.Common;
using System;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
{

View File

@@ -3,7 +3,8 @@ using System.Collections.Generic;
namespace Modbus.Net.OPC
{
public class OpcDaMachine<TKey, TUnitKey> : OpcMachine<TKey, TUnitKey> where TKey : IEquatable<TKey> where TUnitKey : IEquatable<TUnitKey>
public class OpcDaMachine<TKey, TUnitKey> : OpcMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
: base(getAddresses, keepConnect)
@@ -21,12 +22,12 @@ namespace Modbus.Net.OPC
public class OpcDaMachine : OpcMachine
{
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses, bool keepConnect)
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses, bool keepConnect)
: base(getAddresses, keepConnect)
{
BaseUtility = new OpcDaUtility(connectionString);
((OpcUtility)BaseUtility).GetSeperator +=
() => ((AddressFormaterOpc<string, string>)AddressFormater).Seperator;
((OpcUtility) BaseUtility).GetSeperator +=
() => ((AddressFormaterOpc<string, string>) AddressFormater).Seperator;
}
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses)

View File

@@ -1,10 +1,9 @@
using System.Configuration;
using System.Text;
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc Da协议连接器
/// Opc Da协议连接器
/// </summary>
public class OpcDaProtocalLinker : OpcProtocalLinker
{

View File

@@ -1,7 +1,4 @@
using System;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc Da协议Api入口

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
@@ -32,4 +29,4 @@ namespace Modbus.Net.OPC
AddressCombinerSet = new AddressCombinerSingle();
}
}
}
}

View File

@@ -1,6 +1,4 @@
using System.Text;
namespace Modbus.Net.OPC
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc协议
@@ -41,7 +39,7 @@ namespace Modbus.Net.OPC
public override OpcParamIn Format(IInputStruct message)
{
var r_message = (ReadRequestOpcInputStruct) message;
return new OpcParamIn()
return new OpcParamIn
{
IsRead = true,
Tag = r_message.Tag,
@@ -88,7 +86,7 @@ namespace Modbus.Net.OPC
public override OpcParamIn Format(IInputStruct message)
{
var r_message = (WriteRequestOpcInputStruct) message;
return new OpcParamIn()
return new OpcParamIn
{
IsRead = false,
Tag = r_message.Tag,

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
@@ -51,10 +48,8 @@ namespace Modbus.Net.OPC
{
if (content == null || !content.Success) return false;
if (content.Value.Length == 6 && Encoding.ASCII.GetString(content.Value) == "NoData")
{
return null;
}
return base.CheckRight(content);
}
}
}
}

View File

@@ -1,11 +1,5 @@
using Hylasoft.Opc.Common;
using Hylasoft.Opc.Ua;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
@@ -31,4 +25,4 @@ namespace Modbus.Net.OPC
return _instances[host];
}
}
}
}

View File

@@ -1,19 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
public class OpcUaMachine<TKey, TUnitKey> : OpcMachine<TKey, TUnitKey> where TKey : IEquatable<TKey> where TUnitKey : IEquatable<TUnitKey>
public class OpcUaMachine<TKey, TUnitKey> : OpcMachine<TKey, TUnitKey> where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
public OpcUaMachine(string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses, bool keepConnect)
: base(getAddresses, keepConnect)
{
BaseUtility = new OpcUaUtility(connectionString);
((OpcUtility)BaseUtility).GetSeperator +=
() => ((AddressFormaterOpc<string, string>)AddressFormater).Seperator;
((OpcUtility) BaseUtility).GetSeperator +=
() => ((AddressFormaterOpc<string, string>) AddressFormater).Seperator;
}
public OpcUaMachine(string connectionString, IEnumerable<AddressUnit<TUnitKey>> getAddresses)
@@ -28,8 +26,8 @@ namespace Modbus.Net.OPC
: base(getAddresses, keepConnect)
{
BaseUtility = new OpcUaUtility(connectionString);
((OpcUtility)BaseUtility).GetSeperator +=
() => ((AddressFormaterOpc<string, string>)AddressFormater).Seperator;
((OpcUtility) BaseUtility).GetSeperator +=
() => ((AddressFormaterOpc<string, string>) AddressFormater).Seperator;
}
public OpcUaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses)
@@ -37,4 +35,4 @@ namespace Modbus.Net.OPC
{
}
}
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
@@ -33,4 +29,4 @@ namespace Modbus.Net.OPC
return true;
}
}
}
}

View File

@@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc Da协议连接器
/// Opc Da协议连接器
/// </summary>
public class OpcUaProtocalLinker : OpcProtocalLinker
{
@@ -21,4 +16,4 @@ namespace Modbus.Net.OPC
BaseConnector = OpcUaConnector.Instance(host);
}
}
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc Da协议Api入口
@@ -16,4 +10,4 @@ namespace Modbus.Net.OPC
Wrapper = new OpcUaProtocal(ConnectionString);
}
}
}
}

View File

@@ -1,25 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
public abstract class OpcUtility : BaseUtility<OpcParamIn, OpcParamOut, ProtocalUnit<OpcParamIn, OpcParamOut>>
{
{
public delegate char GetSeperatorDelegate();
protected OpcUtility(string connectionString) : base(0, 0)
{
ConnectionString = connectionString;
AddressTranslator = new AddressTranslatorOpc();
}
public delegate char GetSeperatorDelegate();
public override Endian Endian => Endian.BigEndianLsb;
public event GetSeperatorDelegate GetSeperator;
public override Endian Endian => Endian.BigEndianLsb;
public override void SetConnectionType(int connectionType)
{
throw new NotImplementedException();
@@ -33,7 +30,8 @@ namespace Modbus.Net.OPC
var readRequestOpcInputStruct = new ReadRequestOpcInputStruct(startAddress, split);
var readRequestOpcOutputStruct =
await
Wrapper.SendReceiveAsync<ReadRequestOpcOutputStruct>(Wrapper[typeof(ReadRequestOpcProtocal)], readRequestOpcInputStruct);
Wrapper.SendReceiveAsync<ReadRequestOpcOutputStruct>(Wrapper[typeof(ReadRequestOpcProtocal)],
readRequestOpcInputStruct);
return readRequestOpcOutputStruct?.GetValue;
}
catch (Exception)
@@ -50,7 +48,8 @@ namespace Modbus.Net.OPC
var writeRequestOpcInputStruct = new WriteRequestOpcInputStruct(startAddress, split, setContents[0]);
var writeRequestOpcOutputStruct =
await
Wrapper.SendReceiveAsync<WriteRequestOpcOutputStruct>(Wrapper[typeof(WriteRequestOpcProtocal)], writeRequestOpcInputStruct);
Wrapper.SendReceiveAsync<WriteRequestOpcOutputStruct>(Wrapper[typeof(WriteRequestOpcProtocal)],
writeRequestOpcInputStruct);
return writeRequestOpcOutputStruct?.WriteResult == true;
}
catch (Exception e)
@@ -59,4 +58,4 @@ namespace Modbus.Net.OPC
}
}
}
}
}

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="H.Opc" version="0.8.1" targetFramework="net45" />
</packages>

View File

@@ -17,7 +17,7 @@
}
/// <summary>
/// Siemens地址格式化Siemens格式
/// Siemens地址格式化Siemens格式
/// </summary>
public class AddressFormaterSimenseStandard : AddressFormater
{
@@ -25,26 +25,16 @@
{
if (area.Length > 1 &&
area.ToUpper().Substring(0, 2) == "DB")
{
return area.ToUpper() + "." + "DB" + address;
}
else
{
return area.ToUpper() + address;
}
return area.ToUpper() + address;
}
public override string FormatAddress(string area, int address, int subAddress)
{
if (area.Length > 1 &&
area.ToUpper().Substring(0, 2) == "DB")
{
return area.ToUpper() + "." + "DB" + address + "." + subAddress;
}
else
{
return area.ToUpper() + address + "." + subAddress;
}
return area.ToUpper() + address + "." + subAddress;
}
}
}

View File

@@ -53,7 +53,7 @@ namespace Modbus.Net.Siemens
return new AddressDef
{
AreaString = "DB" + head,
Area = int.Parse(head)*256 + AreaCodeDictionary["DB"],
Area = int.Parse(head) * 256 + AreaCodeDictionary["DB"],
Address = int.Parse(tail),
SubAddress = int.Parse(sub)
};
@@ -96,7 +96,7 @@ namespace Modbus.Net.Siemens
{"Q", 0x82},
{"M", 0x83},
{"DB", 0x84},
{"V", 0x184},
{"V", 0x184}
};
}
@@ -118,15 +118,13 @@ namespace Modbus.Net.Siemens
SubAddress = addressSplit.Length == 2 ? 0 : int.Parse(addressSplit[2])
};
}
int i = 0;
var i = 0;
int t;
while (!int.TryParse(address[i].ToString(), out t) && i < address.Length)
{
i++;
}
if (i == 0 || i >= address.Length) throw new FormatException();
string head = address.Substring(0, i);
string[] tail = address.Substring(i).Split('.');
var head = address.Substring(0, i);
var tail = address.Substring(i).Split('.');
return new AddressDef
{
AreaString = head,

View File

@@ -29,9 +29,7 @@ namespace Modbus.Net.Siemens
public override async Task<byte[]> SendReceiveAsync(params object[] content)
{
if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
{
await ConnectAsync();
}
return await base.SendReceiveAsync(Endian, content);
}
@@ -51,17 +49,17 @@ namespace Modbus.Net.Siemens
var inputStruct = new ComCreateReferenceSiemensInputStruct(SlaveAddress, MasterAddress);
var outputStruct =
await await
ForceSendReceiveAsync(this[typeof (ComCreateReferenceSiemensProtocal)],
inputStruct).
ForceSendReceiveAsync(this[typeof(ComCreateReferenceSiemensProtocal)],
inputStruct).
ContinueWith(async answer =>
{
if (!ProtocalLinker.IsConnected) return false;
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(SlaveAddress, MasterAddress);
var outputStruct2 =
(ComConfirmMessageSiemensOutputStruct)
await
ForceSendReceiveAsync(this[typeof (ComConfirmMessageSiemensProtocal)],
inputStruct2);
await
ForceSendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocal)],
inputStruct2);
return outputStruct2 != null;
});
return outputStruct;

View File

@@ -65,15 +65,11 @@ namespace Modbus.Net.Siemens
if (!base.CheckRight(content).Value) return false;
var fcsCheck = 0;
if (content.Length == 1 && content[0] == 0xe5)
{
return true;
}
if (content.Length == 6 && content[3] == 0) return true;
for (var i = 4; i < content.Length - 2; i++)
{
fcsCheck += content[i];
}
fcsCheck = fcsCheck%256;
fcsCheck = fcsCheck % 256;
if (fcsCheck != content[content.Length - 2]) return false;
if (content[content.Length - 1] != 0x16) return false;
if (content[1] != content.Length - 6) return false;

View File

@@ -104,7 +104,8 @@ namespace Modbus.Net.Siemens
public abstract class SiemensProtocal : BaseProtocal
{
protected SiemensProtocal(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress, Endian.BigEndianLsb)
protected SiemensProtocal(byte slaveAddress, byte masterAddress)
: base(slaveAddress, masterAddress, Endian.BigEndianLsb)
{
}
}
@@ -142,7 +143,7 @@ namespace Modbus.Net.Siemens
public override byte[] Format(IInputStruct message)
{
var r_message = (ComCreateReferenceSiemensInputStruct) message;
var crc = (r_message.SlaveAddress + r_message.MasterAddress + 0x49)%256;
var crc = (r_message.SlaveAddress + r_message.MasterAddress + 0x49) % 256;
return Format((byte) 0x10, r_message.SlaveAddress, r_message.MasterAddress, (byte) 0x49, (byte) crc,
(byte) 0x16);
}
@@ -274,7 +275,7 @@ namespace Modbus.Net.Siemens
public override byte[] Format(IInputStruct message)
{
var r_message = (ComConfirmMessageSiemensInputStruct) message;
var crc = r_message.SlaveAddress + r_message.MasterAddress + 0x5c%256;
var crc = r_message.SlaveAddress + r_message.MasterAddress + 0x5c % 256;
return Format((byte) 0x10, r_message.SlaveAddress, r_message.MasterAddress, (byte) 0x5c, (byte) crc,
(byte) 0x16);
}
@@ -370,8 +371,8 @@ namespace Modbus.Net.Siemens
var address = addressTranslator.AddressTranslate(startAddress, true);
Offset = address.Address;
var area = address.Area;
Area = (byte) (area%256);
DbBlock = Area == 0x84 ? (ushort) (area/256) : (ushort) 0;
Area = (byte) (area % 256);
DbBlock = Area == 0x84 ? (ushort) (area / 256) : (ushort) 0;
NumberOfElements = getCount;
}
@@ -426,7 +427,7 @@ namespace Modbus.Net.Siemens
var numberOfElements = r_message.NumberOfElements;
var dbBlock = r_message.DbBlock;
var area = r_message.Area;
var offsetBit = r_message.Offset*8;
var offsetBit = r_message.Offset * 8;
var offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit);
return Format(new byte[4], slaveAddress, masterAddress, (byte) 0x6c, protoId, rosctr, redId, pduRef, parLg,
datLg, serviceId, numberOfVariables
@@ -442,7 +443,7 @@ namespace Modbus.Net.Siemens
var accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var dataType = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var length = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos);
var byteLength = length/8;
var byteLength = length / 8;
var values = new byte[byteLength];
Array.Copy(messageBytes, pos, values, 0, byteLength);
return new ReadRequestSiemensOutputStruct(pduRef, (SiemensAccessResult) accessResult,
@@ -465,8 +466,8 @@ namespace Modbus.Net.Siemens
var address = addressTranslator.AddressTranslate(startAddress, true);
Offset = address.Address;
var area = address.Area;
Area = (byte) (area%256);
DbBlock = Area == 0x84 ? (ushort) (area/256) : (ushort) 0;
Area = (byte) (area % 256);
DbBlock = Area == 0x84 ? (ushort) (area / 256) : (ushort) 0;
WriteValue = writeValue;
}
@@ -514,11 +515,11 @@ namespace Modbus.Net.Siemens
var numberOfElements = (ushort) valueBytes.Length;
var dbBlock = r_message.DbBlock;
var area = r_message.Area;
var offsetBit = r_message.Offset*8;
var offsetBit = r_message.Offset * 8;
var offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit);
const byte reserved = 0x00;
const byte type = (byte) SiemensDataType.OtherAccess;
var numberOfWriteBits = (ushort) (valueBytes.Length*8);
var numberOfWriteBits = (ushort) (valueBytes.Length * 8);
return Format(new byte[4], slaveAddress, masterAddress, (byte) 0x7c, protoId, rosctr, redId, pduRef, parLg,
datLg, serviceId, numberOfVariables
, variableSpec, vAddrLg, syntaxId, typeR, numberOfElements, dbBlock, area,

View File

@@ -35,10 +35,8 @@ namespace Modbus.Net.Siemens
0, 4);
var check = 0;
for (var i = 4; i < newContent.Length - 2; i++)
{
check += newContent[i];
}
check = check%256;
check = check % 256;
newContent[newContent.Length - 2] = (byte) check;
newContent[newContent.Length - 1] = 0x16;
return newContent;

View File

@@ -19,12 +19,16 @@ namespace Modbus.Net.Siemens
private int _connectTryCount;
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled,
ushort maxPdu) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.AppSettings["IP"])
ushort maxPdu)
: this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.AppSettings["IP"])
{
}
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled,
ushort maxPdu, string ip) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ip, int.Parse(ConfigurationManager.AppSettings["SiemensPort"]))
ushort maxPdu, string ip)
: this(
tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ip,
int.Parse(ConfigurationManager.AppSettings["SiemensPort"] ?? "102"))
{
}
@@ -50,9 +54,7 @@ namespace Modbus.Net.Siemens
public override async Task<byte[]> SendReceiveAsync(params object[] content)
{
if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
{
await ConnectAsync();
}
return await base.SendReceiveAsync(Endian, content);
}
@@ -92,7 +94,7 @@ namespace Modbus.Net.Siemens
return
//先建立连接,然后建立设备的引用
await await
ForceSendReceiveAsync(this[typeof (CreateReferenceSiemensProtocal)], inputStruct)
ForceSendReceiveAsync(this[typeof(CreateReferenceSiemensProtocal)], inputStruct)
.ContinueWith(async answer =>
{
if (!ProtocalLinker.IsConnected) return false;
@@ -101,9 +103,9 @@ namespace Modbus.Net.Siemens
_maxPdu);
var outputStruct2 =
(EstablishAssociationSiemensOutputStruct)
await
SendReceiveAsync(this[typeof (EstablishAssociationSiemensProtocal)],
inputStruct2);
await
SendReceiveAsync(this[typeof(EstablishAssociationSiemensProtocal)],
inputStruct2);
return outputStruct2 != null;
});
}

View File

@@ -183,7 +183,8 @@ namespace Modbus.Net.Siemens
0xd3c7, SiemensTypeCode.Byte, startAddress, (ushort) getByteCount, AddressTranslator);
var readRequestSiemensOutputStruct =
await
Wrapper.SendReceiveAsync<ReadRequestSiemensOutputStruct>(Wrapper[typeof (ReadRequestSiemensProtocal)],
Wrapper.SendReceiveAsync<ReadRequestSiemensOutputStruct>(
Wrapper[typeof(ReadRequestSiemensProtocal)],
readRequestSiemensInputStruct);
return readRequestSiemensOutputStruct?.GetValue;
}
@@ -207,7 +208,8 @@ namespace Modbus.Net.Siemens
0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSiemensOutputStruct =
await
Wrapper.SendReceiveAsync<WriteRequestSiemensOutputStruct>(Wrapper[typeof (WriteRequestSiemensProtocal)],
Wrapper.SendReceiveAsync<WriteRequestSiemensOutputStruct>(
Wrapper[typeof(WriteRequestSiemensProtocal)],
writeRequestSiemensInputStruct);
return writeRequestSiemensOutputStruct?.AccessResult == SiemensAccessResult.NoError;
}

View File

@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="COM" value="COM1"/>
<add key="FBoxOpcDaHost" value="opcda://localhost/FBoxOpcServer"/>
<add key="IP" value="192.168.1.1"/>
<add key="ComConnectionTimeout" value="3000"/>
<add key="IPConnectionTimeout" value="5000"/>
<add key="ModbusPort" value="502"/>
<add key="OpcDaHost" value="opcda://localhost/..."/>
<add key="OpcUaHost" value="opc.tcp://localhost/..."/>
<add key="SiemensPort" value="102"/>
<add key="COM" value="COM1" />
<add key="FBoxOpcDaHost" value="opcda://localhost/FBoxOpcServer" />
<add key="IP" value="192.168.1.1" />
<add key="ComConnectionTimeout" value="3000" />
<add key="IPConnectionTimeout" value="5000" />
<add key="ModbusPort" value="502" />
<add key="OpcDaHost" value="opcda://localhost/..." />
<add key="OpcUaHost" value="opc.tcp://localhost/..." />
<add key="SiemensPort" value="102" />
</appSettings>
</configuration>

View File

@@ -9,8 +9,14 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// 具有发送锁的串口
/// </summary>
public class SerialPortLock : SerialPort
{
/// <summary>
/// 发送锁
/// </summary>
public object Lock { get; set; } = new object();
}
@@ -19,42 +25,87 @@ namespace Modbus.Net
/// </summary>
public class ComConnector : BaseConnector, IDisposable
{
public delegate byte[] GetDate(byte[] bts);
private static Dictionary<string, SerialPortLock> Connectors { get; } = new Dictionary<string, SerialPortLock>();
private static Dictionary<string, string> Linkers { get; } = new Dictionary<string, string>();
/// <summary>
/// 波特率
/// </summary>
private readonly int _baudRate;
//private GetDate mygetDate;
/// <summary>
/// 串口地址
/// </summary>
private readonly string _com;
/// <summary>
/// 数据位
/// </summary>
private readonly int _dataBits;
/// <summary>
/// 奇偶校验
/// </summary>
private readonly Parity _parity;
private readonly StopBits _stopBits;
private readonly int _timeoutTime;
/// <summary>
/// 从站号
/// </summary>
private readonly string _slave;
private bool m_disposed = false;
/// <summary>
/// 停止位
/// </summary>
private readonly StopBits _stopBits;
/// <summary>
/// 超时时间
/// </summary>
private readonly int _timeoutTime;
/// <summary>
/// Dispose是否执行
/// </summary>
private bool m_disposed;
/// <summary>
/// 构造器
/// </summary>
/// <param name="com">串口地址:从站号</param>
/// <param name="baudRate">波特率</param>
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
/// <param name="timeoutTime">超时时间</param>
public ComConnector(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits, int timeoutTime)
{
_com = com.Split(':')[0];
_timeoutTime = timeoutTime;
_baudRate = baudRate;
_parity = parity;
_stopBits = stopBits;
_dataBits = dataBits;
_slave = com.Split(':')[1];
//端口号
_com = com.Split(':')[0];
//读超时
//比特率
//奇偶校验
_timeoutTime = timeoutTime;
//波特率
_baudRate = baudRate;
//奇偶校验
_parity = parity;
//停止位
_stopBits = stopBits;
//数据位
//从站号标识
_dataBits = dataBits;
//从站号
_slave = com.Split(':')[1];
}
/// <summary>
/// 连接中的串口
/// </summary>
private static Dictionary<string, SerialPortLock> Connectors { get; } = new Dictionary<string, SerialPortLock>()
;
/// <summary>
/// 连接中的连接器
/// </summary>
private static Dictionary<string, string> Linkers { get; } = new Dictionary<string, string>();
/// <summary>
/// 连接关键字(串口号:从站号)
/// </summary>
public override string ConnectionToken => _slave + ":" + _com;
private SerialPortLock SerialPort
@@ -72,7 +123,7 @@ namespace Modbus.Net
/// </summary>
public void Dispose()
{
Dispose(true);
Dispose(true);
//.NET Framework 类库
// GC..::.SuppressFinalize 方法
//请求系统不要调用指定对象的终结器。
@@ -117,7 +168,9 @@ namespace Modbus.Net
}
else if (nReadLen == 0)
{
nBytelen += 1;
}
}
}
catch (Exception ex)
@@ -146,7 +199,6 @@ namespace Modbus.Net
SerialPort.ReadTimeout = ByteTime;
while (nBytelen < ReadRoom - 1 && SerialPort.BytesToRead > 0)
{
try
{
ReadBuf[nBytelen] = (byte) SerialPort.ReadByte();
@@ -156,7 +208,6 @@ namespace Modbus.Net
{
throw new Exception(ex.Message);
}
}
ReadBuf[nBytelen] = 0x00;
return nBytelen;
}
@@ -171,9 +222,7 @@ namespace Modbus.Net
{
var StringOut = "";
foreach (var InByte in InBytes)
{
StringOut = StringOut + string.Format("{0:X2}", InByte) + " ";
}
return StringOut.Trim();
}
@@ -190,9 +239,7 @@ namespace Modbus.Net
byte[] ByteOut;
ByteOut = new byte[ByteStrings.Length];
for (var i = 0; i <= ByteStrings.Length - 1; i++)
{
ByteOut[i] = byte.Parse(ByteStrings[i], NumberStyles.HexNumber);
}
return ByteOut;
}
@@ -207,7 +254,7 @@ namespace Modbus.Net
InString = InString.Replace(" ", "");
try
{
var ByteStrings = new string[InString.Length/2];
var ByteStrings = new string[InString.Length / 2];
var j = 0;
for (var i = 0; i < ByteStrings.Length; i++)
{
@@ -217,9 +264,7 @@ namespace Modbus.Net
ByteOut = new byte[ByteStrings.Length];
for (var i = 0; i <= ByteStrings.Length - 1; i++)
{
ByteOut[i] = byte.Parse(ByteStrings[i], NumberStyles.HexNumber);
}
}
catch (Exception ex)
{
@@ -285,24 +330,28 @@ namespace Modbus.Net
#region
/// <summary>
/// 是否正在连接
/// </summary>
public override bool IsConnected
{
get
{
if (SerialPort != null && !SerialPort.IsOpen)
{
SerialPort.Dispose();
}
return SerialPort != null && SerialPort.IsOpen && Linkers.ContainsKey(_slave);
}
}
/// <summary>
/// 连接串口
/// </summary>
/// <returns>是否连接成功</returns>
public override bool Connect()
{
try
{
if (!Connectors.ContainsKey(_com))
{
Connectors.Add(_com, new SerialPortLock
{
PortName = _com,
@@ -312,29 +361,33 @@ namespace Modbus.Net
DataBits = _dataBits,
ReadTimeout = _timeoutTime
});
}
if (!Linkers.ContainsKey(_slave))
{
Linkers.Add(_slave, _com);
}
SerialPort.Open();
return true;
}
catch (Exception e)
catch (Exception)
{
return false;
}
}
/// <summary>
/// 连接串口
/// </summary>
/// <returns>是否连接成功</returns>
public override Task<bool> ConnectAsync()
{
return Task.FromResult(Connect());
}
/// <summary>
/// 断开串口
/// </summary>
/// <returns>是否断开成功</returns>
public override bool Disconnect()
{
if (Linkers.ContainsKey(_slave) && Connectors.ContainsKey(_com))
{
try
{
Dispose();
@@ -344,28 +397,43 @@ namespace Modbus.Net
{
return false;
}
}
return false;
}
public void SendMsg(string senStr)
/// <summary>
/// 带返回发送数据
/// </summary>
/// <param name="sendStr">需要发送的数据</param>
/// <returns>是否发送成功</returns>
public string SendMsg(string sendStr)
{
var myByte = StringToByte_2(senStr);
var myByte = StringToByte_2(sendStr);
SendMsg(myByte);
var returnBytes = SendMsg(myByte);
return ByteToString(returnBytes);
}
/// <summary>
/// 无返回发送数据
/// </summary>
/// <param name="message">需要发送的数据</param>
/// <returns>是否发送成功</returns>
public override Task<bool> SendMsgWithoutReturnAsync(byte[] message)
{
return Task.FromResult(SendMsgWithoutReturn(message));
}
/// <summary>
/// 带返回发送数据
/// </summary>
/// <param name="sendbytes">需要发送的数据</param>
/// <returns>是否发送成功</returns>
public override byte[] SendMsg(byte[] sendbytes)
{
try
{
if (!SerialPort.IsOpen)
{
try
{
SerialPort.Open();
@@ -375,7 +443,6 @@ namespace Modbus.Net
Dispose();
SerialPort.Open();
}
}
lock (SerialPort.Lock)
{
SerialPort.Write(sendbytes, 0, sendbytes.Length);
@@ -389,17 +456,26 @@ namespace Modbus.Net
}
}
/// <summary>
/// 带返回发送数据
/// </summary>
/// <param name="message">需要发送的数据</param>
/// <returns>是否发送成功</returns>
public override Task<byte[]> SendMsgAsync(byte[] message)
{
return Task.FromResult(SendMsg(message));
}
/// <summary>
/// 无返回发送数据
/// </summary>
/// <param name="sendbytes">需要发送的数据</param>
/// <returns>是否发送成功</returns>
public override bool SendMsgWithoutReturn(byte[] sendbytes)
{
try
{
if (!SerialPort.IsOpen)
{
try
{
SerialPort.Open();
@@ -409,7 +485,6 @@ namespace Modbus.Net
Dispose();
SerialPort.Open();
}
}
lock (SerialPort.Lock)
{
SerialPort.Write(sendbytes, 0, sendbytes.Length);
@@ -422,24 +497,12 @@ namespace Modbus.Net
}
}
public string ReadMsgStr()
{
var rd = "";
var data = ReadMsg();
rd = ByteToString(data);
return rd;
}
public byte[] ReadMsg()
private byte[] ReadMsg()
{
try
{
if (!SerialPort.IsOpen)
{
SerialPort.Open();
}
byte[] data;
Thread.Sleep(100);

View File

@@ -15,6 +15,7 @@ namespace Modbus.Net
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
/// <param name="slaveAddress">从站地址</param>
protected ComProtocalLinker(int baudRate, Parity parity, StopBits stopBits, int dataBits, int slaveAddress)
: this(ConfigurationManager.AppSettings["COM"], baudRate, parity, stopBits, dataBits, slaveAddress)
{
@@ -28,6 +29,7 @@ namespace Modbus.Net
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
/// <param name="slaveAddress">从站地址</param>
protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits,
int slaveAddress)
: this(
@@ -45,10 +47,12 @@ namespace Modbus.Net
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
/// <param name="connectionTimeout">超时时间</param>
/// <param name="slaveAddress">从站地址</param>
protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits,
int connectionTimeout, int slaveAddress)
{
BaseConnector = new ComConnector(com + ":" + slaveAddress, baudRate, parity, stopBits, dataBits, connectionTimeout);
BaseConnector = new ComConnector(com + ":" + slaveAddress, baudRate, parity, stopBits, dataBits,
connectionTimeout);
}
}
}

View File

@@ -34,7 +34,8 @@ namespace Modbus.Net
/// </summary>
/// <param name="addressTranslator">地址转换器</param>
/// <param name="maxLength">单个发送协议允许的数据最长长度(字节)</param>
public AddressCombinerContinus(AddressTranslator addressTranslator, int maxLength) : base(addressTranslator, maxLength)
public AddressCombinerContinus(AddressTranslator addressTranslator, int maxLength)
: base(addressTranslator, maxLength)
{
}
}
@@ -44,11 +45,6 @@ namespace Modbus.Net
/// </summary>
public class AddressCombinerContinus<TKey> : AddressCombiner<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// 协议的数据最长长度(字节)
/// </summary>
protected int MaxLength { get; set; }
/// <summary>
/// 构造函数
/// </summary>
@@ -60,6 +56,11 @@ namespace Modbus.Net
MaxLength = maxLength;
}
/// <summary>
/// 协议的数据最长长度(字节)
/// </summary>
protected int MaxLength { get; set; }
/// <summary>
/// 地址转换器
/// </summary>
@@ -75,8 +76,8 @@ namespace Modbus.Net
//按从小到大的顺序对地址进行排序
var groupedAddresses = from address in addresses
orderby
AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
AddressTranslator.GetAreaByteLength(address.Area))
AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
AddressTranslator.GetAreaByteLength(address.Area))
group address by address.Area
into grouped
select grouped;
@@ -111,7 +112,7 @@ namespace Modbus.Net
{
//如果当前地址小于已经记录的地址域,表示这个地址的开始已经记录过了
if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
AddressTranslator.GetAreaByteLength(address.Area)) <
AddressTranslator.GetAreaByteLength(address.Area)) <
AddressHelper.GetProtocalCoordinateNextPosition(preNum,
preType,
AddressTranslator.GetAreaByteLength(address.Area)))
@@ -119,20 +120,18 @@ namespace Modbus.Net
originalAddresses.Add(address);
//如果当前地址的末尾被记录,表示地址被记录的地址域覆盖,这个地址没有记录的必要
if (AddressHelper.GetProtocalCoordinateNextPosition(
AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
AddressTranslator.GetAreaByteLength(address.Area)),
address.DataType,
AddressTranslator.GetAreaByteLength(address.Area)) <=
AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
AddressTranslator.GetAreaByteLength(address.Area)),
address.DataType,
AddressTranslator.GetAreaByteLength(address.Area)) <=
AddressHelper.GetProtocalCoordinateNextPosition(preNum,
preType,
AddressTranslator.GetAreaByteLength(address.Area)))
{
continue;
}
}
//如果当前地址大于记录的地址域的开头,则表示地址已经不连续了
else if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
AddressTranslator.GetAreaByteLength(address.Area)) >
AddressTranslator.GetAreaByteLength(address.Area)) >
AddressHelper.GetProtocalCoordinateNextPosition(preNum,
preType,
AddressTranslator.GetAreaByteLength(address.Area)))
@@ -144,12 +143,12 @@ namespace Modbus.Net
Address = (int) Math.Floor(initNum),
GetCount =
(int)
Math.Ceiling(
AddressHelper.MapProtocalGetCountToAbstractByteCount(
preNum - (int) Math.Floor(initNum),
AddressTranslator.GetAreaByteLength(address.Area),
BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
DataType = typeof (byte),
Math.Ceiling(
AddressHelper.MapProtocalGetCountToAbstractByteCount(
preNum - (int) Math.Floor(initNum),
AddressTranslator.GetAreaByteLength(address.Area),
BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
DataType = typeof(byte),
OriginalAddresses = originalAddresses.ToList()
});
initNum = address.Address;
@@ -174,24 +173,25 @@ namespace Modbus.Net
Address = (int) Math.Floor(initNum),
GetCount =
(int)
Math.Ceiling(
AddressHelper.MapProtocalGetCountToAbstractByteCount(
preNum - (int) Math.Floor(initNum), AddressTranslator.GetAreaByteLength(area),
BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
DataType = typeof (byte),
Math.Ceiling(
AddressHelper.MapProtocalGetCountToAbstractByteCount(
preNum - (int) Math.Floor(initNum), AddressTranslator.GetAreaByteLength(area),
BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
DataType = typeof(byte),
OriginalAddresses = originalAddresses.ToList()
});
}
List<CommunicationUnit<TKey>> newAns = new List<CommunicationUnit<TKey>>();
var newAns = new List<CommunicationUnit<TKey>>();
foreach (var communicationUnit in ans)
{
double oldByteCount = communicationUnit.GetCount * BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName];
var oldByteCount = communicationUnit.GetCount *
BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName];
while (oldByteCount * BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName] >
MaxLength)
{
var newOriginalAddresses = new List<AddressUnit<TKey>>();
var oldOriginalAddresses = communicationUnit.OriginalAddresses.ToList();
var newByteCount = 0.0;
var newByteCount = 0.0;
do
{
var currentAddressUnit = oldOriginalAddresses.First();
@@ -200,7 +200,6 @@ namespace Modbus.Net
oldByteCount -= BigEndianValueHelper.Instance.ByteLength[currentAddressUnit.DataType.FullName];
newOriginalAddresses.Add(currentAddressUnit);
oldOriginalAddresses.RemoveAt(0);
} while (newByteCount < MaxLength);
var newCommunicationUnit = new CommunicationUnit<TKey>
{
@@ -212,9 +211,9 @@ namespace Modbus.Net
(int)
Math.Ceiling(newByteCount /
BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName]),
OriginalAddresses = newOriginalAddresses,
OriginalAddresses = newOriginalAddresses
};
newAns.Add(newCommunicationUnit);
}
communicationUnit.GetCount =
@@ -334,12 +333,12 @@ namespace Modbus.Net
EndUnit = continusAddress,
GapNumber =
(int)
Math.Ceiling(AddressHelper.MapProtocalCoordinateToAbstractCoordinate(
continusAddress.Address, preCommunicationUnit.Address,
AddressTranslator.GetAreaByteLength(continusAddress.Area)) -
preCommunicationUnit.GetCount*
BigEndianValueHelper.Instance.ByteLength[
preCommunicationUnit.DataType.FullName])
Math.Ceiling(AddressHelper.MapProtocalCoordinateToAbstractCoordinate(
continusAddress.Address, preCommunicationUnit.Address,
AddressTranslator.GetAreaByteLength(continusAddress.Area)) -
preCommunicationUnit.GetCount *
BigEndianValueHelper.Instance.ByteLength[
preCommunicationUnit.DataType.FullName])
};
addressesGaps.Add(gap);
}
@@ -350,12 +349,14 @@ namespace Modbus.Net
var jumpNumberInner = JumpNumber;
foreach (var orderedGap in orderedGaps)
{
if (orderedGap.GapNumber <= 0) continue;
if (orderedGap.GapNumber <= 0) continue;
var nowAddress = orderedGap.EndUnit;
var index = continusAddresses.IndexOf(nowAddress);
index--;
var preAddress = continusAddresses[index];
if (nowAddress.GetCount*BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName] + preAddress.GetCount*BigEndianValueHelper.Instance.ByteLength[preAddress.DataType.FullName] + orderedGap.GapNumber > MaxLength) continue;
if (nowAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName] +
preAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[preAddress.DataType.FullName] +
orderedGap.GapNumber > MaxLength) continue;
jumpNumberInner -= orderedGap.GapNumber;
if (jumpNumberInner < 0) break;
continusAddresses.RemoveAt(index);
@@ -367,11 +368,11 @@ namespace Modbus.Net
Address = preAddress.Address,
GetCount =
(int)
(preAddress.GetCount*BigEndianValueHelper.Instance.ByteLength[preAddress.DataType.FullName]) +
(preAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[preAddress.DataType.FullName]) +
orderedGap.GapNumber +
(int)
(nowAddress.GetCount*BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName]),
DataType = typeof (byte),
(nowAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName]),
DataType = typeof(byte),
OriginalAddresses = preAddress.OriginalAddresses.ToList().Union(nowAddress.OriginalAddresses)
};
continusAddresses.Insert(index, newAddress);
@@ -430,8 +431,9 @@ namespace Modbus.Net
var addressUnits = addresses as IList<AddressUnit<TKey>> ?? addresses.ToList();
var count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]);
return
new AddressCombinerNumericJump<TKey>((int) (count*Percentage/100.0), MaxLength, AddressTranslator).Combine(
addressUnits);
new AddressCombinerNumericJump<TKey>((int) (count * Percentage / 100.0), MaxLength, AddressTranslator)
.Combine(
addressUnits);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace Modbus.Net
public static double MapAbstractCoordinateToProtocalCoordinate(double abstractAddress, int startAddress,
double byteLength)
{
return abstractAddress/byteLength + startAddress;
return abstractAddress / byteLength + startAddress;
}
/// <summary>
@@ -30,7 +30,7 @@ namespace Modbus.Net
public static double MapProtocalCoordinateToAbstractCoordinate(double protocalAddress, int startAddress,
double byteLength)
{
return (protocalAddress - startAddress)*byteLength;
return (protocalAddress - startAddress) * byteLength;
}
/// <summary>
@@ -43,7 +43,7 @@ namespace Modbus.Net
public static double MapProtocalGetCountToAbstractByteCount(double protocalGetCount, double areaLength,
double byteLength)
{
return protocalGetCount*areaLength + byteLength;
return protocalGetCount * areaLength + byteLength;
}
/// <summary>
@@ -55,7 +55,7 @@ namespace Modbus.Net
/// <returns></returns>
public static double GetProtocalCoordinate(int address, int subAddress, double byteLength)
{
return address + subAddress*(0.125/byteLength);
return address + subAddress * (0.125 / byteLength);
}
/// <summary>
@@ -66,7 +66,7 @@ namespace Modbus.Net
/// <returns></returns>
public static double GetAbstractCoordinate(int address, int subAddress)
{
return address + subAddress*0.125;
return address + subAddress * 0.125;
}
/// <summary>
@@ -80,7 +80,7 @@ namespace Modbus.Net
double byteLength)
{
return protocalAddress +
BigEndianValueHelper.Instance.ByteLength[nextPositionBetweenType.FullName]/byteLength;
BigEndianValueHelper.Instance.ByteLength[nextPositionBetweenType.FullName] / byteLength;
}
/// <summary>

View File

@@ -11,14 +11,17 @@ namespace Modbus.Net
/// 地址区域的字符串描述
/// </summary>
public string AreaString { get; set; }
/// <summary>
/// 地址区域的数字描述
/// </summary>
public int Area { get; set; }
/// <summary>
/// 地址
/// </summary>
public int Address { get; set; }
/// <summary>
/// 子地址
/// </summary>
@@ -34,6 +37,7 @@ namespace Modbus.Net
/// 地址区域的编码
/// </summary>
public int Code { get; set; }
/// <summary>
/// 地址区域的单个地址占用的字节数
/// </summary>
@@ -79,26 +83,22 @@ namespace Modbus.Net
if (split.Length == 2)
{
if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2))
{
return new AddressDef
{
Area = num1,
Address = num2
};
}
}
else if (split.Length == 3)
{
if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2) &&
int.TryParse(split[3], out num3))
{
return new AddressDef
{
Area = num1,
Address = num2,
SubAddress = num3
};
}
}
throw new FormatException();
}

View File

@@ -5,7 +5,7 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// AsyncHelper Class
/// AsyncHelper Class
/// </summary>
public static class AsyncHelper
{

View File

@@ -28,7 +28,7 @@ namespace Modbus.Net
/// <summary>
/// Id
/// </summary>
/// </summary>
Id
}
@@ -54,7 +54,7 @@ namespace Modbus.Net
/// <summary>
/// Id
/// </summary>
/// </summary>
Id
}
@@ -80,7 +80,7 @@ namespace Modbus.Net
/// <summary>
/// Id
/// </summary>
/// </summary>
Id
}
@@ -125,7 +125,8 @@ namespace Modbus.Net
/// </summary>
/// <typeparam name="TKey">设备的Id类型</typeparam>
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
public abstract class BaseMachine<TKey, TUnitKey> : IMachineMethodData, IMachineProperty<TKey> where TKey : IEquatable<TKey>
public abstract class BaseMachine<TKey, TUnitKey> : IMachineMethodData, IMachineProperty<TKey>
where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
private readonly int _maxErrorCount = 3;
@@ -166,11 +167,6 @@ namespace Modbus.Net
private int ErrorCount { get; set; }
/// <summary>
/// 是否处于连接状态
/// </summary>
public bool IsConnected => BaseUtility.IsConnected;
/// <summary>
/// 地址编码器
/// </summary>
@@ -206,11 +202,6 @@ namespace Modbus.Net
/// </summary>
public IEnumerable<AddressUnit<TUnitKey>> GetAddresses { get; set; }
/// <summary>
/// 是否保持连接
/// </summary>
public bool KeepConnect { get; set; }
/// <summary>
/// 从站号
/// </summary>
@@ -221,31 +212,6 @@ namespace Modbus.Net
/// </summary>
public byte MasterAddress { get; set; }
/// <summary>
/// 设备的连接器
/// </summary>
public IUtilityProperty BaseUtility { get; protected set; }
/// <summary>
/// 设备的Id
/// </summary>
public TKey Id { get; set; }
/// <summary>
/// 设备所在工程的名称
/// </summary>
public string ProjectName { get; set; }
/// <summary>
/// 设备的名称
/// </summary>
public string MachineName { get; set; }
/// <summary>
/// 标识设备的连接关键字
/// </summary>
public string ConnectionToken => BaseUtility.ConnectionToken;
/// <summary>
/// 读取数据
/// </summary>
@@ -267,9 +233,7 @@ namespace Modbus.Net
var ans = new Dictionary<string, ReturnUnit>();
//检测并连接设备
if (!BaseUtility.IsConnected)
{
await BaseUtility.ConnectAsync();
}
//如果无法连接,终止
if (!BaseUtility.IsConnected) return null;
//遍历每一个实际向设备获取数据的连续地址
@@ -282,17 +246,17 @@ namespace Modbus.Net
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address,
communicateAddress.SubAddress),
(int)
Math.Ceiling(communicateAddress.GetCount*
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName]));
Math.Ceiling(communicateAddress.GetCount *
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName]));
//如果没有数据,终止
if (datas == null || (datas.Length != 0 && datas.Length <
(int)
Math.Ceiling(communicateAddress.GetCount*
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName])))
if (datas == null || datas.Length != 0 && datas.Length <
(int)
Math.Ceiling(communicateAddress.GetCount *
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName]))
return null;
@@ -300,13 +264,13 @@ namespace Modbus.Net
{
//字节坐标的位置
var localPos = AddressHelper.MapProtocalCoordinateToAbstractCoordinate(address.Address,
communicateAddress.Address,
AddressTranslator.GetAreaByteLength(communicateAddress.Area)) +
address.SubAddress*0.125;
communicateAddress.Address,
AddressTranslator.GetAreaByteLength(communicateAddress.Area)) +
address.SubAddress * 0.125;
//字节坐标的主地址位置
var localMainPos = (int) localPos;
//字节坐标的子地址位置
var localSubPos = (int) ((localPos - localMainPos)*8);
var localSubPos = (int) ((localPos - localMainPos) * 8);
//根据类型选择返回结果的键是通讯标识还是地址
string key;
@@ -341,16 +305,12 @@ namespace Modbus.Net
//如果没有数据返回空
if (datas.Length == 0)
{
ans.Add(key, new ReturnUnit
{
PlcValue = null,
UnitExtend = address.UnitExtend
});
}
else
{
//将获取的数据和对应的通讯标识对应
ans.Add(key,
new ReturnUnit
{
@@ -358,17 +318,14 @@ namespace Modbus.Net
Convert.ToDouble(
ValueHelper.GetInstance(BaseUtility.Endian)
.GetValue(datas, ref localMainPos, ref localSubPos,
address.DataType))*address.Zoom,
address.DataType)) * address.Zoom,
UnitExtend = address.UnitExtend
});
}
}
}
//如果不保持连接,断开连接
if (!KeepConnect)
{
BaseUtility.Disconnect();
}
//返回数据
if (ans.All(p => p.Value.PlcValue == null)) ans = null;
ErrorCount = 0;
@@ -379,9 +336,7 @@ namespace Modbus.Net
Console.WriteLine(ConnectionToken + " " + e.Message);
ErrorCount++;
if (ErrorCount >= _maxErrorCount)
{
Disconnect();
}
return null;
}
}
@@ -409,9 +364,7 @@ namespace Modbus.Net
{
//检测并连接设备
if (!BaseUtility.IsConnected)
{
await BaseUtility.ConnectAsync();
}
//如果设备无法连接,终止
if (!BaseUtility.IsConnected) return false;
var addresses = new List<AddressUnit<TUnitKey>>();
@@ -428,8 +381,8 @@ namespace Modbus.Net
GetAddresses.SingleOrDefault(
p =>
AddressFormater.FormatAddress(p.Area, p.Address, p.SubAddress) == value.Key ||
(p.DataType != typeof (bool) &&
AddressFormater.FormatAddress(p.Area, p.Address) == value.Key));
p.DataType != typeof(bool) &&
AddressFormater.FormatAddress(p.Area, p.Address) == value.Key);
break;
}
case MachineSetDataType.CommunicationTag:
@@ -478,10 +431,11 @@ namespace Modbus.Net
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
communicateAddress.Address);
var datasReturn = await BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<byte[]>>("GetDatasAsync",
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
(int)
Math.Ceiling(communicateAddress.GetCount*
var datasReturn =
await BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<byte[]>>("GetDatasAsync",
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
(int)
Math.Ceiling(communicateAddress.GetCount *
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName]));
@@ -492,9 +446,9 @@ namespace Modbus.Net
//如果没有数据,终止
if (datas == null || datas.Length <
(int)
Math.Ceiling(communicateAddress.GetCount*
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName]))
Math.Ceiling(communicateAddress.GetCount *
BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName]))
return false;
foreach (var addressUnit in communicateAddress.OriginalAddresses)
@@ -503,21 +457,21 @@ namespace Modbus.Net
var byteCount =
AddressHelper.MapProtocalGetCountToAbstractByteCount(
addressUnit.Address - communicateAddress.Address +
addressUnit.SubAddress*0.125/
addressUnit.SubAddress * 0.125 /
AddressTranslator.GetAreaByteLength(communicateAddress.Area),
AddressTranslator.GetAreaByteLength(communicateAddress.Area), 0);
//字节坐标主地址
var mainByteCount = (int) byteCount;
//字节坐标自地址
var localByteCount = (int) ((byteCount - (int) byteCount)*8);
var localByteCount = (int) ((byteCount - (int) byteCount) * 8);
//协议坐标地址
var localPos = byteCount/AddressTranslator.GetAreaByteLength(communicateAddress.Area);
var localPos = byteCount / AddressTranslator.GetAreaByteLength(communicateAddress.Area);
//协议坐标子地址
var subPos =
(int)
((localPos - (int) localPos)/
(0.125/AddressTranslator.GetAreaByteLength(communicateAddress.Area)));
((localPos - (int) localPos) /
(0.125 / AddressTranslator.GetAreaByteLength(communicateAddress.Area)));
//协议主地址字符串
var address = AddressFormater.FormatAddress(communicateAddress.Area,
communicateAddress.Address + (int) localPos, subPos);
@@ -536,7 +490,7 @@ namespace Modbus.Net
//获取要写入的值
value =
values.SingleOrDefault(
p => p.Key == address || (address2 != null && p.Key == address2));
p => p.Key == address || address2 != null && p.Key == address2);
break;
}
case MachineSetDataType.CommunicationTag:
@@ -561,22 +515,20 @@ namespace Modbus.Net
}
}
//将要写入的值加入队列
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
var data = Convert.ChangeType(value.Value / addressUnit.Zoom, dataType);
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
return false;
}
//写入数据
await
BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<bool>>("SetDatasAsync",addressStart,
BaseUtility.InvokeUtilityMethod<IUtilityMethodData, Task<bool>>("SetDatasAsync", addressStart,
valueHelper.ByteArrayToObjectArray(datas,
new KeyValuePair<Type, int>(communicateAddress.DataType, communicateAddress.GetCount)));
}
//如果不保持连接,断开连接
if (!KeepConnect)
{
BaseUtility.Disconnect();
}
}
catch (Exception e)
{
@@ -587,22 +539,39 @@ namespace Modbus.Net
}
/// <summary>
/// 通过Id获取数据字段定义
/// 是否处于连接状态
/// </summary>
/// <param name="addressUnitId">数据字段Id</param>
/// <returns>数据字段</returns>
public AddressUnit<TUnitKey> GetAddressUnitById(TUnitKey addressUnitId)
{
try
{
return GetAddresses.SingleOrDefault(p => p.Id.Equals(addressUnitId));
}
catch (Exception)
{
Console.WriteLine("Id重复请检查");
return null;
}
}
public bool IsConnected => BaseUtility.IsConnected;
/// <summary>
/// 是否保持连接
/// </summary>
public bool KeepConnect { get; set; }
/// <summary>
/// 设备的连接器
/// </summary>
public IUtilityProperty BaseUtility { get; protected set; }
/// <summary>
/// 设备的Id
/// </summary>
public TKey Id { get; set; }
/// <summary>
/// 设备所在工程的名称
/// </summary>
public string ProjectName { get; set; }
/// <summary>
/// 设备的名称
/// </summary>
public string MachineName { get; set; }
/// <summary>
/// 标识设备的连接关键字
/// </summary>
public string ConnectionToken => BaseUtility.ConnectionToken;
/// <summary>
/// 调用Machine中的方法
@@ -617,24 +586,14 @@ namespace Modbus.Net
{
if (this is TMachineMethod)
{
Type t = typeof(TMachineMethod);
object returnValue = t.GetRuntimeMethod(methodName, parameters.Select(p => p.GetType()).ToArray())
var t = typeof(TMachineMethod);
var returnValue = t.GetRuntimeMethod(methodName, parameters.Select(p => p.GetType()).ToArray())
.Invoke(this, parameters);
return (TReturnType) returnValue;
}
throw new InvalidCastException($"Machine未实现{typeof(TMachineMethod).Name}的接口");
}
/// <summary>
/// 获取Utility
/// </summary>
/// <typeparam name="TUtilityMethod">Utility实现的接口名称</typeparam>
/// <returns></returns>
public TUtilityMethod GetUtility<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod
{
return BaseUtility as TUtilityMethod;
}
/// <summary>
/// 连接设备
/// </summary>
@@ -670,6 +629,34 @@ namespace Modbus.Net
{
return Id.ToString();
}
/// <summary>
/// 通过Id获取数据字段定义
/// </summary>
/// <param name="addressUnitId">数据字段Id</param>
/// <returns>数据字段</returns>
public AddressUnit<TUnitKey> GetAddressUnitById(TUnitKey addressUnitId)
{
try
{
return GetAddresses.SingleOrDefault(p => p.Id.Equals(addressUnitId));
}
catch (Exception)
{
Console.WriteLine("Id重复请检查");
return null;
}
}
/// <summary>
/// 获取Utility
/// </summary>
/// <typeparam name="TUtilityMethod">Utility实现的接口名称</typeparam>
/// <returns></returns>
public TUtilityMethod GetUtility<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod
{
return BaseUtility as TUtilityMethod;
}
}
internal class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
@@ -832,7 +819,7 @@ namespace Modbus.Net
/// <returns>是否一致</returns>
public bool Equals(AddressUnit<TKey> other)
{
return (Area.ToUpper() == other.Area.ToUpper() && Address == other.Address) || Id.Equals(other.Id);
return Area.ToUpper() == other.Area.ToUpper() && Address == other.Address || Id.Equals(other.Id);
}
}
@@ -915,6 +902,6 @@ namespace Modbus.Net
/// <summary>
/// Id
/// </summary>
TKey Id { get; set; }
TKey Id { get; set; }
}
}

View File

@@ -20,7 +20,7 @@ namespace Modbus.Net
return (from getValue in getValues
where getValue.Value.PlcValue != null
select new KeyValuePair<string, double>(getValue.Key, getValue.Value.PlcValue.Value)).ToDictionary(
p => p.Key, p => p.Value);
p => p.Key, p => p.Value);
}
}
}

View File

@@ -13,7 +13,8 @@ namespace Modbus.Net
/// <summary>
/// 构造器
/// </summary>
protected BaseProtocal(byte slaveAddress, byte masterAddress, Endian endian) : base(slaveAddress, masterAddress, endian)
protected BaseProtocal(byte slaveAddress, byte masterAddress, Endian endian)
: base(slaveAddress, masterAddress, endian)
{
}
@@ -25,13 +26,9 @@ namespace Modbus.Net
public override async Task<byte[]> SendReceiveAsync(params object[] content)
{
if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
{
await ConnectAsync();
}
if (ProtocalLinker != null)
{
return await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(Endian, content));
}
return null;
}
}
@@ -39,7 +36,8 @@ namespace Modbus.Net
/// <summary>
/// 基本协议
/// </summary>
public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit> : IProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit> :
IProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
{
/// <summary>
/// 构造器
@@ -56,11 +54,12 @@ namespace Modbus.Net
/// 协议的端格式
/// </summary>
protected Endian Endian { get; set; }
/// <summary>
/// 从站地址
/// </summary>
public byte SlaveAddress { get; set; }
/// <summary>
/// 主站地址
/// </summary>
@@ -82,12 +81,10 @@ namespace Modbus.Net
{
var protocalName = type.FullName;
if (Protocals.ContainsKey(protocalName))
{
return Protocals[protocalName];
}
//自动寻找存在的协议并将其加载
var protocalUnit =
Activator.CreateInstance(type.GetTypeInfo().Assembly.GetType(protocalName)) as TProtocalUnit;
Activator.CreateInstance(type.GetTypeInfo().Assembly.GetType(protocalName)) as TProtocalUnit;
if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容");
protocalUnit.Endian = Endian;
Register(protocalUnit);
@@ -100,16 +97,6 @@ namespace Modbus.Net
/// </summary>
protected Dictionary<string, TProtocalUnit> Protocals { get; }
/// <summary>
/// 注册一个协议
/// </summary>
/// <param name="linkProtocal">需要注册的协议</param>
protected void Register(TProtocalUnit linkProtocal)
{
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
@@ -121,18 +108,6 @@ namespace Modbus.Net
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
public virtual T SendReceive<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct
{
return AsyncHelper.RunSync(() => SendReceiveAsync<T>(unit, content));
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
@@ -141,40 +116,9 @@ namespace Modbus.Net
/// <returns>输出信息的结构化描述</returns>
public virtual async Task<IOutputStruct> SendReceiveAsync(TProtocalUnit unit, IInputStruct content)
{
return await SendReceiveAsync<IOutputStruct>(unit, content);
return await SendReceiveAsync<IOutputStruct>(unit, content);
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
public virtual async Task<T> SendReceiveAsync<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct
{
var t = 0;
var formatContent = unit.Format(content);
if (formatContent != null)
{
TParamOut receiveContent;
//如果为特别处理协议的话,跳过协议扩展收缩
if (unit is ISpecialProtocalUnit)
{
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
}
else
{
receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent);
}
if (receiveContent != null)
{
return unit.Unformat<T>(receiveContent, ref t);
}
}
return null;
}
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
@@ -195,6 +139,54 @@ namespace Modbus.Net
throw new NotImplementedException();
}
/// <summary>
/// 注册一个协议
/// </summary>
/// <param name="linkProtocal">需要注册的协议</param>
protected void Register(TProtocalUnit linkProtocal)
{
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
public virtual T SendReceive<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct
{
return AsyncHelper.RunSync(() => SendReceiveAsync<T>(unit, content));
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
public virtual async Task<T> SendReceiveAsync<T>(TProtocalUnit unit, IInputStruct content)
where T : class, IOutputStruct
{
var t = 0;
var formatContent = unit.Format(content);
if (formatContent != null)
{
TParamOut receiveContent;
//如果为特别处理协议的话,跳过协议扩展收缩
if (unit is ISpecialProtocalUnit)
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
else
receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent);
if (receiveContent != null)
return unit.Unformat<T>(receiveContent, ref t);
}
return null;
}
/// <summary>
/// 协议连接开始
/// </summary>
@@ -214,9 +206,7 @@ namespace Modbus.Net
public virtual bool Disconnect()
{
if (ProtocalLinker != null)
{
return ProtocalLinker.Disconnect();
}
return false;
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
/// <summary>
@@ -13,10 +12,12 @@ public enum Endian
/// 小端
/// </summary>
LittleEndianLsb,
/// <summary>
/// 大端-小端位
/// </summary>
BigEndianLsb,
/// <summary>
/// 大端-大端位
/// </summary>
@@ -26,7 +27,7 @@ public enum Endian
namespace Modbus.Net
{
/// <summary>
/// 基础Api入口
/// 基础Api入口
/// </summary>
public abstract class BaseUtility : BaseUtility<byte[], byte[], ProtocalUnit>
{
@@ -35,14 +36,14 @@ namespace Modbus.Net
/// </summary>
protected BaseUtility(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress)
{
}
}
/// <summary>
/// 基础Api入口
/// 基础Api入口
/// </summary>
public abstract class BaseUtility<TParamIn, TParamOut, TProtocalUnit> : IUtilityProperty, IUtilityMethodData where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
public abstract class BaseUtility<TParamIn, TParamOut, TProtocalUnit> : IUtilityProperty, IUtilityMethodData
where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
{
/// <summary>
/// 协议收发主体
@@ -68,37 +69,12 @@ namespace Modbus.Net
/// 从站号
/// </summary>
public byte SlaveAddress { get; set; }
/// <summary>
/// 主站号
/// </summary>
public byte MasterAddress { get; set; }
/// <summary>
/// 协议是否遵循小端格式
/// </summary>
public abstract Endian Endian { get; }
/// <summary>
/// 设备是否已经连接
/// </summary>
public bool IsConnected => Wrapper?.ProtocalLinker != null && Wrapper.ProtocalLinker.IsConnected;
/// <summary>
/// 标识设备的连接关键字
/// </summary>
public string ConnectionToken => Wrapper?.ProtocalLinker == null ? ConnectionString : Wrapper.ProtocalLinker.ConnectionToken;
/// <summary>
/// 地址翻译器
/// </summary>
public AddressTranslator AddressTranslator { get; set; }
/// <summary>
/// 设置连接类型
/// </summary>
/// <param name="connectionType">连接类型</param>
public abstract void SetConnectionType(int connectionType);
/// <summary>
/// 获取数据
/// </summary>
@@ -144,17 +120,16 @@ namespace Modbus.Net
var typeName = getTypeAndCount.Key.FullName;
var bCount = BigEndianValueHelper.Instance.ByteLength[typeName];
var getReturnValue = await GetDatasAsync(startAddress,
(int) Math.Ceiling(bCount*getTypeAndCount.Value));
(int) Math.Ceiling(bCount * getTypeAndCount.Value));
var getBytes = getReturnValue;
return ValueHelper.GetInstance(Endian).ByteArrayToObjectArray(getBytes, getTypeAndCount);
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// 获取数据
/// </summary>
@@ -181,7 +156,7 @@ namespace Modbus.Net
try
{
var getBytes = await GetDatasAsync(startAddress,
new KeyValuePair<Type, int>(typeof (T), getByteCount));
new KeyValuePair<Type, int>(typeof(T), getByteCount));
return ValueHelper.GetInstance(Endian).ObjectArrayToDestinationArray<T>(getBytes);
}
catch (Exception)
@@ -203,7 +178,7 @@ namespace Modbus.Net
AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getTypeAndCountList));
}
/// <summary>GetEndian
/// <summary>
/// 获取数据
/// </summary>
/// <param name="startAddress">开始地址</param>
@@ -219,7 +194,7 @@ namespace Modbus.Net
from getTypeAndCount in translateTypeAndCount
let typeName = getTypeAndCount.Key.FullName
let bCount = BigEndianValueHelper.Instance.ByteLength[typeName]
select (int) Math.Ceiling(bCount*getTypeAndCount.Value)).Sum();
select (int) Math.Ceiling(bCount * getTypeAndCount.Value)).Sum();
var getReturnValue = await GetDatasAsync(startAddress, bAllCount);
var getBytes = getReturnValue;
return ValueHelper.GetInstance(Endian).ByteArrayToObjectArray(getBytes, translateTypeAndCount);
@@ -249,6 +224,27 @@ namespace Modbus.Net
/// <returns>是否设置成功</returns>
public abstract Task<bool> SetDatasAsync(string startAddress, object[] setContents);
/// <summary>
/// 协议是否遵循小端格式
/// </summary>
public abstract Endian Endian { get; }
/// <summary>
/// 设备是否已经连接
/// </summary>
public bool IsConnected => Wrapper?.ProtocalLinker != null && Wrapper.ProtocalLinker.IsConnected;
/// <summary>
/// 标识设备的连接关键字
/// </summary>
public string ConnectionToken
=> Wrapper?.ProtocalLinker == null ? ConnectionString : Wrapper.ProtocalLinker.ConnectionToken;
/// <summary>
/// 地址翻译器
/// </summary>
public AddressTranslator AddressTranslator { get; set; }
/// <summary>
/// 连接设备
/// </summary>
@@ -289,13 +285,19 @@ namespace Modbus.Net
{
if (this is TUtilityMethod)
{
Type t = typeof(TUtilityMethod);
object returnValue = t.GetRuntimeMethod(methodName, parameters.Select(p => p.GetType()).ToArray(), false)
var t = typeof(TUtilityMethod);
var returnValue = t.GetRuntimeMethod(methodName, parameters.Select(p => p.GetType()).ToArray(), false)
.Invoke(this, parameters);
return (TReturnType)returnValue;
return (TReturnType) returnValue;
}
throw new InvalidCastException($"Utility未实现{typeof(TUtilityMethod).Name}的接口");
}
/// <summary>
/// 设置连接类型
/// </summary>
/// <param name="connectionType">连接类型</param>
public abstract void SetConnectionType(int connectionType);
}
/// <summary>
@@ -312,6 +314,7 @@ namespace Modbus.Net
/// 设备是否已经连接
/// </summary>
bool IsConnected { get; }
/// <summary>
/// 标识设备的连接关键字
/// </summary>

View File

@@ -14,16 +14,15 @@ namespace Modbus.Net
{
private static Crc16 _crc16;
private Crc16()
{
}
/// <summary>
/// CRC验证表
/// </summary>
private byte[] crc_table = new byte[512];
private Crc16()
{
}
/// <summary>
/// 获取校验工具实例
/// </summary>
@@ -31,9 +30,7 @@ namespace Modbus.Net
public static Crc16 GetInstance()
{
if (_crc16 == null)
{
_crc16 = new Crc16();
}
return _crc16;
}
@@ -51,7 +48,9 @@ namespace Modbus.Net
CRC = 0xFFFF;
//set all 1
if (Len <= 0)
{
CRC = 0;
}
else
{
Len--;
@@ -59,13 +58,10 @@ namespace Modbus.Net
{
CRC = CRC ^ message[IX];
for (IY = 0; IY <= 7; IY++)
{
if ((CRC & 1) != 0)
CRC = (CRC >> 1) ^ 0xA001;
else
CRC = CRC >> 1;
//
}
}
}
Rcvbuf[1] = (byte) ((CRC & 0xff00) >> 8); //高位置
@@ -91,9 +87,7 @@ namespace Modbus.Net
Array.Copy(byteframe, 0, byteArr, 0, byteArr.Length);
GetCRC(byteArr, ref recvbuff);
if (recvbuff[0] == byteframe[byteframe.Length - 2] && recvbuff[1] == byteframe[byteframe.Length - 1])
{
return true;
}
return false;
}
@@ -121,7 +115,7 @@ namespace Modbus.Net
for (var t = 0; t <= hexArray.GetUpperBound(0); t++)
{
if ((hexArray[t] >= 48) && (hexArray[t] <= 57))
if (hexArray[t] >= 48 && hexArray[t] <= 57)
decNum = hexArray[t] - 48;
@@ -130,7 +124,7 @@ namespace Modbus.Net
if (msb)
{
decNumMSB = decNum*16;
decNumMSB = decNum * 16;
msb = false;
}
else
@@ -154,12 +148,11 @@ namespace Modbus.Net
for (i = 0; decByteTotal > 0; i++)
{
//b = Convert.ToInt32(System.Math.Pow(16.0, i));
var a = decByteTotal%16;
var a = decByteTotal % 16;
decByteTotal /= 16;
if (a <= 9)
hexByte = a.ToString();
else
{
switch (a)
{
case 10:
@@ -181,7 +174,6 @@ namespace Modbus.Net
hexByte = "F";
break;
}
}
hexTotal = string.Concat(hexByte, hexTotal);
}
return hexTotal == checkString;
@@ -200,15 +192,12 @@ namespace Modbus.Net
{
byte sum = 0;
foreach (var b in code)
{
sum += b;
}
sum = (byte)(~sum + 1); //取反+1
sum = (byte) (~sum + 1); //取反+1
var lrc = sum.ToString("X2");
return lrc;
}
#endregion
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net
@@ -11,7 +8,6 @@ namespace Modbus.Net
/// </summary>
public interface IMachineMethod
{
}
/// <summary>

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Modbus.Net
{
@@ -12,7 +8,8 @@ namespace Modbus.Net
/// <typeparam name="TParamIn">向Connector传入的类型</typeparam>
/// <typeparam name="TParamOut">从Connector返回的类型</typeparam>
/// <typeparam name="TProtocalUnit">协议单元的类型</typeparam>
public interface IProtocal<TParamIn, TParamOut, in TProtocalUnit> where TProtocalUnit : IProtocalFormatting<TParamIn, TParamOut>
public interface IProtocal<TParamIn, TParamOut, in TProtocalUnit>
where TProtocalUnit : IProtocalFormatting<TParamIn, TParamOut>
{
/// <summary>
/// 发送协议内容并接收,一般方法
@@ -44,4 +41,4 @@ namespace Modbus.Net
/// <returns>输出信息的结构化描述</returns>
Task<IOutputStruct> SendReceiveAsync(TProtocalUnit unit, IInputStruct content);
}
}
}

View File

@@ -5,7 +5,6 @@
/// </summary>
public interface IProtocalFormatting : IProtocalFormatting<byte[], byte[]>
{
}
/// <summary>
@@ -38,12 +37,12 @@
IOutputStruct Unformat(TParamOut messageBytes, ref int pos);
/// <summary>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
/// <returns>结构化的输出数据</returns>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
/// <returns>结构化的输出数据</returns>
T Unformat<T>(TParamOut messageBytes, ref int pos) where T : class, IOutputStruct;
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Modbus.Net
{
@@ -62,4 +58,4 @@ namespace Modbus.Net
/// <returns>缩减后的协议内容</returns>
TParamOut BytesDecact(TParamOut content);
}
}
}

View File

@@ -5,7 +5,6 @@
/// </summary>
public interface IProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend<byte[], byte[]>
{
}
/// <summary>

View File

@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net
@@ -11,7 +9,6 @@ namespace Modbus.Net
/// </summary>
public interface IUtilityMethod
{
}
/// <summary>
@@ -19,6 +16,14 @@ namespace Modbus.Net
/// </summary>
public interface IUtilityMethodData : IUtilityMethod
{
/// <summary>
/// 获取数据
/// </summary>
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取字节数个数</param>
/// <returns>接收到的byte数据</returns>
byte[] GetDatas(string startAddress, int getByteCount);
/// <summary>
/// 获取数据
/// </summary>
@@ -69,7 +74,7 @@ namespace Modbus.Net
/// <returns>获取数据的对象数组,请强制转换成相应类型</returns>
object[] GetDatas(string startAddress, IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList);
/// <summary>GetEndian
/// <summary>
/// 获取数据
/// </summary>
/// <param name="startAddress">开始地址</param>
@@ -94,11 +99,10 @@ namespace Modbus.Net
}
/// <summary>
/// Utility的时间读写接口
/// Utility的时间读写接口
/// </summary>
public interface IUtilityMethodTime : IUtilityMethod
{
/// <summary>
/// 获取PLC时间
/// </summary>
@@ -111,6 +115,5 @@ namespace Modbus.Net
/// <param name="setTime">设置PLC时间</param>
/// <returns>设置是否成功</returns>
Task<bool> SetTimeAsync(DateTime setTime);
}
}
}

View File

@@ -45,7 +45,8 @@ namespace Modbus.Net
{
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
var bytesExtend =
Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend")) as
Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend"))
as
IProtocalLinkerBytesExtend;
return bytesExtend?.BytesExtend(content);
}
@@ -59,7 +60,8 @@ namespace Modbus.Net
{
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
var bytesExtend =
Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend")) as
Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend"))
as
IProtocalLinkerBytesExtend;
return bytesExtend?.BytesDecact(content);
}
@@ -85,33 +87,6 @@ namespace Modbus.Net
/// </summary>
public bool IsConnected => BaseConnector != null && BaseConnector.IsConnected;
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public bool Connect()
{
return BaseConnector.Connect();
}
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public async Task<bool> ConnectAsync()
{
return await BaseConnector.ConnectAsync();
}
/// <summary>
/// 断开设备
/// </summary>
/// <returns>设备是否断开成功</returns>
public bool Disconnect()
{
return BaseConnector.Disconnect();
}
/// <summary>
/// 发送并接收数据
/// </summary>
@@ -192,5 +167,32 @@ namespace Modbus.Net
{
throw new NotImplementedException();
}
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public bool Connect()
{
return BaseConnector.Connect();
}
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public async Task<bool> ConnectAsync()
{
return await BaseConnector.ConnectAsync();
}
/// <summary>
/// 断开设备
/// </summary>
/// <returns>设备是否断开成功</returns>
public bool Disconnect()
{
return BaseConnector.Disconnect();
}
}
}

View File

@@ -7,7 +7,6 @@ namespace Modbus.Net
/// </summary>
public abstract class ProtocalUnit : ProtocalUnit<byte[], byte[]>
{
}
/// <summary>
@@ -20,12 +19,12 @@ namespace Modbus.Net
/// </summary>
public Endian Endian { get; set; } = Endian.BigEndianLsb;
/// <summary>
/// 从输入结构格式化
/// </summary>s
/// <param name="message">结构化的输入数据</param>
/// <returns>格式化后的字节流</returns>
public abstract TParamIn Format(IInputStruct message);
/// <summary>
/// 从输入结构格式化
/// </summary>
/// <param name="message">结构化的输入数据</param>
/// <returns>格式化后的字节流</returns>
public abstract TParamIn Format(IInputStruct message);
/// <summary>
/// 从对象的参数数组格式化
@@ -37,25 +36,25 @@ namespace Modbus.Net
return TranslateContent(Endian, message);
}
/// <summary>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <returns>结构化的输出数据</returns>
public abstract IOutputStruct Unformat(TParamOut messageBytes, ref int pos);
/// <summary>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <returns>结构化的输出数据</returns>
public abstract IOutputStruct Unformat(TParamOut messageBytes, ref int pos);
/// <summary>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
/// <returns>结构化的输出数据</returns>
public T Unformat<T>(TParamOut messageBytes, ref int pos) where T : class, IOutputStruct
{
return Unformat(messageBytes, ref pos) as T;
}
/// <summary>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
/// <returns>结构化的输出数据</returns>
public T Unformat<T>(TParamOut messageBytes, ref int pos) where T : class, IOutputStruct
{
return Unformat(messageBytes, ref pos) as T;
}
/// <summary>
/// 转换静态方法,把对象数组转换为字节数组。
@@ -64,8 +63,8 @@ namespace Modbus.Net
/// <param name="contents">对象数组</param>
/// <returns>字节数组</returns>
public static byte[] TranslateContent(Endian endian, params object[] contents)
{
return ValueHelper.GetInstance(endian).ObjectArrayToByteArray(contents);
{
return ValueHelper.GetInstance(endian).ObjectArrayToByteArray(contents);
}
}

View File

@@ -17,7 +17,6 @@ namespace Modbus.Net
/// </summary>
public class DataReturnDef : DataReturnDef<string>
{
}
/// <summary>
@@ -29,6 +28,7 @@ namespace Modbus.Net
/// 设备的Id
/// </summary>
public TMachineKey MachineId { get; set; }
/// <summary>
/// 返回的数据值
/// </summary>
@@ -141,7 +141,7 @@ namespace Modbus.Net
TryExecuteTask(item);
}
}
// We're done processing items on the current thread
// We're done processing items on the current thread
finally
{
_currentThreadIsProcessingItems = false;
@@ -176,7 +176,10 @@ namespace Modbus.Net
/// </returns>
protected sealed override bool TryDequeue(Task task)
{
lock (_tasks) return _tasks.Remove(task);
lock (_tasks)
{
return _tasks.Remove(task);
}
}
/// <summary>
@@ -213,7 +216,7 @@ namespace Modbus.Net
private readonly TaskFactory _tasks;
/// <summary>
/// 构造函数
/// 构造函数
/// </summary>
/// <param name="machine">设备</param>
/// <param name="taskFactory">任务工厂</param>
@@ -278,11 +281,9 @@ namespace Modbus.Net
/// <returns>是否停止成功</returns>
public bool StopAllTimers()
{
bool ans = true;
var ans = true;
foreach (var task in TasksWithTimer)
{
ans = ans && StopTimer(task.Name);
}
return ans;
}
@@ -308,11 +309,9 @@ namespace Modbus.Net
/// <returns>是否暂停成功</returns>
public bool PauseAllTimers()
{
bool ans = true;
var ans = true;
foreach (var task in TasksWithTimer)
{
ans = ans && PauseTimer(task.Name);
}
return ans;
}
@@ -338,11 +337,9 @@ namespace Modbus.Net
/// <returns>是否恢复成功</returns>
public bool ContinueAllTimers()
{
bool ans = true;
var ans = true;
foreach (var task in TasksWithTimer)
{
ans = ans && ContinueTimer(task.Name);
}
return ans;
}
@@ -427,7 +424,7 @@ namespace Modbus.Net
return new DataReturnDef
{
MachineId = machine.GetMachineIdString(),
ReturnValues = ans,
ReturnValues = ans
};
};
Params = null;
@@ -436,7 +433,7 @@ namespace Modbus.Net
TimerTime = getCycle;
}
}
/// <summary>
/// 写入数据的预定义任务
/// </summary>
@@ -461,7 +458,7 @@ namespace Modbus.Net
MachineSetDataType.CommunicationTag).WithCancellation(cts.Token));
return ans;
};
Params = new object[]{values};
Params = new object[] {values};
Return = returnFunc;
}
}
@@ -472,46 +469,51 @@ namespace Modbus.Net
/// <typeparam name="TInterType">任务返回值的类型</typeparam>
public class TaskItem<TInterType> : ITaskItem, IEquatable<TaskItem<TInterType>>
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 定时器
/// </summary>
private Timer Timer { get; set; }
/// <summary>
/// 定时器的时间
/// </summary>
public int TimerTime { get; set; }
/// <summary>
/// 离线定时器
/// </summary>
private Timer TimerDisconnected { get; set; }
/// <summary>
/// 离线定时器的时间
/// </summary>
public int TimerDisconnectedTime { get; set; }
/// <summary>
/// 执行的任务
/// </summary>
public Func<IMachinePropertyWithoutKey, TaskFactory, object[], Task<TInterType>> Invoke { get; set; }
/// <summary>
/// 检测设备的在线状态
/// </summary>
internal Func<bool> DetectConnected { get; set; }
internal Func<bool> DetectConnected { get; set; }
/// <summary>
/// 任务执行的参数
/// </summary>
public object[] Params { get; set; }
/// <summary>
/// 返回值的处理函数
/// </summary>
public Action<TInterType> Return { get; set; }
/// <summary>
/// 获取设备
/// </summary>
internal Func<IMachinePropertyWithoutKey> GetMachine { get; set; }
/// <summary>
/// 获取任务工厂
/// </summary>
@@ -527,6 +529,11 @@ namespace Modbus.Net
return Name == other?.Name;
}
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 启动定时器
/// </summary>
@@ -537,6 +544,17 @@ namespace Modbus.Net
return true;
}
/// <summary>
/// 停止定时器
/// </summary>
/// <returns></returns>
public bool StopTimer()
{
DeactivateTimer();
DeactivateTimerDisconnected();
return true;
}
/// <summary>
/// 激活定时器
/// </summary>
@@ -545,7 +563,7 @@ namespace Modbus.Net
Timer = new Timer(async state =>
{
if (!DetectConnected()) TimerChangeToDisconnect();
var ans = await Invoke(GetMachine(),GetTaskFactory(),Params);
var ans = await Invoke(GetMachine(), GetTaskFactory(), Params);
Return?.Invoke(ans);
}, null, 0, TimerTime);
}
@@ -601,17 +619,6 @@ namespace Modbus.Net
ActivateTimerDisconnected();
return true;
}
/// <summary>
/// 停止定时器
/// </summary>
/// <returns></returns>
public bool StopTimer()
{
DeactivateTimer();
DeactivateTimerDisconnected();
return true;
}
}
/// <summary>
@@ -719,16 +726,6 @@ namespace Modbus.Net
_tasks = new TaskFactory(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
}
/// <summary>
/// 强制停止所有正在运行的任务
/// </summary>
public void TaskHalt()
{
_cts.Cancel();
_cts = new CancellationTokenSource();
_tasks = new TaskFactory(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
}
/// <summary>
/// 保持连接
/// </summary>
@@ -742,9 +739,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
machine.Machine.KeepConnect = _keepConnect;
}
}
ContinueTimerAll();
}
@@ -791,6 +786,7 @@ namespace Modbus.Net
/// 设备读数据的关键字
/// </summary>
public MachineGetDataType GetDataType { get; set; }
/// <summary>
/// 设备写数据的关键字
/// </summary>
@@ -810,6 +806,16 @@ namespace Modbus.Net
}
}
/// <summary>
/// 强制停止所有正在运行的任务
/// </summary>
public void TaskHalt()
{
_cts.Cancel();
_cts = new CancellationTokenSource();
_tasks = new TaskFactory(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
}
/// <summary>
/// 添加一台设备
/// </summary>
@@ -834,9 +840,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in machines)
{
AddMachine(machine);
}
}
}
@@ -922,7 +926,7 @@ namespace Modbus.Net
{
lock (_machines)
{
_machines.RemoveWhere(p=>p.Machine.Equals(machine));
_machines.RemoveWhere(p => p.Machine.Equals(machine));
}
}
@@ -938,9 +942,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
ans &= machine.InvokeTimer(item);
}
}
return ans;
}
@@ -955,9 +957,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
ans &= machine.StopAllTimers();
}
}
return ans;
}
@@ -973,9 +973,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
ans &= machine.StopTimer(taskItemName);
}
}
return ans;
}
@@ -990,9 +988,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
ans &= machine.PauseAllTimers();
}
}
return ans;
}
@@ -1008,9 +1004,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
ans &= machine.PauseTimer(taskItemName);
}
}
return ans;
}
@@ -1025,9 +1019,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
ans &= machine.ContinueAllTimers();
}
}
return ans;
}
@@ -1042,9 +1034,7 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
machine.ContinueTimer(taskItemName);
}
}
return true;
}
@@ -1061,12 +1051,10 @@ namespace Modbus.Net
lock (_machines)
{
foreach (var machine in _machines)
{
tasks.Add(machine.InvokeOnce(item));
}
}
var ans = await Task.WhenAll(tasks);
return ans.All(p=>p);
return ans.All(p => p);
}
/// <summary>
@@ -1080,9 +1068,7 @@ namespace Modbus.Net
{
var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId));
if (machine != null)
{
return await machine.InvokeOnce(item);
}
return false;
}
@@ -1097,9 +1083,7 @@ namespace Modbus.Net
{
var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId));
if (machine != null)
{
return machine.InvokeTimer(item);
}
return false;
}
@@ -1113,9 +1097,7 @@ namespace Modbus.Net
{
var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId));
if (machine != null)
{
return machine.StopTimer(taskItemName);
}
return false;
}
@@ -1129,9 +1111,7 @@ namespace Modbus.Net
{
var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId));
if (machine != null)
{
return machine.PauseTimer(taskItemName);
}
return false;
}
@@ -1145,9 +1125,7 @@ namespace Modbus.Net
{
var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId));
if (machine != null)
{
return machine.ContinueTimer(taskItemName);
}
return false;
}
}

View File

@@ -74,9 +74,7 @@ namespace Modbus.Net
{
_timeoutTime = value;
if (_socketClient != null)
{
_socketClient.ReceiveTimeout = _timeoutTime;
}
}
}
@@ -144,9 +142,7 @@ namespace Modbus.Net
public override async Task<bool> ConnectAsync()
{
if (_socketClient != null)
{
Disconnect();
}
try
{
_socketClient = new TcpClient
@@ -187,9 +183,7 @@ namespace Modbus.Net
public override bool Disconnect()
{
if (_socketClient == null)
{
return true;
}
try
{
@@ -239,9 +233,7 @@ namespace Modbus.Net
try
{
if (!IsConnected)
{
await ConnectAsync();
}
var stream = _socketClient.GetStream();
await stream.WriteAsync(datagram, 0, datagram.Length);
@@ -280,9 +272,7 @@ namespace Modbus.Net
try
{
if (!IsConnected)
{
await ConnectAsync();
}
var stream = _socketClient.GetStream();
await stream.WriteAsync(datagram, 0, datagram.Length);
@@ -313,9 +303,7 @@ namespace Modbus.Net
stream.Flush();
// 异步接收回答
if (len > 0)
{
return CheckReplyDatagram(len);
}
return null;
}
catch (Exception err)
@@ -339,9 +327,7 @@ namespace Modbus.Net
RefreshReceiveCount();
if (len <= 0)
{
RefreshErrorCount();
}
return replyMessage;
}

View File

@@ -1,4 +1,5 @@
#if NET40||NET45||NET451||NET452||NET46||NET461||NET462||NET47
#if NET40||NET45||NET451||NET452||NET46||NET461||NET462||NET47
using System.Configuration;
#endif

View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net
{
@@ -16,21 +13,21 @@ namespace Modbus.Net
#region Public Methods
/// <summary>
/// Looks for the method in the type matching the name and arguments.
/// Looks for the method in the type matching the name and arguments.
/// </summary>
/// <param name="type"></param>
/// <param name="methodName">
/// The name of the method to find.
/// The name of the method to find.
/// </param>
/// <param name="args">
/// The types of the method's arguments to match.
/// The types of the method's arguments to match.
/// </param>
/// <param name="isGenericMethod">
/// Is method Generic Method.
/// Is method Generic Method.
/// </param>
/// <returns></returns>
/// <exception cref="ArgumentNullException">
/// Thrown if:
/// Thrown if:
/// - The name of the method is not specified.
/// </exception>
public static MethodInfo GetRuntimeMethod(this Type type, string methodName, Type[] args, bool isGenericMethod)
@@ -42,26 +39,23 @@ namespace Modbus.Net
throw new ArgumentNullException("methodName", "The name of the method has not been specified.");
var methods = type.GetRuntimeMethods().Where(methodInfo => string.Equals(methodInfo.Name, methodName, StringComparison.OrdinalIgnoreCase)).ToList();
var methods =
type.GetRuntimeMethods()
.Where(methodInfo => string.Equals(methodInfo.Name, methodName, StringComparison.OrdinalIgnoreCase))
.ToList();
if (!methods.Any())
return null; // No methods have the specified name.
return null; // No methods have the specified name.
if (isGenericMethod)
{
methods = methods.Where(method => method.IsGenericMethod).ToList();
}
else
{
methods = methods.Where(method => !method.IsGenericMethod).ToList();
}
var ans = methods.Where(method => IsSignatureMatch(method, args));
if (ans.Count() <= 1)
{
return ans.Count() == 1 ? ans.Single() : null;
}
return ans.Count() == 1 ? ans.Single() : null;
// Oh noes, don't make me go there.
throw new NotImplementedException("Resolving overloaded methods is not implemented as of now.");
@@ -72,7 +66,7 @@ namespace Modbus.Net
#region Private Methods
/// <summary>
/// Finds out if the provided arguments matches the specified method's signature.
/// Finds out if the provided arguments matches the specified method's signature.
/// </summary>
/// <param name="methodInfo"></param>
/// <param name="args"></param>
@@ -83,11 +77,11 @@ namespace Modbus.Net
// Gets the parameters of the method to analyze.
ParameterInfo[] parameters = methodInfo.GetParameters();
var parameters = methodInfo.GetParameters();
int currentArgId = 0;
var currentArgId = 0;
foreach (ParameterInfo parameterInfo in parameters)
foreach (var parameterInfo in parameters)
{
if (!ReferenceEquals(args, null) && currentArgId < args.Length)
{
@@ -102,7 +96,7 @@ namespace Modbus.Net
if (parameterInfo.ParameterType.IsGenericParameter)
{
// Gets the base type of the generic parameter.
Type baseType = parameterInfo.ParameterType.GetTypeInfo().BaseType;
var baseType = parameterInfo.ParameterType.GetTypeInfo().BaseType;
// TODO: This is not good v and works with the most simple situation.
@@ -129,4 +123,4 @@ namespace Modbus.Net
#endregion
}
}
}

View File

@@ -410,7 +410,7 @@ namespace Modbus.Net
var temp = data[pos];
for (var i = 0; i < 8; i++)
{
t[i] = temp%2 > 0;
t[i] = temp % 2 > 0;
temp /= 2;
}
pos += 1;
@@ -427,11 +427,11 @@ namespace Modbus.Net
public bool GetBit(byte number, ref int pos, ref int subPos)
{
if (subPos < 0 && subPos >= 8) throw new IndexOutOfRangeException();
var ans = number%2;
var ans = number % 2;
var i = 0;
while (i <= subPos)
{
ans = number%2;
ans = number % 2;
number /= 2;
i++;
}
@@ -491,7 +491,7 @@ namespace Modbus.Net
b = true;
//自动将目标数组中内含的子数组展开,是所有包含在子数组拼接为一个数组
var contentArray =
ArrayList.Adapter((Array) content).ToArray(typeof (object)).OfType<object>();
ArrayList.Adapter((Array) content).ToArray(typeof(object)).OfType<object>();
newContentsList.AddRange(contentArray);
}
else
@@ -520,13 +520,9 @@ namespace Modbus.Net
}
lastIsBool = true;
if (!LittleEndianBit)
{
boolToByteTemp = (byte) (boolToByteTemp*2 + ((bool) content ? 1 : 0));
}
boolToByteTemp = (byte) (boolToByteTemp * 2 + ((bool) content ? 1 : 0));
else
{
boolToByteTemp += (byte) ((bool) content ? Math.Pow(2, boolToByteCount) : 0);
}
boolToByteCount++;
}
else
@@ -594,9 +590,7 @@ namespace Modbus.Net
}
//最后是bool拼装时表示数字还没有添加把数字添加进返回数组中。
if (lastIsBool)
{
translateTarget.Add(boolToByteTemp);
}
//最后把队列转换为数组
return translateTarget.ToArray();
}
@@ -622,7 +616,7 @@ namespace Modbus.Net
public virtual T[] ByteArrayToDestinationArray<T>(byte[] contents, int getCount)
{
var objectArray = _Instance.ByteArrayToObjectArray(contents,
new KeyValuePair<Type, int>(typeof (T), getCount));
new KeyValuePair<Type, int>(typeof(T), getCount));
return _Instance.ObjectArrayToDestinationArray<T>(objectArray);
}
@@ -641,7 +635,6 @@ namespace Modbus.Net
var translation = new List<object>();
var count = 0;
foreach (var translateUnit in translateTypeAndCount)
{
for (var i = 0; i < translateUnit.Value; i++)
{
if (count >= contents.Length) break;
@@ -708,9 +701,7 @@ namespace Modbus.Net
var value = _Instance.GetBits(contents, ref count);
var k = translateUnit.Value - i < 8 ? translateUnit.Value - i : 8;
for (var j = 0; j < k; j++)
{
translation.Add(value[j]);
}
i += 7;
break;
}
@@ -725,7 +716,6 @@ namespace Modbus.Net
count = contents.Length;
}
}
}
return translation.ToArray();
}
@@ -906,21 +896,21 @@ namespace Modbus.Net
switch (endian)
{
case Endian.LittleEndianLsb:
{
return ValueHelper.Instance;
}
{
return Instance;
}
case Endian.BigEndianLsb:
{
return BigEndianValueHelper.Instance;
}
{
return BigEndianValueHelper.Instance;
}
case Endian.BigEndianMsb:
{
return BigEndianMsbValueHelper.Instance;
}
{
return BigEndianMsbValueHelper.Instance;
}
default:
{
return ValueHelper.Instance;
}
{
return Instance;
}
}
}