common/Hardware/Common.Hardware.Ports/SerialPortBase.cs
2026-04-23 17:50:07 +02:00

180 lines
5.1 KiB
C#

namespace Common.Hardware.Ports
{
using System;
using System.Collections.Concurrent;
using System.IO.Ports;
using System.Threading;
public abstract class SerialPortBase
{
private static readonly ConcurrentDictionary<String, System.IO.Ports.SerialPort> serialPorts
= new ConcurrentDictionary<String, System.IO.Ports.SerialPort>();
private readonly SerialPortSettings settings;
public SerialPortBase(SerialPortSettings settings)
{
this.settings = settings;
this.PortName = settings.PortName;
}
public event Action<String> Logging;
public String PortName { get; }
public Int32 ReadSize { get; private set; }
public virtual void Close()
{
try
{
this.ReadSize = default(Int32);
if (serialPorts.TryRemove(this.PortName, out var serialPort))
{
if (serialPort != null)
{
serialPort.Close();
serialPort.Dispose();
serialPort = null;
this.LogMessage($"Disconnected: {this}");
}
else
{
this.LogMessage($"{this.PortName} is null!");
}
}
}
catch (Exception e)
{
this.LogMessage(e.ToString());
}
}
public virtual void EnsureConnected()
{
if (!this.TryGetSerialPort(out var serialPort))
{
this.Open();
}
}
public virtual void Open()
{
this.Close();
try
{
this.ReadSize = default(Int32);
var serialPort = new System.IO.Ports.SerialPort
{
BaudRate = this.settings.BaudRate,
DataBits = this.settings.DataBits,
Parity = this.settings.Parity,
PortName = this.settings.PortName,
StopBits = this.settings.StopBits
};
if (serialPorts.TryAdd(serialPort.PortName, serialPort))
{
serialPort.Open();
if (serialPort.IsOpen)
{
this.ReadSize = serialPort.ReadBufferSize;
}
this.LogMessage($"Connected: {this}");
}
else
{
this.LogMessage($"{this.PortName} can not be addedd!");
}
}
catch (Exception e)
{
this.LogMessage(e.ToString());
}
}
public override String ToString()
=> serialPorts.TryGetValue(this.PortName, out var serialPort)
? $"{serialPort.PortName}, "
+ $"{serialPort.BaudRate}, "
+ $"{serialPort.DataBits}, "
+ $"{serialPort.Parity}, "
+ $"{serialPort.StopBits}"
: $"{this.settings.PortName}, "
+ $"{this.settings.BaudRate}, "
+ $"{this.settings.DataBits}, "
+ $"{this.settings.Parity}, "
+ $"{this.settings.StopBits}";
public virtual Byte[] Write(params Byte[] data)
{
this.Write(data, 0, data.Length);
return data;
}
protected void LogMessage(String message) => this.Logging?.Invoke(message);
protected Byte[] Read(Int32 sleep = 1)
{
Thread.Sleep(sleep);
var bytes = new Byte[0];
if (this.TryGetSerialPort(out var serialPort))
{
try
{
var buffer = new Byte[this.ReadSize];
var length = serialPort.Read(buffer, 0, this.ReadSize);
Array.Resize(ref bytes, length);
Array.Copy(buffer, 0, bytes, 0, length);
}
catch (Exception e)
{
this.LogMessage(e.ToString());
}
}
else
{
this.LogMessage($"{this.PortName} dose not exists!");
}
return bytes;
}
protected void Write(Byte[] bytes, Int32 start, Int32 length, Int32 sleep = 1)
{
if (this.TryGetSerialPort(out var serialPort))
{
try
{
serialPort.Write(bytes, start, length);
}
catch (Exception e)
{
this.LogMessage(e.ToString());
}
}
else
{
this.LogMessage($"{this.PortName} dose not exists!");
}
Thread.Sleep(sleep);
}
private Boolean TryGetSerialPort(out System.IO.Ports.SerialPort serialPort)
=> serialPorts.TryGetValue(this.PortName, out serialPort)
&& serialPort?.IsOpen == true;
}
}