tidstagning/Tidstagning/Relay.cs
Jens True 86cfc546ac
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
Clean up "Using" to remove implied includes.
2021-12-15 17:01:02 +01:00

134 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Threading;
namespace Tidstagning
{
class Relay
{
SerialPort com;
System.Threading.Timer? cooldownTimer;
struct SignalSpec
{
public uint duration;
public bool output_on;
};
Queue<SignalSpec> signals = new Queue<SignalSpec>();
bool processing_queue = false;
public Relay(string ComPort)
{
com = new SerialPort();
com.PortName = ComPort;
com.BaudRate = 9600;
try
{
com.Open();
}
catch
{
}
}
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)
{
Debug.WriteLine("Requesting horn for: " + time.ToString() + "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();
}
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;
}
}
}