501 lines
14 KiB
C#
501 lines
14 KiB
C#
namespace OMNIPruefung.ViewModels.Content
|
|
{
|
|
using ExchangeHub;
|
|
|
|
using OmniPlus;
|
|
using OMNIPruefung.Models;
|
|
using OMNIPruefung.ViewModels.Base;
|
|
using OMNIPruefung.ViewModels.Options;
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
|
|
using TimersTimer = System.Timers.Timer;
|
|
|
|
public class EOLContentVM : ContentVM
|
|
{
|
|
private static readonly string line = new string('=', 500);
|
|
|
|
private readonly EOLSettings omnisettings;
|
|
private readonly ExchangeHubSettings hubsettings;
|
|
private CancellationTokenSource cancellationTokenSource;
|
|
private CancellationToken cancellationToken;
|
|
private OmniPlusDatabase dbcontext;
|
|
private ExchangeConnection signalR;
|
|
private ICollection<Task> tasks;
|
|
private ManualResetEventSlim manualResetEventSlim;
|
|
private TimersTimer timer;
|
|
|
|
public EOLContentVM() : base()
|
|
{
|
|
this.Header = "EOL";
|
|
this.CanStop = false;
|
|
this.CanStart = true;
|
|
this.Option = new EOLOptionVM(this);
|
|
this.Option.OptionSelected += this.NotifyOptionSelected;
|
|
this.omnisettings = new EOLSettings();
|
|
this.hubsettings = new ExchangeHubSettings();
|
|
this.OmniDefaults = new OmniPlusType();
|
|
this.tasks = new List<Task>();
|
|
|
|
this.dbcontext = new OmniPlusDatabase(this.omnisettings.OmniDB);
|
|
this.signalR = new ExchangeConnection();
|
|
this.signalR.OutputDir = this.hubsettings.ExchangeHubOutputDir;
|
|
this.signalR.Connect(this.hubsettings.ExchangeHubURL);
|
|
|
|
this.LoadComPorts = new Command(this.InitializeComPorts);
|
|
this.CancelInspection = new Command(this.CancelInspectionHandler);
|
|
this.StartInspection = new Command(this.StartInspectionHandler);
|
|
|
|
this.InitializeComPorts();
|
|
}
|
|
|
|
public string Type
|
|
{
|
|
get => this.hubsettings[nameof(this.Type)];
|
|
set
|
|
{
|
|
this.hubsettings[nameof(this.Type)] = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.Type));
|
|
}
|
|
}
|
|
|
|
private string text;
|
|
public string Text
|
|
{
|
|
get => this.text;
|
|
set
|
|
{
|
|
this.text = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.Text));
|
|
}
|
|
}
|
|
|
|
private string error;
|
|
public string Error
|
|
{
|
|
get => this.error;
|
|
set
|
|
{
|
|
this.error = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.Error));
|
|
}
|
|
}
|
|
|
|
private string state;
|
|
public string State
|
|
{
|
|
get => this.state;
|
|
set
|
|
{
|
|
this.state = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.State));
|
|
}
|
|
}
|
|
|
|
private bool canStart;
|
|
public bool CanStart
|
|
{
|
|
get => this.canStart;
|
|
set
|
|
{
|
|
this.canStart = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.CanStart));
|
|
}
|
|
}
|
|
|
|
private bool canStop;
|
|
public bool CanStop
|
|
{
|
|
get => this.canStop;
|
|
set
|
|
{
|
|
this.canStop = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.CanStop));
|
|
}
|
|
}
|
|
|
|
private int secondsLeft;
|
|
public int AvailableIn
|
|
{
|
|
get => this.secondsLeft;
|
|
set
|
|
{
|
|
this.secondsLeft = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.AvailableIn));
|
|
}
|
|
}
|
|
|
|
private OmniPlusType omniDefaults;
|
|
public OmniPlusType OmniDefaults
|
|
{
|
|
get => this.omniDefaults;
|
|
set
|
|
{
|
|
this.omniDefaults = value;
|
|
|
|
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
|
|
}
|
|
}
|
|
|
|
public String Line => line;
|
|
|
|
public ICommand LoadComPorts { get; }
|
|
|
|
public ICommand CancelInspection { get; }
|
|
|
|
public ICommand StartInspection { get; }
|
|
|
|
private void InitializeComPorts()
|
|
{
|
|
foreach (var disposable in this.Nodes.Cast<IDisposable>())
|
|
{
|
|
disposable.Dispose();
|
|
}
|
|
|
|
this.Nodes.Clear();
|
|
this.Option.Clear();
|
|
|
|
try
|
|
{
|
|
var placeNr = 1;
|
|
|
|
foreach (var com in this.omnisettings.COMPorts)
|
|
{
|
|
var comVM = new COMContentVM();
|
|
comVM.ContentSelected += this.NotifyCotnentSelected;
|
|
comVM.PortName = com;
|
|
comVM.Nr = placeNr++;
|
|
comVM.Header = $"{com}";
|
|
comVM.State = $"{com}";
|
|
comVM.InitializeAsync();
|
|
|
|
this.Nodes.Add(comVM);
|
|
this.Option.Add(comVM.Option);
|
|
}
|
|
|
|
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
|
|
this.Option.SetIndentation(this.Option.Indent);
|
|
this.dbcontext.LoadOmniDefaults(6, this.Type, this.OmniDefaults);
|
|
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
|
|
this.NotifyPropertyChanged(nameof(this.Nodes));
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.Error = e.ToString();
|
|
}
|
|
|
|
this.CanStop = false;
|
|
this.CanStart = true;
|
|
this.Error = default(string);
|
|
this.State = default(string);
|
|
}
|
|
|
|
private void CancelInspectionHandler()
|
|
{
|
|
this.CanStop = false;
|
|
this.CanStart = false;
|
|
this.Error = default(string);
|
|
this.State = "Warte bis abbruch abgeschlossen ...";
|
|
|
|
try
|
|
{
|
|
this.manualResetEventSlim?.Set();
|
|
this.cancellationTokenSource?.Cancel();
|
|
this.tasks.Clear();
|
|
this.Dispose();
|
|
|
|
this.State = "Vorgang wurde abbgebrochen!";
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.Error = e.ToString();
|
|
this.State = default(string);
|
|
}
|
|
|
|
Task.Factory.StartNew(() =>
|
|
{
|
|
this.CanStart = false;
|
|
|
|
if (this.AvailableIn > 0)
|
|
{
|
|
this.WaitUntil(this.AvailableIn, true);
|
|
}
|
|
|
|
this.CanStart = true;
|
|
this.Error = default(string);
|
|
});
|
|
}
|
|
|
|
private void StartInspectionHandler()
|
|
{
|
|
this.CanStop = true;
|
|
this.CanStart = false;
|
|
|
|
this.cancellationTokenSource = new CancellationTokenSource();
|
|
this.cancellationToken = this.cancellationTokenSource.Token;
|
|
|
|
Task.Factory.StartNew(() =>
|
|
{
|
|
var coms = this.Nodes.Cast<COMContentVM>();
|
|
|
|
//foreach (var comVM in coms)
|
|
//{
|
|
// this.tasks.Add(comVM.ReadSystemParametersTask(this.cancellationToken));
|
|
//}
|
|
|
|
//this.ContinueWhenAll();
|
|
|
|
foreach (var comVM in coms)
|
|
{
|
|
this.tasks.Add(comVM.SetInputVolumeTask(this.OmniDefaults, this.cancellationToken));
|
|
}
|
|
|
|
this.ContinueWhenAll();
|
|
|
|
var results = this.OmniDefaults
|
|
.TestPoints
|
|
.ToDictionary(x => x, x => new List<OmniPlusTest>());
|
|
|
|
foreach (var pp in this.OmniDefaults.TestPoints)
|
|
{
|
|
if (coms.All(x => !x.Running))
|
|
{
|
|
break;
|
|
}
|
|
|
|
var rotations = pp.Rotations;
|
|
var duration = pp.Duration;
|
|
|
|
this.SetFlow(pp.VolumeM3H);
|
|
|
|
foreach (var comVM in coms)
|
|
{
|
|
this.tasks.Add(comVM.StartPPCalibrationTask(pp, this.cancellationToken));
|
|
}
|
|
|
|
this.ContinueWhenAll();
|
|
|
|
this.StartRZ(duration);
|
|
this.WaitUntil((int)(duration * 1.2), true, false);
|
|
|
|
if (this.manualResetEventSlim.IsSet)
|
|
{
|
|
break;
|
|
}
|
|
|
|
var referenceV = this.GetRZVolume();
|
|
|
|
foreach (var comVM in coms)
|
|
{
|
|
this.tasks.Add(comVM.StopPPCalibrationTask(pp, this.cancellationToken));
|
|
}
|
|
|
|
this.ContinueWhenAll();
|
|
|
|
if (coms.All(x => !x.Running))
|
|
{
|
|
break;
|
|
}
|
|
|
|
foreach (var comVM in coms)
|
|
{
|
|
comVM.SetReferenceVolume(pp, referenceV);
|
|
}
|
|
}
|
|
|
|
foreach (var comVM in coms)
|
|
{
|
|
comVM.SaveInspection();
|
|
}
|
|
|
|
if (coms.All(x => x.Running))
|
|
{
|
|
foreach (var comVM in coms)
|
|
{
|
|
comVM.GetCorrectionFactor();
|
|
}
|
|
|
|
foreach (var comVM in coms)
|
|
{
|
|
comVM.Dispose();
|
|
}
|
|
}
|
|
|
|
this.CancelInspectionHandler();
|
|
this.signalR.NotifyStopRef();
|
|
this.signalR.NotifyStopQ();
|
|
this.signalR.Dispose();
|
|
|
|
}, this.cancellationToken);
|
|
}
|
|
|
|
private void WaitUntil(int duration, bool show = false, bool error = true)
|
|
{
|
|
this.AvailableIn = duration;
|
|
|
|
if (this.manualResetEventSlim != null)
|
|
{
|
|
this.manualResetEventSlim.Set();
|
|
this.manualResetEventSlim.Dispose();
|
|
}
|
|
|
|
this.manualResetEventSlim = new ManualResetEventSlim();
|
|
|
|
if (this.timer != null)
|
|
{
|
|
this.timer.Stop();
|
|
this.timer.Dispose();
|
|
}
|
|
|
|
this.timer = new TimersTimer(1000)
|
|
{
|
|
AutoReset = true,
|
|
Enabled = true
|
|
};
|
|
this.timer.Elapsed += (_1, _2) =>
|
|
{
|
|
this.AvailableIn -= 1;
|
|
|
|
if (show)
|
|
{
|
|
if (error)
|
|
{
|
|
this.State = null;
|
|
this.Error = $"Verfügbar in {this.AvailableIn} Sekunden";
|
|
}
|
|
else
|
|
{
|
|
this.Error = null;
|
|
this.State = $"Noch {this.AvailableIn} Sekunden verbleiben";
|
|
}
|
|
}
|
|
|
|
if (this.AvailableIn <= 0)
|
|
{
|
|
this.AvailableIn = 0;
|
|
this.manualResetEventSlim.Set();
|
|
}
|
|
};
|
|
|
|
this.timer.Start();
|
|
this.manualResetEventSlim.Wait(this.AvailableIn * 1000);
|
|
this.timer.Stop();
|
|
}
|
|
|
|
private void ContinueWhenAll()
|
|
{
|
|
if (this.tasks.Any())
|
|
{
|
|
Task.Factory
|
|
.ContinueWhenAll(this.tasks.ToArray(), _ => { })
|
|
.Wait();
|
|
|
|
this.tasks.Clear();
|
|
}
|
|
|
|
Thread.Sleep(1000);
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
foreach (var disposable in this.Nodes.Cast<IDisposable>())
|
|
{
|
|
disposable.Dispose();
|
|
}
|
|
}
|
|
|
|
private void SetFlow(double volumeM3H)
|
|
{
|
|
var received = false;
|
|
var volume = volumeM3H;
|
|
var timeout = 120; // seconds
|
|
|
|
void referenceVolumeReceived(double value)
|
|
{
|
|
received = true;
|
|
volume = value;
|
|
}
|
|
|
|
this.signalR.StartQ += referenceVolumeReceived;
|
|
|
|
this.signalR.NotifyStartQ(volumeM3H);
|
|
|
|
this.State = "Warten auf Q(soll) ...";
|
|
|
|
while (!received && timeout > 0)
|
|
{
|
|
Thread.Sleep(1000);
|
|
|
|
timeout--;
|
|
}
|
|
}
|
|
|
|
private void StartRZ(int duration)
|
|
{
|
|
var received = false;
|
|
var reference = 0;
|
|
var timeout = 30; // seconds
|
|
|
|
void referenceVolumeReceived(int value)
|
|
{
|
|
received = true;
|
|
reference = value;
|
|
}
|
|
|
|
this.signalR.StartRef += referenceVolumeReceived;
|
|
|
|
this.signalR.NotifyStartRef(duration);
|
|
|
|
this.State = "Warten bis RZ gestarted ...";
|
|
|
|
while (!received && timeout > 0)
|
|
{
|
|
Thread.Sleep(1000);
|
|
|
|
timeout--;
|
|
}
|
|
}
|
|
|
|
private double GetRZVolume()
|
|
{
|
|
var received = false;
|
|
var referenceV = 0D;
|
|
var timeout = 30; // seconds
|
|
|
|
void referenceVolumeReceived(double value)
|
|
{
|
|
received = true;
|
|
referenceV = value;
|
|
}
|
|
|
|
this.signalR.StopRef += referenceVolumeReceived;
|
|
|
|
this.signalR.NotifyStopRef();
|
|
|
|
this.State = "Warten RZ Ergebnis ...";
|
|
|
|
while (!received && timeout > 0)
|
|
{
|
|
Thread.Sleep(1000);
|
|
|
|
timeout--;
|
|
}
|
|
|
|
return referenceV;
|
|
}
|
|
}
|
|
}
|