using Newtonsoft.Json; using ProductionUiCordonel.ProductionProcesses; using ProductionUiCordonel.ProductionProcesses.Actions; using ProductionUiCordonel.ProductionProcesses.Enum; using ProductionUiCordonel.UserControls.FinalTest; using System; using System.Collections.Generic; using System.Data; 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.Threading; using Xylem.Common.CommonCore.Configuration; using Xylem.Common.CommonCore.Consts; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore; using Xylem.Common.Hardware.WaterMeter.WaterMeterCore; using Xylem.Common.Logic.SoftwareAccessHelper; namespace ProductionUiCordonel { /// /// Interaction logic for FinalRadioTest.xaml /// public partial class FinalRadioTest : Window { 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 { return genesisMeter; } set { var oldMeter = genesisMeter; genesisMeter = value; meterHasChanged(oldMeter, genesisMeter); } } private int orderNumber = 0; public int OrderNumber { ////lblOrderNumber get { return orderNumber; } set { orderNumber = value; updateContentControl(lblOrderNumber, "-"); if (orderNumber != 0) { updateContentControl(lblOrderNumber, orderNumber.ToString()); } } } private long radioAdress = 0; public long RadioAdress { get { return radioAdress; } set { radioAdress = value; updateContentControl(lblRadioAdress, "-"); if (radioAdress != 0) { updateContentControl(lblRadioAdress, radioAdress.ToString()); } } } private string serialNumber = "-"; public string SerialNumber { get { return serialNumber; } set { serialNumber = value; updateContentControl(lblSerialNumber, "-"); if (!String.IsNullOrEmpty(serialNumber)) { updateContentControl(lblSerialNumber, serialNumber); } } } private string lastPcbID; private string currentProcess = "-"; public string CurrentProcess { get { return 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 int intervalWithoutDetect = 1000; private int intervalWithDetect = 10000; private string _currentPcbID; private Timer tmrAutoDetect; public ApplicationSettings Settings { get; set; } private void Window_Initialized(object sender, EventArgs e) { var configfile = System.IO.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, System.ComponentModel.CancelEventArgs e) { DisposeAllConnections(); } private void useSetting(bool 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 bool detectIsLocked; private string _lastMsg; public string LastMsg { set { _lastMsg = value; updateUi(lblMessage, _lastMsg); } get { return _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 { return _currentPcbID; } } private void GetPcbMapping(string pcbID) { if (string.IsNullOrEmpty(pcbID)) { return; } var url = $"{ServiceUrls.MarriageServiceUrl()}GetSerialNumberAndOrderNumber?PcbId={pcbID}&withRadioAdress=true"; Task.Run(() => { try { var responseJson = LocalWebRequest.GetRequest(url); var a = JsonConvert.DeserializeObject(responseJson); var tmpInt = 0; int.TryParse(a[1], out tmpInt); OrderNumber = tmpInt; long tmpLong = 0; if (a.Length > 2) { long.TryParse(a[2], out tmpLong); } RadioAdress = 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 bool Detect(bool IgnorErrors, int slot) { if (!detectIsLocked) { LastMsg = "Start Detect"; CurrentProcess = "Suche Cordonel"; bool 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.QuickLogin(); } 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"; hasDetect = false; DisposeAllConnections(); CurrentPcbID = ""; Detect(IgnorErrors, slot); } else { LastMsg = "Meter is still connected"; hasDetect = true; } } return hasDetect; } else { 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(bool retry, bool abort = false) { pc.Processes = new List(); pc.ProcessStateChangedHandler += Pc_ProcessStateChangedHandler; pc.ProcessLogHandler += PcOnProcessLogHandler; pc.ProcessProgressHandler += Pc_ProcessProgressHandler; var connectProcess = new ProductionProcessConnect(); 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, RadioAdress.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 ProductionProcessFinalParameterizationFix()); //[x] [x] [] pc.Processes.Add(new ProductionProcessFinalParameterizationVakoCsd(connectProcess, RadioAdress != 0)); //[x] [x] [] if (RadioAdress != 0) { 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 ProductionProcessShippingMode(true, RadioAdress != 0)); //[] [] [] pc.Processes.Add(new ProductionProcessFinalParameterizationVakoCsd(connectProcess, RadioAdress != 0)); //[x] [x] [] pc.Processes.Add(new ProductionProcessShippingMode(false, RadioAdress != 0)); //[] [] [] 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(false); 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 && oldMeter != 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(); }); //real change } private void UiElmEnable(UIElement elm, bool 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 + System.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(() => { if (e != null) { pbTotalProgress.Value = e.Progress; } } )); } else if (e.ProgressType == PopUpProcessProgressArgs.ProcessProgessType.SubProcess) { pbSubProgress.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { if (e != null) { pbSubProgress.Value = e.Progress; } } )); } } private void updateContentControl(ContentControl ctl, string text) { ctl.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { if (ctl != null) // 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 (dt != null) // 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 currentProcess = ((IProductionProcess)sender); updateProcessControl(currentProcess.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 = "-"; RadioAdress = 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) { var hasDetect = Detect(false, (int)cbxSlotBox.SelectedValue); Settings.Slot = (int)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"; 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 System.Diagnostics.Process.Start(fileName); } private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { txtInputHidden.Focus(); if (e.Key == System.Windows.Input.Key.Enter) { if (serialBarcode?.GetUserControl() is UcBarcodeInput bar) { bar?.inputKey(txtInputHidden.Text); } if (orderBarcode?.GetUserControl() is UcBarcodeInput obar) { obar?.inputKey(txtInputHidden.Text); } txtInputHidden.Clear(); } } } }