tidstagning/Relay.cs
2022-11-03 21:58:32 +01:00

150 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO.Ports;
using System.Threading;
namespace Tidstagning
{
class Relay
{
SerialPort com = new SerialPort();
struct SignalSpec
{
public uint duration;
public bool output_on;
};
Queue<SignalSpec> signals = new Queue<SignalSpec>();
bool processing_queue;
public Relay()
{
}
public bool Open(string ComPort)
{
if (com.IsOpen)
{
Close();
}
com.PortName = ComPort;
com.BaudRate = 9600;
try
{
com.Open();
return true;
}
catch (ArgumentException)
{
return false;
}
}
private void On()
{
Debug.WriteLine("Output on");
Set(0x00, 0x01);
}
private void Off()
{
Debug.WriteLine("Output off");
Set(0x00, 0x00);
}
/**
* Sound the horn for a given time
* Uses a thread to postpone the off call.
*/
public void Sound(uint time)
{
if (!com.IsOpen)
{
Debug.WriteLine("ComPort not open");
return;
}
Debug.WriteLine("Requesting horn for: " + time.ToString(new CultureInfo("da-DK")) + "ms");
SignalSpec on_signal;
on_signal.duration = time;
on_signal.output_on = true;
signals.Enqueue(on_signal);
SignalSpec gracePeriod;
gracePeriod.duration = time;
gracePeriod.output_on = false;
signals.Enqueue(gracePeriod);
if (processing_queue == false)
{
Run();
}
}
private void Run()
{
if (signals.Count == 0)
{
processing_queue = false;
}
else
{
processing_queue = true;
SignalSpec signal = signals.Peek();
if (signal.output_on)
{
On();
}
else
{
Off();
}
System.Threading.Timer cooldownTimer = new System.Threading.Timer(x =>
{
signals.Dequeue();
Run();
}, null, signal.duration, Timeout.Infinite);
}
}
private void Set(int output, byte state)
{
byte[] command = { 0xff, 0x01, state };
if (com.IsOpen)
{
Debug.WriteLine("COM: " + com.PortName + " Write: 0x" + Convert.ToString(command[2], 16));
com.Write(command, 0, 3);
}
}
public void Close()
{
if (com.IsOpen)
{
Off(); //Make sure the horn is off before closing the com port...
com.Close();
}
}
public static string[] GetPorts()
{
string[] ports;
if (SerialPort.GetPortNames().Length != 0)
{
ports = SerialPort.GetPortNames();
}
else
{
ports = new string[] { "N/A" };
}
return ports;
}
}
}