BOB/DeviceCommand/Device/LQ7500-D.cs

255 lines
8.2 KiB
C#

using Common.Attributes;
using DeviceCommand.Base;
using Logger;
using System;
using System.IO.Ports;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace DeviceCommand.Device
{
[BOBCommand]
public class LQ7500_D : ModbusRtu
{
public LQ7500_D(string , int , int , StopBits , Parity , int , int )
{
ConfigureDevice(, , , , , , );
}
#region
private CancellationTokenSource? _cancellationTokenSource;
private Task? _heartbeatTask;
private const int HeartbeatInterval = 3000;
public bool IsActive = false;
public int ReConnectionAttempts = 0;
public const int MaxReconnectAttempts = 10;
public override async Task<bool> ConnectAsync(CancellationToken ct = default)
{
try
{
if (SerialPort.IsOpen)
SerialPort.Close();
SerialPort.PortName = PortName;
SerialPort.BaudRate = BaudRate;
SerialPort.DataBits = DataBits;
SerialPort.StopBits = StopBits;
SerialPort.Parity = Parity;
SerialPort.ReadTimeout = ReadTimeout;
SerialPort.WriteTimeout = WriteTimeout;
if (SerialPort.IsOpen) return true;
SerialPort.Open();
IsActive = true;
StartHeartbeat();
return true;
}
finally
{
}
}
public override void Close()
{
StopHeartbeat();
if (SerialPort.IsOpen) SerialPort.Close();
}
public void StartHeartbeat()
{
if (_heartbeatTask != null && !_heartbeatTask.IsCompleted)
return;
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
_cancellationTokenSource = new CancellationTokenSource();
_heartbeatTask = Task.Run(() => HeartbeatLoop(_cancellationTokenSource.Token));
}
public void StopHeartbeat()
{
try
{
IsActive = false;
_cancellationTokenSource.Cancel();
_heartbeatTask = null;
}
catch { }
_heartbeatTask = null;
}
private async Task HeartbeatLoop(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
await Task.Delay(HeartbeatInterval, ct);
try
{
await WriteSingleRegisterAsync(1,0,1);
}
catch (Exception ex)
{
IsActive = false;
ReConnectionAttempts++;
if (ReConnectionAttempts > MaxReconnectAttempts)
{
LoggerHelper.InfoWithNotify("IT6724C重连多次失败");
StopHeartbeat();
return;
}
await ReconnectDevice(ct);
}
}
}
private async Task ReconnectDevice(CancellationToken ct)
{
try
{
bool ok = await ConnectAsync(ct);
if (ok)
ReConnectionAttempts = 0;
}
catch { }
}
#endregion
public byte { get; set; } = 1; // 默认从站地址
private static readonly int[] Pow10Table =
{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
private async Task ()
{
if (SerialPort == null || !SerialPort.IsOpen)
await ConnectAsync();
}
#region
public virtual async Task<ushort> ()
{
await ();
return (await ReadHoldingRegistersAsync(, 35, 1))[0];
}
public virtual async Task<double> (ushort = 0)
{
await ();
if ( == 0) = await ();
var data = await ReadHoldingRegistersAsync(, 0, 1);
return Math.Round(data[0] / (double)Pow10Table[], + 1);
}
public virtual async Task<double> (ushort = 0)
{
await ();
if ( == 0) = await ();
var data = await ReadHoldingRegistersAsync(, 1, 1);
return data[0] / (double)Pow10Table[];
}
public virtual async Task<ushort> ()
{
await ();
return (await ReadHoldingRegistersAsync(, 1, 1))[0];
}
public virtual async Task<ushort> ()
{
await ();
return (await ReadHoldingRegistersAsync(, 3, 1))[0];
}
public virtual async Task<ushort> ()
{
await ();
return (await ReadHoldingRegistersAsync(, 4, 1))[0];
}
public virtual async Task<double> ()
{
await ();
var data = await ReadHoldingRegistersAsync(, 17, 1);
return Math.Round(data[0] / 10.0, 1);
}
#endregion
#region
public virtual async Task (double )
{
await ();
short temp = (short)( * 10);
ushort result = Unsafe.As<short, ushort>(ref temp);
await WriteSingleRegisterAsync(, 24, result);
}
public virtual async Task (bool )
{
await ();
await WriteSingleRegisterAsync(, 3, (ushort)( ? 1 : 0));
}
public virtual async Task (bool )
{
await ();
await WriteSingleRegisterAsync(, 4, (ushort)( ? 1 : 0));
}
public virtual async Task (double )
{
await ();
short temp = (short)( * 100);
ushort result = Unsafe.As<short, ushort>(ref temp);
await WriteSingleRegisterAsync(, 2, result);
}
public virtual async Task (double )
{
await ();
short temp = (short)( * 100);
ushort result = Unsafe.As<short, ushort>(ref temp);
await WriteSingleRegisterAsync(, 5, result);
}
public virtual async Task (double )
{
await ();
short temp = (short)( * 100);
ushort result = Unsafe.As<short, ushort>(ref temp);
await WriteSingleRegisterAsync(, 6, result);
}
public virtual async Task (double , double )
{
await ();
short v1 = (short)( * 100);
short v2 = (short)( * 100);
ushort[] data = MemoryMarshal.Cast<short, ushort>(new short[] { v1, v2 }).ToArray();
await WriteSingleRegisterAsync(, 30, data[0]);
await Task.Delay(5);
await WriteSingleRegisterAsync(, 31, data[1]);
}
public virtual async Task (double )
{
await ();
short v1 = (short)( * 100);
ushort result = Unsafe.As<short, ushort>(ref v1);
await WriteSingleRegisterAsync(, 32, result);
}
#endregion
}
}