714 lines
22 KiB
C#
714 lines
22 KiB
C#
using Newtonsoft.Json;
|
|
using ProductionUiCordonel.ProductionProcesses;
|
|
using ProductionUiCordonel.ProductionProcesses.Actions;
|
|
using ProductionUiCordonel.ProductionProcesses.Enum;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
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
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for FinalRadioTest.xaml
|
|
/// </summary>
|
|
public partial class FinalRadioTest : Window
|
|
{
|
|
public event EventHandler OnLockMeter;
|
|
public event EventHandler OnReleaseMeter;
|
|
public event EventHandler OrderHasChanged;
|
|
#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();
|
|
|
|
|
|
|
|
}
|
|
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<SlotConfig[]>(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<string[]>(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;
|
|
}
|
|
|
|
|
|
public void SetUpBlank()
|
|
{
|
|
|
|
pc.Processes = new List<IProductionProcess>();
|
|
pc.ProcessStateChangedHandler += Pc_ProcessStateChangedHandler;
|
|
pc.ProcessLogHandler += PcOnProcessLogHandler;
|
|
pc.ProcessProgressHandler += Pc_ProcessProgressHandler;
|
|
|
|
var connectProcess = new ProductionProcessConnect();
|
|
pc.Processes.Add(connectProcess); //[x] [x] [x]
|
|
|
|
|
|
|
|
var CheckOrder = new ProductionProcessCheckOrderNumber(OrderNumber);
|
|
CheckOrder.isDone += CheckOrder_isDone;
|
|
|
|
pc.Processes.Add(CheckOrder); //[x] [x] [x]
|
|
pc.Processes.Add(new ProductionProcessCheckSerialNumber(SerialNumber)); //[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)); //[x] [x] []
|
|
var radioCheck = new ProductionProcessRadioCheck();
|
|
CheckOrder.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()); //[] [] []
|
|
|
|
pc.Processes.Add(new ProductionProcessFinalParameterizationVakoCsd(connectProcess)); //[x] [x] []
|
|
pc.Processes.Add(new ProductionProcessShippingMode()); //[] [] []
|
|
|
|
pc.Processes.Add(new ProductionProcessFullReadOut()); //[x] [x] [x]
|
|
pc.Processes.Add(new ProductionProcessLogOff()); //[] [] []
|
|
|
|
var checkAttach = new ProductionProcessCheckAttachment(OrderNumber);
|
|
CheckOrder.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);
|
|
}
|
|
|
|
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, EventArgs e)
|
|
{
|
|
detectIsLocked = false;
|
|
SetUpBlank();
|
|
}
|
|
|
|
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(btnStart, false);
|
|
UiElmEnable(btnDetect, true);
|
|
Task.Run(() => { LoadDetails(); });
|
|
return;
|
|
}
|
|
|
|
if (oldMeter?.PcbId == newMeter?.PcbId && newMeter?.PcbId == lastPcbID)
|
|
{
|
|
return;
|
|
}
|
|
|
|
UiElmEnable(btnStart, true);
|
|
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;
|
|
}
|
|
}
|
|
));
|
|
}
|
|
|
|
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 & Dock.Right);
|
|
}
|
|
));
|
|
|
|
|
|
}
|
|
|
|
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)
|
|
{
|
|
OnLockMeter?.Invoke(sender, EventArgs.Empty);
|
|
btnStart.IsEnabled = false;
|
|
CurrentGenesisMeter.SerialNumber = SerialNumber;
|
|
CurrentProcess = "gestartet";
|
|
pc.Start(CurrentGenesisMeter);
|
|
|
|
}
|
|
|
|
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 BtnDetect_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
var hasDetect = Detect(true,1);
|
|
}
|
|
}
|
|
}
|