omni inspection:

- new acc
- new crrf
- psnr
This commit is contained in:
Stoyan Zlatev
2024-01-31 11:13:03 +01:00
parent c6a76c07ee
commit 22e7b947ba
24 changed files with 620 additions and 642 deletions
+5 -4
View File
@@ -3,11 +3,12 @@
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<appSettings>
<appSettings>
<add key="PSNR" value="1000"/>
<add key="HubURL" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb" />
<!--<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=AuftragKopie; User ID=sa; Password=sqlserver;" />-->
<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;"/>
<!--<add key="COMPorts" value="COM1, COM3, COM5, COM7, COM5, COM9, COM11, COM13, COM15, COM17"/>-->
<add key="COMPorts" value="COM4"/>
</appSettings>
<!--<add key="COMPorts" value="COM1, COM3, COM5, COM7, COM5, COM9, COM11, COM13, COM15, COM17"/>-->
<add key="COMPorts" value="COM4"/>
</appSettings>
</configuration>
+11 -2
View File
@@ -1,12 +1,21 @@
namespace InspectionUI
{
using InspectionUI.Models;
using OmniPlus;
using System;
using System.Globalization;
using System.Threading;
using System.Windows;
public partial class App : Application
{
public App()
{
ServiceProvider
.ServiceCollection
.AddSingleton(OmniContext.GetOrCreateInstance(Appsettings.OmniDB, Appsettings.OutputDirectory));
}
internal static event Action Exiting;
protected override void OnExit(ExitEventArgs e)
@@ -62,8 +62,10 @@
<Compile Include="ItemsGrid.xaml.cs">
<DependentUpon>ItemsGrid.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModels\Appsettings.cs" />
<Compile Include="ViewModels\CompilerServices.cs" />
<Compile Include="Models\AppLogger.cs" />
<Compile Include="Models\ServiceProvider.cs" />
<Compile Include="Models\Appsettings.cs" />
<Compile Include="Models\CompilerServices.cs" />
<Compile Include="ViewModels\DefaultsHeaderRow.cs" />
<Compile Include="ViewModels\DefaultsRowVM.cs" />
<Compile Include="ViewModels\HeadersRowVM.cs" />
+5 -7
View File
@@ -99,13 +99,11 @@
</Grid>
</Border>
<Border Grid.Row="1">
<Label Content="{Binding Errors}"
FontFamily="Consolas"
FontWeight="Bold"
Foreground="Red"
Margin="5"
Padding="0" />
<Border Grid.Row="1" Margin="10">
<TextBlock FontFamily="Consolas"
Padding="0"
Text="{Binding Errors}"
TextWrapping="Wrap"/>
</Border>
<!-- TODO: Order head -->
@@ -0,0 +1,35 @@
namespace InspectionUI.Models
{
using System;
using System.Collections.Concurrent;
using System.IO;
using static System.Environment;
public class AppLogger
{
private static readonly string app_state = Path.Combine(Appsettings.OutputDirectory, $"{nameof(app_state)}.txt");
private static readonly ConcurrentQueue<object> statesQueue = new ConcurrentQueue<object>();
private static bool dequeuing;
public static void Log(object state)
{
statesQueue.Enqueue(state);
DequeueStates();
}
private static void DequeueStates()
{
if (!dequeuing)
{
while (statesQueue.TryDequeue(out var state))
{
File.AppendAllText(app_state, $"[{DateTime.Now}] {state}{NewLine}");
}
dequeuing = true;
}
}
}
}
@@ -0,0 +1,57 @@
namespace InspectionUI.Models
{
using System;
using System.Configuration;
using System.IO;
public class Appsettings
{
private static readonly string exeLocation
= typeof(App).Assembly.Location;
private static readonly Configuration configuration
= ConfigurationManager.OpenExeConfiguration(exeLocation);
private static readonly KeyValueConfigurationCollection appsettings
= configuration.AppSettings.Settings;
public static string COMPorts
{
get => GetSetting(nameof(COMPorts));
}
public static string OmniDB
{
get => GetSetting(nameof(OmniDB));
}
public static string HubURL
{
get => GetSetting(nameof(HubURL));
}
public static string OutputDirectory
{
get
{
var currentDirectory = new FileInfo(exeLocation).DirectoryName;
var outputDirectoryToday = Path.Combine(currentDirectory, "Debug", $"{DateTime.Now:yyyy-MM-dd}");
return Directory.CreateDirectory(outputDirectoryToday).FullName;
}
}
public static string PSNR
{
get => GetSetting(nameof(PSNR));
}
private static string GetSetting(string setting)
{
var appsettingsSection = configuration.AppSettings.SectionInformation.Name;
ConfigurationManager.RefreshSection(appsettingsSection);
return appsettings[setting].Value;
}
}
}
@@ -0,0 +1,101 @@
namespace InspectionUI.Models
{
using System;
using System.Collections.Concurrent;
using System.Linq;
public interface IServiceCollection
{
IServiceCollection AddSingleton<T>(T instance);
}
public class ServiceProvider : IServiceProvider, IServiceCollection
{
private static readonly ServiceProvider serviceProvider = new ServiceProvider();
private readonly ConcurrentDictionary<Type, object> services;
private ServiceProvider()
{
this.services = new ConcurrentDictionary<Type, object>();
}
public IServiceCollection AddSingleton<T>(T instance)
{
services.AddOrUpdate(typeof(T), instance, (t, i) => instance);
return this;
}
public object GetService(Type serviceType)
{
return services.GetOrAdd(serviceType, default(object));
}
public static IServiceCollection ServiceCollection
{
get => serviceProvider;
}
public static T GetService<T>()
{
var serviceType = typeof(T);
var serviceInstance = default(T);
if (serviceProvider.GetService(serviceType) is T existingInstance)
{
serviceInstance = existingInstance;
}
else if (CreateInstance(serviceType) is T newInstance)
{
serviceInstance = newInstance;
}
return serviceInstance;
}
private static object CreateInstance(Type instanceType)
{
var instance = default(object);
var constructors = instanceType
.GetConstructors()
.OrderByDescending(x => x.GetParameters().Length);
foreach (var constructor in constructors)
{
var parameters = constructor.GetParameters();
var parametersLength = parameters.Length;
var createParameters = new object[parametersLength];
for (int i = 0; i < parametersLength; i++)
{
var parameterType = parameters[i].ParameterType;
var parameter = serviceProvider.GetService(parameterType);
if (parameter is null)
{
parameter = CreateInstance(parameterType);
}
createParameters[i] = parameter;
}
try
{
instance = constructor.Invoke(createParameters);
if (instance != null)
{
break;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
return instance;
}
}
}
@@ -1,45 +0,0 @@
namespace InspectionUI.ViewModels
{
using System;
using System.Configuration;
using System.IO;
public class Appsettings
{
private static readonly string ExeLocation
= typeof(App).Assembly.Location;
private static readonly Configuration configuration
= ConfigurationManager.OpenExeConfiguration(ExeLocation);
private static readonly KeyValueConfigurationCollection appsettings
= configuration.AppSettings.Settings;
public static string[] COMPorts
{
get => appsettings[nameof(COMPorts)]
.Value
.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
}
public static string CurrentDirectory
{
get => new FileInfo(ExeLocation).DirectoryName;
}
public static string OmniDB
{
get => appsettings[nameof(OmniDB)]?.Value;
}
public static string HubURL
{
get => appsettings[nameof(HubURL)]?.Value;
}
public static String OutputDirectory
{
get => Directory
.CreateDirectory(Path.Combine(CurrentDirectory, "Debug", $"{DateTime.Now:yyyy-MM-dd}"))
.FullName;
}
}
}
@@ -14,8 +14,8 @@
foreach (var pp in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridHeaderVM { Value = $"m³/h" });
this.Add(new ItemsGridHeaderVM { Value = $"r/s" });
this.Add(new ItemsGridHeaderVM { Value = $"m³/h" });
this.Add(new ItemsGridHeaderVM { Value = $"acc. %" });
}
@@ -14,8 +14,8 @@
foreach (var pp in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridHeaderVM { Value = $"{pp.Rotations}/{pp.Duration:0.0}" });
this.Add(new ItemsGridHeaderVM { Value = $"{pp.FlowM3H:0.000}" });
this.Add(new ItemsGridHeaderVM { Value = $"{pp.Rotations}/{pp.Duration}" });
this.Add(new ItemsGridHeaderVM { Value = $"{pp.MinAccuracy}-{pp.MaxAccuracy}" });
}
@@ -65,7 +65,7 @@
protected void Set<T>(T value, string format, int index)
{
this.InvokeAsync(() =>
this.DispatcherInvoke(() =>
{
if (string.IsNullOrWhiteSpace(format))
{
@@ -78,7 +78,7 @@
protected void Set(Action<ItemsGridCellVM> setter, int index)
{
this.InvokeAsync(() => setter(this[index]));
this.DispatcherInvoke(() => setter(this[index]));
}
}
}
@@ -10,6 +10,8 @@
protected ItemsGridVM() : base()
{
this.rows = new List<ItemsGridRowVM>();
this.InitializeItemsGridRows();
}
public IEnumerator<ItemsGridRowVM> GetEnumerator()
@@ -46,5 +48,7 @@
{
this.rows.Insert(index, item);
}
protected abstract void InitializeItemsGridRows();
}
}
@@ -1,24 +1,21 @@
namespace InspectionUI.ViewModels
{
using InspectionUI.Models;
using OmniPlus;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
public class MainVM : VM
{
private readonly OmniContext omniContext;
public MainVM() : base()
{
this.IsReloadEnabled = true;
this.MetersPool = new MetersPoolVM();
this.Reload = new Command(this.ReloadCommand);
this.CheckInspection = new Command(this.CheckInspectionCommand);
this.StartInspection = new Command(this.StartInspectionCommand);
this.CancelInspection = new Command(this.CancelInspectionCommand);
this.omniContext = OmniContext.GetOrCreateInstance(Appsettings.OmniDB, Appsettings.OutputDirectory);
}
private int size;
@@ -46,7 +43,7 @@
public bool IsReloadEnabled
{
get => this.reloadEnabled;
set => this.Set(() => this.reloadEnabled = value);
private set => this.Set(() => this.reloadEnabled = value);
}
public ICommand Reload { get; }
@@ -55,7 +52,7 @@
public bool IsCheckInspectionEnabled
{
get => this.checkInspectionEnabled;
set => this.Set(() => this.checkInspectionEnabled = value);
private set => this.Set(() => this.checkInspectionEnabled = value);
}
public ICommand CheckInspection { get; }
@@ -64,7 +61,7 @@
public bool IsStartInspectionEnabled
{
get => this.startInspectionEnabled;
set => this.Set(() => this.startInspectionEnabled = value);
private set => this.Set(() => this.startInspectionEnabled = value);
}
public ICommand StartInspection { get; }
@@ -73,7 +70,7 @@
public bool IsCancelInspectionEnabled
{
get => this.cancelInspectionEnabled;
set => this.Set(() => this.cancelInspectionEnabled = value);
private set => this.Set(() => this.cancelInspectionEnabled = value);
}
public ICommand CancelInspection { get; }
@@ -82,10 +79,15 @@
public string Errors
{
get => this.errors;
set => this.Set(() => this.errors = value);
private set => this.Set(() => this.errors = value);
}
public MetersPoolVM MetersPool { get; }
private MetersPoolVM metersPoolVM;
public MetersPoolVM MetersPool
{
get => this.metersPoolVM;
private set => this.Set(() => this.metersPoolVM = value);
}
private void ReloadCommand()
{
@@ -93,34 +95,38 @@
this.Errors = default(string);
var omniContext = ServiceProvider.GetService<OmniContext>();
if (!string.IsNullOrWhiteSpace(this.SuchNr))
{
this.omniContext.LoadAuftrag(this.SuchNr);
ServiceProvider
.GetService<OmniContext>()
.LoadAuftrag(this.SuchNr);
}
else if (this.size >= 0 && !string.IsNullOrWhiteSpace(this.type))
{
this.omniContext.LoadAuftrag((byte)this.size, this.type);
ServiceProvider
.GetService<OmniContext>()
.LoadAuftrag((byte)this.size, this.type);
}
else
{
this.Errors = "FertigungauftragsNr oder Größe und Typ eingeben.";
this.Errors = "FertigungauftragsNr oder Größe und Typ eingeben!";
}
if (string.IsNullOrWhiteSpace(this.Errors))
{
Task.Factory
.StartNew(() =>
{
this.MetersPool.LoadMeters();
})
.ContinueWith(_ =>
{
this.MetersPool.SaveMeterStates();
})
.ContinueWith(_ =>
{
this.EnableButtons(true);
});
this.StartNewTask(() =>
{
this.Errors = "Connecting meters ...";
this.MetersPool = ServiceProvider.GetService<MetersPoolVM>();
this.MetersPool.LoadMeters();
})
.ContinueWith(_ =>
{
this.Errors = default(string);
this.EnableButtons(true);
});
}
else
{
@@ -130,7 +136,7 @@
private void CheckInspectionCommand()
{
Task.Factory.StartNew(() =>
this.StartNewTask(() =>
{
this.EnableButtons(false);
this.MetersPool.RunCheckInspection();
@@ -140,7 +146,7 @@
private void StartInspectionCommand()
{
Task.Factory.StartNew(() =>
this.StartNewTask(() =>
{
this.EnableButtons(false);
this.MetersPool.RunInspection();
@@ -150,7 +156,7 @@
private void CancelInspectionCommand()
{
Task.Factory.StartNew(() =>
this.StartNewTask(() =>
{
this.EnableButtons(false);
this.MetersPool.CancelInspection();
@@ -1,5 +1,6 @@
namespace InspectionUI.ViewModels
{
using InspectionUI.Models;
using OmniPlus;
using System;
@@ -32,6 +33,9 @@
}
this.Add(new ItemsGridCellVM());
this.MeterNr = this.meter.MeterNr;
this.SerialNr = this.meter.SerialNr;
}
private string meterId;
@@ -62,28 +66,14 @@
base.Dispose();
}
internal Task ConnectAsync()
{
void Connect()
{
this.meter.ConnectIrda();
this.meter.IdentitfyMeter();
this.MeterNr = this.meter.MeterNr;
this.SerialNr = this.meter.SerialNr;
}
return this.StartNew(Connect);
}
public Task SaveMeterStateAsync()
{
return this.StartNew(this.meter.SaveMeterState);
return this.StartNewTask(this.meter.SaveMeterState);
}
public Task LoadTestRunAsync()
{
return this.StartNew(this.meter.LoadTestRun);
return this.StartNewTask(this.meter.LoadTestRun);
}
public Task InitializeInspectionAsync(bool preserveState = false)
@@ -97,7 +87,7 @@
this.Set(this.meter.TestRun.CrrfBefore, "{0:0.0}", this.LastIndex);
}
return this.StartNew(InitializeInspection);
return this.StartNewTask(InitializeInspection);
}
public Task StartCalibrationAsync(OmniPruefpunkt pp)
@@ -108,10 +98,10 @@
{
this.meter.StartCalibration((ushort)pp.Rotations, (ushort)pp.Duration);
this.ShowRestTime(pp.Duration, this.uinr * 3 + 1);
this.ShowRestTime(pp.Duration, this.uinr * 3);
}
return this.StartNew(StartCalibration);
return this.StartNewTask(StartCalibration);
}
public Task StopCalibrationAsync(OmniPruefpunkt pp, double refm3s)
@@ -121,12 +111,12 @@
var response = this.meter.StopCalibration(pp, refm3s);
var index = this.uinr * 3;
this.Set(response.Item1, "{0:0.00000000}", index);
this.Set(response.Item2, "{0}", index + 1);
this.Set(response.Item2, "{0}", index);
this.Set(response.Item1, "{0:0.0000000000}", index + 1);
this.Set(response.Item3, "{0:0.00}", index + 2);
}
return this.StartNew(StopCalibration);
return this.StartNewTask(StopCalibration);
}
public Task FinishInspectionAsync()
@@ -136,15 +126,11 @@
this.meter.FinishInspection();
var crrf = this.meter.TestRun.CrrfAfter;
var background = this.meter.TestRun.Succeeded == true
var foreground = this.meter.TestRun.Succeeded == true
? Brushes.Green
: Brushes.Red;
this.Set(x =>
{
x.Background = background;
x.Foreground = Brushes.White;
}, this.LastIndex);
this.Set(x => x.Foreground = foreground, this.LastIndex);
this.Set(crrf, "{0:0.0}", this.LastIndex);
@@ -152,15 +138,22 @@
foreach (var testedPP in this.meter.TestRun.TestedPoints)
{
var index = this.uinr * 3;
var index = this.uinr * 3 + 2;
this.Set(testedPP.Acc, "{0:0.00}", index + 2);
this.Set(testedPP.Acc, "{0:0.00}", index);
this.Set(x =>
{
foreground = testedPP.Succeeded == true
? Brushes.Green
: Brushes.Red;
x.Foreground = foreground;
}, index);
this.uinr++;
}
}
return this.StartNew(FinishInspection);
return this.StartNewTask(FinishInspection);
}
private void ShowRestTime(int duration, int index)
@@ -198,19 +191,5 @@
this.Set(default(string), "{0}", index);
}
private Task StartNew(Action task)
{
return Task
.Factory
.StartNew(task)
.ContinueWith(t =>
{
if (t.Exception != null)
{
this.meter.NotifyStateChanged($"[{DateTime.Now}] {t.Exception}");
}
});
}
}
}
@@ -1,17 +1,22 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
using InspectionUI.Models;
using OmniPlus;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class MetersPoolVM : ItemsGridVM
{
private readonly OmniContext omniContext;
private ReferenceMeterVM referenceMeter;
public MetersPoolVM() : base()
public MetersPoolVM(OmniContext omniContext) : base()
{
this.omniContext = omniContext;
}
public void CancelInspection()
@@ -19,55 +24,29 @@
this.referenceMeter.Stop();
}
public void LoadMeters()
public override void Dispose()
{
this.InvokeAsync(() =>
{
this.Clear();
this.Add(new HeadersRowVM());
this.Add(new DefaultsHeaderRow());
this.Add(new DefaultsRowVM());
this.referenceMeter = new ReferenceMeterVM();
this.Add(this.referenceMeter);
});
var tasks = new List<Task>();
var nr = 1;
foreach (var portName in Appsettings.COMPorts)
{
var meter = OmniContext.Current.LoadMeter(nr++, portName);
var meterVM = new MeterVM(meter);
this.Add(meterVM);
tasks.Add(meterVM.ConnectAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.NotifyPropertyChanged();
this.omniContext.Dispose();
this.Clear();
}
internal void SaveMeterStates()
public void LoadMeters()
{
var tasks = new List<Task>();
this.referenceMeter = ServiceProvider.GetService<ReferenceMeterVM>();
this.Add(this.referenceMeter);
foreach (var item in this.ToArray())
{
if (item is MeterVM meterVM)
this.omniContext
.LoadMetersAsync(Appsettings.COMPorts, Appsettings.PSNR)
.ContinueWith(_ =>
{
tasks.Add(meterVM.SaveMeterStateAsync());
}
}
foreach (var meter in this.omniContext.Meters)
{
this.Add(new MeterVM(meter));
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.NotifyPropertyChanged();
});
}
public void RunCheckInspection()
@@ -88,20 +67,21 @@
tasks.Add(meterVM.LoadTestRunAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.ContinueWhenAll(tasks);
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.SaveMeterStateAsync());
}
this.ContinueWhenAll(tasks);
foreach (var meterVM in meters)
{
tasks.Add(meterVM.InitializeInspectionAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.ContinueWhenAll(tasks);
var pruefpunkte = OmniContext
.Current
@@ -112,43 +92,41 @@
{
this.referenceMeter.Start(pp);
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.StartCalibrationAsync(pp));
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.ContinueWhenAll(tasks);
var refm3s = this.referenceMeter.GetFlow();
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.StopCalibrationAsync(pp, refm3s));
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.ContinueWhenAll(tasks);
}
this.referenceMeter.Stop();
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.FinishInspectionAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.ContinueWhenAll(tasks);
}
protected override void InitializeItemsGridRows()
{
this.DispatcherInvoke(() =>
{
this.Add(ServiceProvider.GetService<HeadersRowVM>());
this.Add(ServiceProvider.GetService<DefaultsHeaderRow>());
this.Add(ServiceProvider.GetService<DefaultsRowVM>());
});
}
}
}
@@ -2,6 +2,8 @@
{
using ExchangeHub;
using InspectionUI.Models;
using OmniPlus;
using System;
@@ -34,7 +36,7 @@
this.Add(new ItemsGridHeaderVM());
this.signarR = new ExchangeConnection();
this.signarR.StateChanged += SignarR_StateChanged;
this.signarR.StateChanged += this.SignarR_StateChanged;
this.outputFile = Path.Combine(Appsettings.OutputDirectory, "signalr.txt");
this.signarR.Connect(Appsettings.HubURL);
@@ -80,7 +82,7 @@
}
else
{
this.Set(timeout, "... {0}", this.ppnr);
this.Set(timeout, "... {0}", this.ppnr + 1);
}
timeout--;
@@ -99,7 +101,7 @@
waitHandle.Wait(1000);
this.Set(default(string), "{0}", this.ppnr);
this.Set(volume, "{0:0.000}", this.ppnr + 1);
}
private void StartRZ(OmniPruefpunkt pp)
@@ -134,7 +136,7 @@
}
else
{
this.Set(timeout, "... {0}", this.ppnr + 1);
this.Set(timeout, "... {0}", this.ppnr);
}
timeout--;
@@ -153,7 +155,7 @@
waitHandle.Wait(1000);
this.Set(seconds, "{0}", this.ppnr + 1);
this.Set(seconds, ".../{0:0.0}", this.ppnr);
}
internal double GetFlow()
@@ -208,8 +210,8 @@
waitHandle.Wait(1000);
this.Set(referenceV, "{0:0.00000000}", this.ppnr);
this.Set(default(string), "{0}", this.ppnr + 2);
this.Set(referenceV, "{0:0.0000000000}", this.ppnr + 1);
this.Set(referenceV == 0 ? 0 : 100, "{0:0.00}", this.ppnr + 2);
return referenceV;
}
+57 -4
View File
@@ -1,8 +1,12 @@
namespace InspectionUI.ViewModels
{
using InspectionUI.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
@@ -23,7 +27,42 @@
App.Exiting -= this.Dispose;
}
protected void NotifyPropertyChanged(string propertyName = "")
protected void ContinueWhenAll(List<Task> tasks, Action continuationCallback = null)
{
if (tasks is null || tasks.Count == 0)
{
return;
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _tasks =>
{
foreach (var task in _tasks)
{
if (task.Exception != null)
{
AppLogger.Log(task.Exception);
}
}
tasks.Clear();
continuationCallback?.Invoke();
})
.Wait();
}
protected void NotifyPropertyChanged()
{
if (this.PropertyChanged != null)
{
dispatcher.Invoke(new Action(() =>
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(default(string)));
}));
}
}
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (this.PropertyChanged != null)
{
@@ -34,17 +73,31 @@
}
}
protected void InvokeAsync(Action action)
protected void DispatcherInvoke(Action action)
{
dispatcher.Invoke(action);
}
protected void Set(Action propertySetterAction, [CallerMemberName] string property = "")
protected void Set(Action setExpression, [CallerMemberName] string property = "")
{
this.InvokeAsync(propertySetterAction);
this.DispatcherInvoke(setExpression);
this.NotifyPropertyChanged(property);
}
protected Task StartNewTask(Action action)
{
return Task
.Factory
.StartNew(action)
.ContinueWith(task =>
{
if (task.Exception != null)
{
AppLogger.Log(task.Exception);
}
});
}
protected class Command : ICommand
{
private readonly Action executable;
@@ -134,19 +134,20 @@
{
succeeded = false;
var crrf = default(double);
if (points is null || points.Length != 3)
{
return default(double);
return crrf;
}
var min = points[0];
var mid = points[1];
var max = points[2];
var crrf = default(double);
if (min == 0 || mid == 0 || max == 0)
{
succeeded = false;
return crrf;
}
if (Math.Abs(mid - max) <= 3 && Math.Max(mid, max) - min <= 6.5)
@@ -162,12 +163,7 @@
crrf = 100 - avgMidMax;
}
if (double.IsNaN(crrf) || double.IsInfinity(crrf))
{
crrf = default(double);
}
succeeded = crrf != 0D;
succeeded = Math.Abs(crrf) <= 12;
}
else
{
@@ -181,11 +177,11 @@
{
crrf = 100 - avgMidMax;
}
}
if (double.IsNaN(crrf) || double.IsInfinity(crrf))
{
crrf = default(double);
}
if (double.IsNaN(crrf) || double.IsInfinity(crrf))
{
crrf = default(double);
}
return crrf;
+65 -22
View File
@@ -1,9 +1,12 @@
namespace OmniPlus
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
public class OmniContext
public class OmniContext : IDisposable
{
private readonly ConcurrentDictionary<int, OmniMeter> meters;
private readonly OmniDatabase database;
@@ -20,16 +23,34 @@
public OmniAuftrag Auftrag { get; set; }
public static OmniContext Current { get; private set; }
public static OmniContext GetOrCreateInstance(string connectionString, string outputDirectory)
public ReadOnlyCollection<OmniMeter> Meters
{
if (Current is null)
get => this.meters.Values as ReadOnlyCollection<OmniMeter>;
}
public void Add(string meterNr, string meterState)
{
_ = this.database.OmniPlus_Insert(meterNr, meterState);
}
public OmniPruefgang AddTestRun(string psnr, int slotnr, string meterNr)
{
return this.database.AddTestRun(this.runId, psnr, slotnr, meterNr);
}
public void Dispose()
{
foreach (var meter in this.meters.Values)
{
Current = new OmniContext(connectionString, outputDirectory);
meter.Dispose();
}
return Current;
this.meters.Clear();
}
public bool Exists(string meterNr)
{
return this.database.OmniPlus_Exists(meterNr);
}
public void LoadAuftrag(string suchnr)
@@ -44,31 +65,53 @@
this.runId = this.database.GetNextRunId();
}
public OmniMeter LoadMeter(int nr, string portName)
public Task LoadMetersAsync(string portNames, string psnr)
{
var meter = new OmniMeter(nr, portName, this.outputDirectory);
this.Dispose();
return this.meters.AddOrUpdate(nr, meter, (_, _1) => meter);
}
var tasks = new List<Task>();
var slotNr = 1;
public bool Exists(string meterNr)
{
return this.database.OmniPlus_Exists(meterNr);
}
foreach (var portName in portNames.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries))
{
var meter = new OmniMeter(psnr, slotNr, portName, this.outputDirectory);
public void Add(string meterNr, string meterState)
{
_ = this.database.OmniPlus_Insert(meterNr, meterState);
}
this.meters.AddOrUpdate(slotNr, meter, (_, _1) => meter);
public OmniPruefgang AddTestRun(int slotnr, string meterNr)
{
return this.database.AddTestRun(this.runId, slotnr, meterNr);
tasks.Add(Task.Factory.StartNew(() => meter.ConnectIrda()));
slotNr++;
}
return Task.Factory.ContinueWhenAll(tasks.ToArray(), _tasks =>
{
foreach (var task in _tasks)
{
if (task.Exception != null)
{
// TODO: Add logging.
}
}
tasks.Clear();
});
}
internal int UpdateTestRun(IDictionary<string, object> parameters, int id, byte slotNr)
{
return this.database.UpdateTestRun(parameters, id, slotNr);
}
public static OmniContext Current { get; private set; }
public static OmniContext GetOrCreateInstance(string connectionString, string outputDirectory)
{
if (Current is null)
{
Current = new OmniContext(connectionString, outputDirectory);
}
return Current;
}
}
}
+6 -3
View File
@@ -217,18 +217,19 @@
};
}
public OmniPruefgang AddTestRun(int id, int slotnr, string meterNr)
public OmniPruefgang AddTestRun(int id, string psnr, int slotnr, string meterNr)
{
return this.sqlConnection
.CreateCommand($@"
INSERT
INTO [OmniTestRuns] ([Id], [SlotNr], [MeterNr])
INTO [OmniTestRuns] ([Id], [PsNr], [SlotNr], [MeterNr])
OUTPUT [inserted].[Id]
, [inserted].[SlotNr]
, [inserted].[MeterNr]
, [inserted].[AddDate]
VALUES (@{nameof(id)}, @{nameof(slotnr)}, @{nameof(meterNr)})")
VALUES (@{nameof(id)}, @{nameof(psnr)}, @{nameof(slotnr)}, @{nameof(meterNr)})")
.SetParameter(nameof(id), id)
.SetParameter(nameof(psnr), psnr)
.SetParameter(nameof(slotnr), slotnr)
.SetParameter(nameof(meterNr), meterNr)
.FirstOrDefault(reader => new OmniPruefgang
@@ -476,6 +477,8 @@
public double? Acc { get; set; }
public bool Succeeded { get; set; }
public IDictionary<string, object> ToDictionary()
{
return new Dictionary<string, object>
+46 -34
View File
@@ -21,14 +21,17 @@
private OmniConnection connection;
public OmniMeter(int nr, string portName, string outputDirectory)
public OmniMeter(string psnr, int nr, string portName, string outputDirectory)
{
this.PSNR = psnr;
this.SlotNr = nr;
this.PortName = portName;
this.outputDirectory = outputDirectory;
this.outputFile = GetOrCreateOutputFile(nr, portName, outputDirectory);
}
public string PSNR { get; }
public int SlotNr { get; }
public string PortName { get; }
@@ -52,10 +55,7 @@
this.connection.Close();
this.connection.Open();
}
}
public void IdentitfyMeter()
{
var buildInfo = this.connection.ViewBuildInformation();
if (buildInfo.Status == Status.Completed)
@@ -66,9 +66,6 @@
{
this.MeterNr = NA;
}
// TODO: Change identNr to real serialNr
// this.SerialNr = OmniContext.Current.Auftrag.IdentNr;
}
public void Dispose()
@@ -82,8 +79,6 @@
this.connection = null;
this.states.Enqueue($"=== {DateTime.Now:HH:mm:ss} {new string('=', 100)}");
while (this.states.TryDequeue(out var state))
{
File.AppendAllText(this.outputFile, $"{state}{Environment.NewLine}");
@@ -139,7 +134,7 @@
public void LoadTestRun()
{
this.TestRun = OmniContext.Current.AddTestRun(this.SlotNr, this.MeterNr);
this.TestRun = OmniContext.Current.AddTestRun(this.PSNR, this.SlotNr, this.MeterNr);
}
public void SaveMeterState()
@@ -247,39 +242,56 @@
.GetAccuracies()
.GetCorrectionFactor(out bool succeeded);
var defaults = OmniContext.Current.Auftrag.TypParameter;
var testPoints = OmniContext
.Current
.Auftrag
.Pruefpunkte
.ToDictionary(x => x.PPNR, x => new Tuple<double, double>(x.MinAccuracy, x.MaxAccuracy));
if (succeeded)
foreach (var test in this.TestRun.TestedPoints)
{
var response = this.connection.Set(new RegisterSettings
var ppnr = test.PPNR ?? 0;
if (!testPoints.ContainsKey(ppnr))
{
IntPart = defaults.IntPart,
Fraction = (ushort)defaults.Fraction,
Size = defaults.Size,
Range = defaults.Range,
VolumePerPulseUnit = 0x00,
MeterUnits = (byte)MessurementUnits.CubicMeters,
FlowUnits = (byte)MessurementUnits.CubicMeters,
FlowRate = (byte)TimeUnits.Hours,
FactoryCorrection = (sbyte)(crrf * 10),
FieldCorrection = 0x00,
PulseWeight = 0,
PulseWidth = 7,
PulseUpdate = 0,
});
succeeded = false;
break;
}
var point = testPoints[ppnr];
var acc = test.Accuracy * (1 + crrf / 100D);
test.Acc = acc;
test.Succeeded = point.Item1 <= acc && acc <= point.Item2;
if (!test.Succeeded)
{
succeeded = false;
}
}
var response = this.connection.Set(new RegisterSettings
{
IntPart = defaults.IntPart,
Fraction = (ushort)defaults.Fraction,
Size = defaults.Size,
Range = defaults.Range,
VolumePerPulseUnit = 0x00,
MeterUnits = (byte)MessurementUnits.CubicMeters,
FlowUnits = (byte)MessurementUnits.CubicMeters,
FlowRate = (byte)TimeUnits.Hours,
FactoryCorrection = (sbyte)((succeeded ? crrf : 3.3) * 10),
FieldCorrection = 0x00,
PulseWeight = 0,
PulseWidth = 7,
PulseUpdate = 0,
});
this.TestRun.Succeeded = succeeded;
this.TestRun.CrrfAfter = crrf;
foreach (var testedPP in this.TestRun.TestedPoints)
{
testedPP.Acc = testedPP.Accuracy * (1 + crrf / 100D);
}
this.TestRun.CloseTestRun();
this.states.Enqueue($"=== {DateTime.Now:HH:mm:ss} {new string('=', 100)}");
while (this.states.TryDequeue(out var state))
{
File.AppendAllText(this.outputFile, $"{state}{Environment.NewLine}");
@@ -1,10 +1,18 @@
USE [Auftrag];
IF OBJECT_ID(N'Auftrag2Omni') IS NOT NULL DROP TABLE [Auftrag2Omni];
IF OBJECT_ID(N'OmniTestRuns') IS NOT NULL DROP TABLE [OmniTestRuns];
IF OBJECT_ID(N'OmniTestPoints') IS NOT NULL DROP TABLE [OmniTestPoints];
IF OBJECT_ID(N'OmniTypes') IS NOT NULL DROP TABLE [OmniTypes];
IF OBJECT_ID(N'OmniPlus') IS NOT NULL DROP TABLE [OmniPlus];
CREATE TABLE [Auftrag2Omni] (
[FertigungsauftragNr] INT NOT NULL,
[SerialNr] INT NOT NULL,
[BuildInfo] VARCHAR(30) NOT NULL,
[DateAdded] DATETIME NOT NULL DEFAULT(GETDATE())
);
CREATE TABLE [OmniTypes] (
[TypeId] TINYINT NOT NULL IDENTITY(1, 1),
[Type] VARCHAR(5) NOT NULL,
@@ -33,7 +41,6 @@ CREATE TABLE [OmniTestPoints] (
[MinAccuracy] FLOAT NULL,
[MaxAccuracy] FLOAT NULL,
CONSTRAINT [PK_OmniTestPoints_TestPointId] PRIMARY KEY ([TestPointId]),
CONSTRAINT [FK_OmniTestPoints_OmniTypes_OmniTypeId] FOREIGN KEY ([OmniTypeId]) REFERENCES [OmniTypes]([TypeId]),
CONSTRAINT [CHK_OmniTestPoints_Rotations] CHECK ([Rotations] BETWEEN 1 AND 5000),
CONSTRAINT [CHK_OmniTestPoints_Duration] CHECK ([Duration] BETWEEN 1 AND 3600)
);
@@ -72,6 +79,7 @@ CREATE TABLE [OmniPlus] (
CREATE TABLE [OmniTestRuns] (
[Id] INT NOT NULL,
[PsNr] VARCHAR(10) NOT NULL,
[SlotNr] TINYINT NOT NULL,
[MeterNr] VARCHAR(32) NOT NULL,
[AddDate] DATETIME NOT NULL DEFAULT(GETDATE()),