Initial commit
This commit is contained in:
+114
@@ -0,0 +1,114 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.Vako;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessCheckAttachment : BaseProductionProcess
|
||||
{
|
||||
public event EventHandler isDone;
|
||||
private UcDialog UserControl;
|
||||
public DialogResult Result = DialogResult.Error;
|
||||
public enum DialogResult
|
||||
{
|
||||
Error,
|
||||
Acknowledge
|
||||
}
|
||||
public bool DialogIsDone { get; private set; }
|
||||
public int OrderNumber { get; set; }
|
||||
public ProductionProcessCheckAttachment(int orderNumber)
|
||||
{
|
||||
OrderNumber = orderNumber;
|
||||
DialogIsDone = false;
|
||||
name = "Zubehör/Beigaben überprüfen";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcDialog();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
isDone?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void StepError()
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
isDone?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
|
||||
public override async void StartProcess()
|
||||
{
|
||||
|
||||
var a = LocalWebRequest.GetRequest($"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetSingleVakoKey?ProductionOrderNumber={OrderNumber}&KeyName=C_GEN_PULS");
|
||||
var myJsonResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<VakoKeyValue>(a);
|
||||
if (myJsonResponse.Value.ToLower() == "q" || myJsonResponse.Value.ToLower() == "k")
|
||||
{
|
||||
UserControl.SetDesc("Pulse Module anbauen!");
|
||||
}
|
||||
else
|
||||
{
|
||||
StepDone();
|
||||
}
|
||||
|
||||
|
||||
|
||||
var OptionList = new List<UcDialog.DialogOption>();
|
||||
var retry = new UcDialog.DialogOption("Nicht möglich", "", () =>
|
||||
{
|
||||
Result = DialogResult.Error;
|
||||
StepError();
|
||||
|
||||
});
|
||||
|
||||
|
||||
OptionList.Add(retry);
|
||||
|
||||
var Acknowledge = new UcDialog.DialogOption("Erledigt", "", () =>
|
||||
{
|
||||
Result = DialogResult.Acknowledge;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
|
||||
OptionList.Add(Acknowledge);
|
||||
|
||||
|
||||
UserControl.SetDialogOptions(OptionList);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessCheckOrderNumber : BaseProductionProcess
|
||||
{
|
||||
public event EventHandler isDone;
|
||||
private UcBarcodeInput UserControl;
|
||||
public DialogResult Result = DialogResult.None;
|
||||
public enum DialogResult
|
||||
{
|
||||
None,
|
||||
Retry,
|
||||
Print,
|
||||
Abort
|
||||
}
|
||||
public bool DialogIsDone { get; private set; }
|
||||
public int SerialNumber { get; private set; }
|
||||
public int Ordernumber { get; private set; }
|
||||
|
||||
private int? OldOrderNumber { get; set; }
|
||||
|
||||
private bool Error = false;
|
||||
public ProductionProcessCheckOrderNumber(int? oldOrderNumber = null)
|
||||
|
||||
{
|
||||
OldOrderNumber = oldOrderNumber;
|
||||
|
||||
DialogIsDone = false;
|
||||
name = "Überprüfe Auftrag";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcBarcodeInput();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
isDone?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void StepMismatch(string msg)
|
||||
{
|
||||
|
||||
UserControl.SetDesc(msg);
|
||||
UserControl.SetFocusMe();
|
||||
//UserControl.Focus();
|
||||
UserControl.BarcodeInput += UserControl_KeyDown;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void UserControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
var a = UserControl.txtHiddenInput.Text;
|
||||
|
||||
UserControl.txtHiddenInput.Text = "";
|
||||
if (OldOrderNumber.HasValue && a == Ordernumber.ToString())
|
||||
{
|
||||
StepDone();
|
||||
}
|
||||
else
|
||||
{
|
||||
StepMismatch($"Falscher oder fehlender Auftrag!{Environment.NewLine}Dieser Zähler ({SerialNumber}) ist teil des Auftrags {Ordernumber}.{Environment.NewLine}Bitte den Auftrag scannen.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
//StepDone();
|
||||
}
|
||||
|
||||
public override async void StartProcess()
|
||||
{
|
||||
|
||||
//get order number
|
||||
GetPcbMapping(Meter.PcbId);
|
||||
|
||||
if (OldOrderNumber.HasValue && OldOrderNumber.Value == Ordernumber)
|
||||
{
|
||||
StepDone();
|
||||
}
|
||||
|
||||
StepMismatch($"Falscher oder fehlender Auftrag!{Environment.NewLine}Dieser Zähler ({SerialNumber}) ist teil des Auftrags {Ordernumber}.{Environment.NewLine}Bitte den Auftrag scannen.");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void GetPcbMapping(string pcbID)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pcbID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var url = $"{ServiceUrls.MarriageServiceUrl()}GetSerialNumberAndOrderNumber?PcbId={pcbID}";
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var http = (HttpWebRequest)WebRequest.Create(url);
|
||||
HttpWebResponse response = null;
|
||||
try
|
||||
{
|
||||
response = (HttpWebResponse)http.GetResponse();
|
||||
}
|
||||
catch (WebException exception)
|
||||
{
|
||||
response = (HttpWebResponse)exception.Response;
|
||||
}
|
||||
|
||||
if (response != null && response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
var responseStream = response.GetResponseStream();
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
var a = JsonConvert.DeserializeObject<string[]>(responseJson);
|
||||
SerialNumber = Convert.ToInt32(a[0]);
|
||||
Ordernumber = Convert.ToInt32(a[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is WebException)
|
||||
{
|
||||
//MessageBox.Show($"Error on Store: {Environment.NewLine} { ((WebException)ex).Message}");
|
||||
}
|
||||
|
||||
//MessageBox.Show(ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessCheckSerialNumber : BaseProductionProcess
|
||||
{
|
||||
public event EventHandler isDone;
|
||||
private UcBarcodeInput UserControl;
|
||||
public DialogResult Result = DialogResult.None;
|
||||
public enum DialogResult
|
||||
{
|
||||
None,
|
||||
Retry,
|
||||
Print,
|
||||
Abort
|
||||
}
|
||||
public bool DialogIsDone { get; private set; }
|
||||
public string PcbSerialNumber { get; private set; }
|
||||
|
||||
private bool Error = false;
|
||||
public ProductionProcessCheckSerialNumber(String pcbSerialNumber)
|
||||
|
||||
{
|
||||
PcbSerialNumber = pcbSerialNumber;
|
||||
|
||||
DialogIsDone = false;
|
||||
name = "Überprüfe Seriennummer/Deckel";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcBarcodeInput();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
isDone?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void StepMismatch(string msg)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
isDone?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void UserControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
var a = UserControl.txtHiddenInput.Text;
|
||||
|
||||
UserControl.txtHiddenInput.Text = "";
|
||||
if (a.Trim().Contains(PcbSerialNumber.Trim()))
|
||||
{
|
||||
StepDone();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PcbSerialNumber.Contains("/") && (a.Trim().Contains(PcbSerialNumber.Split('/')[0].Trim()) || a.Trim().Contains(PcbSerialNumber.Split('/')[1].Trim())))
|
||||
{
|
||||
StepDone();
|
||||
}
|
||||
else
|
||||
{
|
||||
StepMismatch($"Falsche oder fehlerhafter Scan! {Environment.NewLine} Dieser Zähler müsste die ({PcbSerialNumber}) haben");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//StepDone();
|
||||
}
|
||||
|
||||
public override async void StartProcess()
|
||||
{
|
||||
PcbSerialNumber = Meter.SerialNumber;
|
||||
UserControl.SetDesc($"Bitte den Deckel des Zählers Scannern{Environment.NewLine} Die Seriennummer muss abgeglichen werden.");
|
||||
UserControl.SetFocusMe();
|
||||
//UserControl.Focus();
|
||||
UserControl.BarcodeInput += UserControl_KeyDown;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Logic.ProductionOrderCore;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessConnect : BaseProductionProcess
|
||||
{
|
||||
public Task<IList<ProgrammingParameters>> asyncprogrammingParametersTask;
|
||||
private UcPlain UserControl;
|
||||
private GenesisMeter Meter;
|
||||
public ProductionProcessConnect()
|
||||
{
|
||||
name = "Connect";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "";
|
||||
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
base.NewStatus($"Prüfe Verbindung");
|
||||
base.Progress = 0;
|
||||
if (!base.Meter.IsLoggedOn)
|
||||
{
|
||||
base.NewStatus($"Login wird gestartet");
|
||||
base.Meter.Login();
|
||||
}
|
||||
//Check access in
|
||||
base.Progress = 50;
|
||||
base.NewStatus($"Zugang wird überprüft");
|
||||
//var res = base.Meter.ReadRegister(Register.Genesisflow.LedMode);
|
||||
//if (res != null && res.Length > 0)
|
||||
//{
|
||||
base.Progress = 100;
|
||||
base.NewStatus($"Zugang verifiziert");
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
|
||||
asyncprogrammingParametersTask = new Task<IList<ProgrammingParameters>>(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
//var url = $"http://localhost:56011/api/FinalCheck/GetProgrammingParameters?PcbID={base.Meter.PcbId}";
|
||||
var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={base.Meter.PcbId}";
|
||||
var csdRet = LocalWebRequest.GetRequest(url, 80000);
|
||||
|
||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<IList<ProgrammingParameters>>(csdRet);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
return new List<ProgrammingParameters>() { };
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
asyncprogrammingParametersTask.Start();
|
||||
|
||||
|
||||
return;
|
||||
//}
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
// throw new Exception($"Not able to login");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessDone : BaseProductionProcess
|
||||
{
|
||||
public event EventHandler isDone;
|
||||
private UcDialog UserControl;
|
||||
public DialogResult Result = DialogResult.None;
|
||||
public enum DialogResult
|
||||
{
|
||||
None,
|
||||
Retry,
|
||||
Print,
|
||||
Abort
|
||||
}
|
||||
public bool DialogIsDone { get; private set; }
|
||||
private bool Error = false;
|
||||
public ProductionProcessDone(bool error = false)
|
||||
{
|
||||
Error = error;
|
||||
DialogIsDone = false;
|
||||
name = "Fertig";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcDialog();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
isDone?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void StepError()
|
||||
{
|
||||
|
||||
UserControl.SetDesc("Errors occur");
|
||||
var errorOptionList = new List<UcDialog.DialogOption>();
|
||||
var retry = new UcDialog.DialogOption("Wiederholen", "Alle Schritte werden wiederholt", () =>
|
||||
{
|
||||
Result = DialogResult.Retry;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
var Abort = new UcDialog.DialogOption("Abbruch", "Diesen Zähler NICHT verpacken", () =>
|
||||
{
|
||||
Result = DialogResult.Abort;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
var print = new UcDialog.DialogOption("Rückläuferschein drucken", "Rückläuferschein beim Zähler lassen und auf Klärung durch QS warten", () =>
|
||||
{
|
||||
Result = DialogResult.Retry;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
|
||||
errorOptionList.Add(retry);
|
||||
errorOptionList.Add(Abort);
|
||||
errorOptionList.Add(print);
|
||||
|
||||
UserControl.SetDialogOptions(errorOptionList);
|
||||
}
|
||||
|
||||
private void StepSuccsess()
|
||||
{
|
||||
|
||||
UserControl.SetDesc("Zähler verpacken");
|
||||
var OptionList = new List<UcDialog.DialogOption>();
|
||||
var retry = new UcDialog.DialogOption("Ok", "", () =>
|
||||
{
|
||||
Result = DialogResult.None;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
|
||||
OptionList.Add(retry);
|
||||
|
||||
UserControl.SetDialogOptions(OptionList);
|
||||
}
|
||||
|
||||
public override async void StartProcess()
|
||||
{
|
||||
if (Error)
|
||||
{
|
||||
StepError();
|
||||
}
|
||||
else
|
||||
{
|
||||
StepSuccsess();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFinalParameterization : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessFinalParameterization()
|
||||
{
|
||||
name = "Final Parameterization";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public Task<Tuple<String, Boolean>> _currentGenesis_WriteRegister<T>(String reg, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
|
||||
var ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
if (!ret)
|
||||
{
|
||||
ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, ret);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public Task<Tuple<String, Boolean>> wirteRegisterInBetweenCheck(String reg, Int32 value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false, int addToCheck = 10, int addFromCheck = 0)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Meter.WriteRegister(reg, value, waitForResult);
|
||||
|
||||
var accucalValue = RegisterConverter.ConvertTo<Int32>(Meter.ReadRegister(reg));
|
||||
if (accucalValue >= (value + addFromCheck) && value <= accucalValue + (addToCheck))
|
||||
{
|
||||
return new Tuple<String, Boolean>(reg, true);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
|
||||
base.Progress = 0;
|
||||
|
||||
var useRadio = true;
|
||||
var radioParams = new RadioConfigurationParams();
|
||||
if (useRadio)
|
||||
{
|
||||
|
||||
|
||||
|
||||
var url = ServiceUrls.GenesisFinalCheckServiceUrl();
|
||||
url = url + $"GetRadioConfiguration?PcbId={Meter.PcbId}";
|
||||
|
||||
|
||||
var http = (HttpWebRequest)WebRequest.Create(url);
|
||||
http.Method = "GET";
|
||||
http.Timeout = 2000;
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
radioParams = JsonConvert.DeserializeObject<RadioConfigurationParams>(responseJson);
|
||||
}
|
||||
}
|
||||
base.Progress = 20;
|
||||
|
||||
|
||||
|
||||
|
||||
var overAllResult = new List<Task<Tuple<String, Boolean>>>();
|
||||
//611.219.280
|
||||
//
|
||||
var ts = DateTimeOffset.UtcNow - new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(0));
|
||||
|
||||
//Alarms
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_MainAlarmMask?
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_ExtendedAlarmMask ?
|
||||
//CUSTOMER_AlarmBroadcastMask?
|
||||
//CUSTOMER_AlarmEnableMask ?
|
||||
//CUSTOMER_AlarmVisualAutoClearMask?
|
||||
//CUSTOMER_AlarmVisualMask ?
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//Meter.SetLcdText(true, null);
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister(Register.Customer.TriggerAlarmCancel,
|
||||
// (new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_LeakFlowThreshold", 375, true, true, 1, -1));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_ExcessFlowVolumeThreshold", 25000, true, true, 1, -1));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ExcessFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_LeakTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x4E, 0xC0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_Locale",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xD0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x0B, 0x71, 0xB0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x75, 0x30 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ReverseFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x78 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0xF4 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x14 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ArrowThreshold",
|
||||
(new Byte[] { 0x00, 0x1E, 0x84, 0x80 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayPow10",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xFD }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ForwardArrow",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_HardErrorLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LedMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", (new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", 60 << 16, true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xC8 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MeterSize",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_PipeFillingDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1E }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ResetAccumulators",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SampleRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_UpdateThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_AdapterPresenceLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x60 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_PulseReportRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowPoint",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x03, 0xF5 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressurePresent",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureRate",
|
||||
(new Byte[] { 0x00, 0x0D, 0xBB, 0xA0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseLength",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseWeight",
|
||||
(new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_TemperatureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_AverageFlowPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateDayOfMonth",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateReadingContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_PeriodicLogLifeTimeCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_ResetCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_BatterySelection",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_WarnFromClamp",
|
||||
(new Byte[] { 0x25, 0x89, 0x06, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_WakeupInterval",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x03 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_MbusState",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_UtcTimeOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
//// just read later //overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_FrequencyIndicator}).Reverse(), true, true);
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_HistoricalAlarmsDays",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1D }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
//Original
|
||||
//0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44
|
||||
//Write to register
|
||||
//0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42, 0x41
|
||||
|
||||
|
||||
//good one
|
||||
//E6-C8-88-00-DE-B8-68-C0-D6-A8-48-80-CE-98-28-40
|
||||
//0E-05-04-04-00-14-30-68-D0-14-0E-80-40-63-93-73-22
|
||||
|
||||
//&bad one
|
||||
//0E-05-04-05-00-00-88-C8-E6-C0-68-B8-DE-80-48-A8-D6-40-28-98-CE
|
||||
|
||||
|
||||
//0E-05-04-04-00-22-73-93-63-40-80-0E-14-D0-68-30-14
|
||||
|
||||
if (useRadio)
|
||||
{
|
||||
|
||||
|
||||
//var funkadresse = new List<byte>();
|
||||
//funkadresse.AddRange((new Byte[] { 0xE6, 0xC8, 0x88, 0x00 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xDE, 0xB8, 0x68, 0xC0 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xD6, 0xA8, 0x48, 0x80 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xCE, 0x98, 0x28, 0x40 }).ToArray());
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(),
|
||||
// true, true));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey",
|
||||
(new Byte[]
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}).ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_RadioAddress", radioParams.RadioAddress, true, true));
|
||||
|
||||
if (radioParams.PowerLevel > 0 && radioParams.PowerLevelOption > 0 && radioParams.ImpedanceCodeNew > 0 && radioParams.ImpedanceCodeOption > 0)
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevel", radioParams.PowerLevel, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevelOption", radioParams.PowerLevelOption, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeNew", radioParams.ImpedanceCodeNew, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeOption", radioParams.ImpedanceCodeOption, true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_currentGenesis_WriteRegister("SENSUSRADIO_CustomerText",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("SYSTEM_CalendarSeconds", Convert.ToInt32(ts.TotalSeconds)));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
|
||||
////radio end state!
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
var ret = true;
|
||||
int done = 0;
|
||||
foreach (var cTask in overAllResult)
|
||||
{
|
||||
cTask.RunSynchronously();
|
||||
if (cTask.Result.Item2)
|
||||
{
|
||||
base.NewStatus($"set Parameter {cTask.Result.Item1} succeed");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.NewStatus($"set Parameter {cTask.Result.Item1} failed");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
base.Progress = 20 + ((Int32)Math.Round(((Double)done / (Double)overAllResult.Count) * 80, 0));
|
||||
done = done + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+384
@@ -0,0 +1,384 @@
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFinalParameterizationFix : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessFinalParameterizationFix()
|
||||
{
|
||||
name = "Final Parameterization";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public Task<Tuple<String, Boolean>> _currentGenesis_WriteRegister<T>(String reg, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
|
||||
var ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
if (!ret)
|
||||
{
|
||||
ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, ret);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public Task<Tuple<String, Boolean>> wirteRegisterInBetweenCheck(String reg, Int32 value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false, int addToCheck = 10, int addFromCheck = 0)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Meter.WriteRegister(reg, value, waitForResult);
|
||||
|
||||
var accucalValue = RegisterConverter.ConvertTo<Int32>(Meter.ReadRegister(reg));
|
||||
if (accucalValue >= (value + addFromCheck) && value <= accucalValue + (addToCheck))
|
||||
{
|
||||
return new Tuple<String, Boolean>(reg, true);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
|
||||
base.Progress = 0;
|
||||
|
||||
var useRadio = true;
|
||||
var radioParams = new RadioConfigurationParams();
|
||||
if (useRadio)
|
||||
{
|
||||
|
||||
|
||||
|
||||
var url = ServiceUrls.GenesisFinalCheckServiceUrl();
|
||||
url = "http://localhost:56011/api/FinalCheck/";
|
||||
url = url + $"GetRadioConfiguration?PcbId={Meter.PcbId}&withPressure=false";
|
||||
|
||||
|
||||
var http = (HttpWebRequest)WebRequest.Create(url);
|
||||
http.Method = "GET";
|
||||
http.Timeout = 20000;
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
radioParams = JsonConvert.DeserializeObject<RadioConfigurationParams>(responseJson);
|
||||
}
|
||||
}
|
||||
base.Progress = 20;
|
||||
|
||||
|
||||
|
||||
|
||||
var overAllResult = new List<Task<Tuple<String, Boolean>>>();
|
||||
//611.219.280
|
||||
//
|
||||
|
||||
//Alarms
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_MainAlarmMask?
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_ExtendedAlarmMask ?
|
||||
//CUSTOMER_AlarmBroadcastMask?
|
||||
//CUSTOMER_AlarmEnableMask ?
|
||||
//CUSTOMER_AlarmVisualAutoClearMask?
|
||||
//CUSTOMER_AlarmVisualMask ?
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//Meter.SetLcdText(true, null);
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister(Register.Customer.TriggerAlarmCancel,
|
||||
// (new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_LeakFlowThreshold", 375, true, true, 1, -1));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_ExcessFlowVolumeThreshold", 25000, true, true, 1, -1));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ExcessFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_LeakTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x4E, 0xC0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_Locale",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xD0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x0B, 0x71, 0xB0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x75, 0x30 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ReverseFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x78 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0xF4 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x14 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ArrowThreshold",
|
||||
(new Byte[] { 0x00, 0x1E, 0x84, 0x80 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayPow10",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xFD }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
if (useRadio)
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ForwardArrow",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
}
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_HardErrorLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LedMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", (new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", 60 << 16, true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xC8 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MeterSize",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_PipeFillingDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1E }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ResetAccumulators",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SampleRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MinValidAmplitude",
|
||||
(new Byte[] { 0x25, 0x80, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MaxValidDeltaToF",
|
||||
(new Byte[] { 0x00, 0x03, 0xC6, 0x5E }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_UpdateThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_AdapterPresenceLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x60 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_PulseReportRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowPoint",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x03, 0xF5 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressurePresent",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureRate",
|
||||
(new Byte[] { 0x00, 0x0D, 0xBB, 0xA0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseLength",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseWeight",
|
||||
(new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_TemperatureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_BatterySelection",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_WarnFromClamp",
|
||||
(new Byte[] { 0x25, 0x89, 0x06, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
//// just read later //overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_FrequencyIndicator}).Reverse(), true, true);
|
||||
|
||||
|
||||
|
||||
//Original
|
||||
//0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44
|
||||
//Write to register
|
||||
//0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42, 0x41
|
||||
|
||||
|
||||
//good one
|
||||
//E6-C8-88-00-DE-B8-68-C0-D6-A8-48-80-CE-98-28-40
|
||||
//0E-05-04-04-00-14-30-68-D0-14-0E-80-40-63-93-73-22
|
||||
|
||||
//&bad one
|
||||
//0E-05-04-05-00-00-88-C8-E6-C0-68-B8-DE-80-48-A8-D6-40-28-98-CE
|
||||
|
||||
|
||||
//0E-05-04-04-00-22-73-93-63-40-80-0E-14-D0-68-30-14
|
||||
|
||||
if (useRadio)
|
||||
{
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_WakeupInterval",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x03 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_MbusState",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_UtcTimeOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_HistoricalAlarmsDays",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1D }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_AverageFlowPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateDayOfMonth",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateReadingContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_PeriodicLogLifeTimeCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_ResetCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, true));
|
||||
|
||||
//var funkadresse = new List<byte>();
|
||||
//funkadresse.AddRange((new Byte[] { 0xE6, 0xC8, 0x88, 0x00 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xDE, 0xB8, 0x68, 0xC0 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xD6, 0xA8, 0x48, 0x80 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xCE, 0x98, 0x28, 0x40 }).ToArray());
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(),
|
||||
// true, true));
|
||||
|
||||
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey",
|
||||
// (new Byte[]
|
||||
// {
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
// }).ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
var funkadresse = new List<byte>();
|
||||
funkadresse.AddRange((new Byte[] { 0x0E, 0x9F, 0xAC, 0xC6 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xA0, 0xE1, 0xEF, 0x1C }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0x3B, 0x27, 0xA4, 0x9B }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xAC, 0x21, 0x65, 0x35 }).ToArray());
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_RadioAddress", radioParams.RadioAddress, true, true));
|
||||
|
||||
if (radioParams.PowerLevel > 0 && radioParams.PowerLevelOption > 0 && radioParams.ImpedanceCodeNew > 0 && radioParams.ImpedanceCodeOption > 0)
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevel", radioParams.PowerLevel, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevelOption", radioParams.PowerLevelOption, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeNew", radioParams.ImpedanceCodeNew, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeOption", radioParams.ImpedanceCodeOption, true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_currentGenesis_WriteRegister("SENSUSRADIO_CustomerText",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
var ts = DateTimeOffset.UtcNow - new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(0));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("SYSTEM_CalendarSeconds", Convert.ToInt32(ts.TotalSeconds)));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
|
||||
////radio end state!
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
var ret = true;
|
||||
int done = 0;
|
||||
foreach (var cTask in overAllResult)
|
||||
{
|
||||
cTask.RunSynchronously();
|
||||
if (cTask.Result.Item2)
|
||||
{
|
||||
base.NewStatus($"set Parameter {cTask.Result.Item1} succeed");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.NewStatus($"set Parameter {cTask.Result.Item1} failed");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
base.Progress = 20 + ((Int32)Math.Round(((Double)done / (Double)overAllResult.Count) * 80, 0));
|
||||
done = done + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.ProductionOrderCore;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFinalParameterizationVakoCsd : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
private ProductionProcessConnect connectProcess;
|
||||
|
||||
|
||||
public ProductionProcessFinalParameterizationVakoCsd(ProductionProcessConnect connectProcess)
|
||||
{
|
||||
this.connectProcess = connectProcess;
|
||||
name = "Kunden Parametrierung";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Kann bis zu 1 Minute dauern!";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public Task<Tuple<String, Boolean>> _currentGenesis_WriteRegister<T>(String reg, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
|
||||
|
||||
Task.Delay(10).Wait();
|
||||
var ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
if (!ret)
|
||||
{
|
||||
ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, ret);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public Task<Tuple<String, Boolean>> wirteRegisterInBetweenCheck(String reg, Int32 value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false, int addToCheck = 10, int addFromCheck = 0)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Meter.WriteRegister(reg, value, waitForResult);
|
||||
|
||||
var accucalValue = RegisterConverter.ConvertTo<Int32>(Meter.ReadRegister(reg));
|
||||
if (accucalValue >= (value + addFromCheck) && value <= accucalValue + (addToCheck))
|
||||
{
|
||||
return new Tuple<String, Boolean>(reg, true);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, false);
|
||||
});
|
||||
}
|
||||
|
||||
private void doStartProcessLoop()
|
||||
{
|
||||
var reTrysLeft = 4;
|
||||
while (reTrysLeft >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (connectProcess.asyncprogrammingParametersTask.Status == TaskStatus.Running)
|
||||
{
|
||||
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
if (connectProcess.asyncprogrammingParametersTask.Status == TaskStatus.RanToCompletion
|
||||
&& connectProcess.asyncprogrammingParametersTask.Result != null
|
||||
&& connectProcess.asyncprogrammingParametersTask.Result.Any())
|
||||
{
|
||||
var myJsonResponse = connectProcess.asyncprogrammingParametersTask.Result;
|
||||
|
||||
base.Progress = 15;
|
||||
|
||||
//fix
|
||||
// CUSTOMER_LeakFlowThreshold
|
||||
//CUSTOMER_ExcessFlowVolumeThreshold
|
||||
|
||||
var overAllResult = new List<Task<Tuple<String, Boolean>>>();
|
||||
//611.219.280
|
||||
//
|
||||
var ts = DateTimeOffset.UtcNow - new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(0));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressurePresent",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressurePresent",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false));
|
||||
|
||||
foreach (var item in myJsonResponse.Where(m => m.Source == ProgrammingSource.Vako))
|
||||
{
|
||||
if (!item.RegisterName.Contains("GENESISFLOW_DisplayPow10")
|
||||
&& !item.RegisterName.ToLower().Contains("apparrangement")
|
||||
&& !item.RegisterName.ToLower().Contains("SENSUSRADIO_RadioAddress")
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
}
|
||||
if (item.RegisterName.Contains("pulse"))
|
||||
{
|
||||
|
||||
}
|
||||
if (item.RegisterName.Contains("SENSUSRADIO_RadioAddress"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
}
|
||||
if (item.RegisterName.Contains("GENESISFLOW_DisplayPow10"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, 253, true, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var item in myJsonResponse.Where(m => m.Source == ProgrammingSource.Csd))
|
||||
{
|
||||
if (!item.RegisterName.Contains("GENESISFLOW_DisplayPow10")
|
||||
&& !item.RegisterName.ToLower().Contains("apparrangement")
|
||||
&& !item.RegisterName.ToLower().Contains("SENSUSRADIO_RadioAddress")
|
||||
&& !item.RegisterName.ToLower().Contains("SENSUSRADIO_EncryptionKey")
|
||||
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
}
|
||||
if (item.RegisterName.Contains("SENSUSRADIO_EncryptionKey"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.ToArray(), true, true));
|
||||
|
||||
}
|
||||
if (item.RegisterName.Contains("pulse"))
|
||||
{
|
||||
|
||||
}
|
||||
if (item.RegisterName.Contains("SENSUSRADIO_RadioAddress"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
}
|
||||
if (item.RegisterName.Contains("SENSUSRADIO_RadioAddress"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
}
|
||||
if (item.RegisterName.Contains("GENESISFLOW_DisplayPow10"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, 253, true, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ResetAccumulators",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("SYSTEM_CalendarSeconds", Convert.ToInt32(ts.TotalSeconds)));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("LOGGER_TriggerLogFlush",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("NFC_EraseRMA",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_ResetCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
var ret = true;
|
||||
int done = 0;
|
||||
|
||||
foreach (var cTask in overAllResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Thread.Sleep(2500);
|
||||
cTask.RunSynchronously();
|
||||
if (cTask.Result.Item2)
|
||||
{
|
||||
base.NewStatus($"Schreiben des Parameter {cTask.Result.Item1} war erfolgreich");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cTask.Result.Item1.ToLower() == "SENSUSRADIO_MetroRadioLifeTimeCounter".ToLower() || cTask.Result.Item1.ToLower() == "CUSTOMER_LeakFlowThreshold".ToLower() || cTask.Result.Item1.ToLower() == "CUSTOMER_ExcessFlowVolumeThreshold".ToLower())
|
||||
{
|
||||
base.NewStatus($"Warnung!Schreiben des Parameter {cTask.Result.Item1} war nicht erfolgreich");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.NewStatus($"Warnung!Schreiben des Parameter {cTask.Result.Item1} war nicht erfolgreich");
|
||||
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
base.Progress = 15 + ((Int32)Math.Round(((Double)done / (Double)overAllResult.Count) * 85, 0));
|
||||
done = done + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
reTrysLeft = reTrysLeft - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
reTrysLeft = 0;
|
||||
base.NewStatus($"Warnung!Fehler beim laden des Parametersatzes");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
reTrysLeft = reTrysLeft - 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
doStartProcessLoop();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using System.Windows.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFullReadOut : BaseProductionProcess
|
||||
{
|
||||
private UcFullReadOut UserControl;
|
||||
public ProductionProcessFullReadOut()
|
||||
{
|
||||
name = "Sicherung des Zählerzustandes";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcFullReadOut();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
try
|
||||
{
|
||||
UserControl.lblHl.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() => { UserControl.lblHl.Content = "Read out Registers"; }
|
||||
));
|
||||
var oldConfigEntry = Meter._configuration.UseRegisterWatchService;
|
||||
if (oldConfigEntry)
|
||||
{
|
||||
Meter._configuration.UseRegisterWatchService = false;
|
||||
}
|
||||
|
||||
var total = Meter.GetRegistersDic().Keys.ToList();
|
||||
var done = 0;
|
||||
foreach (var dic in total)
|
||||
{
|
||||
try
|
||||
{
|
||||
UserControl.lblText.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
|
||||
UserControl.lblText.Content = $"Read {dic.GetIdent()}({done}/{total.Count})";
|
||||
}
|
||||
));
|
||||
if (dic.RegisterName.ToLower() != "password" && dic.RegisterDetail.Privilege.Lvl8 != Access.Wo)
|
||||
{
|
||||
Meter.ReadRegister(dic.GetIdent());
|
||||
}
|
||||
base.Progress = (Int32)Math.Round(((Double)done / (Double)total.Count) * 100, 0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//todo: error logger
|
||||
}
|
||||
|
||||
done = done + 1;
|
||||
}
|
||||
|
||||
Meter.StoreCurrentRegisterDic();
|
||||
Meter._configuration.UseRegisterWatchService = oldConfigEntry;
|
||||
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.ProductionOrderCore;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessGetFinalParameterizationVakoCsd : BaseProductionProcess
|
||||
{
|
||||
public IList<ProgrammingParameters> Result = new List<ProgrammingParameters>();
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessGetFinalParameterizationVakoCsd()
|
||||
{
|
||||
name = "Hole Kunden Parametrierung";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Kann bis zu 1 Minute dauern!";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
|
||||
private void doStartProcessLoop()
|
||||
{
|
||||
var reTrysLeft = 2;
|
||||
while (reTrysLeft >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.Progress = 0;
|
||||
//var url = $"http://localhost:56011/api/FinalCheck/GetProgrammingParameters?PcbID={Meter.PcbId}";
|
||||
var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={Meter.PcbId}";
|
||||
var csdRet = LocalWebRequest.GetRequest(url, 60000);
|
||||
|
||||
Result = Newtonsoft.Json.JsonConvert.DeserializeObject<IList<ProgrammingParameters>>(csdRet);
|
||||
|
||||
base.Progress = 100;
|
||||
|
||||
if (!Result.Any())
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
reTrysLeft = reTrysLeft - 1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
reTrysLeft = reTrysLeft - 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
doStartProcessLoop();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Logic.ProductionToProductMapper.Cordonel;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessLogOff : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessLogOff()
|
||||
{
|
||||
name = "Log Off";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Abmelden um Einstellungen zu übernehmen";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
var apps = new List<CordonelAppVersion>();
|
||||
foreach (var item in Meter.MeterAppListVersion)
|
||||
{
|
||||
apps.Add(new CordonelAppVersion(item.AppId, item.StrVersion, (item.AppId != 15 ? true : false)));
|
||||
}
|
||||
|
||||
apps.Add(new CordonelAppVersion(-1, Meter.CoreRevision, false));
|
||||
|
||||
var url = $"{ServiceUrls.MeterProcessStateUrl()}SetCordonelProgress?PcbId={Meter.PcbId}&ProgressName=Shipping&version={Assembly.GetExecutingAssembly().GetName().Version.ToString()}";
|
||||
var a = LocalWebRequest.PostRequestAsync(url, json: apps);
|
||||
Meter.PushProgress("Shipping", Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
Meter.Logout();
|
||||
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
}
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessPasswordFile : BaseProductionProcess
|
||||
{
|
||||
private UcPasswordFile UserControl;
|
||||
|
||||
public ProductionProcessPasswordFile()
|
||||
{
|
||||
name = "PasswordFile";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPasswordFile();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
private void updateImage(Image ctlImage, bool? success = null)
|
||||
{
|
||||
string path = "/Resources/iconWating.png";
|
||||
if (success.HasValue)
|
||||
{
|
||||
if (success.Value)
|
||||
{
|
||||
path = "/Resources/iconCheck.png";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = "/Resources/iconWarn.png";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
bool ret = RequestPassword();
|
||||
updateImage(UserControl.RequestPassword, ret);
|
||||
base.Progress = base.Progress + 16;
|
||||
|
||||
|
||||
if (Encoding.UTF8.GetString(pwContainer.listOfPasswords.Last()) == pwContainer.Skeleton)//pwContainer.Skeleton )
|
||||
{
|
||||
NewStatus("Passwörter schon geschrieben. Prozess wird übersprungen");
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = CreatePasswordFile();
|
||||
}
|
||||
|
||||
|
||||
updateImage(UserControl.CreateFile, ret);
|
||||
base.Progress = base.Progress + 16;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = WritePasswordFileToMeter();
|
||||
}
|
||||
updateImage(UserControl.WriteToMeter, ret);
|
||||
base.Progress = base.Progress + 16;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = UpdatePasswordinDb();
|
||||
}
|
||||
updateImage(UserControl.UpdatePassword, ret);
|
||||
base.Progress = base.Progress + 16;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = Meter.Logout();
|
||||
}
|
||||
updateImage(UserControl.Logout, ret);
|
||||
base.Progress = base.Progress + 16;
|
||||
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = Meter.Login();
|
||||
}
|
||||
updateImage(UserControl.CheckNewPassword, ret);
|
||||
base.Progress = 100;
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
}
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
#region realWork
|
||||
public class MeterPasswordContainer
|
||||
{
|
||||
public Int64? orderNumber = null;
|
||||
public Int64? radioAdress = null;
|
||||
public string Skeleton = "";
|
||||
public List<byte[]> listOfHashes = new List<byte[]>();
|
||||
public List<byte[]> listOfPasswords = new List<byte[]>();
|
||||
}
|
||||
|
||||
private MeterPasswordContainer pwContainer = new MeterPasswordContainer();
|
||||
private MeterPwdFile meterPwdFile;
|
||||
public bool RequestPassword()
|
||||
{
|
||||
base.NewStatus($"Request Passwords");
|
||||
var url = ServiceUrls.GenesisGetPasswordContainerServiceUrl();
|
||||
//url = "http://localhost:56011/api/Password/GetPasswordHashFileContent?PcbId=";
|
||||
url = ($"{url}{Meter.PcbId}");
|
||||
|
||||
var errorCode = 0;
|
||||
var header = new Dictionary<string, string>();
|
||||
header.Add("Cache-Control", "no-cache");
|
||||
header.Add("X-Node-Token", "d5b8c0b2-81f6-4421-80d0-44eb2093e616");
|
||||
var resp = LocalWebRequest.GetRequestWithError(url, out errorCode, 20000, header,true);
|
||||
if (errorCode == HttpStatusCode.OK.GetHashCode())
|
||||
{
|
||||
pwContainer = JsonConvert.DeserializeObject<MeterPasswordContainer>(resp);
|
||||
base.NewStatus($"Passwörter verfügbar");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public bool CreatePasswordFile()
|
||||
{
|
||||
|
||||
meterPwdFile = new MeterPwdFile(Meter);
|
||||
return meterPwdFile.BuildPwdFile(pwContainer.listOfPasswords, 1, pwContainer.Skeleton);
|
||||
}
|
||||
public bool WritePasswordFileToMeter()
|
||||
{
|
||||
if (meterPwdFile.UnlockEraseWriteMeterPwdFile())
|
||||
{
|
||||
return meterPwdFile.WriteMeterPwdFile();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool UpdatePasswordinDb()
|
||||
{
|
||||
|
||||
var newPs = Encoding.UTF8.GetString(pwContainer.listOfPasswords.Last());
|
||||
var passwordSetServiceUrl = ServiceUrls.GenesisSetPasswordServiceUrl();
|
||||
var http = (HttpWebRequest)WebRequest.Create(passwordSetServiceUrl + Meter.PcbId + "&Password=" + newPs + "&keepOldPw=true");
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var sr = new StreamReader(responseStream);
|
||||
|
||||
var responseJson = sr.ReadToEnd();
|
||||
if (responseJson.ToLower().Contains("store"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+448
@@ -0,0 +1,448 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using System.Configuration;
|
||||
using System.Net.Http;
|
||||
using System.Windows.Threading;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessRadioCheck : BaseProductionProcess
|
||||
{
|
||||
private UcRadioCheck UserControl;
|
||||
public ProductionProcessRadioCheck()
|
||||
{
|
||||
|
||||
name = "Radio Check";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
|
||||
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcRadioCheck();
|
||||
|
||||
UserControl.OnRetryRequested += delegate (Object sender, EventArgs args) { GetRssi(); };
|
||||
|
||||
|
||||
UserControl.OnResetRequested += delegate (Object sender, EventArgs args) { Reset(); };
|
||||
UserControl.OnForceAPam += delegate (Object sender, EventArgs args) { forcePush(); };
|
||||
UserControl.OnDoneRequested += delegate (Object sender, EventArgs args)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
if (SENSUSRADIO_WakeupInterval != null)
|
||||
{
|
||||
var ret = Meter.WriteRegister("SENSUSRADIO_WakeupInterval", SENSUSRADIO_WakeupInterval,true,true);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
//clear
|
||||
}
|
||||
|
||||
private Byte[] SENSUSRADIO_WakeupInterval = null;
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
//readout adress, freq,
|
||||
//FrequencyIndicator
|
||||
var freq = RegisterConverter.ConvertTo<UInt32>(Meter.ReadRegister("SENSUSRADIO_FrequencyIndicator"));
|
||||
RadioAdress = RegisterConverter.ConvertTo<UInt32>(Meter.ReadRegister("SENSUSRADIO_RadioAddress"));
|
||||
var enc = Meter.ReadRegister("SENSUSRADIO_EncryptionKey",16);
|
||||
EncyptionKey = BitConverter.ToString(enc).Replace("-", "");
|
||||
|
||||
Comport = Convert.ToByte(ConfigurationManager.AppSettings[$"SirtComport{freq}"]);
|
||||
|
||||
//if (freq == 868)
|
||||
//{
|
||||
// Comport = 8;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Comport = 7;
|
||||
//}
|
||||
BoxNr = Convert.ToByte(ConfigurationManager.AppSettings[$"SirtBoxNr"]);
|
||||
|
||||
DebugMessage($"Start RadioCheck Comport:{Comport} ,BoxNr:{BoxNr}, freq: {freq}, RadioAdress:{RadioAdress}s\r\n", false);
|
||||
|
||||
Meter.WriteRegister("SENSUSRADIO_IrDAModulePresent", 1, true, true);
|
||||
|
||||
|
||||
SENSUSRADIO_WakeupInterval = Meter.ReadRegister("SENSUSRADIO_WakeupInterval");
|
||||
|
||||
|
||||
|
||||
GetRssi();
|
||||
}
|
||||
|
||||
#region FormerForm
|
||||
|
||||
private SaveData saveData;
|
||||
private SIRTCOM.Statemashine stm;
|
||||
private static HttpClient httpclient;
|
||||
|
||||
private byte? RSSI_PAM_Min;
|
||||
private byte? RSSI_PAM_Max;
|
||||
private byte? RSSI_PAM;
|
||||
private byte? RSSI_SEMI_Min;
|
||||
private byte? RSSI_SEMI_Max;
|
||||
private byte? RSSI_SEMI;
|
||||
|
||||
public byte BoxNr;
|
||||
|
||||
public int Ordernumber;
|
||||
public UInt32 RadioAdress;
|
||||
|
||||
public byte Comport;
|
||||
|
||||
public string EncyptionKey = "";
|
||||
|
||||
|
||||
private void enableBtn(Button btn, bool enable)
|
||||
{
|
||||
btn.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
btn.IsEnabled = enable;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
private void SetUi()
|
||||
{
|
||||
UserControl.SetUi(new UcRadioCheck.UIContainer(RSSI_PAM_Min, RSSI_SEMI_Min, RSSI_PAM, RSSI_SEMI, RSSI_PAM_Max, RSSI_SEMI_Max));
|
||||
}
|
||||
|
||||
private async void GetRssi()
|
||||
{
|
||||
|
||||
//StartProcess();
|
||||
enableBtn(UserControl.btnGetRssi, false);
|
||||
|
||||
DebugMessage("");
|
||||
|
||||
|
||||
saveData = new SaveData();
|
||||
|
||||
SetUi();
|
||||
|
||||
|
||||
|
||||
//Meter.WriteRegister("SENSUSRADIO_PowerLevel", 67, true, true);
|
||||
//Meter.WriteRegister("SENSUSRADIO_PowerLevelOption", 59, true, true);
|
||||
//Meter.WriteRegister("SENSUSRADIO_ImpedanceCodeNew", 2992, true, true);
|
||||
//Meter.WriteRegister("SENSUSRADIO_ImpedanceCodeOption", 2936, true, true);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
await GetRssiMinMaxAsync(BoxNr, Ordernumber);
|
||||
SetUi();
|
||||
GetRSSI((int)RadioAdress, Comport, EncyptionKey);
|
||||
SetUi();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugMessage($"Fehler in buttonSende_Click():\r\n{ex.Message}\r\n{ex.InnerException}", true);
|
||||
}
|
||||
enableBtn(UserControl.btnGetRssi, true);
|
||||
}
|
||||
|
||||
private void clearRssi()
|
||||
{
|
||||
RSSI_PAM_Min = null;
|
||||
RSSI_PAM_Max = null;
|
||||
RSSI_PAM = null;
|
||||
RSSI_SEMI_Min = null;
|
||||
RSSI_SEMI_Max = null;
|
||||
RSSI_SEMI = null;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
if (!(stm == null))
|
||||
{
|
||||
stm.ClearPam();
|
||||
stm.Stop();
|
||||
}
|
||||
DebugMessage("Reset\r\n", false);
|
||||
clearRssi();
|
||||
SetUi();
|
||||
StartProcess();
|
||||
}
|
||||
|
||||
private class SaveData
|
||||
{
|
||||
public Int32 RadioAdress { get; set; }
|
||||
public byte RSSI_PAM { get; set; }
|
||||
public byte RSSI_SEMI { get; set; }
|
||||
public int LimitId { get; set; }
|
||||
public byte Result { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Speichert das gefüllte saveData Objekt via SaveRSSI Webservice
|
||||
/// </summary>
|
||||
private async void SaveDataToDB()
|
||||
{
|
||||
DebugMessage("Calling SaveRSSI Webservice...", true);
|
||||
try
|
||||
{
|
||||
saveData.RadioAdress = (int)RadioAdress; // 0-4294967295
|
||||
string url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}SaveRSSI";
|
||||
string body = JsonConvert.SerializeObject(saveData);
|
||||
await PostDataAsync(url, body);
|
||||
DebugMessage(" Ready\r\n", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugMessage($"Fehler in SaveDataToDB():\r\n{ex.Message}\r\n{ex.InnerException}", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task GetRssiMinMaxAsync(byte BoxNr, Int32 FaNr)
|
||||
{
|
||||
//DebugMessage("Calling GetLimits Webservice...", true);
|
||||
try
|
||||
{
|
||||
// TODO anpassen
|
||||
string url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}GetLimits/{BoxNr}/{FaNr}";
|
||||
string body = await GetResponseAsync(url);
|
||||
JObject o = JObject.Parse(body);
|
||||
|
||||
saveData.LimitId = Convert.ToInt32(o.SelectToken("LimitId").ToString());
|
||||
RSSI_PAM_Min = Convert.ToByte(o.SelectToken("RSSI_PAM_Min").ToString());
|
||||
RSSI_PAM_Max = Convert.ToByte(o.SelectToken("RSSI_PAM_Max").ToString());
|
||||
RSSI_SEMI_Min = Convert.ToByte(o.SelectToken("RSSI_SEMI_Min").ToString());
|
||||
RSSI_SEMI_Max = Convert.ToByte(o.SelectToken("RSSI_SEMI_Max").ToString());
|
||||
DebugMessage(" Ready\r\n", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
saveData.LimitId = 0;
|
||||
RSSI_PAM_Min = 120;
|
||||
|
||||
RSSI_PAM_Max = 163;
|
||||
RSSI_SEMI_Min = 150;
|
||||
RSSI_SEMI_Max = 182;
|
||||
// RSSI_PAM_Min RSSI_PAM_Max RSSI_SEMI_Min RSSI_SEMI_Max
|
||||
//145 164 182
|
||||
|
||||
throw new Exception("Fehler in GetRssiMinMax()", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetRSSI(Int32 RadioAdress, Int32 ByteCOMPort, string strKey)
|
||||
{
|
||||
|
||||
RSSI_PAM = null;
|
||||
RSSI_SEMI = null;
|
||||
|
||||
stm = new SIRTCOM.Statemashine();
|
||||
|
||||
byte P81_1 = 0;
|
||||
|
||||
saveData.RadioAdress = RadioAdress;
|
||||
|
||||
stm.initialise((byte)ByteCOMPort);
|
||||
SIRTCOM.Wrapper wrp = new SIRTCOM.Wrapper();
|
||||
stm.StartLoggin("C:\\GenesisLog\\log.txt");
|
||||
// ist wohl nicht nötig da der SIRT richtig konfiguroert ist:
|
||||
// wrp.ActivateSirt(byte modul1, byte modul2, byte actTimeout, out byte outP12_01, out byte outP12_02);
|
||||
|
||||
DebugMessage($"Sending PAM to {RadioAdress.ToString()} ...", true);
|
||||
stm.ClearPam();
|
||||
stm.Timeout_s = 60;
|
||||
|
||||
if (strKey == "")
|
||||
{
|
||||
// Dummy PAM 00 OHNE Funkschlüssel
|
||||
stm.SendPAM(RadioAdress.ToString(), "00", "", P81_1, 1, 0, "", "0", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dummy PAM 00 mit Funkschlüssel
|
||||
stm.SendPAM(RadioAdress.ToString(), "00", "", P81_1, 1, 0, strKey, "0", true);
|
||||
}
|
||||
|
||||
stm.OnStateChanged += Stm_OnStateChanged;
|
||||
stm.Start(); // Start polling
|
||||
|
||||
DebugMessage($" OK\r\n", true);
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.EMPTY_PIPE);
|
||||
Thread.Sleep(5000);
|
||||
//Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x01, true, false);
|
||||
forcePush();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void forcePush()
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x55, true, false);
|
||||
Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x02, true, false);
|
||||
}
|
||||
|
||||
|
||||
public void DebugMessage(string value, Boolean Append = false)
|
||||
{
|
||||
NewStatus(value);
|
||||
}
|
||||
|
||||
private void GotRSSICallback(byte Rssi_Semi_Sirt, byte Rssi_Pam_Cord)
|
||||
{
|
||||
// RSSI beim Empfangen der PAM gemessen vom Cordonel (Sendestärke des SIRT verpackt in SEMI, byte 20)
|
||||
DebugMessage($"RSSI Cord of PAM (Sirt => Cord):{Rssi_Pam_Cord}\r\n", true);
|
||||
RSSI_PAM = Rssi_Pam_Cord;
|
||||
RSSI_SEMI = Rssi_Semi_Sirt;
|
||||
|
||||
// RSSI beim Empfangen der SEMI gemessen vom SIRT (Sendestärke des Cordonel in byte 4)
|
||||
DebugMessage($"RSSI Sirt of SEMI (Cord => Sirt):{Rssi_Semi_Sirt}\r\n", true);
|
||||
saveData.RSSI_PAM = Rssi_Pam_Cord;
|
||||
saveData.RSSI_SEMI = Rssi_Semi_Sirt;
|
||||
|
||||
saveData.Result = 1;
|
||||
|
||||
if (RSSI_PAM < RSSI_PAM_Min)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
if (RSSI_SEMI < RSSI_SEMI_Min)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
if (RSSI_PAM > RSSI_PAM_Max)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
if (RSSI_SEMI > RSSI_SEMI_Max)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
|
||||
SaveDataToDB();
|
||||
SetUi();
|
||||
if (saveData.Result == 1)
|
||||
{
|
||||
UserControl.ViewResult(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void Stm_OnStateChanged(object sender, SIRTCOM.MyEventArgs e)
|
||||
{
|
||||
// our Pam
|
||||
SIRTCOM.PAM Pam = stm.GetPAM(1);
|
||||
|
||||
if (Pam.State == SIRTCOM.PAM.PAMStates.Timeout)
|
||||
{
|
||||
DebugMessage($"Timeout nach {Pam.GetTime()} s\r\n", false);
|
||||
}
|
||||
|
||||
if (Pam.CountSemi > 0)
|
||||
{
|
||||
// we recieved the SEMI
|
||||
|
||||
//btnGetRssi.IsEnabled = true;
|
||||
stm.Stop();
|
||||
stm.ClearPam();
|
||||
|
||||
string HexbytesSEMI = Pam.Semi.HexData.Replace(" ", "");
|
||||
byte[] SEMI_bytes = new byte[HexbytesSEMI.Length / 2];
|
||||
|
||||
for (int i = 0; i < HexbytesSEMI.Length; i += 2)
|
||||
SEMI_bytes[i / 2] = Convert.ToByte(HexbytesSEMI.Substring(i, 2), 16);
|
||||
|
||||
// SEMI Status
|
||||
if (SEMI_bytes[19] == 0)
|
||||
{
|
||||
// RSSI beim Empfangen der SEMI gemessen vom Sirt
|
||||
byte Semi_Rssi_Sirt = SEMI_bytes[2];
|
||||
|
||||
// RSSI beim Empfangen der PAM gemessen vom Cordonel
|
||||
byte Pam_Rssi_Cord = SEMI_bytes[20];
|
||||
|
||||
GotRSSICallback(Semi_Rssi_Sirt, Pam_Rssi_Cord);
|
||||
}
|
||||
else
|
||||
{
|
||||
// SEMI Status ist nicht 0.
|
||||
DebugMessage(Pam.Semi.GetPamErrorMessage(), true);
|
||||
}
|
||||
stm.ClearPam();
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage($"BUPS:{Pam.CountBup}\r\n", true);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<string> PostDataAsync(string url, string data)
|
||||
{
|
||||
httpclient = new HttpClient();
|
||||
// 20 Sekunden Timeout
|
||||
httpclient.Timeout = new TimeSpan(0, 0, 20);
|
||||
|
||||
StringContent queryString = new StringContent(data, Encoding.UTF8, "application/json");
|
||||
HttpResponseMessage response = await httpclient.PostAsync(url, queryString);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
return content;
|
||||
}
|
||||
|
||||
static async Task<string> GetResponseAsync(string url)
|
||||
{
|
||||
httpclient = new HttpClient();
|
||||
// 20 Sekunden Timeout
|
||||
httpclient.Timeout = new TimeSpan(0, 0, 20);
|
||||
|
||||
HttpResponseMessage response = httpclient.GetAsync(url).Result;
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
return content;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessShippingMode : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessShippingMode()
|
||||
{
|
||||
name = "Versandbereitschaft herstellen";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Display und Alarme für den Kunden einstellen.";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.ALL);//(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.SetLcdText(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.EMPTY_PIPE);//(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
var useRadio = true;
|
||||
if (useRadio)
|
||||
{
|
||||
if (Meter.StoreAllApps())
|
||||
{
|
||||
|
||||
var writeList = new List<bool>();
|
||||
|
||||
writeList.Add(Meter.WriteRegister("SENSUSRADIO_SystemState", 1, true, false));
|
||||
writeList.Add(Meter.WriteRegister("SENSUSRADIO_MainAlarmMask", 0, true, false));
|
||||
writeList.Add(Meter.WriteRegister("SENSUSRADIO_ExtendedAlarmMask", 0, true, false));
|
||||
|
||||
|
||||
|
||||
writeList.Add(Meter.WriteRegister("SENSUSRADIO_SystemState", 0xFF, true, false));
|
||||
//Thread.Sleep(5000);
|
||||
Meter.Logout();
|
||||
Thread.Sleep(5000);
|
||||
Meter.Login();
|
||||
var radioResetSuccess = Meter.ReadRegister("SENSUSRADIO_SystemState");
|
||||
var SENSUSRADIO_MainAlarmMask = Meter.ReadRegister("SENSUSRADIO_MainAlarmMask");
|
||||
var SENSUSRADIO_ExtendedAlarmMask = Meter.ReadRegister("SENSUSRADIO_ExtendedAlarmMask");
|
||||
if (radioResetSuccess[0] == 0x02 && writeList.All(a => a == true) && SENSUSRADIO_MainAlarmMask[0] != 0)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Meter.StoreAllApps())
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
}
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessSpecialConfig : BaseProductionProcess
|
||||
{
|
||||
private UcDialog UserControl;
|
||||
|
||||
public bool DialogIsDone { get; private set; }
|
||||
|
||||
public ProductionProcessSpecialConfig()
|
||||
{
|
||||
DialogIsDone = false;
|
||||
name = "Customer Parameterization";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcDialog();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
private void StepRadio()
|
||||
{
|
||||
|
||||
UserControl.SetDesc("Set EncryptionKey");
|
||||
var radioOptionList = new List<UcDialog.DialogOption>();
|
||||
var radioDefault = new UcDialog.DialogOption("old default", "same as iperl", () =>
|
||||
{
|
||||
|
||||
var funkadresse = new List<byte>();
|
||||
funkadresse.AddRange((new Byte[] { 0xE6, 0xC8, 0x88, 0x00 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xDE, 0xB8, 0x68, 0xC0 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xD6, 0xA8, 0x48, 0x80 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xCE, 0x98, 0x28, 0x40 }).ToArray());
|
||||
Meter.WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(), true, true);
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
var upRadioOnly = new UcDialog.DialogOption("alpha", "000...", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_EncryptionKey", (new Byte[]
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}).ToArray(), true, true);
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
var optOneLiter = new UcDialog.DialogOption("new default", "new default key", () =>
|
||||
{
|
||||
var funkadresse = new List<byte>();
|
||||
funkadresse.AddRange((new Byte[] { 0x0E, 0x9F, 0xAC, 0xC6 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xA0, 0xE1, 0xEF, 0x1C }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0x3B, 0x27, 0xA4, 0x9B }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xAC, 0x21, 0x65, 0x35 }).ToArray());
|
||||
Meter.WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(), true, true);
|
||||
StepDone();
|
||||
});
|
||||
|
||||
radioOptionList.Add(radioDefault);
|
||||
radioOptionList.Add(upRadioOnly);
|
||||
radioOptionList.Add(optOneLiter);
|
||||
|
||||
UserControl.SetDialogOptions(radioOptionList);
|
||||
}
|
||||
private void StepWakeUp()
|
||||
{
|
||||
UserControl.SetDesc("Set Radio WakeUp");
|
||||
var wakeupOptionList = new List<UcDialog.DialogOption>();
|
||||
var wakeUpDefault = new UcDialog.DialogOption("wakeup Water and Radio", "Default for nearly all", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", (new Byte[] { 0x00, 0x00, 0x00, 0x03 }).Reverse().ToArray(), true, true);
|
||||
StepRadio();
|
||||
});
|
||||
|
||||
var wakeUpRadioOnly = new UcDialog.DialogOption("wakeup only Radio", "WakeupInterval to 6 (only radio)", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", (new Byte[] { 0x00, 0x00, 0x00, 0x06 }).Reverse().ToArray(), true, true);
|
||||
StepRadio();
|
||||
});
|
||||
|
||||
var pulseOptOneLiter = new UcDialog.DialogOption("wakeup off", "WakeupInterval to 0, no Radio active (e.g. USA))", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true);
|
||||
StepRadio();
|
||||
});
|
||||
|
||||
wakeupOptionList.Add(wakeUpDefault);
|
||||
wakeupOptionList.Add(wakeUpRadioOnly);
|
||||
wakeupOptionList.Add(pulseOptOneLiter);
|
||||
|
||||
UserControl.SetDialogOptions(wakeupOptionList);
|
||||
}
|
||||
|
||||
private void StepPulse()
|
||||
{
|
||||
UserControl.SetDesc("Set Pulse Configuration");
|
||||
var pulseOptionList = new List<UcDialog.DialogOption>();
|
||||
var pulseOptOff = new UcDialog.DialogOption("Pulse off", "set pulsemode to off", () =>
|
||||
{
|
||||
Meter.WriteRegister("METROLOGYASST_PulseLength", (new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseMode", (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseWeight", (new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true);
|
||||
StepWakeUp();
|
||||
});
|
||||
|
||||
var pulseOptDefault = new UcDialog.DialogOption("Pulse Default", "1 pulse per 10 l, pulse mode a4 and 200ms pulse length", () =>
|
||||
{
|
||||
Meter.WriteRegister("METROLOGYASST_PulseLength", (new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseMode", (new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseWeight", (new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true);
|
||||
StepWakeUp();
|
||||
});
|
||||
|
||||
var pulseOptOneLiter = new UcDialog.DialogOption("One Liter Pulse", "1 pulse per 1l, pulse mode a4 and 20ms pulse length", () =>
|
||||
{
|
||||
Meter.WriteRegister("METROLOGYASST_PulseLength", (new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseMode", (new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseWeight", (new Byte[] { 0x00, 0x00, 0x03, 0xE8 }).Reverse().ToArray(), true, true);
|
||||
StepWakeUp();
|
||||
});
|
||||
|
||||
pulseOptionList.Add(pulseOptOff);
|
||||
pulseOptionList.Add(pulseOptDefault);
|
||||
pulseOptionList.Add(pulseOptOneLiter);
|
||||
|
||||
UserControl.SetDialogOptions(pulseOptionList);
|
||||
}
|
||||
|
||||
public override async void StartProcess()
|
||||
{
|
||||
|
||||
StepPulse();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public abstract class BaseProductionProcess : IProductionProcess
|
||||
{
|
||||
private int _progress = 0;
|
||||
public int Progress
|
||||
{
|
||||
get { return _progress; }
|
||||
set
|
||||
{
|
||||
_progress = value;
|
||||
PopUpProcessProgressChangedHandler?.Invoke(this, new PopUpProcessProgressArgs(_progress, PopUpProcessProgressArgs.ProcessProgessType.SubProcess));
|
||||
}
|
||||
}
|
||||
public ProductionProcessState currentProcessState;
|
||||
public string name;
|
||||
|
||||
public GenesisMeter Meter { get; internal set; }
|
||||
|
||||
public event EventHandler PopUpProcessStateChangedHandler;
|
||||
|
||||
public event EventHandler<PopUpProcessLogArgs> PopUpProcessLogHandler;
|
||||
public event EventHandler<PopUpProcessProgressArgs> PopUpProcessProgressChangedHandler;
|
||||
|
||||
StringBuilder sbLog = new StringBuilder();
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public ProductionProcessState GetState()
|
||||
{
|
||||
return currentProcessState;
|
||||
}
|
||||
|
||||
public UserControl GetUserControl()
|
||||
{
|
||||
return GetControl();
|
||||
}
|
||||
|
||||
public abstract UserControl GetControl();
|
||||
|
||||
public abstract void StartProcess();
|
||||
|
||||
public abstract void ProcessDone();
|
||||
public void Start(GenesisMeter meter, CancellationToken cancellationToken)
|
||||
{
|
||||
Meter = meter;
|
||||
currentProcessState = ProductionProcessState.Started;
|
||||
PopUpProcessStateChangedHandler?.Invoke(this, EventArgs.Empty);
|
||||
StartProcess();
|
||||
NewStatus($"Starte {name}");
|
||||
while (currentProcessState == ProductionProcessState.Started)
|
||||
{
|
||||
|
||||
Task.Delay(500);
|
||||
}
|
||||
|
||||
ProcessDone();
|
||||
NewStatus($"Prozess {name} is beendet (code:{currentProcessState.GetHashCode()})");
|
||||
PopUpProcessStateChangedHandler?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
}
|
||||
|
||||
internal void NewStatus(string v)
|
||||
{
|
||||
PopUpProcessLogHandler?.Invoke(this, new PopUpProcessLogArgs(v));
|
||||
sbLog.AppendLine(v);
|
||||
Meter.WriteLog($"{name} : {v}");
|
||||
}
|
||||
|
||||
public abstract void InitUserControl();
|
||||
public void Init()
|
||||
{
|
||||
InitUserControl();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Enum
|
||||
{
|
||||
public enum ProductionProcessState
|
||||
{
|
||||
Waiting,
|
||||
Started,
|
||||
Done,
|
||||
Error
|
||||
}
|
||||
|
||||
public static class ProductionProcessStateHelper
|
||||
{
|
||||
public static string GetTextFromProductionProcessState(ProductionProcessState sate)
|
||||
{
|
||||
switch (sate)
|
||||
{
|
||||
case ProductionProcessState.Waiting:
|
||||
return "Warte";
|
||||
case ProductionProcessState.Started:
|
||||
return "Läuft";
|
||||
case ProductionProcessState.Done:
|
||||
return "Fertig";
|
||||
default:
|
||||
return "Fehler";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public interface IProductionProcess
|
||||
{
|
||||
event EventHandler PopUpProcessStateChangedHandler;
|
||||
|
||||
event EventHandler<PopUpProcessProgressArgs> PopUpProcessProgressChangedHandler;
|
||||
|
||||
event EventHandler<PopUpProcessLogArgs> PopUpProcessLogHandler;
|
||||
string GetName();
|
||||
ProductionProcessState GetState();
|
||||
UserControl GetUserControl();
|
||||
void Start(GenesisMeter Meter,CancellationToken cancellationToken);
|
||||
void Init();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Actions;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public class MultiProcessController
|
||||
{
|
||||
public List<IProductionProcess> Processes;
|
||||
public event EventHandler ProcessStateChangedHandler;
|
||||
public event EventHandler<PopUpProcessLogArgs> ProcessLogHandler;
|
||||
public event EventHandler<PopUpProcessProgressArgs> ProcessProgressHandler;
|
||||
|
||||
private CancellationTokenSource canncelToken = new CancellationTokenSource();
|
||||
|
||||
public IProductionProcess ErrorProcess { get; internal set; }
|
||||
public IProductionProcess DoneProcess { get; internal set; }
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
canncelToken.Cancel();
|
||||
}
|
||||
|
||||
internal void InitUserControl()
|
||||
{
|
||||
Processes.ForEach(a => a.Init());
|
||||
}
|
||||
|
||||
internal void Start(GenesisMeter meter)
|
||||
{
|
||||
Processes.ForEach(f=> f.Init());
|
||||
DoneProcess.Init();
|
||||
ErrorProcess.Init();
|
||||
var t = new Task(() =>
|
||||
{
|
||||
while (Processes.Any(cp => cp.GetState() == ProductionProcessState.Waiting) && !Processes.Any(cp => cp.GetState() == ProductionProcessState.Error))
|
||||
{
|
||||
var process = Processes.First(cp => cp.GetState() == ProductionProcessState.Waiting);
|
||||
AddProccessEvents(process);
|
||||
process.Start(meter,canncelToken.Token);
|
||||
RemoveProccessEvents(process);
|
||||
CalcAndPushOverAllProcess();
|
||||
}
|
||||
|
||||
var showLastStep = DoneProcess;
|
||||
if (Processes.Any(cp => cp.GetState() == ProductionProcessState.Error))
|
||||
{
|
||||
showLastStep = ErrorProcess;
|
||||
}
|
||||
|
||||
|
||||
AddProccessEvents(showLastStep);
|
||||
showLastStep.Start(meter, canncelToken.Token);
|
||||
RemoveProccessEvents(showLastStep);
|
||||
CalcAndPushOverAllProcess();
|
||||
});
|
||||
|
||||
t.Start();
|
||||
|
||||
}
|
||||
|
||||
void CalcAndPushOverAllProcess()
|
||||
{
|
||||
|
||||
var Total = Processes.Count;
|
||||
var Done = Processes.Where(w => w.GetState() == ProductionProcessState.Done).Count();
|
||||
var progress = 0;
|
||||
if (Done > 0)
|
||||
{
|
||||
progress = (100 / Total) * Done;
|
||||
}
|
||||
ProcessProgressHandler?.Invoke(this, new PopUpProcessProgressArgs(progress, PopUpProcessProgressArgs.ProcessProgessType.Total ));
|
||||
}
|
||||
|
||||
private void AddProccessEvents(IProductionProcess process)
|
||||
{
|
||||
process.PopUpProcessProgressChangedHandler += Process_PopUpProcessProgressChangedHandler;
|
||||
process.PopUpProcessLogHandler += Process_PopUpProcessLogHandler;
|
||||
process.PopUpProcessStateChangedHandler += ProcessOnPopUpProcessStateChangedHandler;
|
||||
}
|
||||
private void RemoveProccessEvents(IProductionProcess process)
|
||||
{
|
||||
process.PopUpProcessProgressChangedHandler -= Process_PopUpProcessProgressChangedHandler;
|
||||
process.PopUpProcessLogHandler -= Process_PopUpProcessLogHandler;
|
||||
process.PopUpProcessStateChangedHandler -= ProcessOnPopUpProcessStateChangedHandler;
|
||||
}
|
||||
|
||||
|
||||
private void Process_PopUpProcessProgressChangedHandler(object sender, PopUpProcessProgressArgs e)
|
||||
{
|
||||
ProcessProgressHandler?.Invoke(sender,e);
|
||||
}
|
||||
|
||||
private void Process_PopUpProcessLogHandler(object sender, PopUpProcessLogArgs e)
|
||||
{
|
||||
ProcessLogHandler?.Invoke(sender,e);
|
||||
}
|
||||
|
||||
private void ProcessOnPopUpProcessStateChangedHandler(Object sender, EventArgs e)
|
||||
{
|
||||
ProcessStateChangedHandler?.Invoke(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public class PopUpProcessLogArgs : EventArgs
|
||||
{
|
||||
public readonly string Data;
|
||||
public PopUpProcessLogArgs(string text)
|
||||
{
|
||||
Data = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public class PopUpProcessProgressArgs : EventArgs
|
||||
{
|
||||
public enum ProcessProgessType
|
||||
{
|
||||
Total,
|
||||
SubProcess,
|
||||
}
|
||||
public readonly ProcessProgessType ProgressType;
|
||||
public readonly int Progress;
|
||||
public PopUpProcessProgressArgs(int progress, ProcessProgessType type)
|
||||
{
|
||||
Progress = progress;
|
||||
ProgressType = type;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public class ProcessStateChangedArgs : EventArgs
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user