159 lines
5.2 KiB
C#
159 lines
5.2 KiB
C#
using System.IO.Ports;
|
|
using System.Text;
|
|
|
|
namespace c64_inteface;
|
|
|
|
public class MonitorBackgroundService : IHostedService, IDisposable
|
|
{
|
|
private const string ArduinoId = "F28339B0-78C6-4445-905A-76F77F667D95";
|
|
private const string ArduinoPingMsg = "ping " + ArduinoId + "\n";
|
|
private const string ArduinoPongMsg = "pong " + ArduinoId;
|
|
|
|
private readonly ILogger<MonitorBackgroundService> _logger;
|
|
private readonly ArduinoMessageContainer _arduinoMessageContainer;
|
|
private readonly ArduinoHub _arduinoHub;
|
|
private SerialPort? _arduinoPort;
|
|
|
|
public MonitorBackgroundService(ILogger<MonitorBackgroundService> logger, ArduinoMessageContainer arduinoMessageContainer, ArduinoHub arduinoHub)
|
|
{
|
|
_logger = logger;
|
|
_arduinoMessageContainer = arduinoMessageContainer;
|
|
_arduinoHub = arduinoHub;
|
|
}
|
|
|
|
public Task StartAsync(CancellationToken stoppingToken)
|
|
{
|
|
_logger.LogInformation("{Service} running.", nameof(MonitorBackgroundService));
|
|
Task.Run(() => RunServiceAsync(stoppingToken), stoppingToken);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private async Task DoWork(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("DoWork running...");
|
|
while (!cancellationToken.IsCancellationRequested)
|
|
{
|
|
if (_arduinoMessageContainer.Ready)
|
|
{
|
|
try
|
|
{
|
|
await _arduinoHub.SendMessage(new ArduinoMessage
|
|
{
|
|
Status = "online",
|
|
StatusText =
|
|
$"Sending message with {Encoding.ASCII.GetBytes(_arduinoMessageContainer.Message).Length} bytes..."
|
|
});
|
|
_logger.LogInformation("Sending message: {Message}", _arduinoMessageContainer.Message);
|
|
|
|
|
|
await _arduinoHub.SendMessage(new ArduinoMessage
|
|
{
|
|
Status = "online",
|
|
StatusText = "Done"
|
|
});
|
|
|
|
|
|
_arduinoPort?.WriteLine(_arduinoMessageContainer.Message);
|
|
|
|
_arduinoMessageContainer.Ready = false;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
await _arduinoHub.SendMessage(new ArduinoMessage()
|
|
{
|
|
StatusText = "Error: " + e.Message,
|
|
Status = "offline"
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task RunServiceAsync(CancellationToken cancellationToken)
|
|
{
|
|
await FindArduinoPort(cancellationToken);
|
|
await DoWork(cancellationToken);
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken stoppingToken)
|
|
{
|
|
_logger.LogInformation("{Service} is stopping.", nameof(MonitorBackgroundService));
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private async Task FindArduinoPort(CancellationToken cancellationToken)
|
|
{
|
|
while (_arduinoPort is null && !cancellationToken.IsCancellationRequested)
|
|
{
|
|
await _arduinoHub.SendMessage(new ArduinoMessage()
|
|
{
|
|
StatusText = "Searching for Arduino...",
|
|
Status = "offline"
|
|
});
|
|
|
|
var ports = SerialPort.GetPortNames().ToList();
|
|
|
|
_logger.LogInformation("available ports: {Ports}", ports);
|
|
|
|
foreach (var portName in ports)
|
|
{
|
|
var port = new SerialPort(portName, 9600);
|
|
|
|
port.ReadTimeout = 1000;
|
|
|
|
try
|
|
{
|
|
port.Open();
|
|
await Task.Delay(2000, cancellationToken);
|
|
}
|
|
catch (IOException)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
port.WriteLine(ArduinoPingMsg);
|
|
|
|
try
|
|
{
|
|
var response = port.ReadLine();
|
|
|
|
|
|
_logger.LogInformation(response);
|
|
|
|
if (!response.Contains(ArduinoPongMsg))
|
|
{
|
|
_logger.LogInformation("{portName} not my arduino", portName);
|
|
port.Close();
|
|
continue;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, ex.Message);
|
|
_logger.LogInformation("{portName} did not respond", portName);
|
|
continue;
|
|
}
|
|
|
|
_logger.LogInformation("Arduino found on {portName}", portName);
|
|
await _arduinoHub.SendMessage(new ArduinoMessage()
|
|
{
|
|
StatusText = $"Arduino found on {portName}",
|
|
Status = "online"
|
|
});
|
|
|
|
_arduinoPort = port;
|
|
|
|
return;
|
|
}
|
|
|
|
await Task.Delay(1000, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_arduinoPort?.Close();
|
|
_arduinoPort?.Dispose();
|
|
}
|
|
} |