517 lines
19 KiB
C#
517 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Media;
|
|
using Logic.ProductionToProductMapper.Cordonel;
|
|
using Newtonsoft.Json;
|
|
using Xylem.Common.CommonCore.Configuration;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
|
using Xylem.Common.Logic.SoftwareAccessHelper;
|
|
|
|
namespace ProductionUiCordonelLegacy.Model
|
|
{
|
|
internal class MultiModeMasterViewModel : INotifyPropertyChanged
|
|
{
|
|
private String pickingState = "Warte auf Scanner";
|
|
private String pickingScanner = "keine Verbindung";
|
|
private String pickingSlot = "-";
|
|
private String pickingResult = "-";
|
|
|
|
private Brush pickingResultColor;
|
|
public Brush PickingResultColor
|
|
{
|
|
get => pickingResultColor;
|
|
set
|
|
{
|
|
pickingResultColor = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
public String PickingState
|
|
{
|
|
get => pickingState;
|
|
set
|
|
{
|
|
pickingState = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
public String PickingScanner
|
|
{
|
|
get => pickingScanner;
|
|
set
|
|
{
|
|
pickingScanner = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
public String PickingSlot
|
|
{
|
|
get => pickingSlot;
|
|
set
|
|
{
|
|
pickingSlot = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
public String PickingResult
|
|
{
|
|
get => pickingResult;
|
|
set
|
|
{
|
|
pickingResult = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
protected virtual void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
|
|
{
|
|
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
|
|
|
|
|
|
public void StartPicking(CancellationTokenSource cancle)
|
|
{
|
|
var s = new Task(() => { PickingLoop(cancle.Token); }, cancle.Token);
|
|
s.Start();
|
|
}
|
|
public enum PickingStateMachine
|
|
{
|
|
Init,
|
|
WaitForScanning,
|
|
ScanningDone,
|
|
WaitForDetect,
|
|
GetOrderDetails,
|
|
Compare,
|
|
MeterDone,
|
|
MeterError,
|
|
StartCom,
|
|
WaitForBuildingMeterReady,
|
|
WaitForBuildingPressureReady,
|
|
}
|
|
private PickingStateMachine sm = PickingStateMachine.Init;
|
|
|
|
private class BarScanner : IDisposable
|
|
{
|
|
private Boolean isRuning;
|
|
public String Input = "";
|
|
private String Port;
|
|
private CancellationToken Cancellation;
|
|
private Task WaitForScannerTask;
|
|
public BarScanner(String port, CancellationToken cancellation)
|
|
{
|
|
Port = port;
|
|
Cancellation = cancellation;
|
|
}
|
|
public void Start()
|
|
{
|
|
if (!isRuning)
|
|
{
|
|
if (Port == null)
|
|
{
|
|
return;
|
|
}
|
|
WaitForScannerTask = new Task(() =>
|
|
{
|
|
using (var a = new SerialPort(Port))
|
|
{
|
|
a.Open();
|
|
a.NewLine = "\r";
|
|
while (true)
|
|
{
|
|
if (Cancellation.IsCancellationRequested)
|
|
{
|
|
isRuning = false;
|
|
break;
|
|
}
|
|
|
|
Input = a.ReadLine();
|
|
a.Close();
|
|
isRuning = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
}, Cancellation);
|
|
WaitForScannerTask.Start();
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (WaitForScannerTask.Status != TaskStatus.Faulted && WaitForScannerTask.Status != TaskStatus.RanToCompletion && WaitForScannerTask.Status != TaskStatus.Canceled)
|
|
{
|
|
WaitForScannerTask.Dispose();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public Boolean Compare(Dictionary<UInt32, UInt32> checkAppsIdVersion, UInt32 Frequency, UInt32 MeterSize, Boolean PressurePresent)
|
|
{
|
|
using (var Batch = new MeterBatch())
|
|
{
|
|
|
|
using (var meter = new GenesisMeter())
|
|
{
|
|
|
|
meter.SetupFromConfigFile(PickingSlotNr);
|
|
Batch.AddMeter(meter);
|
|
PickingState = "Am Zähler anmelden";
|
|
if (meter.Login())
|
|
{
|
|
meter.SetProcessState(DisplayCodes.PickingStarted);
|
|
var ret = RunCheck(checkAppsIdVersion, Frequency, MeterSize, PressurePresent, meter);
|
|
|
|
if (ret)
|
|
{
|
|
meter.SetProcessState(DisplayCodes.PickingTested);
|
|
var url = $"{ServiceUrls.MeterProcessStateUrl()}SetPickingState?PcbID={meter.PcbId}&FertigungsauftragsNr={PickingOrder}";
|
|
var RetString = LocalWebRequest.PostRequestAsyncAndGetContent(url);
|
|
|
|
var result = false;
|
|
if (bool.TryParse(RetString, out result))
|
|
{
|
|
return result;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
meter.SetProcessState(DisplayCodes.PickingFailed);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private Boolean RunCheck(Dictionary<UInt32, UInt32> checkAppsIdVersion, UInt32 Frequency, UInt32 MeterSize, Boolean PressurePresent, GenesisMeter meter)
|
|
{
|
|
PickingState = "Üperprüfe Parameter";
|
|
var FrequencyReadOut = RegisterConverter.ByteArrayToValue<UInt32>(meter.ReadRegister("SENSUSRADIO_FrequencyIndicator"));
|
|
if (FrequencyReadOut != Frequency)
|
|
{
|
|
PickingState = $"Falsche Frequenz! soll {Frequency}MHz ist {FrequencyReadOut}MHz";
|
|
return false;
|
|
}
|
|
|
|
var MeterSizeReadOut = RegisterConverter.ByteArrayToValue<UInt32>(meter.ReadRegister("GENESISFLOW_MeterSize"));
|
|
if (MeterSizeReadOut != MeterSize)
|
|
{
|
|
PickingState = $"Meter Dn falsch! soll {MeterSize}DN ist {MeterSizeReadOut}DN";
|
|
return false;
|
|
}
|
|
|
|
|
|
var PressureReadOut = RegisterConverter.ByteArrayToValue<Boolean>(meter.ReadRegister("METROLOGYASST_PressurePresent"));
|
|
if (PressureReadOut != PressurePresent)
|
|
{
|
|
if (PressurePresent)
|
|
{
|
|
PickingState = "Pcb mit Drucksensor. Laut Auftrag keine verbaut";
|
|
}
|
|
else
|
|
{
|
|
PickingState = "Pcb ohne Drucksensor. Laut Auftrag soll eine verbaut werden";
|
|
}
|
|
//todo raus
|
|
return false;
|
|
}
|
|
|
|
foreach (var item in checkAppsIdVersion)
|
|
{
|
|
|
|
try
|
|
{
|
|
var MeterFWApp = meter.MeterAppListVersion.First(a => item.Key == a.AppId);
|
|
if (MeterFWApp == null || MeterFWApp.Version != item.Value)
|
|
{
|
|
PickingState = "Falsche FW, bitte Updaten";
|
|
return false;
|
|
}
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
PickingState = "Fehler beim auslesen der FW";
|
|
return false;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
try
|
|
{
|
|
meter.WriteRegister("METROLOGYASST_StoreConfiguration", 1);
|
|
Thread.Sleep(100);
|
|
var storeRet = meter.ReadRegister("METROLOGYASST_StoreConfiguration");
|
|
if (!storeRet.All(a => a.Equals(0)))
|
|
{
|
|
PickingState = "Filesystem corrupt";
|
|
return false;
|
|
}
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
PickingState = "Fehler beim überprüfen des Filesystems";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private PickingCompareItem PickingOrderDetails;
|
|
private BarScanner PickingBarScanner;
|
|
private String PickingOrder;
|
|
private String PickingPcbId;
|
|
|
|
|
|
private String PickingScannerPort = "COM6";
|
|
private Int32 PickingSlotNr = 1;
|
|
//PickingState,PickingScanner,PickingSlot,PickingResult
|
|
private void PickingLoop(CancellationToken token)
|
|
{
|
|
while (!token.IsCancellationRequested)
|
|
{
|
|
switch (sm)
|
|
{
|
|
case PickingStateMachine.Init:
|
|
PickingState = "Initialisierung";
|
|
PickingSlot = $"Inaktiv EP {PickingSlotNr}";
|
|
PickingScanner = $"Geschlossen {PickingScannerPort}";
|
|
//CheckAllPorts?
|
|
|
|
sm = PickingStateMachine.StartCom;
|
|
|
|
break;
|
|
case PickingStateMachine.StartCom:
|
|
PickingOrderDetails = null;
|
|
PickingScanner = $"Öfffne {PickingScannerPort}";
|
|
//CheckAllPorts?
|
|
PickingBarScanner = new BarScanner(PickingScannerPort, token);
|
|
PickingBarScanner.Start();
|
|
|
|
sm = PickingStateMachine.WaitForScanning;
|
|
|
|
break;
|
|
case PickingStateMachine.WaitForScanning:
|
|
PickingScanner = $"Offen {PickingScannerPort}";
|
|
PickingState = $"Warte auf Scannereingabe({PickingScannerPort})";
|
|
if (PickingBarScanner != null && !string.IsNullOrEmpty(PickingBarScanner.Input))
|
|
{
|
|
PickingOrder = PickingBarScanner.Input;
|
|
PickingScanner = $"Geschlossen {PickingScannerPort}";
|
|
PickingBarScanner = null;
|
|
|
|
|
|
sm = PickingStateMachine.WaitForDetect;
|
|
|
|
}
|
|
|
|
break;
|
|
case PickingStateMachine.WaitForDetect:
|
|
using (var Batch = new MeterBatch())
|
|
{
|
|
|
|
using (var tryMeter = new GenesisMeter())
|
|
{
|
|
try
|
|
{
|
|
PickingState = "Warte auf Pcb";
|
|
PickingSlot = $"Öffne EP {PickingSlotNr}";
|
|
tryMeter.SetupFromConfigFile(PickingSlotNr);
|
|
Batch.AddMeter(tryMeter);
|
|
tryMeter.Logout();
|
|
Log("Try to get PcbID");
|
|
PickingPcbId = tryMeter.GetPcbId();
|
|
|
|
var hasDetect = !string.IsNullOrEmpty(PickingPcbId);
|
|
|
|
if (hasDetect)
|
|
{
|
|
|
|
PickingState = $"Pcb gefunden {PickingPcbId}";
|
|
Log($"New PcbID detected {PickingPcbId}");
|
|
sm = PickingStateMachine.GetOrderDetails;
|
|
}
|
|
else
|
|
{
|
|
PickingSlot = $"Keine Konnektivität EP {PickingSlotNr}";
|
|
Log("No Meter found");
|
|
|
|
}
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log($"Error occur.{ Environment.NewLine} {e.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
case PickingStateMachine.GetOrderDetails:
|
|
|
|
PickingState = $"Lade Auftragsdaten {PickingOrder}";
|
|
var retCode = 0;
|
|
var str = LocalWebRequest.GetRequestWithError($"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetOrderOverview?ProductionOrderNumber={PickingOrder}&CheckPcbId={PickingPcbId}", out retCode, 15000);
|
|
if (retCode == 417)
|
|
{
|
|
sm = PickingStateMachine.MeterError;
|
|
PickingResult = "Keine Radio Parameter";
|
|
}
|
|
else
|
|
{
|
|
var retStr = JsonConvert.DeserializeObject<OrderOverViewCordonelWithPicking>(str);
|
|
PickingOrderDetails = retStr.PickingCompareItem;
|
|
|
|
if (retStr.OrderOverViewCordonel.Count == retStr.OrderOverViewCordonel.AssignedPicking)
|
|
{
|
|
PickingResult = "Auftrag schon komplett";
|
|
sm = PickingStateMachine.MeterError;
|
|
}
|
|
else
|
|
{
|
|
PickingState = $"Auftragsdaten geladen {PickingOrder}";
|
|
sm = PickingStateMachine.Compare;
|
|
}
|
|
}
|
|
|
|
break;
|
|
case PickingStateMachine.Compare:
|
|
//Compare
|
|
PickingState = $"Vergleiche Auftragsdaten {PickingOrder} mit Pcb Eigenschaften";
|
|
|
|
|
|
var converter = new BrushConverter();
|
|
if (Compare(PickingOrderDetails.CheckAppsIdVersion, PickingOrderDetails.FrequencyIndicator, PickingOrderDetails.MeterSize, PickingOrderDetails.PressurePresent))
|
|
{
|
|
//erfolg anzeigen und weiter
|
|
var b = (Brush)converter.ConvertFromString("#419C14");
|
|
b.Freeze();
|
|
PickingResultColor = b;
|
|
sm = PickingStateMachine.MeterDone;
|
|
}
|
|
else
|
|
{
|
|
sm = PickingStateMachine.MeterError;
|
|
|
|
var b = (Brush)converter.ConvertFromString("#FF8000");
|
|
b.Freeze();
|
|
PickingResultColor = b;
|
|
}
|
|
break;
|
|
case PickingStateMachine.MeterError:
|
|
PickingOrderDetails = null;
|
|
PickingState = "Vergleich abgeschlossen";
|
|
PickingResult = "Vergleich fertig fehlgeschlagen";
|
|
Thread.Sleep(10000);
|
|
sm = PickingStateMachine.StartCom;
|
|
|
|
break;
|
|
case PickingStateMachine.MeterDone:
|
|
|
|
|
|
PickingState = "Vergleich abgeschlossen warten auf Montage Rückmeldung";
|
|
PickingResult = $"Pcb {PickingPcbId} wurde dem Auftrag {PickingOrder} hinzugefügt";
|
|
Thread.Sleep(10000);
|
|
PickingScanner = $"Öfffne {PickingScannerPort}";
|
|
PickingBarScanner = new BarScanner(PickingScannerPort, token);
|
|
|
|
PickingBarScanner.Start();
|
|
sm = PickingStateMachine.WaitForBuildingMeterReady;
|
|
|
|
//CheckAllPorts?
|
|
|
|
|
|
|
|
break;
|
|
case PickingStateMachine.WaitForBuildingMeterReady:
|
|
|
|
if (PickingBarScanner != null && !string.IsNullOrEmpty(PickingBarScanner.Input))
|
|
{
|
|
|
|
if (PickingBarScanner.Input == "%Cordonel_SAP_100%")
|
|
{
|
|
|
|
var url = ServiceUrls.MeterProcessStateUrl();
|
|
url = url + $"setSapState?PcbID={PickingPcbId}&code=100&version=1";
|
|
try
|
|
{
|
|
LocalWebRequest.PostRequestAsync(url);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
}
|
|
|
|
if (PickingOrderDetails.PressurePresent)
|
|
{
|
|
PickingBarScanner = new BarScanner(PickingScannerPort, token);
|
|
|
|
PickingBarScanner.Start();
|
|
PickingState = "Montage Rückmeldung erhalten, Montage des Drucksensors bestätigen";
|
|
sm = PickingStateMachine.WaitForBuildingPressureReady;
|
|
}
|
|
else
|
|
{
|
|
PickingState = "Montage Rückmeldung erhalten, auftrag Scannen";
|
|
sm = PickingStateMachine.StartCom;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case PickingStateMachine.WaitForBuildingPressureReady:
|
|
|
|
if (PickingBarScanner != null && !string.IsNullOrEmpty(PickingBarScanner.Input))
|
|
{
|
|
|
|
if (PickingBarScanner.Input == "%Cordonel_SAP_101%")
|
|
{
|
|
var url = ServiceUrls.MeterProcessStateUrl();
|
|
url = url + $"setSapState?PcbID={PickingPcbId}&code=101&version=1";
|
|
try
|
|
{
|
|
LocalWebRequest.PostRequestAsync(url);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
}
|
|
|
|
PickingState = "Montage Rückmeldung erhalten, auftrag Scannen";
|
|
sm = PickingStateMachine.StartCom;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
Thread.Sleep(1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private void Log(String v)
|
|
{
|
|
//throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|