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 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 checkAppsIdVersion, UInt32 Frequency, UInt32 MeterSize, Boolean PressurePresent, GenesisMeter meter) { PickingState = "Üperprüfe Parameter"; var FrequencyReadOut = RegisterConverter.ByteArrayToValue(meter.ReadRegister("SENSUSRADIO_FrequencyIndicator")); if (FrequencyReadOut != Frequency) { PickingState = $"Falsche Frequenz! soll {Frequency}MHz ist {FrequencyReadOut}MHz"; return false; } var MeterSizeReadOut = RegisterConverter.ByteArrayToValue(meter.ReadRegister("GENESISFLOW_MeterSize")); if (MeterSizeReadOut != MeterSize) { PickingState = $"Meter Dn falsch! soll {MeterSize}DN ist {MeterSizeReadOut}DN"; return false; } var PressureReadOut = RegisterConverter.ByteArrayToValue(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(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(); } } }