///**********************************************************
///RJCP.IO.Ports 可以跨平台,同样System.Ports也同样可以使用
///**********************************************************
using System;
using RJCP.IO.Ports;
using System.Threading;
using SHJX.Service.Common.Logging;
using Microsoft.Extensions.Logging;
namespace SHJX.Service.ServerClient.RS485
{
public static class Rs485Client
{
private static readonly ILogger logger = LogFactory.BuildLogger(typeof(Rs485Client));
///
/// RS485通信对象
///
public static SerialPortStream Sport { get; set; }
///
/// 发送命令时锁定
///
private static readonly object SnedLocker = new();
///
/// 延时等待的单位间隔,默认20ms
///
private static int DelayUnit { get; set; }
///
/// 超时时长,默认1000ms
///
private static int Timeout { get; set; }
///
/// 端口状态:
/// True=打开,False=关闭
///
public static bool IsValid => Sport is not null && Sport.IsOpen;
///
/// 初始化
///
public static void InitPort()
{
// 创建COM通信对象
Sport ??= new SerialPortStream
{
BaudRate = 9600,
DataBits = 8,
StopBits = StopBits.One,
Parity = Parity.None
};
DelayUnit = 10;
Timeout = 1000;
}
///
/// 打开COM通信端口,使用指定参数
///
/// 端口号
/// 是否正常打开
public static bool Open(string portName)
{
try
{
lock (SnedLocker)
{
if (Sport.IsOpen) Sport.Close();
Sport.PortName = portName;
try
{
Sport.Open();
}
catch (Exception ex)
{
logger?.LogError(ex.Message);
}
}
return Sport.IsOpen;
}
catch (UnauthorizedAccessException exIo)
{
logger?.LogError(exIo.ToString());
return false;
}
catch (Exception ex)
{
logger?.LogError(ex.ToString());
return false;
}
}
///
/// 关闭COM通信端口
///
/// true=已关闭,false=未关闭
public static void Close()
{
//var open = Sport.IsOpen;
if (!Sport.IsOpen) return;
Sport.Close();
//Sport.Dispose();
}
///
/// 向端口发送指令,并等待回复。
/// 以lastChar字符作为回复的结尾识别字符,收到该字符后返回。
/// 失败时,返回string.Empty
///
/// 指令
/// 结尾识别字符
/// 完整的应答数据,含结尾识别字符
public static string SendData(string cmdStr, char lastChar)
{
if (Sport.IsOpen.Equals(false)) return string.Empty;
lock (SnedLocker)
{
for (; ; )
{
try
{
var strRes = string.Empty;
Sport.DiscardInBuffer();
Sport.DiscardOutBuffer();
Sport.Write(cmdStr);// 发送指令
// 等待回复
for (var i = 0; i < Timeout / DelayUnit; i++)
{
// 判断数据是否接收完整
if (Sport.BytesToRead > 0)
strRes += Sport.ReadExisting();
if (strRes.IndexOf(lastChar) != -1)
break;
Thread.Sleep(DelayUnit);
}
if (strRes.Length.Equals(0))
{
strRes = string.Empty;
}
return strRes;
}
catch (UnauthorizedAccessException exIo)
{
logger?.LogError(exIo.ToString());
}
catch (Exception ex)
{
logger?.LogError(ex.ToString());
}
}
}
}
///
/// 向端口发送指令,并等待回复。
/// 以lastStr字符串作为回复的结尾识别字符,收到该字符串后返回。
/// 失败时,返回string.Empty
///
/// 指令
///
/// 收到的回复数据,含结尾识别字符串
public static string SendData(string cmdStr, string lastStr)
{
if (Sport.IsOpen == false)
return string.Empty;
lock (SnedLocker)
{
for (; ; )
{
try
{
var strRes = string.Empty;
Sport.DiscardInBuffer();
Sport.DiscardOutBuffer();
Sport.Write(cmdStr);// 发送指令
// 等待回复
for (var i = 0; i < Timeout / DelayUnit; i++)
{
// 判断数据是否接收完整
if (Sport.BytesToRead > 0)
{
strRes += Sport.ReadExisting();
}
if (strRes.IndexOf(lastStr, StringComparison.Ordinal) > 0)
{
break;
}
Thread.Sleep(DelayUnit);
}
if (strRes.Length == 0)
{
strRes = string.Empty;
}
return strRes;
}
catch (UnauthorizedAccessException exIo)
{
logger?.LogError(exIo.ToString());
}
catch (Exception ex)
{
logger?.LogError(ex.ToString());
}
}
}
}
}
}