1.0.7
This commit is contained in:
@@ -1,7 +1,33 @@
|
|||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Hawkeye.VisionBuilder.Workflow;
|
using Hawkeye.VisionBuilder.Workflow;
|
||||||
|
|
||||||
var files = Directory.GetFiles(AppContext.BaseDirectory, "*.hrcp", SearchOption.TopDirectoryOnly);
|
// Check if directory argument is provided
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Usage: RecipeConverter.exe <directory>");
|
||||||
|
Console.WriteLine("Example: RecipeConverter.exe C:\\MyRecipes");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string targetDirectory = args[0];
|
||||||
|
|
||||||
|
// Validate directory exists
|
||||||
|
if (!Directory.Exists(targetDirectory))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error: Directory '{targetDirectory}' does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(targetDirectory, "*.hrcp", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
if (files.Length == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"No *.hrcp files found in directory '{targetDirectory}'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Found {files.Length} recipe file(s) in '{targetDirectory}'");
|
||||||
|
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -9,8 +35,13 @@ foreach (var file in files)
|
|||||||
Console.WriteLine($"Converting {file}");
|
Console.WriteLine($"Converting {file}");
|
||||||
var f = File.OpenRead(file);
|
var f = File.OpenRead(file);
|
||||||
WorkflowList list = new WorkflowList();
|
WorkflowList list = new WorkflowList();
|
||||||
list.Load(new BinaryReader(f),new OperationDiscoveryService(list));
|
list.Load(new BinaryReader(f), new OperationDiscoveryService(list));
|
||||||
list.SaveJSON(Path.GetFileNameWithoutExtension(file)+".jhrcp");
|
|
||||||
|
// Save the converted file in the same directory as the source
|
||||||
|
string outputPath = Path.Combine(targetDirectory, Path.GetFileNameWithoutExtension(file) + ".jhrcp");
|
||||||
|
list.SaveJSON(outputPath);
|
||||||
|
|
||||||
|
Console.WriteLine($"Saved: {outputPath}");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace Inspectron.Camera.UEye
|
|||||||
{
|
{
|
||||||
uEye.Defines.ColorMode mode;
|
uEye.Defines.ColorMode mode;
|
||||||
_camera.PixelFormat.Get(out mode);
|
_camera.PixelFormat.Get(out mode);
|
||||||
|
|
||||||
int channels = 0;
|
int channels = 0;
|
||||||
|
|
||||||
if (mode == uEye.Defines.ColorMode.Mono8)
|
if (mode == uEye.Defines.ColorMode.Mono8)
|
||||||
@@ -53,7 +54,7 @@ namespace Inspectron.Camera.UEye
|
|||||||
}
|
}
|
||||||
else if (mode == uEye.Defines.ColorMode.BGRA8Packed)
|
else if (mode == uEye.Defines.ColorMode.BGRA8Packed)
|
||||||
{
|
{
|
||||||
channels = 3;
|
channels = 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -68,8 +69,17 @@ namespace Inspectron.Camera.UEye
|
|||||||
Byte[] u8img;
|
Byte[] u8img;
|
||||||
_camera.Memory.CopyToArray(idx, out u8img);
|
_camera.Memory.CopyToArray(idx, out u8img);
|
||||||
|
|
||||||
Mat mat = new Mat(size.Height,pitch, MatType.CV_8UC(channels));
|
|
||||||
mat.SetArray(u8img);
|
// Warning! This will work only if pitch == width * channels
|
||||||
|
if (pitch != size.Width * channels)
|
||||||
|
{
|
||||||
|
throw new Exception("pitch must be equal to width * channels");
|
||||||
|
}
|
||||||
|
Mat mat = new Mat(size.Height, size.Width,MatType.CV_8UC3);
|
||||||
|
// copy data to mat
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(u8img, 0, mat.Data, u8img.Length);
|
||||||
|
|
||||||
|
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,14 +98,13 @@ namespace Inspectron.Camera.UEye
|
|||||||
}
|
}
|
||||||
uEye.Types.SensorInfo info = new uEye.Types.SensorInfo();
|
uEye.Types.SensorInfo info = new uEye.Types.SensorInfo();
|
||||||
_camera.Information.GetSensorInfo(out info);
|
_camera.Information.GetSensorInfo(out info);
|
||||||
Console.WriteLine($"Camera {cameraIdx} opened: {info.SensorName} ({info.SensorID})");
|
Log.Information($"Camera {cameraIdx} opened: {info.SensorName} ({info.SensorID})");
|
||||||
_camera.Parameter.Load();
|
_camera.Parameter.Load();
|
||||||
Console.WriteLine($"Camera {cameraIdx} parameters loaded");
|
Log.Information($"Camera {cameraIdx} parameters loaded");
|
||||||
|
|
||||||
_camera.Trigger.Set(uEye.Defines.TriggerMode.Continuous);
|
_camera.Trigger.Set(uEye.Defines.TriggerMode.Continuous);
|
||||||
|
|
||||||
statusRet = _camera.Memory.Allocate();
|
statusRet = _camera.Memory.Allocate();
|
||||||
Console.WriteLine("Memory allocated");
|
|
||||||
if (statusRet != uEye.Defines.Status.Success)
|
if (statusRet != uEye.Defines.Status.Success)
|
||||||
{
|
{
|
||||||
throw new Exception("Allocate Memory failed");
|
throw new Exception("Allocate Memory failed");
|
||||||
|
|||||||
@@ -16,5 +16,9 @@
|
|||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
<ExcludeAssets>runtime</ExcludeAssets>
|
<ExcludeAssets>runtime</ExcludeAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\..\VisionBuilder.UI.Statistics\VisionBuilder.UI.Statistics.csproj" >
|
||||||
|
<Private>false</Private>
|
||||||
|
<ExcludeAssets>runtime</ExcludeAssets>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using VisionBuilder.UI.Common;
|
using Serilog;
|
||||||
|
using VisionBuilder.UI.Common;
|
||||||
|
using VisionBuilder.UI.Statistics;
|
||||||
|
|
||||||
namespace B24SiemensPlugin;
|
namespace B24SiemensPlugin;
|
||||||
|
|
||||||
@@ -6,13 +8,15 @@ public class SiemensCameraModule: IVisionBuilderModule
|
|||||||
{
|
{
|
||||||
private readonly SingleCameraVM _singleCameraVm;
|
private readonly SingleCameraVM _singleCameraVm;
|
||||||
private readonly B24SiemensSettings _settings;
|
private readonly B24SiemensSettings _settings;
|
||||||
|
private readonly VisionBuilderStatistics _statistics;
|
||||||
|
|
||||||
private SiemensServer _server;
|
private SiemensServer _server;
|
||||||
|
|
||||||
public SiemensCameraModule(SingleCameraVM singleCameraVm,B24SiemensSettings settings)
|
public SiemensCameraModule(SingleCameraVM singleCameraVm,B24SiemensSettings settings, VisionBuilderStatistics statistics)
|
||||||
{
|
{
|
||||||
_singleCameraVm = singleCameraVm;
|
_singleCameraVm = singleCameraVm;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
_statistics = statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeModule()
|
public void InitializeModule()
|
||||||
@@ -32,6 +36,11 @@ public class SiemensCameraModule: IVisionBuilderModule
|
|||||||
}
|
}
|
||||||
private PLCPacket _server_OnPLCPacket(PLCPacket packet)
|
private PLCPacket _server_OnPLCPacket(PLCPacket packet)
|
||||||
{
|
{
|
||||||
|
if (_singleCameraVm.SynchronizationContext == null)
|
||||||
|
{
|
||||||
|
Log.Warning("Synchronization context is null, cannot update UI from PLC packet.");
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
packet.KameraStart= _singleCameraVm.IsRunning;
|
packet.KameraStart= _singleCameraVm.IsRunning;
|
||||||
var recipe = GetMapping(packet.Materialnummer);
|
var recipe = GetMapping(packet.Materialnummer);
|
||||||
var selectedRecipe = _singleCameraVm.SelectedRecipe;
|
var selectedRecipe = _singleCameraVm.SelectedRecipe;
|
||||||
@@ -45,7 +54,7 @@ public class SiemensCameraModule: IVisionBuilderModule
|
|||||||
{
|
{
|
||||||
_singleCameraVm.ProcessRecipeSelectionVm(vm);
|
_singleCameraVm.ProcessRecipeSelectionVm(vm);
|
||||||
}, null);
|
}, null);
|
||||||
|
_statistics.Metadata = packet.Materialnummer.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,6 @@ public class ImageProcessedEvent:IEvent
|
|||||||
public bool HasError { get; set; }
|
public bool HasError { get; set; }
|
||||||
public List<string> ErrorNames { get; set; }
|
public List<string> ErrorNames { get; set; }
|
||||||
public TimeSpan AnalysisTime { get; set; }
|
public TimeSpan AnalysisTime { get; set; }
|
||||||
|
public TimeSpan AcquisitionTime { get; set; }
|
||||||
|
public TimeSpan SleepTime { get; set; }
|
||||||
}
|
}
|
||||||
@@ -27,12 +27,18 @@ public abstract class BaseRecognitionControl: IRecognitionControl
|
|||||||
|
|
||||||
public void SetRecipe(RecipeData recipe)
|
public void SetRecipe(RecipeData recipe)
|
||||||
{
|
{
|
||||||
// error if running
|
lock (_lock)
|
||||||
if (IsRunning)
|
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Cannot change recipe while recognition is running.");
|
|
||||||
|
|
||||||
|
// error if running
|
||||||
|
if (IsRunning)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Cannot change recipe while recognition is running.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentRecipe = recipe;
|
||||||
}
|
}
|
||||||
_currentRecipe = recipe;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRunning { get; set; }
|
public bool IsRunning { get; set; }
|
||||||
@@ -44,47 +50,57 @@ public abstract class BaseRecognitionControl: IRecognitionControl
|
|||||||
|
|
||||||
private DateTime _startTime;
|
private DateTime _startTime;
|
||||||
|
|
||||||
|
object _lock = new object();
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
lock (_lock)
|
||||||
if (_currentRecipe == null)
|
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("No recipe set.");
|
|
||||||
|
|
||||||
|
if (_currentRecipe == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No recipe set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsRunning)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Recognition is already running.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadingService.StartLoading($"Starting recipe {_currentRecipe.RecipeName} on {_settings.CameraName}...");
|
||||||
|
Initialize(_currentRecipe);
|
||||||
|
_startTime = DateTime.Now;
|
||||||
|
IsRunning = true;
|
||||||
|
_cts = new CancellationTokenSource();
|
||||||
|
|
||||||
|
|
||||||
|
Log.Information($"Warming up");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var swWarmup = Stopwatch.StartNew();
|
||||||
|
WarmUp();
|
||||||
|
swWarmup.Stop();
|
||||||
|
Log.Information($"Warmup run took {swWarmup.ElapsedMilliseconds} ms");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error during warmup run");
|
||||||
|
}
|
||||||
|
|
||||||
|
_loopTask = Task.Run(() => Loop(_cts.Token), _cts.Token);
|
||||||
|
|
||||||
|
SessionStarted?.Invoke(new SessionStartedEvent
|
||||||
|
{
|
||||||
|
RecipeName = _currentRecipe.RecipeName,
|
||||||
|
SessionStarted = _startTime,
|
||||||
|
|
||||||
|
});
|
||||||
|
_loadingService.StopLoading($"Starting recipe {_currentRecipe.RecipeName} on {_settings.CameraName}...");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (IsRunning)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Recognition is already running.");
|
|
||||||
}
|
|
||||||
_loadingService.StartLoading($"Starting recipe {_currentRecipe.RecipeName} on {_settings.CameraName}...");
|
|
||||||
Initialize(_currentRecipe);
|
|
||||||
_startTime = DateTime.Now;
|
|
||||||
IsRunning = true;
|
|
||||||
_cts = new CancellationTokenSource();
|
|
||||||
|
|
||||||
|
|
||||||
Log.Information($"Warming up");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var swWarmup = Stopwatch.StartNew();
|
|
||||||
WarmUp();
|
|
||||||
swWarmup.Stop();
|
|
||||||
Log.Information($"Warmup run took {swWarmup.ElapsedMilliseconds} ms");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error during warmup run");
|
|
||||||
}
|
|
||||||
|
|
||||||
_loopTask = Task.Run(() => Loop(_cts.Token), _cts.Token);
|
|
||||||
|
|
||||||
SessionStarted?.Invoke(new SessionStartedEvent
|
|
||||||
{
|
|
||||||
RecipeName = _currentRecipe.RecipeName,
|
|
||||||
SessionStarted = _startTime,
|
|
||||||
|
|
||||||
});
|
|
||||||
_loadingService.StopLoading($"Starting recipe {_currentRecipe.RecipeName} on {_settings.CameraName}...");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void Initialize(RecipeData currentRecipe);
|
protected abstract void Initialize(RecipeData currentRecipe);
|
||||||
@@ -95,50 +111,62 @@ public abstract class BaseRecognitionControl: IRecognitionControl
|
|||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
if (!IsRunning)
|
lock (_lock)
|
||||||
return;
|
|
||||||
_loadingService.StartLoading($"Stopping {_settings.CameraName}");
|
|
||||||
_cts?.Cancel();
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
_loopTask?.Wait();
|
if (!IsRunning)
|
||||||
}
|
return;
|
||||||
catch (TaskCanceledException)
|
|
||||||
{
|
|
||||||
// Ignore cancellation exceptions
|
|
||||||
}
|
|
||||||
catch (AggregateException ex) when (ex.Flatten().InnerExceptions.Any(x=>x is TaskCanceledException))
|
|
||||||
{
|
|
||||||
// Ignore cancellation exceptions
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error while stopping recognition loop");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsRunning = false;
|
|
||||||
_cts?.Dispose();
|
|
||||||
_cts = null;
|
|
||||||
_loopTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
SessionEnded?.Invoke(new SessionEndedEvent
|
|
||||||
{
|
|
||||||
SessionEnded = DateTime.Now
|
_loadingService.StartLoading($"Stopping {_settings.CameraName}");
|
||||||
});
|
_cts?.Cancel();
|
||||||
_loadingService.StopLoading($"Stopping {_settings.CameraName}");
|
try
|
||||||
IsPaused=false; // ensure paused is reset
|
{
|
||||||
|
_loopTask?.Wait();
|
||||||
|
}
|
||||||
|
catch (TaskCanceledException)
|
||||||
|
{
|
||||||
|
// Ignore cancellation exceptions
|
||||||
|
}
|
||||||
|
catch (AggregateException ex) when (ex.Flatten().InnerExceptions.Any(x => x is TaskCanceledException))
|
||||||
|
{
|
||||||
|
// Ignore cancellation exceptions
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error while stopping recognition loop");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsRunning = false;
|
||||||
|
_cts?.Dispose();
|
||||||
|
_cts = null;
|
||||||
|
_loopTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionEnded?.Invoke(new SessionEndedEvent
|
||||||
|
{
|
||||||
|
SessionEnded = DateTime.Now
|
||||||
|
});
|
||||||
|
_loadingService.StopLoading($"Stopping {_settings.CameraName}");
|
||||||
|
IsPaused = false; // ensure paused is reset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
IsPaused = true;
|
lock (_lock)
|
||||||
|
{
|
||||||
|
IsPaused = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Resume()
|
public void Resume()
|
||||||
{
|
{
|
||||||
IsPaused = false;
|
lock (_lock)
|
||||||
|
{
|
||||||
|
IsPaused = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _errorsInSequence = 0;
|
int _errorsInSequence = 0;
|
||||||
@@ -161,10 +189,13 @@ public abstract class BaseRecognitionControl: IRecognitionControl
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int sleepTime=0;
|
||||||
if (processed.Value.processingTime.Milliseconds < _settings.MinimumProcessingTime)
|
if (processed.Value.processingTime.Milliseconds < _settings.MinimumProcessingTime)
|
||||||
{
|
{
|
||||||
Thread.Sleep(_settings.MinimumProcessingTime - (int)processed.Value.processingTime.Milliseconds);
|
|
||||||
|
sleepTime = _settings.MinimumProcessingTime - (int)processed.Value.processingTime.Milliseconds;
|
||||||
|
Log.Debug("Sleeping for {sleepTime}",sleepTime);
|
||||||
|
Thread.Sleep(sleepTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processed.Value.errorNames.Length > 0)
|
if (processed.Value.errorNames.Length > 0)
|
||||||
@@ -185,6 +216,8 @@ public abstract class BaseRecognitionControl: IRecognitionControl
|
|||||||
SessionStart = _startTime,
|
SessionStart = _startTime,
|
||||||
RecipeName = _currentRecipe.RecipeName,
|
RecipeName = _currentRecipe.RecipeName,
|
||||||
AnalysisTime = processed.Value.processingTime - processed.Value.acquisitionTime,
|
AnalysisTime = processed.Value.processingTime - processed.Value.acquisitionTime,
|
||||||
|
AcquisitionTime = processed.Value.acquisitionTime,
|
||||||
|
SleepTime = TimeSpan.FromMilliseconds(sleepTime),
|
||||||
ErrorNames = processed.Value.errorNames.ToList(),
|
ErrorNames = processed.Value.errorNames.ToList(),
|
||||||
HasError = processed.Value.errorNames.Length > 0,
|
HasError = processed.Value.errorNames.Length > 0,
|
||||||
ImageSource = _settings.CameraName,
|
ImageSource = _settings.CameraName,
|
||||||
@@ -195,7 +228,7 @@ public abstract class BaseRecognitionControl: IRecognitionControl
|
|||||||
var swProcessed = Stopwatch.StartNew();
|
var swProcessed = Stopwatch.StartNew();
|
||||||
ImageProcessed(processingResult);
|
ImageProcessed(processingResult);
|
||||||
swProcessed.Stop();
|
swProcessed.Stop();
|
||||||
Log.Information($"ImageProcessed event handled in {swProcessed.ElapsedMilliseconds} ms");
|
Log.Information("ImageProcessed event handled in {processed} ms", swProcessed.ElapsedMilliseconds);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ namespace VisionBuilder.UI.Common
|
|||||||
|
|
||||||
public bool CanStop => IsRunning;
|
public bool CanStop => IsRunning;
|
||||||
public bool CanStart => !IsRunning && SelectedRecipe!=null;
|
public bool CanStart => !IsRunning && SelectedRecipe!=null;
|
||||||
public bool CanPause => (IsRunning && !IsPaused)&&_uiConfiguration.ShowPauseButton;
|
public bool CanPause => (IsRunning && !IsPaused);
|
||||||
public bool CanResume => (IsRunning && IsPaused) && _uiConfiguration.ShowPauseButton;
|
public bool CanResume => (IsRunning && IsPaused);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -129,16 +129,17 @@ namespace VisionBuilder.UI.Common
|
|||||||
CurrentRecipeName = SelectedRecipe?.RecipeName ?? "Select recipe";
|
CurrentRecipeName = SelectedRecipe?.RecipeName ?? "Select recipe";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[RelayCommand(CanExecute = nameof(CanStart))]
|
[RelayCommand(CanExecute = nameof(CanStart))]
|
||||||
public async Task Start()
|
public async Task Start()
|
||||||
{
|
{
|
||||||
|
|
||||||
IsRunning = true;
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
IsRunning = true;
|
||||||
_recognitionControl.Start();
|
await Task.Run(() => { _recognitionControl.Start(); });
|
||||||
});
|
_handlingEnabled = true;
|
||||||
_handlingEnabled = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ namespace VisionBuilder.UI.Statistics
|
|||||||
|
|
||||||
private void _recognitionControl_SessionEnded(SessionEndedEvent obj)
|
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;
|
var endedAt = obj.SessionEnded;
|
||||||
_endTime = endedAt;
|
_endTime = endedAt;
|
||||||
Log.Information("Start processing statistics");
|
Log.Information("Start processing statistics");
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<ApplicationIcon>Inspectron icon-512.ico</ApplicationIcon>
|
<ApplicationIcon>Inspectron icon-512.ico</ApplicationIcon>
|
||||||
<Deterministic>false</Deterministic>
|
<Deterministic>false</Deterministic>
|
||||||
<Version>1.0.6</Version>
|
<Version>1.0.7</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user