file-watcher/Helpers/HelperSerial.cs
Mike Phares 27ba309e88 HelperEDADatabase
HelperEAFProgramData
HelperCompass
HelperInfinityQS
HelperSerial
HelperTCP
dotnet_analyzer_diagnostic
2024-04-16 10:32:55 -07:00

281 lines
11 KiB
C#

using File_Watcher.Models;
using System.Diagnostics;
using System.IO.Ports;
namespace File_Watcher.Helpers;
internal static partial class HelperSerial
{
private record Record(List<byte> Data,
string Destination,
ILogger<Worker> Logger,
CancellationToken CancellationToken);
private static Record? _Record;
private static SerialPort? _SerialPort;
private static void PCLToPDF(string fullPath)
{
string ghostPCLFileName = Path.Combine(AppContext.BaseDirectory, "gpcl6win64.exe");
if (!File.Exists(ghostPCLFileName))
throw new Exception("Ghost PCL FileName doesn't Exist!");
string lincPDFCFileName = Path.Combine(AppContext.BaseDirectory, "LincPDFC.exe");
if (!File.Exists(lincPDFCFileName))
throw new Exception("Linc PDFC FileName doesn't Exist!");
string pdfFile;
string fileName;
string arguments;
for (int i = 1; i < 3; i++)
{
if (i == 1)
{
fileName = ghostPCLFileName;
pdfFile = $"{fullPath}-ghost.pdf";
arguments = $"-dSAFER -dBATCH -dNOPAUSE -sOutputFile=\"{pdfFile}\" -sDEVICE=pdfwrite \"{fullPath}\"";
// arguments = $"-dSAFER -dBATCH -dNOPAUSE -dFIXEDMEDIA -dFitPage -dAutoRotatePages=/All -dDEVICEWIDTHPOINTS=792 -dDEVICEHEIGHTPOINTS=612 -sOutputFile=\"{pdfFile}\" -sDEVICE=pdfwrite \"{fullPath}\"";
}
else if (i == 2)
{
fileName = lincPDFCFileName;
pdfFile = $"{fullPath}-linc.pdf";
arguments = $"-i \"{fullPath}\" -o \"{pdfFile}\"";
}
else
throw new Exception();
Process process = Process.Start(fileName, arguments);
long breakAfter = DateTime.Now.AddSeconds(30).Ticks;
for (short j = 0; j < short.MaxValue; j++)
{
if (process.HasExited || process.WaitForExit(500) || DateTime.Now.Ticks > breakAfter)
break;
}
if (!File.Exists(pdfFile))
throw new Exception("PDF file wasn't created");
}
}
private static List<byte> GetBytes(List<byte> bytes)
{
List<byte> results = [];
foreach (byte @byte in bytes)
results.Add(@byte);
return results;
}
private static void SerialPortWrite(string destination, DateTime dateTime, List<byte> bytes, string v, bool convert)
{
if (_SerialPort is null)
throw new NullReferenceException(nameof(_SerialPort));
string directory = Path.Combine(destination, _SerialPort.PortName);
if (!Directory.Exists(destination))
_ = Directory.CreateDirectory(destination);
string fileName = Path.Combine(directory, $"{_SerialPort.PortName}-{v}-{dateTime:yyyyMMddHHmmssfff}.pcl");
File.WriteAllBytes(fileName, bytes.ToArray());
if (convert)
PCLToPDF(fileName);
}
private static int? SearchBytes(byte[] haystack, byte[] needle)
{
int? result = null;
int k;
int len = needle.Length;
int limit = haystack.Length - len;
for (int i = 0; i <= limit; i++)
{
k = 0;
for (; k < len; k++)
{
if (needle[k] != haystack[i + k])
break;
}
if (k == len)
{
result = i;
break;
}
}
return result;
}
private static bool Contains()
{
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
bool result;
// char endOfLine = '\u001b';
// lock (_Record)
// result = _Record.Data.Contains(Convert.ToByte(endOfLine));
// if (!result)
// {
// }
int? index = null;
// byte[] pageDelimiter =
// {
// Convert.ToByte(27),
// Convert.ToByte(69)
// };
lock (_Record)
{
byte[] bytes = _Record.Data.ToArray();
// index = Array.IndexOf(bytes, pageDelimiter);
// if (index == -1)
// {
// }
byte[] documentDelimiter =
[
Convert.ToByte(32),
Convert.ToByte(83),
Convert.ToByte(116),
Convert.ToByte(97),
Convert.ToByte(116),
Convert.ToByte(105),
Convert.ToByte(115),
Convert.ToByte(116),
Convert.ToByte(105),
Convert.ToByte(99),
Convert.ToByte(115),
Convert.ToByte(58)
];
index = SearchBytes(bytes, documentDelimiter);
}
result = index is not null;
return result;
}
private static void PinChanged(object sender, SerialPinChangedEventArgs serialPinChangedEventArgs)
{
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
try
{ _Record.Logger.LogDebug($"EventType = {serialPinChangedEventArgs.EventType}"); }
catch (Exception exception) { _Record.Logger.LogError(exception, "Error"); }
}
private static void DataReceived(object? sender, SerialDataReceivedEventArgs dataReceivedEventArgs)
{
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
if (_SerialPort is null)
throw new NullReferenceException(nameof(_SerialPort));
DateTime dateTime = DateTime.Now;
try
{
_Record.Logger.LogDebug($"EventType = {dataReceivedEventArgs.EventType}");
List<byte>? bytes;
lock (_Record)
{
byte[] buffer = new byte[_SerialPort.BytesToRead];
int count = _SerialPort.Read(buffer, 0, buffer.Length);
if (count == 0)
bytes = null;
else
{
_Record.Data.AddRange(buffer.Take(count));
bytes = dataReceivedEventArgs.EventType != SerialData.Eof ? null : GetBytes(_Record.Data);
}
}
if (bytes is not null)
SerialPortWrite(_Record.Destination, dateTime, bytes, nameof(SerialData.Eof), convert: false);
}
catch (Exception exception)
{
string fileName = Path.Combine(_Record.Destination, _SerialPort.PortName, $"{dateTime:yyyyMMddHHmmssfff}.err");
File.WriteAllLines(fileName, [exception.Message, Environment.NewLine, Environment.NewLine, string.Concat(exception.StackTrace)]);
}
}
private static void ErrorReceived(object sender, SerialErrorReceivedEventArgs serialErrorReceivedEventArgs)
{
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
try
{ _Record.Logger.LogDebug($"EventType = {serialErrorReceivedEventArgs.EventType}"); }
catch (Exception exception) { _Record.Logger.LogError(exception, "Error"); }
}
private static void SerialPortWriteConditionally(SerialConfiguration serialConfiguration, ILogger<Worker> logger)
{
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
DateTime dateTime = DateTime.Now;
logger.LogDebug($"Worker:Process:SerialPort running at: {dateTime} serial port {serialConfiguration.PortName} status with Length = {_Record.Data.Count}.");
bool contains = Contains();
if (contains)
{
List<byte> bytes;
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
lock (_Record)
{
bytes = GetBytes(_Record.Data);
_Record.Data.Clear();
}
SerialPortWrite(_Record.Destination, dateTime, bytes, nameof(Contains), convert: true);
}
}
private static void SerialPortClose()
{
if (_SerialPort is not null)
{
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
lock (_Record)
{
_SerialPort.Close();
int length = _Record is null ? 0 : _Record.Data.Count;
if (_Record is null)
throw new NullReferenceException(nameof(_Record));
_Record.Logger.LogDebug($"Serial port {_SerialPort.PortName} closed with Length = {length}.");
}
}
}
internal static bool ReadWrite(AppSettings appSettings, ILogger<Worker> logger, CancellationToken cancellationToken)
{
_Record ??= new([], appSettings.SerialConfiguration.Destination, logger, cancellationToken);
if (_SerialPort is null)
{
string ghostPCLFileName = Path.Combine(AppContext.BaseDirectory, appSettings.SerialConfiguration.GhostPCLFileName);
if (!File.Exists(ghostPCLFileName))
throw new Exception("Ghost PCL FileName doesn't Exist!");
string lincPDFCFileName = Path.Combine(AppContext.BaseDirectory, appSettings.SerialConfiguration.LincPDFCFileName);
if (!File.Exists(lincPDFCFileName))
throw new Exception("Linc PDFC FileName doesn't Exist!");
_SerialPort = new SerialPort
{
PortName = appSettings.SerialConfiguration.PortName,
// BaudRate = 9600,
BaudRate = 115200,
DataBits = 8,
Parity = Parity.None,
StopBits = StopBits.One,
// Handshake = Handshake.None,
Handshake = Handshake.RequestToSend,
// DtrEnable = true,
// RtsEnable = true,
ReadTimeout = 5000
};
string[] portNames = SerialPort.GetPortNames();
string[] matchPortNames = (from l in portNames where l == appSettings.SerialConfiguration.PortName select l).ToArray();
if (matchPortNames.Length == 0)
throw new Exception($"Didn't find matching COM port! {string.Join(Environment.NewLine, portNames)}");
if (matchPortNames.Length != 1)
throw new Exception($"Matching count is more than one! {string.Join(Environment.NewLine, portNames)}");
_SerialPort.Open();
_SerialPort.DiscardInBuffer();
_SerialPort.DiscardOutBuffer();
logger.LogDebug("Waiting for data.");
_SerialPort.PinChanged += PinChanged;
_SerialPort.DataReceived += DataReceived;
_SerialPort.ErrorReceived += ErrorReceived;
}
SerialPortWriteConditionally(appSettings.SerialConfiguration, logger);
if (cancellationToken.IsCancellationRequested)
SerialPortClose();
return true;
}
}