HJ212 Implementation
This commit is contained in:
97
Modbus.Net/Modbus.Net.HJ212/HJ212Machine.cs
Normal file
97
Modbus.Net/Modbus.Net.HJ212/HJ212Machine.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
public class HJ212Machine<TKey, TUnitKey> : BaseMachine<TKey, TUnitKey, string, string> where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
private static readonly ILogger<HJ212Machine<TKey, TUnitKey>> logger = LogProvider.CreateLogger<HJ212Machine<TKey, TUnitKey>>();
|
||||
|
||||
private readonly int _maxErrorCount = 3;
|
||||
|
||||
protected string ST { get; }
|
||||
|
||||
protected string CN { get; }
|
||||
|
||||
protected string PW { get; }
|
||||
|
||||
protected string MN { get; }
|
||||
|
||||
private int ErrorCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
/// <param name="getAddresses">需要读写的地址</param>
|
||||
public HJ212Machine(TKey id, string connectionString, string st, string cn, string pw, string mn)
|
||||
: base(id, null, true)
|
||||
{
|
||||
BaseUtility = new HJ212Utility(connectionString);
|
||||
ST = st;
|
||||
CN = cn;
|
||||
PW = pw;
|
||||
MN = mn;
|
||||
}
|
||||
|
||||
public override async Task<ReturnStruct<bool>> SetDatasAsync(MachineDataType setDataType, Dictionary<string, double> values)
|
||||
{
|
||||
try
|
||||
{
|
||||
//检测并连接设备
|
||||
if (!BaseUtility.IsConnected)
|
||||
await BaseUtility.ConnectAsync();
|
||||
//如果设备无法连接,终止
|
||||
if (!BaseUtility.IsConnected) return new ReturnStruct<bool>()
|
||||
{
|
||||
Datas = false,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -1,
|
||||
ErrorMsg = "Connection Error"
|
||||
};
|
||||
|
||||
//遍历每个要设置的值
|
||||
Dictionary<string, string> formatValues = new Dictionary<string, string>();
|
||||
foreach (var value in values)
|
||||
{
|
||||
//根据设置类型找到对应的地址描述
|
||||
formatValues.Add(value.Key, value.Value.ToString());
|
||||
}
|
||||
var sendValues = new List<Dictionary<string, string>>() { formatValues };
|
||||
//写入数据
|
||||
await
|
||||
BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().SetDatasAsync("0", new object[] { ST, CN, PW, MN, sendValues, DateTime.Now });
|
||||
|
||||
//如果不保持连接,断开连接
|
||||
if (!KeepConnect)
|
||||
BaseUtility.Disconnect();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorCount++;
|
||||
logger.LogError(e, $"BaseMachine -> SetDatas, Id:{Id} Connection:{ConnectionToken} error. ErrorCount {ErrorCount}.");
|
||||
|
||||
if (ErrorCount >= _maxErrorCount)
|
||||
Disconnect();
|
||||
return new ReturnStruct<bool>()
|
||||
{
|
||||
Datas = false,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -100,
|
||||
ErrorMsg = "Unknown Exception"
|
||||
};
|
||||
}
|
||||
return new ReturnStruct<bool>()
|
||||
{
|
||||
Datas = true,
|
||||
IsSuccess = true,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = ""
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
130
Modbus.Net/Modbus.Net.HJ212/HJ212Protocol.cs
Normal file
130
Modbus.Net/Modbus.Net.HJ212/HJ212Protocol.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
/// <summary>
|
||||
/// HJ212协议
|
||||
/// </summary>
|
||||
public class HJ212Protocol : BaseProtocol
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public HJ212Protocol(string connectionToken)
|
||||
: base(0, 0, Endian.BigEndianLsb)
|
||||
{
|
||||
ProtocolLinker = new HJ212ProtocolLinker(connectionToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public override async Task<bool> ConnectAsync()
|
||||
{
|
||||
return await ProtocolLinker.ConnectAsync();
|
||||
}
|
||||
}
|
||||
|
||||
#region 写数据
|
||||
/// <summary>
|
||||
/// 写数据协议
|
||||
/// </summary>
|
||||
public class WriteRequestHJ212Protocol : ProtocolUnit<byte[], byte[]>
|
||||
{
|
||||
/// <summary>
|
||||
/// 从对象的参数数组格式化
|
||||
/// </summary>
|
||||
/// <param name="message">非结构化的输入数据</param>
|
||||
/// <returns>格式化后的字节流</returns>
|
||||
public override byte[] Format(IInputStruct message)
|
||||
{
|
||||
var r_message = (WriteRequestHJ212InputStruct)message;
|
||||
string formatMessage = "##0633";
|
||||
formatMessage += "QN=" + r_message.QN + ";";
|
||||
formatMessage += "ST=" + r_message.ST + ";";
|
||||
formatMessage += "CN=" + r_message.CN + ";";
|
||||
formatMessage += "PW=" + r_message.PW + ";";
|
||||
formatMessage += "MN=" + r_message.MN + ";";
|
||||
formatMessage += "CP=&&";
|
||||
formatMessage += "DateTime=" + r_message.Datetime.ToString("yyyyMMddHHmmss") + ";";
|
||||
foreach (var record in r_message.CP)
|
||||
{
|
||||
foreach (var data in record)
|
||||
{
|
||||
formatMessage += data.Key + "=" + data.Value + ",";
|
||||
}
|
||||
formatMessage = formatMessage[..^1];
|
||||
formatMessage += ";";
|
||||
}
|
||||
formatMessage = formatMessage[..^1];
|
||||
formatMessage += "&&";
|
||||
return Encoding.ASCII.GetBytes(formatMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把仪器返回的内容填充到输出结构中
|
||||
/// </summary>
|
||||
/// <param name="messageBytes">返回数据的字节流</param>
|
||||
/// <param name="pos">转换标记位</param>
|
||||
/// <returns>结构化的输出数据</returns>
|
||||
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
|
||||
{
|
||||
return new WriteRequestHJ212OutputStruct(Encoding.ASCII.GetString(messageBytes));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写数据输入
|
||||
/// </summary>
|
||||
public class WriteRequestHJ212InputStruct : IInputStruct
|
||||
{
|
||||
public WriteRequestHJ212InputStruct(string st, string cn, string pw, string mn, List<Dictionary<string, string>> cp, DateTime datetime)
|
||||
{
|
||||
ST = st;
|
||||
CN = cn;
|
||||
PW = pw;
|
||||
MN = mn;
|
||||
CP = cp;
|
||||
Datetime = datetime;
|
||||
}
|
||||
|
||||
public string QN => "20170101000926706";
|
||||
|
||||
public string ST { get; }
|
||||
|
||||
public string CN { get; }
|
||||
|
||||
public string PW { get; }
|
||||
|
||||
public string MN { get; }
|
||||
|
||||
public List<Dictionary<string, string>> CP { get; }
|
||||
|
||||
public DateTime Datetime { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写数据输出
|
||||
/// </summary>
|
||||
public class WriteRequestHJ212OutputStruct : IOutputStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="value">读取的数据</param>
|
||||
public WriteRequestHJ212OutputStruct(string value)
|
||||
{
|
||||
GetValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取的地址
|
||||
/// </summary>
|
||||
public string GetValue { get; private set; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
24
Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinker.cs
Normal file
24
Modbus.Net/Modbus.Net.HJ212/HJ212ProtocolLinker.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
/// <summary>
|
||||
/// HJ212协议连接器
|
||||
/// </summary>
|
||||
public class HJ212ProtocolLinker : ProtocolLinker
|
||||
{
|
||||
public HJ212ProtocolLinker(string connectionToken)
|
||||
{
|
||||
BaseConnector = new TcpConnector(connectionToken, 443);
|
||||
((IConnectorWithController<byte[], byte[]>)BaseConnector).AddController(new FifoController(1000));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查接收的数据是否正确
|
||||
/// </summary>
|
||||
/// <param name="content">接收协议的内容</param>
|
||||
/// <returns>协议是否是正确的</returns>
|
||||
public override bool? CheckRight(byte[] content)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
/// <summary>
|
||||
/// Rtu协议字节伸缩
|
||||
/// </summary>
|
||||
public class HJ212ProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议扩展,协议内容发送前调用
|
||||
/// </summary>
|
||||
/// <param name="content">扩展前的原始协议内容</param>
|
||||
/// <returns>扩展后的协议内容</returns>
|
||||
public byte[] BytesExtend(byte[] content)
|
||||
{
|
||||
var crc = new byte[2];
|
||||
//Modbus/Rtu协议扩张,增加CRC校验
|
||||
var newFormat = new byte[content.Length + 4];
|
||||
Crc16.GetInstance().GetCRC(content, ref crc);
|
||||
Array.Copy(content, 0, newFormat, 0, content.Length);
|
||||
string crcString = BitConverter.ToString(crc).Replace("-", string.Empty);
|
||||
var crcCalc = Encoding.ASCII.GetBytes(crcString);
|
||||
Array.Copy(crcCalc, 0, newFormat, newFormat.Length - 4, 4);
|
||||
return newFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议收缩,协议内容接收后调用
|
||||
/// </summary>
|
||||
/// <param name="content">收缩前的完整协议内容</param>
|
||||
/// <returns>收缩后的协议内容</returns>
|
||||
public byte[] BytesDecact(byte[] content)
|
||||
{
|
||||
//Modbus/Rtu协议收缩,抛弃后面2个字节的内容
|
||||
var newContent = new byte[content.Length - 2];
|
||||
Array.Copy(content, 0, newContent, 0, newContent.Length);
|
||||
return newContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Modbus.Net/Modbus.Net.HJ212/HJ212Utility.cs
Normal file
61
Modbus.Net/Modbus.Net.HJ212/HJ212Utility.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
public class HJ212Utility : BaseUtility<byte[], byte[], ProtocolUnit<byte[], byte[]>, PipeUnit>
|
||||
{
|
||||
private static readonly ILogger<HJ212Utility> logger = LogProvider.CreateLogger<HJ212Utility>();
|
||||
|
||||
public HJ212Utility(string connectionString) : base(0, 0)
|
||||
{
|
||||
ConnectionString = connectionString;
|
||||
Wrapper = new HJ212Protocol(connectionString);
|
||||
}
|
||||
|
||||
public override Endian Endian => throw new NotImplementedException();
|
||||
|
||||
public override Task<ReturnStruct<byte[]>> GetDatasAsync(string startAddress, int getByteCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetConnectionType(int connectionType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<ReturnStruct<bool>> SetDatasAsync(string startAddress, object[] setContents)
|
||||
{
|
||||
try
|
||||
{
|
||||
var writeRequestHJ212InputStruct =
|
||||
new WriteRequestHJ212InputStruct((string)setContents[0], (string)setContents[1], (string)setContents[2], (string)setContents[3], (List<Dictionary<string, string>>)setContents[4], (DateTime)setContents[5]);
|
||||
var writeRequestOpcOutputStruct =
|
||||
await
|
||||
Wrapper.SendReceiveAsync<WriteRequestHJ212OutputStruct>(Wrapper[typeof(WriteRequestHJ212Protocol)],
|
||||
writeRequestHJ212InputStruct);
|
||||
return new ReturnStruct<bool>
|
||||
{
|
||||
Datas = writeRequestOpcOutputStruct?.GetValue != null,
|
||||
IsSuccess = writeRequestOpcOutputStruct?.GetValue != null,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null,
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, $"OpcUtility -> SetDatas: {ConnectionString} error: {e.Message}");
|
||||
return new ReturnStruct<bool>
|
||||
{
|
||||
Datas = false,
|
||||
IsSuccess = false,
|
||||
ErrorCode = -100,
|
||||
ErrorMsg = e.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Modbus.Net/Modbus.Net.HJ212/Modbus.Net.HJ212.csproj
Normal file
39
Modbus.Net/Modbus.Net.HJ212/Modbus.Net.HJ212.csproj
Normal file
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<AssemblyName>Modbus.Net.HJ212</AssemblyName>
|
||||
<RootNamespace>Modbus.Net.HJ212</RootNamespace>
|
||||
<PackageId>Modbus.Net.HJ212</PackageId>
|
||||
<Version>1.4.2</Version>
|
||||
<Authors>Chris L.(Luo Sheng)</Authors>
|
||||
<Company>Hangzhou Delian Science Technology Co.,Ltd.</Company>
|
||||
<Product>Modbus.Net.HJ212</Product>
|
||||
<Description>Modbus.Net Modbus Implementation</Description>
|
||||
<Copyright>Copyright 2023 Hangzhou Delian Science Technology Co.,Ltd.</Copyright>
|
||||
<PackageProjectUrl>https://github.com/parallelbgls/Modbus.Net/tree/master/Modbus.Net/Modbus.Net.HJ212</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/parallelbgls/Modbus.Net</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>hardware communicate protocol modbus Delian</PackageTags>
|
||||
<PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\Modbus.Net.HJ212.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Modbus.Net\Modbus.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath=""/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
7
Modbus.Net/Modbus.Net.HJ212/README.md
Normal file
7
Modbus.Net/Modbus.Net.HJ212/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Modbus.Net.HJ212
|
||||
===================
|
||||
[](https://www.nuget.org/packages/Modbus.Net.HJ212/)
|
||||
|
||||
HJ212 Implementation of Modbus.Net
|
||||
|
||||
Doc has been moved to wiki.
|
||||
@@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Technosoftware.DaAeHdaClien
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Technosoftware.DaAeHdaClient.Com", "..\Technosoftware\DaAeHdaClient.Com\Technosoftware.DaAeHdaClient.Com.csproj", "{ACAF0A16-FC51-4369-BFA8-484FF20707D7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus.Net.HJ212", "Modbus.Net.HJ212\Modbus.Net.HJ212.csproj", "{057644EF-1407-4C2B-808A-AEF0F2979EA8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -181,6 +183,14 @@ Global
|
||||
{ACAF0A16-FC51-4369-BFA8-484FF20707D7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ACAF0A16-FC51-4369-BFA8-484FF20707D7}.Release|x64.ActiveCfg = Release|x64
|
||||
{ACAF0A16-FC51-4369-BFA8-484FF20707D7}.Release|x64.Build.0 = Release|x64
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{057644EF-1407-4C2B-808A-AEF0F2979EA8}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user