common/ProductionUiCordonel/Model/MultiModeMasterViewModel.cs
2026-04-23 17:50:07 +02:00

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();
}
}
}