check point
This commit is contained in:
145
VisionBuilder.UI.Statistics/VisionBuilderStatistics.cs
Normal file
145
VisionBuilder.UI.Statistics/VisionBuilderStatistics.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
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<string, int>();
|
||||
}
|
||||
|
||||
ConcurrentDictionary<string, int> _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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user