using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using Newtonsoft.Json; using ProductionUiCordonelLegacy.ProductionProcesses; using ProductionUiCordonelLegacy.ProductionProcesses.Actions; using ProductionUiCordonelLegacy.ProductionProcesses.Enum; using ProductionUiCordonelLegacy.UserControls.FinalTest; using Xylem.Common.CommonCore.Configuration; using Xylem.Common.CommonCore.Consts; using Xylem.Common.Hardware.Interfaces.Ports.PortCore; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore; using Xylem.Common.Hardware.WaterMeter.WaterMeterCore; using Xylem.Common.Logic.SoftwareAccessHelper; namespace ProductionUiCordonelLegacy { /// /// Interaction logic for FinalRadioTest.xaml /// public partial class FinalRadioTest { public event EventHandler OnLockMeter; public event EventHandler OnReleaseMeter; public event EventHandler OrderHasChanged; //public event EventHandler KeyInputMainFrom; #region prop private GenesisMeter genesisMeter; public GenesisMeter CurrentGenesisMeter { get => genesisMeter; set { var oldMeter = genesisMeter; genesisMeter = value; meterHasChanged(oldMeter, genesisMeter); } } private Int32 orderNumber; public Int32 OrderNumber { ////lblOrderNumber get => orderNumber; set { orderNumber = value; updateContentControl(lblOrderNumber, "-"); if (orderNumber != 0) { updateContentControl(lblOrderNumber, orderNumber.ToString()); } } } private Int64 radioAddress; public Int64 RadioAddress { get => radioAddress; set { radioAddress = value; updateContentControl(lblRadioAdress, "-"); if (radioAddress != 0) { updateContentControl(lblRadioAdress, radioAddress.ToString()); } } } private String serialNumber = "-"; public String SerialNumber { get => serialNumber; set { serialNumber = value; updateContentControl(lblSerialNumber, "-"); if (!string.IsNullOrEmpty(serialNumber)) { updateContentControl(lblSerialNumber, serialNumber); } } } private String lastPcbID; private String currentProcess = "-"; public String CurrentProcess { get => currentProcess; set { currentProcess = value; updateContentControl(lblCurrentProcess, "-"); if (!string.IsNullOrEmpty(currentProcess)) { updateContentControl(lblCurrentProcess, currentProcess); } } } //Wait for a Meter to connect #endregion private MultiProcessController pc = new MultiProcessController(); public FinalRadioTest() { InitializeComponent(); SetUpBlank(false); } public EventHandler OnPcbIdDetect; private Int32 intervalWithoutDetect = 1000; private Int32 intervalWithDetect = 10000; private String _currentPcbID; private Timer tmrAutoDetect; public ApplicationSettings Settings { get; set; } private void Window_Initialized(Object sender, EventArgs e) { var configfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(Xylem.Common.Hardware.WaterMeter.Genesis), ProgramConfig.SerialConfigFileName); if (!File.Exists(configfile)) { throw new ApplicationException($"Configuration file {configfile} not found "); } var tr = new StreamReader(configfile); var meterConfigList = JsonConvert.DeserializeObject(tr.ReadToEnd()); cbxSlotBox.Items.Clear(); foreach (var item in meterConfigList.OrderBy(s => s.Slot)) { cbxSlotBox.Items.Add(item.Slot); } cbxSlotBox.SelectedIndex = 0; tmrAutoDetect = new Timer(intervalWithoutDetect); tmrAutoDetect.Elapsed += TmrAutoDetect_Elapsed; tmrAutoDetect.Enabled = false; Settings = new ApplicationSettings("ProductionUiConfig.json"); useSetting(true); } private void Window_Closing(Object sender, CancelEventArgs e) { DisposeAllConnections(); } private void useSetting(Boolean setSlot = false) { tmrAutoDetect.Enabled = Settings.AutoDetect; tblkAutodetectState.Text = "Off"; if (Settings.AutoDetect) { tblkAutodetectState.Text = "On"; } if (setSlot) { cbxSlotBox.SelectedValue = Settings.Slot; } } private void DisposeAllConnections() { if (CurrentBatch != null) { CurrentBatch.RemoveAllMeters(); if (CurrentGenesisMeter != null) { CurrentGenesisMeter.Dispose(); } CurrentBatch.Dispose(); } } private MeterBatch CurrentBatch; private Boolean detectIsLocked; private String _lastMsg; public String LastMsg { set { _lastMsg = value; updateUi(lblMessage, _lastMsg); } get => _lastMsg; } private void updateUi(ContentControl c, String content) { c.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { c.Content = content; })); } private void updateUi(TextBox c, String content) { c.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { c.Text = content; })); } private void updateUi(TextBlock c, String content) { c.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { c.Text = content; })); } public String CurrentPcbID { set { if (_currentPcbID != value && !(string.IsNullOrEmpty(_currentPcbID) && value == null)) { if (_currentPcbID != value) { if (!string.IsNullOrEmpty(_currentPcbID) && string.IsNullOrEmpty(value)) { _currentPcbID = value; updateUi(lblPcbID, _currentPcbID); } else { _currentPcbID = value; updateUi(lblPcbID, _currentPcbID); if (!string.IsNullOrEmpty(_currentPcbID)) { GetPcbMapping(_currentPcbID); } } } OnPcbIdDetect?.Invoke(CurrentPcbID, EventArgs.Empty); } } get => _currentPcbID; } private void GetPcbMapping(String pcbID) { if (string.IsNullOrEmpty(pcbID)) { return; } var url = $"{ServiceUrls.MarriageServiceUrl()}GetSerialNumberAndOrderNumber?PcbId={pcbID}&withRadioAdress=true"; try { var responseJson = LocalWebRequest.GetRequest(url); var a = JsonConvert.DeserializeObject(responseJson); int.TryParse(a[1], out var tmpInt); OrderNumber = tmpInt; Int64 tmpLong = 0; if (a.Length > 2) { long.TryParse(a[2], out tmpLong); } RadioAddress = tmpLong; SerialNumber = a[0]; if (a.Length > 3 && a[3] != SerialNumber) { SerialNumber = $"{SerialNumber} / {a[3]}"; } } catch (Exception ex) { if (ex is WebException) { MessageBox.Show($"Error on Store: {Environment.NewLine} { ((WebException)ex).Message}"); } MessageBox.Show(ex.Message); } } private Boolean Detect(Boolean IgnorErrors, Int32 slot) { slot = 1; if (!detectIsLocked) { LastMsg = "Start Detect"; CurrentProcess = "Suche Cordonel"; Boolean hasDetect = false; if (string.IsNullOrEmpty(CurrentPcbID) || CurrentGenesisMeter == null) { var mb = new MeterBatch(); var tryMeter = new GenesisMeter(); try { tryMeter.SetupFromConfigFile(slot); mb.AddMeter(tryMeter); tryMeter.Logout(); LastMsg = "Try to get PcbID"; CurrentPcbID = tryMeter.GetPcbId(); hasDetect = !string.IsNullOrEmpty(CurrentPcbID); CurrentBatch = mb; CurrentGenesisMeter = tryMeter; if (hasDetect) { LastMsg = $"New PcbID detected {CurrentPcbID}"; CurrentProcess = "Cordonel verbunden"; CurrentGenesisMeter.ReLogin(); } else { CurrentProcess = "Cordonel nicht gefunden"; LastMsg = "No Meter found"; DisposeAllConnections(); } } catch (Exception e) { if (!IgnorErrors) { MessageBox.Show($"Error occur.{ Environment.NewLine} {e.Message}"); } } } else { LastMsg = "Check if Meter is still connected"; var ret = CurrentGenesisMeter.GetPcbId(); if (string.IsNullOrEmpty(ret) || ret != CurrentPcbID) { LastMsg = "Meter connection lost"; DisposeAllConnections(); CurrentPcbID = ""; Detect(IgnorErrors, slot); } else { LastMsg = "Meter is still connected"; hasDetect = true; } } return hasDetect; } LastMsg = "Meter is still connected (locked)"; return true; } private void TmrAutoDetect_Elapsed(Object sender, ElapsedEventArgs e) { tmrAutoDetect.Enabled = false; var hasDetect = Detect(true, 1); if (hasDetect) { tmrAutoDetect.Interval = intervalWithDetect; } else { tmrAutoDetect.Interval = intervalWithoutDetect; } tmrAutoDetect.Enabled = Settings.AutoDetect; } private ProductionProcessCheckOrderNumber orderBarcode; private ProductionProcessCheckSerialNumber serialBarcode; public void SetUpBlank(Boolean retry, Boolean abort = false) { pc.Processes = new List(); pc.ProcessStateChangedHandler += Pc_ProcessStateChangedHandler; pc.ProcessLogHandler += PcOnProcessLogHandler; pc.ProcessProgressHandler += Pc_ProcessProgressHandler; var connectProcess = new ProductionProcessConnect(CurrentGenesisMeter); pc.Processes.Add(connectProcess); //[x] [x] [x] orderBarcode = new ProductionProcessCheckOrderNumber(0); orderBarcode.isDone += CheckOrder_isDone; pc.Processes.Add(orderBarcode); //[x] [x] [x] serialBarcode = new ProductionProcessCheckSerialNumber(SerialNumber, RadioAddress.ToString()); pc.Processes.Add(serialBarcode); //[x] [x] [x] //pc.Processes.Add(new ProductionProcessFullReadOut()); //[x] [x] [x] pc.Processes.Add(new ProductionCheckShippingState()); //[x] [x] [x] pc.Processes.Add(new ProductionProcessPasswordFile()); //[x] [x] [x] //pc.Processes.Add(new ProductionProcessFinalParametrizationFix()); //[x] [x] [] pc.Processes.Add(new ProductionProcessFinalParametrizationVakoCsd(connectProcess, true)); //[x] [x] [] pc.Processes.Add(new ProductionProcessShippingMode(true, true)); //[] [] [] var radioCheck = new ProductionProcessRadioCheck(); orderBarcode.isDone += delegate (object sender, EventArgs e) { radioCheck.Ordernumber = ((ProductionProcessCheckOrderNumber)sender).Ordernumber; }; pc.Processes.Add(radioCheck); //[] [] [] //pc.Processes.Add(new ProductionProcessSpecialConfig()); //[x] [x] [] pc.Processes.Add(new ProductionProcessFinalParametrizationVakoCsd(connectProcess, true)); //[x] [x] [] pc.Processes.Add(new ProductionProcessShippingMode(false, true)); //[] [] [] pc.Processes.Add(new ProductionProcessFullReadOut()); //[x] [x] [x] pc.Processes.Add(new ProductionProcessLogOff()); //[] [] [] var checkAttach = new ProductionProcessCheckAttachment(OrderNumber); orderBarcode.isDone += (x, g) => { checkAttach.OrderNumber = ((ProductionProcessCheckOrderNumber)x).Ordernumber; }; pc.Processes.Add(checkAttach); //[] [] [] var errorP = new ProductionProcessDone(true); errorP.isDone += allProcessesDone; pc.ErrorProcess = errorP; var successeP = new ProductionProcessDone(); successeP.isDone += allProcessesDone; pc.DoneProcess = successeP; updateStatusGrid(); UiElmEnable(btnDetect, true); if (retry) { runDetect(); } else if (abort) { dpSubProcess.Children.Clear(); } } private void CheckOrder_isDone(Object sender, EventArgs e) { OrderNumber = ((ProductionProcessCheckOrderNumber)sender).Ordernumber; OrderHasChanged?.Invoke(this, e); } private void Radio_CheckOrder_isDone(Object sender, EventArgs e) { OrderNumber = ((ProductionProcessCheckOrderNumber)sender).Ordernumber; OrderHasChanged?.Invoke(this, e); } private void allProcessesDone(Object sender, Tuple e) { detectIsLocked = false; if (e.Item3) { printErrorNote(); } SetUpBlank(e.Item1, e.Item2); } private void meterHasChanged(GenesisMeter oldMeter, GenesisMeter newMeter) { if (newMeter == null && oldMeter == null) { return; } if (newMeter == null) { //remove all CurrentProcess = "Warte auf Zähler"; UiElmEnable(btnDetect, true); Task.Run(() => { LoadDetails(); }); return; } if (oldMeter?.PcbId == newMeter.PcbId && newMeter.PcbId == lastPcbID) { return; } UiElmEnable(btnDetect, false); CurrentProcess = "Bitte den Startknopf drücken"; Task.Run(() => { LoadDetails(); }); } private void UiElmEnable(UIElement elm, Boolean isEnabled) { elm.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { elm.IsEnabled = isEnabled; } )); } private void PcOnProcessLogHandler(Object sender, PopUpProcessLogArgs e) { txtLog.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { if (e != null) { txtLog.Text = e.Data + Environment.NewLine + txtLog.Text; } } )); } private void Pc_ProcessProgressHandler(Object sender, PopUpProcessProgressArgs e) { if (e.ProgressType == PopUpProcessProgressArgs.ProcessProgessType.Total) { pbTotalProgress.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { pbTotalProgress.Value = e.Progress; } )); } else if (e.ProgressType == PopUpProcessProgressArgs.ProcessProgessType.SubProcess) { pbSubProgress.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { pbSubProgress.Value = e.Progress; } )); } } private void updateContentControl(ContentControl ctl, String text) { ctl.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { if (true) // table is a DataTable { ctl.Content = text; } } )); } private void updateStatusGrid() { var dt = new DataTable(); dt.Columns.Add("Process"); dt.Columns.Add("State"); var i = 0; foreach (var item in pc.Processes) { dt.Rows.Add(); dt.Rows[i][0] = item.GetName(); dt.Rows[i][1] = ProductionProcessStateHelper.GetTextFromProductionProcessState(item.GetState()); i++; } dgTotalProcess.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { if (true) // table is a DataTable { dgTotalProcess.DataContext = dt; } } )); } private void updateProcessControl(UserControl c) { dgTotalProcess.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { dpSubProcess.Children.Clear(); dpSubProcess.Children.Add(c); DockPanel.SetDock(c, Dock.Top); // & Dock.Left); } )); } private void Pc_ProcessStateChangedHandler(Object sender, EventArgs e) { if (sender is IProductionProcess) { var process = ((IProductionProcess)sender); updateProcessControl(process.GetUserControl()); } updateStatusGrid(); } private void ButtonBase_OnClick(Object sender, RoutedEventArgs e) { } public void LoadDetails() { if (CurrentGenesisMeter == null || string.IsNullOrEmpty(CurrentGenesisMeter.PcbId)) { currentProcess = "Warte auf Zähler"; OrderNumber = 0; SerialNumber = "-"; RadioAddress = 0; return; } lastPcbID = CurrentGenesisMeter.PcbId; currentProcess = "Bitte starten"; } private void BtnSwitchAutoDetect_Click(Object sender, RoutedEventArgs e) { Settings.AutoDetect = !Settings.AutoDetect; storeSetting(); useSetting(); } private void CbxSlotBox_SelectionChanged(Object sender, SelectionChangedEventArgs e) { } private void storeSetting() { Settings.Update("ProductionUiConfig.json"); } private void BtnConntect_Click(Object sender, RoutedEventArgs e) { Detect(false, (Int32)cbxSlotBox.SelectedValue); Settings.Slot = (Int32)cbxSlotBox.SelectedValue; storeSetting(); } private void runDetect() { var hasDetect = Detect(true, 1); btnDetect.IsEnabled = false; if (hasDetect) { OnLockMeter?.Invoke(null, EventArgs.Empty); CurrentGenesisMeter.SerialNumber = SerialNumber; CurrentProcess = "gestartet"; SetUpBlank(false); pc.Start(CurrentGenesisMeter); } } private void BtnDetect_Click(Object sender, RoutedEventArgs e) { runDetect(); } private void printErrorNote() { var sb = new StringBuilder(); var fileName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}_ReturnNoteTxt_{lblPcbID.Content}.txt"; sb.AppendLine($"Aufallschein {DateTime.Now}"); sb.AppendLine("----------------------------------"); sb.AppendLine($"PcbId {lblPcbID.Content}"); sb.AppendLine($"Auftrag {lblOrderNumber.Content}"); sb.AppendLine($"Seriennummer {lblSerialNumber.Content}"); sb.AppendLine($"Status {lblMessage.Text}"); sb.AppendLine("-------------Meldung---------------"); sb.Append($"{txtLog.Text}"); File.WriteAllText(fileName, sb.ToString()); //txtLog.Text Process.Start(fileName); } private void Window_PreviewKeyDown(Object sender, KeyEventArgs e) { txtInputHidden.Focus(); if (e.Key == Key.Enter) { if (serialBarcode?.GetUserControl() is UcBarcodeInput bar) { bar.inputKey(txtInputHidden.Text); } if (orderBarcode?.GetUserControl() is UcBarcodeInput orderBar) { orderBar.inputKey(txtInputHidden.Text); } txtInputHidden.Clear(); } } protected virtual void OnOnReleaseMeter() { OnReleaseMeter?.Invoke(this, EventArgs.Empty); } } }