using System.IO.Ports; using System.Text; using MaterialSkin.Controls; using Serilog; using VisionBuilder.UI.Common; using VisionBuilder.UI.Common.Processing; using VisionBuilder.UI.Statistics; namespace CandyboxPlugin.Modules.Barcode; public class CandyboxBarcodeReader : IVisionBuilderModule { private readonly ILoadingService _loadingService; private readonly CandyboxBarcodeReaderSettings _settings; private readonly IRecognitionControl _recognitionControl; private readonly VisionBuilderStatistics _statistics; private SerialPort _port; public EReaderState _readerState = EReaderState.ReadingRecipe; private MaterialCancellableLoader? _loader; public CandyboxBarcodeReader(CandyboxBarcodeReaderSettings settings, IRecognitionControl recognitionControl, VisionBuilderStatistics statistics) { _settings = settings; _recognitionControl = recognitionControl; _statistics = statistics; } private void _port_DataReceived(object sender, SerialDataReceivedEventArgs e) { Thread.Sleep(100); if(_readerState == EReaderState.ReadingRecipe) ReadRecipe(); if (_readerState == EReaderState.ReadingAUF) ReadAUF(); } private void ReadRecipe() { if (_recognitionControl.IsRunning) return; byte[] buffer = new byte[_port.BytesToRead]; _port.Read(buffer, 0, _port.BytesToRead); var data = Encoding.ASCII.GetString(buffer).Trim(); var recipes = _recognitionControl.GetRecipesData(); string searchString = data; if (_settings.BarcodeRecipeMappings.Any(x => x.Barcode == searchString)) { searchString = _settings.BarcodeRecipeMappings.First(x => x.Barcode == searchString).RecipeName; } var existingRecipe = recipes.FirstOrDefault(x => x.RecipeName == searchString); if (existingRecipe == null) { Log.Warning("No matching recipe found for data: {Data}", data); return; } _recognitionControl.SetRecipe(existingRecipe); _readerState = EReaderState.ReadingAUF; _loader = new MaterialCancellableLoader(); _loader.StartLoading("Waiting for AUF..."); _loader.LoadingCancelled += CancelWaiting; } private void CancelWaiting(object? sender, string e) { _readerState = EReaderState.ReadingRecipe; _loader.Close(); _loader.LoadingCancelled -= CancelWaiting; _loader = null; } private void ReadAUF() { byte[] buffer = new byte[_port.BytesToRead]; _port.Read(buffer, 0, _port.BytesToRead); var data = Encoding.ASCII.GetString(buffer).Trim(); if (_loader != null) { _loader.Close(); _loader.LoadingCancelled -= CancelWaiting; _loader = null; } _statistics.Metadata = data; _recognitionControl.Start(); _readerState = EReaderState.ReadingAUF; } public void InitializeModule() { try { _port = new SerialPort(_settings.ComPort, 9600); _port.Open(); _port.DataReceived += _port_DataReceived; } catch (Exception e) { Log.Warning(e, "Failed to open com-port"); } } }