using Inspectron.Statistics; using Lindt.Colorballs.Duo.Utils; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Reflection.PortableExecutable; using Ninject; using Serilog; using VisionBuilder.UI.Common; using VisionBuilder.UI.Common.Commands; using VisionBuilder.UI.Common.RecipeProcessing; namespace VisionBuilder.UI.Statistics { public class VisionBuilderStatistics:IInitializable { private CsvStatistics _csvStatistics; private readonly VisionBuilderStatisticsSettings _settings; private string _filePath; private readonly IRecognitionControl _recognitionControl; private readonly ILoadingService _loadingService; private DateTime _startTime; private string _currentRecipe; private string _fileName; private string _directoryPath; private const string BY_EVENTS_FILE_NAME = "statistics_by_events.csv"; private const string MONTHLY_FILE_NAME = "statistics_month.csv"; private const string EMPTY_DATE = ""; private const string EMPTY_TIME = ""; public VisionBuilderStatistics(VisionBuilderStatisticsSettings settings, IRecognitionControl recognitionControl, ILoadingService loadingService) { _settings = settings; _recognitionControl = recognitionControl; _loadingService = loadingService; _recognitionControl.SessionStarted += _recognitionControl_SessionStarted; _recognitionControl.ImageProcessed += _recognitionControl_ImageProcessed; _recognitionControl.SessionEnded += _recognitionControl_SessionEnded; } private void _recognitionControl_SessionEnded(SessionEndedEvent obj) { _loadingService.StartLoading("Writing statistics for " + _settings.CameraName); try { _csvStatistics.WriteLine([_startTime.ToString("d"), _startTime.ToString("T"), DateTime.Now.ToString("d"), DateTime.Now.ToString("T"), "", "", ""]); _csvStatistics.Dispose(); WriteFinalStatistics(); } finally { _loadingService.StopLoading("Writing statistics for " + _settings.CameraName); } } private void _recognitionControl_ImageProcessed(ImageProcessedEvent obj) { if (obj.HasError) { RecordBadImage(obj.ErrorNames[0]); } } private void _recognitionControl_SessionStarted(SessionStartedEvent obj) { _startTime = DateTime.Now; _currentRecipe = obj.RecipeName; _fileName = "tmp_"+Guid.NewGuid().ToString()+".csv"; _directoryPath = PathSettingsUtils.ConvertVariables(_settings.PathTemplate, DateTime.Now, DateTime.Now, obj.RecipeName, cameraName: _settings.CameraName); _filePath = Path.Combine(_directoryPath, _fileName); var headers = new[] { _settings.StartDateColumnName, _settings.StartTimeColumnName, _settings.EndDateColumnName, _settings.EndTimeColumnName, _settings.ErrorTimeColumnName, _settings.ProductColumnName, _settings.ErrorColumnName }; if (!Directory.Exists(Path.GetDirectoryName(_filePath))) { Directory.CreateDirectory(Path.GetDirectoryName(_filePath)); } _csvStatistics = new CsvStatistics(_filePath, headers); _csvStatistics.WriteLine([_startTime.ToString("d"), _startTime.ToString("T")]); // session started _defects = new ConcurrentDictionary(); } ConcurrentDictionary _defects = new(); private void RecordBadImage(string defectName) { _csvStatistics.WriteLine( [_startTime.ToString("d"), _startTime.ToString("T"), EMPTY_DATE, EMPTY_TIME, DateTime.Now.ToString("T"), _currentRecipe, defectName] ); _defects.AddOrUpdate(defectName, 1, (key, oldValue) => oldValue + 1); } private void WriteMonthStatistics(string filename) { // read second line to get the start time var lines = File.ReadAllLines(filename); var lastLine = lines[^1]; if (lines.Length < 2) return; // no data to write var startDate = DateTime.Parse(lastLine.Split(',')[0]); var startTime = DateTime.Parse(lastLine.Split(',')[1]); var endDate = DateTime.Parse(lastLine.Split(',')[2]); var endTime = DateTime.Parse(lastLine.Split(',')[3]); // all must be non-empty if (startDate == DateTime.MinValue || startTime == DateTime.MinValue || endDate == DateTime.MinValue || endTime == DateTime.MinValue) { Log.Error("Invalid date or time in statistics file: " + filename); throw new InvalidOperationException("Invalid date or time in statistics file: " + filename); } } private void WriteFinalStatistics() { try { var tmpFiles = Directory.GetFiles(_directoryPath, "tmp_*"); // order by creation time Array.Sort(tmpFiles, (x, y) => File.GetCreationTime(x).CompareTo(File.GetCreationTime(y))); foreach (var file in tmpFiles) { var finalFileName = Path.Combine(_directoryPath, BY_EVENTS_FILE_NAME); var lines = File.ReadAllLines(file); File.AppendAllLines(finalFileName, lines.Skip(1)); // skip header WriteMonthStatistics(file); File.Delete(file); } } catch (Exception e) { Log.Error("Error writing statistics for " + _settings.CameraName+ e); } } public void Initialize() { WriteFinalStatistics(); } } }