This commit is contained in:
parallelbgls
2017-02-14 11:31:45 +08:00
52 changed files with 701 additions and 148 deletions

View File

@@ -1,5 +1,8 @@
namespace Modbus.Net.Modbus
{
/// <summary>
/// 南大奥拓NA200H专用AddressFormater
/// </summary>
public class AddressFormaterNA200H : AddressFormater
{
public override string FormatAddress(string area, int address)
@@ -13,6 +16,9 @@
}
}
/// <summary>
/// Modbus标准AddressFormater
/// </summary>
public class AddressFormaterModbus : AddressFormater
{
public override string FormatAddress(string area, int address)

View File

@@ -4,12 +4,21 @@ using System.Linq;
namespace Modbus.Net.Modbus
{
/// <summary>
/// NA200H数据单元翻译器
/// 南大奥拓NA200H数据单元翻译器
/// </summary>
public class AddressTranslatorNA200H : AddressTranslator
{
/// <summary>
/// 读功能码
/// </summary>
protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
/// <summary>
/// 功能码翻译至标准Modbus地址位置
/// </summary>
protected Dictionary<string, int> TransDictionary;
/// <summary>
/// 写功能码
/// </summary>
protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
public AddressTranslatorNA200H()
@@ -188,7 +197,13 @@ namespace Modbus.Net.Modbus
/// </summary>
public class AddressTranslatorModbus : AddressTranslator
{
/// <summary>
/// 读功能码
/// </summary>
protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
/// <summary>
/// 写功能码
/// </summary>
protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
public AddressTranslatorModbus()

View File

@@ -2,18 +2,18 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Modbus.Net.Modbus</id>
<version>1.2.1</version>
<version>1.2.2</version>
<title>Modbus.Net.Modbus</title>
<authors>Chris L.(Luo Sheng)</authors>
<owners>Hangzhou Delian Information and Science Technology Co.,Ltd.</owners>
<owners>Hangzhou Delian IoT Science Technology Co.,Ltd.</owners>
<licenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</licenseUrl>
<projectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.Modbus</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Modbus.Net Modbus Implementation</description>
<copyright>Copyright 2015 Hangzhou Delian Science and Technology Co.,Ltd.</copyright>
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal modbus Delian</tags>
<dependencies>
<dependency id="Modbus.Net" version="1.2.1" />
<dependency id="Modbus.Net" version="1.2.2" />
</dependencies>
</metadata>
<files>

View File

@@ -1,7 +1,7 @@
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus/Rtu协议
/// Modbus/Ascii码协议
/// </summary>
public class ModbusAsciiProtocal : ModbusProtocal
{

View File

@@ -3,6 +3,9 @@ using System.Text;
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus/Ascii码协议连接器
/// </summary>
public class ModbusAsciiProtocalLinker : ComProtocalLinker
{
public ModbusAsciiProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8)

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus设备
/// </summary>
public class ModbusMachine : BaseMachine
{
public ModbusMachine(ModbusType connectionType, string connectionString,

View File

@@ -4,6 +4,9 @@ using System.Threading.Tasks;
namespace Modbus.Net.Modbus
{
/// <summary>
/// 变量功能码
/// </summary>
internal enum ModbusProtocalVariableFunctionCode : byte
{
ReadVariable = 20,
@@ -39,6 +42,9 @@ namespace Modbus.Net.Modbus
WriteMultiRegister = 16
}
/// <summary>
/// Modbus协议
/// </summary>
public abstract class ModbusProtocal : BaseProtocal
{
protected ModbusProtocal(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress)
@@ -58,7 +64,7 @@ namespace Modbus.Net.Modbus
#region PLC数据
public class ReadDataModbusInputStruct : InputStruct
public class ReadDataModbusInputStruct : IInputStruct
{
public ReadDataModbusInputStruct(byte slaveAddress, string startAddress, ushort getCount,
AddressTranslator addressTranslator)
@@ -79,7 +85,7 @@ namespace Modbus.Net.Modbus
public ushort GetCount { get; }
}
public class ReadDataModbusOutputStruct : OutputStruct
public class ReadDataModbusOutputStruct : IOutputStruct
{
public ReadDataModbusOutputStruct(byte slaveAddress, byte functionCode,
int dataCount, byte[] dataValue)
@@ -101,14 +107,14 @@ namespace Modbus.Net.Modbus
public class ReadDataModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (ReadDataModbusInputStruct) message;
return Format(r_message.SlaveAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
@@ -130,7 +136,7 @@ namespace Modbus.Net.Modbus
#region PLC数据
public class WriteDataModbusInputStruct : InputStruct
public class WriteDataModbusInputStruct : IInputStruct
{
public WriteDataModbusInputStruct(byte slaveAddress, string startAddress, object[] writeValue,
AddressTranslator addressTranslator)
@@ -159,7 +165,7 @@ namespace Modbus.Net.Modbus
public byte[] WriteValue { get; }
}
public class WriteDataModbusOutputStruct : OutputStruct
public class WriteDataModbusOutputStruct : IOutputStruct
{
public WriteDataModbusOutputStruct(byte slaveAddress, byte functionCode,
ushort startAddress, ushort writeCount)
@@ -184,7 +190,7 @@ namespace Modbus.Net.Modbus
/// </summary>
public class WriteDataModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (WriteDataModbusInputStruct) message;
var functionCode = r_message.FunctionCode;
@@ -201,7 +207,7 @@ namespace Modbus.Net.Modbus
return formattingBytes;
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
{
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
@@ -216,7 +222,7 @@ namespace Modbus.Net.Modbus
#region PLC时间
public class GetSystemTimeModbusInputStruct : InputStruct
public class GetSystemTimeModbusInputStruct : IInputStruct
{
public GetSystemTimeModbusInputStruct(byte slaveAddress)
{
@@ -235,7 +241,7 @@ namespace Modbus.Net.Modbus
public ushort GetCount { get; }
}
public class GetSystemTimeModbusOutputStruct : OutputStruct
public class GetSystemTimeModbusOutputStruct : IOutputStruct
{
public GetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode,
byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute,
@@ -261,14 +267,14 @@ namespace Modbus.Net.Modbus
/// </summary>
public class GetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (GetSystemTimeModbusInputStruct) message;
return Format(r_message.SlaveAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
{
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
@@ -289,7 +295,7 @@ namespace Modbus.Net.Modbus
#region PLC时间
public class SetSystemTimeModbusInputStruct : InputStruct
public class SetSystemTimeModbusInputStruct : IInputStruct
{
public SetSystemTimeModbusInputStruct(byte slaveAddress, DateTime time)
{
@@ -332,7 +338,7 @@ namespace Modbus.Net.Modbus
public ushort Millisecond { get; }
}
public class SetSystemTimeModbusOutputStruct : OutputStruct
public class SetSystemTimeModbusOutputStruct : IOutputStruct
{
public SetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode,
ushort startAddress, ushort writeCount)
@@ -357,7 +363,7 @@ namespace Modbus.Net.Modbus
/// </summary>
public class SetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (SetSystemTimeModbusInputStruct) message;
return Format(r_message.SlaveAddress, r_message.FunctionCode,
@@ -366,7 +372,7 @@ namespace Modbus.Net.Modbus
r_message.Month, r_message.Hour, r_message.Second, r_message.Minute, r_message.Millisecond);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
public override IOutputStruct Unformat(byte[] messageBytes, ref int flag)
{
var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);

View File

@@ -8,9 +8,9 @@ namespace Modbus.Net.Modbus
/// <summary>
/// Tcp协议字节伸缩
/// </summary>
public class ModbusTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
public class ModbusTcpProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
public byte[] BytesExtend(byte[] content)
{
//Modbus/Tcp协议扩张前面加6个字节前面4个为0后面两个为协议整体内容的长度
var newFormat = new byte[6 + content.Length];
@@ -22,7 +22,7 @@ namespace Modbus.Net.Modbus
return newFormat;
}
public override byte[] BytesDecact(byte[] content)
public byte[] BytesDecact(byte[] content)
{
//Modbus/Tcp协议收缩抛弃前面6个字节的内容
var newContent = new byte[content.Length - 6];
@@ -31,9 +31,9 @@ namespace Modbus.Net.Modbus
}
}
public class ModbusRtuProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
public class ModbusRtuProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
public byte[] BytesExtend(byte[] content)
{
var crc = new byte[2];
//Modbus/Rtu协议扩张增加CRC校验
@@ -44,7 +44,7 @@ namespace Modbus.Net.Modbus
return newFormat;
}
public override byte[] BytesDecact(byte[] content)
public byte[] BytesDecact(byte[] content)
{
//Modbus/Rtu协议收缩抛弃后面2个字节的内容
var newContent = new byte[content.Length - 2];
@@ -53,10 +53,11 @@ namespace Modbus.Net.Modbus
}
}
public class ModbusAsciiProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
public class ModbusAsciiProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
public byte[] BytesExtend(byte[] content)
{
//Modbus/Ascii协议扩张前面增加:后面增加LRC校验和尾字符
var newContent = new List<byte>();
newContent.AddRange(Encoding.ASCII.GetBytes(":"));
foreach (var number in content)
@@ -69,8 +70,9 @@ namespace Modbus.Net.Modbus
return newContent.ToArray();
}
public override byte[] BytesDecact(byte[] content)
public byte[] BytesDecact(byte[] content)
{
//Modbus/Ascii协议收缩抛弃头尾。
var newContent = new List<byte>();
var ans = Encoding.ASCII.GetString(content);
var index = ans.IndexOf(Environment.NewLine);

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus/Rtu协议连接器
/// </summary>
public class ModbusRtuProtocalLinker : ComProtocalLinker
{
public ModbusRtuProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8)

View File

@@ -1,5 +1,8 @@
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus/Tcp协议连接器
/// </summary>
public class ModbusTcpProtocalLinker : TcpProtocalLinker
{
public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.ModbusPort))

View File

@@ -23,8 +23,14 @@ namespace Modbus.Net.Modbus
Ascii = 2
}
/// <summary>
/// Modbus基础Api入口
/// </summary>
public class ModbusUtility : BaseUtility
{
/// <summary>
/// Modbus协议类型
/// </summary>
private ModbusType _modbusType;
public ModbusUtility(int connectionType, byte slaveAddress, byte masterAddress)
@@ -81,6 +87,7 @@ namespace Modbus.Net.Modbus
_modbusType = value;
switch (_modbusType)
{
//Rtu协议
case ModbusType.Rtu:
{
Wrapper = ConnectionString == null
@@ -88,6 +95,7 @@ namespace Modbus.Net.Modbus
: new ModbusRtuProtocal(ConnectionString, SlaveAddress, MasterAddress);
break;
}
//Tcp协议
case ModbusType.Tcp:
{
Wrapper = ConnectionString == null
@@ -98,6 +106,7 @@ namespace Modbus.Net.Modbus
MasterAddress));
break;
}
//Ascii协议
case ModbusType.Ascii:
{
Wrapper = ConnectionString == null
@@ -114,6 +123,12 @@ namespace Modbus.Net.Modbus
ModbusType = (ModbusType) connectionType;
}
/// <summary>
/// 读数据
/// </summary>
/// <param name="startAddress">起始地址</param>
/// <param name="getByteCount">获取字节个数</param>
/// <returns>获取的结果</returns>
public override async Task<byte[]> GetDatasAsync(string startAddress, int getByteCount)
{
try
@@ -131,6 +146,12 @@ namespace Modbus.Net.Modbus
}
}
/// <summary>
/// 写数据
/// </summary>
/// <param name="startAddress">起始地址</param>
/// <param name="setContents">需要设置的数据</param>
/// <returns>设置是否成功</returns>
public override async Task<bool> SetDatasAsync(string startAddress, object[] setContents)
{
try
@@ -149,6 +170,10 @@ namespace Modbus.Net.Modbus
}
/*
/// <summary>
/// 读时间
/// </summary>
/// <returns>设备的时间</returns>
public override DateTime GetTime()
{
try
@@ -165,6 +190,11 @@ namespace Modbus.Net.Modbus
}
}
/// <summary>
/// 写时间
/// </summary>
/// <param name="setTime">需要写入的时间</param>
/// <returns>写入是否成功</returns>
public override bool SetTime(DateTime setTime)
{
try

View File

@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Modbus.Net.Modbus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("杭州德联物联网科技有限公司")]
[assembly: AssemblyProduct("Modbus.Net.Modbus")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyCopyright("Copyright © Chris L. 2017 HangZhou Delian IoT Science Technology Co.,Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: AssemblyVersion("1.2.2")]
[assembly: AssemblyFileVersion("1.2.2")]

View File

@@ -1,4 +1,4 @@
Modbus.Net
Modbus.Net.Modbus
===================
[![NuGet](https://img.shields.io/nuget/v/Modbus.Net.Modbus.svg)](https://www.nuget.org/packages/Modbus.Net.Modbus/)

View File

@@ -3,8 +3,17 @@ using System.Linq;
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc地址编码器
/// </summary>
public class AddressFormaterOpc : AddressFormater
{
/// <summary>
/// 协议构造器
/// </summary>
/// <param name="tagGeter">如何通过BaseMachine和AddressUnit构造Opc的标签</param>
/// <param name="machine">调用这个编码器的设备</param>
/// <param name="seperator">每两个标签之间用什么符号隔开,默认为/</param>
public AddressFormaterOpc(Func<BaseMachine, AddressUnit, string[]> tagGeter, BaseMachine machine,
char seperator = '/')
{

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc地址解析器
/// </summary>
public class AddressTranslatorOpc : AddressTranslator
{
public override AddressDef AddressTranslate(string address, bool isRead)

View File

@@ -90,6 +90,7 @@
<ItemGroup>
<None Include="Modbus.Net.OPC.nuspec" />
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -2,18 +2,18 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Modbus.Net.OPC</id>
<version>1.2.1</version>
<version>1.2.2</version>
<title>Modbus.Net.OPC</title>
<authors>Chris L.(Luo Sheng)</authors>
<owners>Hangzhou Delian Information and Science Technology</owners>
<owners>Hangzhou Delian IoT Science Technology Co.,Ltd.</owners>
<licenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</licenseUrl>
<projectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.OPC</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Modbus.Net OPC Implementation</description>
<copyright>Copyright 2015 Hangzhou Delian Science and Technology Co.,Ltd.</copyright>
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal OPC DA Delian</tags>
<dependencies>
<dependency id="Modbus.Net" version="1.2.1" />
<dependency id="Modbus.Net" version="1.2.2" />
<dependency id="H.Opc" version="0.7.0" />
</dependencies>
</metadata>

View File

@@ -5,6 +5,9 @@ using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
/// <summary>
/// OpcDa协议连接实现
/// </summary>
public class OpcDaConnector : BaseConnector
{
protected static Dictionary<string, OpcDaConnector> _instances = new Dictionary<string, OpcDaConnector>();

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.OPC
{
/// <summary>
/// OpcDa设备
/// </summary>
public class OpcDaMachine : BaseMachine
{
public OpcDaMachine(string connectionString, IEnumerable<AddressUnit> getAddresses, bool keepConnect)

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.OPC
{
/// <summary>
/// OpcDa协议
/// </summary>
public class OpcDaProtocal : OpcProtocal
{
private readonly string _host;

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc Da协议连接器
/// </summary>
public class OpcDaProtocalLinker : ProtocalLinker
{
public OpcDaProtocalLinker() : this(ConfigurationManager.OpcDaHost)

View File

@@ -3,6 +3,9 @@ using System.Threading.Tasks;
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc Da协议Api入口
/// </summary>
public class OpcDaUtility : BaseUtility
{
public OpcDaUtility(string connectionString) : base(0, 0)

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.OPC
{
/// <summary>
/// Opc协议
/// </summary>
public abstract class OpcProtocal : BaseProtocal
{
protected OpcProtocal() : base(0, 0)
@@ -9,7 +12,9 @@ namespace Modbus.Net.OPC
}
}
public class ReadRequestOpcInputStruct : InputStruct
#region
public class ReadRequestOpcInputStruct : IInputStruct
{
public ReadRequestOpcInputStruct(string tag)
{
@@ -19,7 +24,7 @@ namespace Modbus.Net.OPC
public string Tag { get; }
}
public class ReadRequestOpcOutputStruct : OutputStruct
public class ReadRequestOpcOutputStruct : IOutputStruct
{
public ReadRequestOpcOutputStruct(byte[] value)
{
@@ -29,21 +34,25 @@ namespace Modbus.Net.OPC
public byte[] GetValue { get; private set; }
}
public class ReadRequestOpcProtocal : SpecialProtocalUnit
public class ReadRequestOpcProtocal : ProtocalUnit, ISpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (ReadRequestOpcInputStruct) message;
return Format((byte) 0x00, Encoding.UTF8.GetBytes(r_message.Tag));
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
return new ReadRequestOpcOutputStruct(messageBytes);
}
}
public class WriteRequestOpcInputStruct : InputStruct
#endregion
#region
public class WriteRequestOpcInputStruct : IInputStruct
{
public WriteRequestOpcInputStruct(string tag, object setValue)
{
@@ -55,7 +64,7 @@ namespace Modbus.Net.OPC
public object SetValue { get; }
}
public class WriteRequestOpcOutputStruct : OutputStruct
public class WriteRequestOpcOutputStruct : IOutputStruct
{
public WriteRequestOpcOutputStruct(bool writeResult)
{
@@ -65,9 +74,9 @@ namespace Modbus.Net.OPC
public bool WriteResult { get; private set; }
}
public class WriteRequestOpcProtocal : SpecialProtocalUnit
public class WriteRequestOpcProtocal : ProtocalUnit, ISpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (WriteRequestOpcInputStruct) message;
var tag = Encoding.UTF8.GetBytes(r_message.Tag);
@@ -75,11 +84,13 @@ namespace Modbus.Net.OPC
return Format((byte) 0x01, tag, 0x00ffff00, fullName, 0x00ffff00, r_message.SetValue);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
var ansByte = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var ans = ansByte != 0;
return new WriteRequestOpcOutputStruct(ans);
}
}
#endregion
}

View File

@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Modbus.Net.OPC")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("杭州德联物联网科技有限公司")]
[assembly: AssemblyProduct("Modbus.Net.OPC")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyCopyright("Copyright © Chris L. 2017 HangZhou Delian IoT Science Technology Co.,Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: AssemblyVersion("1.2.2")]
[assembly: AssemblyFileVersion("1.2.2")]

View File

@@ -0,0 +1,36 @@
Modbus.Net.OPC
===================
[![NuGet](https://img.shields.io/nuget/v/Modbus.Net.OPC.svg)](https://www.nuget.org/packages/Modbus.Net.OPC/)
Modbus Implementation of Modbus.Net
Table of Content:
* [Basic Concept](#basic)
* [Address Mapping](#address)
* [Link](#link)
##<a name="basic"></a> Basic Concept
Siemens Protocal is derived by Profibus and Profinet.
##<a name="address"></a> Address Mapping
Modbus.Net.OPC has a simple address formatting tool. You can find it from AddressFormaterOPC.
You need to use messages in BaseMachine and AddressUnit to create an OPC tag.
Here is a Sample.
If your tag is "1/15/Value_Opening", 1 is MachineId, 15 is StationId and Value_Opening is point name.
Your tagGeter code should be.
```C#
(baseMachine, addressUnit) => return new string[]{baseMachine.Id, ((XXUnitExtend)addressUnit.unitExtend).stationId, addressUnit.Name};
```
If you want change your tag to "1.15.Value_Opening", just set the seperator to '.' .
##<a name="link"></a> Link
The link of OPC DA should like "opcda://PC-Name/OPC-Software-Name".

View File

@@ -1,5 +1,8 @@
namespace Modbus.Net.Siemens
{
/// <summary>
/// Siemens地址格式化Modbus.Net专用格式
/// </summary>
public class AddressFormaterSiemens : AddressFormater
{
public override string FormatAddress(string area, int address)
@@ -12,4 +15,36 @@
return area + " " + address + "." + subAddress;
}
}
/// <summary>
/// Siemens地址格式化Siemens格式
/// </summary>
public class AddressFormaterSimenseStandard : AddressFormater
{
public override string FormatAddress(string area, int address)
{
if (area.Length > 1 &&
area.ToUpper().Substring(0, 2) == "DB")
{
return area.ToUpper() + "." + "DB" + address;
}
else
{
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;
}
}
}
}

View File

@@ -1,8 +1,12 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Modbus.Net.Siemens
{
/// <summary>
/// 地址翻译器Modbus.Net格式
/// </summary>
public class AddressTranslatorSiemens : AddressTranslator
{
protected Dictionary<string, int> AreaCodeDictionary;
@@ -69,4 +73,72 @@ namespace Modbus.Net.Siemens
return 1;
}
}
/// <summary>
/// 地址翻译器Siemens格式
/// </summary>
public class AddressTranslatorSimenseStandard : AddressTranslator
{
protected Dictionary<string, int> AreaCodeDictionary;
public AddressTranslatorSimenseStandard()
{
AreaCodeDictionary = new Dictionary<string, int>
{
{"S", 0x04},
{"SM", 0x05},
{"AI", 0x06},
{"AQ", 0x07},
{"C", 0x1E},
{"T", 0x1F},
{"HC", 0x20},
{"I", 0x81},
{"Q", 0x82},
{"M", 0x83},
{"DB", 0x84},
{"V", 0x184},
};
}
public override AddressDef AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
if (address.Substring(0, 2) == "DB")
{
var addressSplit = address.Split('.');
if (addressSplit.Length != 2 && addressSplit.Length != 3) throw new FormatException();
addressSplit[0] = addressSplit[0].Substring(2);
if (addressSplit[1].Substring(0, 2) == "DB")
addressSplit[1] = addressSplit[1].Substring(2);
return new AddressDef
{
AreaString = "DB" + addressSplit[0],
Area = int.Parse(addressSplit[0]) * 256 + AreaCodeDictionary["DB"],
Address = int.Parse(addressSplit[1]),
SubAddress = addressSplit.Length == 2 ? 0 : int.Parse(addressSplit[2])
};
}
int 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('.');
return new AddressDef
{
AreaString = head,
Area = AreaCodeDictionary[head],
Address = int.Parse(tail[0]),
SubAddress = tail.Length == 1 ? 0 : int.Parse(tail[1])
};
}
public override double GetAreaByteLength(string area)
{
return 1;
}
}
}

View File

@@ -64,6 +64,7 @@
<None Include="Modbus.Net.Siemens.nuspec">
<SubType>Designer</SubType>
</None>
<None Include="README.md" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -2,18 +2,18 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Modbus.Net.Siemens</id>
<version>1.2.1</version>
<version>1.2.2</version>
<title>Modbus.Net.Siemens</title>
<authors>Chris L.(Luo Sheng)</authors>
<owners>Hangzhou Delian Information and Science Technology Co.,Ltd.</owners>
<owners>Hangzhou Delian IoT Science Technology Co.,Ltd.</owners>
<licenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</licenseUrl>
<projectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.Siemens</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Modbus.Net Siemens Profinet Implementation</description>
<copyright>Copyright 2015 Hangzhou Delian Science and Technology Co.,Ltd.</copyright>
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal Siemens profinet Delian</tags>
<dependencies>
<dependency id="Modbus.Net" version="1.2.1" />
<dependency id="Modbus.Net" version="1.2.2" />
</dependencies>
</metadata>
<files>

View File

@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Modbus.Net.Siemens")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("杭州德联物联网科技有限公司")]
[assembly: AssemblyProduct("Modbus.Net.Siemens")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyCopyright("Copyright © Chris L. 2017 HangZhou Delian IoT Science Technology Co.,Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: AssemblyVersion("1.2.2")]
[assembly: AssemblyFileVersion("1.2.2")]

View File

@@ -0,0 +1,42 @@
Modbus.Net.Siemens
===================
[![NuGet](https://img.shields.io/nuget/v/Modbus.Net.Siemens.svg)](https://www.nuget.org/packages/Modbus.Net.Siemens/)
Modbus Implementation of Modbus.Net
Table of Content:
* [Basic Concept](#basic)
* [Address Mapping](#address)
* [Addres Coding](#coding)
* [SubAddress Rules](#subpos)
##<a name="basic"></a> Basic Concept
Siemens Protocal is derived by Profibus and Profinet.
##<a name="address"></a> Address Mapping
Modbus.Net.Siemens has two types of AddressMapping -- Modbus.Net way or Siemens way.
But Modbus.Net already decleared the type in AddressUnit, so all of the formatting ways will ignore the address type.
The following table shows the differences between them.
Standard Siemens Address | Modbus.Net Address Format | Siemens Address Format |
------------------------ | ------------------------- | ---------------------- |
I0.0 | I 0.0 | I0.0 |
IB0 | I 0 | I0 |
V10.5 | V 10.5 | V10.5 |
VB19 | V 19 | V19 |
DB1.DBD22 | DB1 22 | DB1.DB22 |
DB2.DB35.1 | DB2 35.1 | DB2.DB35.1 |
##<a name="coding"></a> Address Coding
The Coding of Modbus.Net.Siemens is the same as standard siemens protocal.
##<a name="subpos"></a> SubAddress Rules
SubAddress Rules is the same as standard siemens protocal.
Area length will always be 1.

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子设备
/// </summary>
public class SiemensMachine : BaseMachine
{
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子Ppi协议
/// </summary>
public class SiemensPpiProtocal : SiemensProtocal
{
private readonly string _com;
@@ -31,7 +34,7 @@ namespace Modbus.Net.Siemens
return await base.SendReceiveAsync(isLittleEndian, content);
}
private async Task<OutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, InputStruct content)
private async Task<IOutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{
return await base.SendReceiveAsync(unit, content);
}

View File

@@ -4,6 +4,9 @@ using System.Threading.Tasks;
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子Ppi协议连接器
/// </summary>
public class SiemensPpiProtocalLinker : ComProtocalLinker
{
public SiemensPpiProtocalLinker(string com)

View File

@@ -4,31 +4,101 @@ using System.Linq;
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子数据类型
/// </summary>
public enum SiemensTypeCode : byte
{
/// <summary>
/// 布尔
/// </summary>
Bool = 0x01,
/// <summary>
/// 字节
/// </summary>
Byte = 0x02,
/// <summary>
/// 字
/// </summary>
Word = 0x03,
/// <summary>
/// 双字
/// </summary>
DWord = 0x04,
/// <summary>
/// 计数器
/// </summary>
C = 0x1E,
/// <summary>
/// 计时器
/// </summary>
T = 0x1F,
/// <summary>
/// 高速计数器
/// </summary>
HC = 0x20
}
/// <summary>
/// 西门子通讯报错信息
/// </summary>
public enum SiemensAccessResult : byte
{
/// <summary>
/// 无错误
/// </summary>
NoError = 0xFF,
/// <summary>
/// 硬件错误
/// </summary>
HardwareFault = 0x01,
/// <summary>
/// 非法对象访问Area错误
/// </summary>
IllegalObjectAccess = 0x03,
/// <summary>
/// 非法地址访问
/// </summary>
InvalidAddress = 0x05,
/// <summary>
/// 不支持的数据类型
/// </summary>
DataTypeNotSupport = 0x06,
/// <summary>
/// 对象不存在或长度超出允许范围
/// </summary>
ObjNotExistOrLengthError = 0x0A
}
/// <summary>
/// 西门子数据访问类型
/// </summary>
public enum SiemensDataType : byte
{
/// <summary>
/// 错误
/// </summary>
Error = 0x00,
/// <summary>
/// 比特位访问
/// </summary>
BitAccess = 0x03,
/// <summary>
/// 一般访问
/// </summary>
OtherAccess = 0x04
}
@@ -39,7 +109,9 @@ namespace Modbus.Net.Siemens
}
}
internal class ComCreateReferenceSiemensInputStruct : InputStruct
#region
internal class ComCreateReferenceSiemensInputStruct : IInputStruct
{
public ComCreateReferenceSiemensInputStruct(byte slaveAddress, byte masterAddress)
{
@@ -51,7 +123,7 @@ namespace Modbus.Net.Siemens
public byte MasterAddress { get; set; }
}
internal class ComCreateReferenceSiemensOutputStruct : OutputStruct
internal class ComCreateReferenceSiemensOutputStruct : IOutputStruct
{
public ComCreateReferenceSiemensOutputStruct(byte slaveAddress, byte masterAddress, byte confirmMessage)
{
@@ -65,9 +137,9 @@ namespace Modbus.Net.Siemens
public byte ConfirmMessage { get; set; }
}
internal class ComCreateReferenceSiemensProtocal : SpecialProtocalUnit
internal class ComCreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (ComCreateReferenceSiemensInputStruct) message;
var crc = (r_message.SlaveAddress + r_message.MasterAddress + 0x49)%256;
@@ -75,7 +147,7 @@ namespace Modbus.Net.Siemens
(byte) 0x16);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 1;
var masterAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
@@ -85,7 +157,11 @@ namespace Modbus.Net.Siemens
}
}
internal class CreateReferenceSiemensInputStruct : InputStruct
#endregion
#region
internal class CreateReferenceSiemensInputStruct : IInputStruct
{
public byte TdpuSize;
@@ -101,7 +177,7 @@ namespace Modbus.Net.Siemens
}
}
internal class CreateReferenceSiemensOutputStruct : OutputStruct
internal class CreateReferenceSiemensOutputStruct : IOutputStruct
{
public CreateReferenceSiemensOutputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
{
@@ -115,9 +191,9 @@ namespace Modbus.Net.Siemens
public ushort TsapDst { get; private set; }
}
internal class CreateReferenceSiemensProtocal : SpecialProtocalUnit
internal class CreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (CreateReferenceSiemensInputStruct) message;
const ushort head = 0x0300;
@@ -137,7 +213,7 @@ namespace Modbus.Net.Siemens
srcTsapCode, srcTsapContent, dstTsapCode, dstTsapContent);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 11;
byte tdpuSize = 0;
@@ -167,7 +243,11 @@ namespace Modbus.Net.Siemens
}
}
public class ComConfirmMessageSiemensInputStruct : InputStruct
#endregion
#region
public class ComConfirmMessageSiemensInputStruct : IInputStruct
{
public ComConfirmMessageSiemensInputStruct(byte slaveAddress, byte masterAddress)
{
@@ -179,7 +259,7 @@ namespace Modbus.Net.Siemens
public byte MasterAddress { get; set; }
}
public class ComConfirmMessageSiemensOutputStruct : OutputStruct
public class ComConfirmMessageSiemensOutputStruct : IOutputStruct
{
public ComConfirmMessageSiemensOutputStruct(byte confirmByte)
{
@@ -189,9 +269,9 @@ namespace Modbus.Net.Siemens
public byte ConfirmByte { get; set; }
}
public class ComConfirmMessageSiemensProtocal : SpecialProtocalUnit
public class ComConfirmMessageSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (ComConfirmMessageSiemensInputStruct) message;
var crc = r_message.SlaveAddress + r_message.MasterAddress + 0x5c%256;
@@ -199,14 +279,18 @@ namespace Modbus.Net.Siemens
(byte) 0x16);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
var confirmByte = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
return new ComConfirmMessageSiemensOutputStruct(confirmByte);
}
}
internal class EstablishAssociationSiemensInputStruct : InputStruct
#endregion
#region
internal class EstablishAssociationSiemensInputStruct : IInputStruct
{
public EstablishAssociationSiemensInputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
{
@@ -222,7 +306,7 @@ namespace Modbus.Net.Siemens
public ushort MaxPdu { get; }
}
internal class EstablishAssociationSiemensOutputStruct : OutputStruct
internal class EstablishAssociationSiemensOutputStruct : IOutputStruct
{
public EstablishAssociationSiemensOutputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
{
@@ -240,7 +324,7 @@ namespace Modbus.Net.Siemens
internal class EstablishAssociationSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (EstablishAssociationSiemensInputStruct) message;
const byte protoId = 0x32;
@@ -258,7 +342,7 @@ namespace Modbus.Net.Siemens
maxCalled, maxPdu);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
var pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos);
@@ -270,7 +354,11 @@ namespace Modbus.Net.Siemens
}
}
public class ReadRequestSiemensInputStruct : InputStruct
#endregion
#region
public class ReadRequestSiemensInputStruct : IInputStruct
{
public ReadRequestSiemensInputStruct(byte slaveAddress, byte masterAddress, ushort pduRef,
SiemensTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator)
@@ -297,7 +385,7 @@ namespace Modbus.Net.Siemens
public int Offset { get; }
}
public class ReadRequestSiemensOutputStruct : OutputStruct
public class ReadRequestSiemensOutputStruct : IOutputStruct
{
public ReadRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult, SiemensDataType dataType,
ushort getLength, byte[] value)
@@ -318,7 +406,7 @@ namespace Modbus.Net.Siemens
public class ReadRequestSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (ReadRequestSiemensInputStruct) message;
var slaveAddress = r_message.SlaveAddress;
@@ -346,7 +434,7 @@ namespace Modbus.Net.Siemens
offsetBitBytes.Skip(1).ToArray());
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
var pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos);
@@ -362,7 +450,11 @@ namespace Modbus.Net.Siemens
}
}
public class WriteRequestSiemensInputStruct : InputStruct
#endregion
#region
public class WriteRequestSiemensInputStruct : IInputStruct
{
public WriteRequestSiemensInputStruct(byte slaveAddress, byte masterAddress, ushort pduRef, string startAddress,
object[] writeValue, AddressTranslator addressTranslator)
@@ -387,7 +479,7 @@ namespace Modbus.Net.Siemens
public object[] WriteValue { get; }
}
public class WriteRequestSiemensOutputStruct : OutputStruct
public class WriteRequestSiemensOutputStruct : IOutputStruct
{
public WriteRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult)
{
@@ -401,7 +493,7 @@ namespace Modbus.Net.Siemens
public class WriteRequestSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
var r_message = (WriteRequestSiemensInputStruct) message;
var valueBytes = BigEndianValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue);
@@ -433,7 +525,7 @@ namespace Modbus.Net.Siemens
offsetBitBytes.Skip(1).ToArray(), reserved, type, numberOfWriteBits, valueBytes);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
if (messageBytes.Length == 1)
{
@@ -452,8 +544,11 @@ namespace Modbus.Net.Siemens
}
}
#endregion
/*
public class ReadTimeSiemensInputStruct : InputStruct
#region 读时间请求
public class ReadTimeSiemensInputStruct : IInputStruct
{
public ReadTimeSiemensInputStruct(ushort pduRef)
{
@@ -463,7 +558,7 @@ namespace Modbus.Net.Siemens
public ushort PduRef { get; private set; }
}
public class ReadTimeSiemensOutputStruct : OutputStruct
public class ReadTimeSiemensOutputStruct : IOutputStruct
{
public ReadTimeSiemensOutputStruct(ushort pduRef, DateTime dateTime, TodClockStatus todClockStatus)
{
@@ -479,18 +574,22 @@ namespace Modbus.Net.Siemens
public class ReadTimeSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
throw new NotImplementedException();
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
throw new NotImplementedException();
}
}
public class WriteTimeSiemensInputStruct : InputStruct
#endregion
#region 写时间请求
public class WriteTimeSiemensInputStruct : IInputStruct
{
public WriteTimeSiemensInputStruct(ushort pduRef, DateTime dateTime, TodClockStatus todClockStatus)
{
@@ -504,7 +603,7 @@ namespace Modbus.Net.Siemens
public TodClockStatus TodClockStatus { get; private set; }
}
public class WriteTimeSiemensOutputStruct : OutputStruct
public class WriteTimeSiemensOutputStruct : IOutputStruct
{
public WriteTimeSiemensOutputStruct(ushort pduRef, byte errCod)
{
@@ -518,18 +617,23 @@ namespace Modbus.Net.Siemens
public class WriteTimeSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
public override byte[] Format(IInputStruct message)
{
throw new NotImplementedException();
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{
throw new NotImplementedException();
}
}
#endregion
*/
/// <summary>
/// 西门子通讯报错信息
/// </summary>
public class SiemensProtocalErrorException : ProtocalErrorException
{
private static readonly Dictionary<int, string> ProtocalErrorDictionary = new Dictionary<int, string>

View File

@@ -2,16 +2,19 @@
namespace Modbus.Net.Siemens
{
public class SiemensTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
/// <summary>
/// 西门子Tcp协议扩展
/// </summary>
public class SiemensTcpProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
public byte[] BytesExtend(byte[] content)
{
Array.Copy(new byte[] {0x03, 0x00, 0x00, 0x00, 0x02, 0xf0, 0x80}, 0, content, 0, 7);
Array.Copy(BigEndianValueHelper.Instance.GetBytes((ushort) content.Length), 0, content, 2, 2);
return content;
}
public override byte[] BytesDecact(byte[] content)
public byte[] BytesDecact(byte[] content)
{
var newContent = new byte[content.Length - 7];
Array.Copy(content, 7, newContent, 0, newContent.Length);
@@ -19,9 +22,12 @@ namespace Modbus.Net.Siemens
}
}
public class SiemensPpiProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
/// <summary>
/// 西门子Ppi协议扩展
/// </summary>
public class SiemensPpiProtocalLinkerBytesExtend : IProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
public byte[] BytesExtend(byte[] content)
{
var newContent = new byte[content.Length + 2];
Array.Copy(content, 0, newContent, 0, content.Length);
@@ -38,7 +44,7 @@ namespace Modbus.Net.Siemens
return newContent;
}
public override byte[] BytesDecact(byte[] content)
public byte[] BytesDecact(byte[] content)
{
var newContent = new byte[content.Length - 9];
Array.Copy(content, 7, newContent, 0, newContent.Length);

View File

@@ -2,17 +2,19 @@
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子Tcp协议
/// </summary>
public class SiemensTcpProtocal : SiemensProtocal
{
private readonly ushort _taspSrc;
private readonly ushort _tsapDst;
private readonly ushort _maxCalling;
private readonly ushort _maxCalled;
private readonly ushort _maxPdu;
private readonly byte _tdpuSize;
private readonly string _ip;
private readonly ushort _maxCalled;
private readonly ushort _maxCalling;
private readonly ushort _maxPdu;
private readonly int _port;
private readonly ushort _taspSrc;
private readonly byte _tdpuSize;
private readonly ushort _tsapDst;
private int _connectTryCount;
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled,
@@ -53,12 +55,12 @@ namespace Modbus.Net.Siemens
return await base.SendReceiveAsync(isLittleEndian, content);
}
public override OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
public override IOutputStruct SendReceive(ProtocalUnit unit, IInputStruct content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
}
public override async Task<OutputStruct> SendReceiveAsync(ProtocalUnit unit, InputStruct content)
public override async Task<IOutputStruct> SendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{
if (ProtocalLinker != null && ProtocalLinker.IsConnected) return await base.SendReceiveAsync(unit, content);
if (_connectTryCount > 10) return null;
@@ -69,7 +71,7 @@ namespace Modbus.Net.Siemens
.ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null);
}
private async Task<OutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, InputStruct content)
private async Task<IOutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{
return await base.SendReceiveAsync(unit, content);
}
@@ -87,6 +89,7 @@ namespace Modbus.Net.Siemens
_connectTryCount = 0;
var inputStruct = new CreateReferenceSiemensInputStruct(_tdpuSize, _taspSrc, _tsapDst);
return
//先建立连接,然后建立设备的引用
await await
ForceSendReceiveAsync(this[typeof (CreateReferenceSiemensProtocal)], inputStruct)
.ContinueWith(async answer =>

View File

@@ -2,6 +2,9 @@
namespace Modbus.Net.Siemens
{
/// <summary>
/// 西门子Tcp协议连接器
/// </summary>
public class SiemensTcpProtocalLinker : TcpProtocalLinker
{
public SiemensTcpProtocalLinker(string ip)

View File

@@ -20,15 +20,17 @@ namespace Modbus.Net.Siemens
S7_1500 = 5
}
/// <summary>
/// 西门子通讯Api入口
/// </summary>
public class SiemensUtility : BaseUtility
{
private readonly byte _tdpuSize;
private readonly ushort _taspSrc;
private readonly ushort _tsapDst;
private readonly ushort _maxCalling;
private readonly ushort _maxCalled;
private readonly ushort _maxCalling;
private readonly ushort _maxPdu;
private readonly ushort _taspSrc;
private readonly byte _tdpuSize;
private readonly ushort _tsapDst;
private SiemensType _siemensType;
@@ -119,6 +121,9 @@ namespace Modbus.Net.Siemens
}
}
/// <summary>
/// 西门子连接类型
/// </summary>
public SiemensType ConnectionType
{
get { return _siemensType; }
@@ -127,6 +132,7 @@ namespace Modbus.Net.Siemens
_siemensType = value;
switch (_siemensType)
{
//PPI
case SiemensType.Ppi:
{
Wrapper = ConnectionString == null
@@ -134,10 +140,12 @@ namespace Modbus.Net.Siemens
: new SiemensPpiProtocal(ConnectionString, SlaveAddress, MasterAddress);
break;
}
//MPI
//case SiemensType.Mpi:
// {
// throw new NotImplementedException();
// }
//Ethenet
case SiemensType.Tcp:
{
Wrapper = ConnectionString == null
@@ -153,11 +161,21 @@ namespace Modbus.Net.Siemens
}
}
/// <summary>
/// 设置连接类型
/// </summary>
/// <param name="connectionType">需要设置的连接类型</param>
public override void SetConnectionType(int connectionType)
{
ConnectionType = (SiemensType) connectionType;
}
/// <summary>
/// 读数据
/// </summary>
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">读取字节个数</param>
/// <returns>从设备中读取的数据</returns>
public override async Task<byte[]> GetDatasAsync(string startAddress, int getByteCount)
{
try
@@ -176,6 +194,12 @@ namespace Modbus.Net.Siemens
}
}
/// <summary>
/// 写数据
/// </summary>
/// <param name="startAddress">开始地址</param>
/// <param name="setContents">需要写入的数据</param>
/// <returns>写入是否成功</returns>
public override async Task<bool> SetDatasAsync(string startAddress, object[] setContents)
{
try

View File

@@ -233,7 +233,7 @@ namespace Modbus.Net
var preAddress = continusAddresses[index];
continusAddresses.RemoveAt(index);
continusAddresses.RemoveAt(index);
//变为新的地址段
//合并两个已有的地址段,变为一个新的地址段
var newAddress = new CommunicationUnit
{
Area = nowAddress.Area,

View File

@@ -102,7 +102,7 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
public virtual IOutputStruct SendReceive(ProtocalUnit unit, IInputStruct content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
}
@@ -113,7 +113,7 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
public virtual async Task<OutputStruct> SendReceiveAsync(ProtocalUnit unit, InputStruct content)
public virtual async Task<IOutputStruct> SendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{
var t = 0;
var formatContent = unit.Format(content);
@@ -121,7 +121,7 @@ namespace Modbus.Net
{
byte[] receiveContent;
//如果为特别处理协议的话,跳过协议扩展收缩
if (unit is SpecialProtocalUnit)
if (unit is ISpecialProtocalUnit)
{
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
}

View File

@@ -5,6 +5,9 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// 基础Api入口
/// </summary>
public abstract class BaseUtility
{
/// <summary>

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net
{
public interface IProtocal
{
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="isLittleEndian">是否是小端格式</param>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
byte[] SendReceive(bool isLittleEndian, params object[] content);
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="isLittleEndian">是否是小端格式</param>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
Task<byte[]> SendReceiveAsync(bool isLittleEndian, params object[] content);
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
IOutputStruct SendReceive(ProtocalUnit unit, IInputStruct content);
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
Task<IOutputStruct> SendReceiveAsync(ProtocalUnit unit, IInputStruct content);
}
}

View File

@@ -10,7 +10,7 @@
/// </summary>
/// <param name="message">结构化的输入数据</param>
/// <returns>格式化后的字节流</returns>
byte[] Format(InputStruct message);
byte[] Format(IInputStruct message);
/// <summary>
/// 从对象的参数数组格式化
@@ -25,6 +25,6 @@
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <returns>结构化的输出数据</returns>
OutputStruct Unformat(byte[] messageBytes, ref int pos);
IOutputStruct Unformat(byte[] messageBytes, ref int pos);
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net
{
public interface IProtocalLinker
{
/// <summary>
/// 发送并接收数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
byte[] SendReceive(byte[] content);
/// <summary>
/// 发送并接收数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
Task<byte[]> SendReceiveAsync(byte[] content);
/// <summary>
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
byte[] SendReceiveWithoutExtAndDec(byte[] content);
/// <summary>
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
Task<byte[]> SendReceiveWithoutExtAndDecAsync(byte[] content);
/// <summary>
/// 检查接收的数据是否正确
/// </summary>
/// <param name="content">接收协议的内容</param>
/// <returns>协议是否是正确的</returns>
bool? CheckRight(byte[] content);
/// <summary>
/// 协议内容扩展,发送时根据需要扩展
/// </summary>
/// <param name="content">扩展前的基本协议内容</param>
/// <returns>扩展后的协议内容</returns>
byte[] BytesExtend(byte[] content);
/// <summary>
/// 协议内容缩减,接收时根据需要缩减
/// </summary>
/// <param name="content">缩减前的完整协议内容</param>
/// <returns>缩减后的协议内容</returns>
byte[] BytesDecact(byte[] content);
}
}

View File

@@ -3,20 +3,20 @@
/// <summary>
/// 协议字节伸缩
/// </summary>
public abstract class ProtocalLinkerBytesExtend
public interface IProtocalLinkerBytesExtend
{
/// <summary>
/// 协议扩展,协议内容发送前调用
/// </summary>
/// <param name="content">扩展前的原始协议内容</param>
/// <returns>扩展后的协议内容</returns>
public abstract byte[] BytesExtend(byte[] content);
byte[] BytesExtend(byte[] content);
/// <summary>
/// 协议收缩,协议内容接收后调用
/// </summary>
/// <param name="content">收缩前的完整协议内容</param>
/// <returns>收缩后的协议内容</returns>
public abstract byte[] BytesDecact(byte[] content);
byte[] BytesDecact(byte[] content);
}
}

View File

@@ -2,15 +2,15 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Modbus.Net</id>
<version>1.2.1</version>
<version>1.2.2</version>
<title>Modbus.Net</title>
<authors>Chris L.(Luo Sheng)</authors>
<owners>Hangzhou Delian Information and Science Technology Co.,Ltd.</owners>
<owners>Hangzhou Delian IoT Science Technology Co.,Ltd.</owners>
<licenseUrl>https://github.com/parallelbgls/Modbus.Net/blob/master/LICENSE.md</licenseUrl>
<projectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>High extensible hardware communication implementation platform</description>
<copyright>Copyright 2015 Hangzhou Delian Science and Technology Co.,Ltd.</copyright>
<copyright>Copyright 2017 Hangzhou Delian IoT Science Technology Co.,Ltd.</copyright>
<tags>hardware communicate protocal Delian</tags>
</metadata>
<files>

View File

@@ -68,9 +68,11 @@
</Compile>
<Compile Include="BaseConnector.cs" />
<Compile Include="CRC16.cs" />
<Compile Include="IProtocal.cs" />
<Compile Include="IProtocalFormatting.cs" />
<Compile Include="IProtocalLinker.cs" />
<Compile Include="ProtocalLinker.cs" />
<Compile Include="ProtocalLinkerBytesExtend.cs" />
<Compile Include="IProtocalLinkerBytesExtend.cs" />
<Compile Include="ProtocalUnit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TaskManager.cs" />

View File

@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Modbus.Net")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("杭州德联科技股份有限公司")]
[assembly: AssemblyCompany("杭州德联物联网科技有限公司")]
[assembly: AssemblyProduct("Modbus.Net")]
[assembly: AssemblyCopyright("Copyright © Chris L. 2014 HangZhou Delian Technology")]
[assembly: AssemblyCopyright("Copyright © Chris L. 2017 HangZhou Delian IoT Science Technology Co.,Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.0")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: AssemblyVersion("1.2.2")]
[assembly: AssemblyFileVersion("1.2.2")]

View File

@@ -113,7 +113,7 @@ namespace Modbus.Net
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
var bytesExtend =
Assembly.Load(GetType().Assembly.FullName).CreateInstance(GetType().FullName + "BytesExtend") as
ProtocalLinkerBytesExtend;
IProtocalLinkerBytesExtend;
return bytesExtend?.BytesExtend(content);
}
@@ -127,7 +127,7 @@ namespace Modbus.Net
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
var bytesExtend =
Assembly.Load(GetType().Assembly.GetName().Name).CreateInstance(GetType().FullName + "BytesExtend") as
ProtocalLinkerBytesExtend;
IProtocalLinkerBytesExtend;
return bytesExtend?.BytesDecact(content);
}
}

View File

@@ -17,7 +17,7 @@ namespace Modbus.Net
/// </summary>
/// <param name="message">结构化的输入数据</param>
/// <returns>格式化后的字节流</returns>
public abstract byte[] Format(InputStruct message);
public abstract byte[] Format(IInputStruct message);
/// <summary>
/// 从对象的参数数组格式化
@@ -35,7 +35,7 @@ namespace Modbus.Net
/// <param name="messageBytes">返回数据的字节流</param>
/// <param name="pos">转换标记位</param>
/// <returns>结构化的输出数据</returns>
public abstract OutputStruct Unformat(byte[] messageBytes, ref int pos);
public abstract IOutputStruct Unformat(byte[] messageBytes, ref int pos);
/// <summary>
/// 转换静态方法,把对象数组转换为字节数组。
@@ -52,23 +52,23 @@ namespace Modbus.Net
}
/// <summary>
/// 特殊协议单元,继承这个类的协议不会执行BytesExtend和BytesDecact
/// 特殊协议单元,写入这个协议不会执行BytesExtend和BytesDecact
/// </summary>
public abstract class SpecialProtocalUnit : ProtocalUnit
public interface ISpecialProtocalUnit
{
}
/// <summary>
/// 输入结构
/// </summary>
public class InputStruct
public interface IInputStruct
{
}
/// <summary>
/// 输出结构
/// </summary>
public class OutputStruct
public interface IOutputStruct
{
}

View File

@@ -557,9 +557,9 @@ Remember subpos system cannot cross a byte in current version. If you want to cr
* New Samples (Complete)
###Version 1.2.2
* Address Utility (In Road)
* More functions in TaskManager (In Road)
* More interfaces (In Road)
* Address Utility (Not Test)
* More functions in TaskManager (Not Test)
* More interfaces (Not Test)
###Version 1.2.3
* OPC UA Support (In Road)