laatzen/Common/Hardware/Common.Hardware.SIRT/SIRTHub.cs
2025-04-28 10:10:33 +02:00

127 lines
3.8 KiB
C#

namespace Common.Hardware.SIRT
{
using Common.Hardware.SIRT.Tasks;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
public class SIRTHub
{
private static readonly ConcurrentDictionary<string, SIRTBroadcaster> broadcasters
= new ConcurrentDictionary<string, SIRTBroadcaster>();
public event Action<SIRTBroadcaster> Connected;
public event Action<SIRTBroadcaster> Disconnected;
public event Action<object> StateLogging;
public event Action<SIRTMessage> MessageProcessed;
public void Close(string portName)
{
if (broadcasters.TryRemove(portName, out var sirtBroadcaster))
{
var disconnectedEvent = new ManualResetEventSlim();
void SIRTBroadcaster_Disconnected(SIRTBroadcaster _sirtBroadcaster)
{
disconnectedEvent.Set();
this.Disconnected?.Invoke(_sirtBroadcaster);
}
sirtBroadcaster.Disconnected += SIRTBroadcaster_Disconnected;
sirtBroadcaster.Close();
disconnectedEvent.Wait(3000);
sirtBroadcaster.Disconnected -= SIRTBroadcaster_Disconnected;
sirtBroadcaster.MessageReceived -= this.Invoke_MessageProcessed;
}
}
public bool Start(SIRTTask task)
{
var started = false;
foreach (var broadcaster in broadcasters.Values)
{
if (broadcaster.Start(task))
{
started = true;
break;
}
}
return started;
}
public bool TryOpen(string portName, out string hexId, out int frequency)
{
hexId = default(string);
frequency = default(int);
var connectedEvent = new ManualResetEventSlim();
var sirtBroadcaster = new SIRTBroadcaster(portName);
void SIRTBroadcasterConnected(SIRTBroadcaster _)
{
broadcasters.GetOrAdd(portName, sirtBroadcaster);
connectedEvent.Set();
this.Connected?.Invoke(sirtBroadcaster);
}
void SIRTBroadcasterDisconnected(SIRTBroadcaster _)
{
connectedEvent.Set();
this.Disconnected?.Invoke(sirtBroadcaster);
}
sirtBroadcaster.Connected += SIRTBroadcasterConnected;
sirtBroadcaster.Disconnected += SIRTBroadcasterDisconnected;
sirtBroadcaster.Open();
connectedEvent.Wait(3000);
hexId = sirtBroadcaster.Id;
frequency = sirtBroadcaster.Frequency;
sirtBroadcaster.Connected -= SIRTBroadcasterConnected;
sirtBroadcaster.Disconnected -= SIRTBroadcasterDisconnected;
sirtBroadcaster.MessageReceived += this.Invoke_MessageProcessed;
return sirtBroadcaster.IsOpen;
}
public void Stop()
{
try
{
foreach (var broadcaster in broadcasters.Values.ToList())
{
broadcaster.Close();
}
broadcasters.Clear();
}
catch (Exception e)
{
this.Invoke_StateLogging(e);
}
}
private void Invoke_StateLogging(object state)
=> this.StateLogging?.Invoke($"{nameof(SIRTHub)}|{state}");
private void Invoke_StateLogging(object state, [CallerMemberName] string member = "")
=> this.StateLogging?.Invoke($"{nameof(SIRTHub)}|{member}|{state}");
private void Invoke_MessageProcessed(SIRTMessage message)
=> this.MessageProcessed?.Invoke(message);
}
}