218 lines
7.8 KiB
C#
218 lines
7.8 KiB
C#
using Inspectron.Statistics;
|
|
using Lindt.Colorballs.Duo.Utils;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Reflection.PortableExecutable;
|
|
using Ninject;
|
|
using Serilog;
|
|
using VisionBuilder.UI.Common;
|
|
using VisionBuilder.UI.Common.Commands;
|
|
using VisionBuilder.UI.Common.Processing;
|
|
|
|
namespace VisionBuilder.UI.Statistics
|
|
{
|
|
public class VisionBuilderStatistics:IVisionBuilderModule,IDisposable
|
|
{
|
|
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 int _total = 0;
|
|
|
|
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 = "";
|
|
private const string DATE_FORMAT = "dd.MM.yyyy";
|
|
private const string TIME_FORMAT = "HH:mm:ss";
|
|
public bool DoNotDeleteTempFiles { get; set; } = false;
|
|
|
|
public VisionBuilderStatistics(VisionBuilderStatisticsSettings settings, IRecognitionControl recognitionControl, ILoadingService loadingService)
|
|
{
|
|
_settings = settings;
|
|
_recognitionControl = recognitionControl;
|
|
_loadingService = loadingService;
|
|
|
|
|
|
}
|
|
|
|
public string Metadata { get; set; } = "";
|
|
|
|
private void _recognitionControl_SessionEnded(SessionEndedEvent obj)
|
|
{
|
|
if (_csvStatistics == null)
|
|
{
|
|
Log.Warning("Session ended but CSV statistics is null, nothing to do.");
|
|
return;
|
|
}
|
|
var endedAt = obj.SessionEnded;
|
|
_endTime = endedAt;
|
|
Log.Information("Start processing statistics");
|
|
_loadingService.StartLoading("Writing statistics for " + _settings.CameraName);
|
|
try
|
|
{
|
|
_csvStatistics.WriteLine([_startTime.ToString(DATE_FORMAT), _startTime.ToString(TIME_FORMAT), endedAt.ToString(DATE_FORMAT), endedAt.ToString(TIME_FORMAT), "", "", ""]);
|
|
_csvStatistics.Dispose();
|
|
_csvStatistics = null;
|
|
|
|
WriteFinalStatistics();
|
|
}
|
|
finally
|
|
{
|
|
_loadingService.StopLoading("Writing statistics for " + _settings.CameraName);
|
|
Log.Information("End processing statistics");
|
|
}
|
|
}
|
|
|
|
private void _recognitionControl_ImageProcessed(ImageProcessedEvent obj)
|
|
{
|
|
var sw = Stopwatch.StartNew();
|
|
_total++;
|
|
if (obj.HasError)
|
|
{
|
|
RecordBadImage(obj.ErrorNames[0]);
|
|
}
|
|
sw.Stop();
|
|
Log.Debug($"Recording statistics took {sw.ElapsedMilliseconds} ms");
|
|
}
|
|
|
|
private void _recognitionControl_SessionStarted(SessionStartedEvent obj)
|
|
{
|
|
_startTime = obj.SessionStarted;
|
|
_total = 0;
|
|
_currentRecipe = obj.RecipeName;
|
|
_fileName = BY_EVENTS_FILE_NAME;
|
|
_directoryPath = PathSettingsUtils.ConvertVariables(_settings.PathTemplate, _startTime, _startTime,
|
|
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, _settings.MetadataColumnName };
|
|
if (!Directory.Exists(Path.GetDirectoryName(_filePath)))
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(_filePath));
|
|
}
|
|
_csvStatistics = new CsvStatistics(_filePath, headers);
|
|
_csvStatistics.WriteLine([_startTime.ToString(DATE_FORMAT), _startTime.ToString(TIME_FORMAT)]); // session started
|
|
_defects = new ConcurrentDictionary<string, int>();
|
|
}
|
|
|
|
ConcurrentDictionary<string, int> _defects = new();
|
|
private DateTime _endTime;
|
|
|
|
private void RecordBadImage(string defectName)
|
|
{
|
|
|
|
_csvStatistics.WriteLine(
|
|
|
|
[_startTime.ToString(DATE_FORMAT), _startTime.ToString(TIME_FORMAT), EMPTY_DATE, EMPTY_TIME, DateTime.Now.ToString(TIME_FORMAT), _currentRecipe, defectName, Metadata]
|
|
|
|
);
|
|
|
|
_defects.AddOrUpdate(defectName, 1, (key, oldValue) => oldValue + 1);
|
|
}
|
|
|
|
private void WriteMonthStatistics()
|
|
{
|
|
|
|
var startDate = _startTime.Date;
|
|
var startTime = _startTime;
|
|
var endDate = _endTime.Date;
|
|
var endTime = _endTime;
|
|
|
|
var monthFilePath = Path.Combine(_directoryPath, MONTHLY_FILE_NAME);
|
|
|
|
var monthStatistics = new CsvStatistics(monthFilePath, [
|
|
|
|
]);
|
|
|
|
monthStatistics.WriteLine(
|
|
["Start", _startTime.ToString($"{DATE_FORMAT} {TIME_FORMAT}")]
|
|
);
|
|
monthStatistics.WriteLine([
|
|
_settings.MetadataColumnName, Metadata
|
|
]);
|
|
monthStatistics.WriteLine(
|
|
[_settings.ProductColumnName, _currentRecipe]
|
|
);
|
|
monthStatistics.WriteLine(
|
|
[_settings.ErrorColumnName, "Amount"]
|
|
);
|
|
|
|
foreach (var defect in _defects)
|
|
{
|
|
monthStatistics.WriteLine(
|
|
[defect.Key, defect.Value.ToString()]
|
|
);
|
|
}
|
|
|
|
var totalDefects = 0;
|
|
foreach (var defect in _defects)
|
|
{
|
|
totalDefects += defect.Value;
|
|
}
|
|
|
|
monthStatistics.WriteLine([]);
|
|
monthStatistics.WriteLine(
|
|
["Total errors", totalDefects.ToString()]
|
|
);
|
|
monthStatistics.WriteLine(
|
|
["Total produced(including errors)", _total.ToString()]
|
|
);
|
|
|
|
var percentage = _total > 0 ? (double)totalDefects / _total * 100 : 0;
|
|
|
|
monthStatistics.WriteLine(
|
|
["Error rate", percentage.ToString("F2") + "%"]
|
|
);
|
|
|
|
monthStatistics.WriteLine(
|
|
[
|
|
"End", _endTime.ToString($"{DATE_FORMAT} {TIME_FORMAT}")
|
|
]);
|
|
|
|
monthStatistics.WriteLine([]);
|
|
monthStatistics.WriteLine([]);
|
|
monthStatistics.Dispose();
|
|
|
|
|
|
}
|
|
|
|
private void WriteFinalStatistics()
|
|
{
|
|
try
|
|
{
|
|
Log.Debug("Writing month statistics");
|
|
WriteMonthStatistics();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error("Error writing statistics for " + _settings.CameraName+ "\n"+ e);
|
|
}
|
|
_csvStatistics?.Dispose();
|
|
_csvStatistics = null;
|
|
}
|
|
|
|
public void InitializeModule()
|
|
{
|
|
_recognitionControl.SessionStarted += _recognitionControl_SessionStarted;
|
|
_recognitionControl.ImageProcessed += _recognitionControl_ImageProcessed;
|
|
_recognitionControl.SessionEnded += _recognitionControl_SessionEnded;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_csvStatistics?.Dispose();
|
|
_recognitionControl.SessionStarted -= _recognitionControl_SessionStarted;
|
|
_recognitionControl.ImageProcessed -= _recognitionControl_ImageProcessed;
|
|
_recognitionControl.SessionEnded -= _recognitionControl_SessionEnded;
|
|
}
|
|
}
|
|
}
|