using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using CordonelPreadjustmentUi; using CordonelPreadjustmentUi.Processes.Itinerary; using Newtonsoft.Json; using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; using Xylem.Common.Logic.SoftwareAccessHelper; using Xylem.Common.Ui.CordonelPreadjustmentUi.Helper.Extensions; namespace Xylem.Common.Ui.CordonelPreadjustmentUi { public partial class MeterStateControl : UserControl { public EventHandler OnRequestDetails; public EventHandler OnTempretureChangedHandler; public EventHandler OnWatcherFailed; private Int32 WatcherInvervalS = 2; private decimal? minTemp; private decimal? maxTemp; private decimal? currentTemp; private bool watcherFailed = false; private decimal? watcherMinTemp; private decimal? watcherMaxTemp; private decimal? watcherMaxDeviation; public void SetWatcher(decimal? MinTemp, decimal? MaxTemp, decimal? MaxDeviation) { watcherMinTemp = MinTemp; watcherMaxTemp = MaxTemp; watcherMaxDeviation = MaxDeviation; } public MeterStateControl(string Text) { InitializeComponent(); IsEnabled = cB_ZeroFlowCal_EnableMeter.Checked; Failed = false; setImage(Xylem.Common.Ui.CordonelPreadjustmentUi.Properties.Resources.NormalImage); Slot = -1; setSerialNumbersVisible(false); setTempinputVisible(false); nUD_TempField_Celsius.ValueChanged += delegate (Object sender, EventArgs args) { if (sender is NumericUpDown) { changedTempreture(((NumericUpDown)sender).Value); } }; l_ZeroFlowCal_Meter.Text = Text; } public MeterStateControl(int slot) { InitializeComponent(); IsEnabled = cB_ZeroFlowCal_EnableMeter.Checked; Failed = false; setImage(Xylem.Common.Ui.CordonelPreadjustmentUi.Properties.Resources.NormalImage); Slot = slot; setSerialNumbersVisible(false); setTempinputVisible(false); nUD_TempField_Celsius.ValueChanged += delegate (Object sender, EventArgs args) { if (sender is NumericUpDown) { changedTempreture(((NumericUpDown)sender).Value); } }; l_ZeroFlowCal_Meter.Text = $"METER {slot}"; } private void watcherIsFailed() { OnWatcherFailed?.Invoke(this, EventArgs.Empty); watcherFailed = true; Failed = true; } private void RunWatchActions() { try { var cRecords = Meter.CurrentRecords.ToList(); Log($"cRecords.Count={cRecords.Count}"); if (cRecords != null && cRecords.Any()) { decimal checkTempMeter = 0; if (MeterTempMode == TempMode.CalcTof) { // var sumTof = 0.0; var countTof = 0; foreach (var tofItem in cRecords.Where(c => c.Channel == 2)) { if (tofItem.Channel == 2) { Log($"TotalTimeOfFlightS;{(tofItem.TotalTimeOfFlightS * 1000).ToString()}"); Log($"RAWTEMP;{interPol(TempFromTofLUT, (tofItem.TotalTimeOfFlightS * 1000))}"); sumTof = (tofItem.TotalTimeOfFlightS * 1000) + sumTof; countTof = countTof + 1; } } var x = (sumTof / countTof) / 1000; Log($"avgTof;{x}({sumTof}/{countTof})"); checkTempMeter = interPol(TempFromTofLUT, x); Meter.CurrentRecords.Clear(); } else { checkTempMeter = (decimal)cRecords.Last().TemperatureDegC; } currentTemp = checkTempMeter; Log($"{DateTime.UtcNow};currentTemp;{currentTemp};°C"); if (!minTemp.HasValue || currentTemp < minTemp.Value) { minTemp = currentTemp; } if (!maxTemp.HasValue || currentTemp > maxTemp.Value) { maxTemp = currentTemp; } SetTemperature(currentTemp.Value, false); if (watcherMinTemp.HasValue && minTemp < watcherMinTemp.Value) { watcherIsFailed(); } if (watcherMaxTemp.HasValue && maxTemp > watcherMaxTemp.Value) { watcherIsFailed(); } if (watcherMaxDeviation.HasValue && Math.Abs(maxTemp.Value - minTemp.Value) > watcherMaxDeviation.Value) { watcherIsFailed(); } } else { Log($"temp NA"); } } catch (Exception ex) { Log($"temp NA - {ex.Message}"); } } private static decimal interPol(List> points, double x) { var x1 = 0.000; var y1 = 0.000; var x2 = 0.000; var y2 = 0.000; decimal checkTempMeter; try { if ((x <= points[0].Item1) && (x >= points.Last().Item1)) { var i = 0; foreach (var val in points) { if (points[i].Item1 <= x) { x1 = points[i - 1].Item1; y1 = points[i - 1].Item2; x2 = points[i].Item1; y2 = points[i].Item2; break; } i = i + 1; } checkTempMeter = (decimal)((y2 - y1) / (x2 - x1) * (x - x1) + y1); } else { checkTempMeter = 1; } return checkTempMeter; } catch (Exception ex) { return 2; } } public void setImage(Bitmap img) { pB_Meter.Image = img; } private StringBuilder logSb = new StringBuilder(); public bool EnableOpening { get; internal set; } public bool IsEnabled { get; internal set; } public bool IsDisabeldForRetry { get; private set; } public bool Ok { get; internal set; } public bool SetToUnknownStatus { get; internal set; } public int Slot { get; internal set; } public ZeroFlowGenesisMeter Meter { get; internal set; } public bool LoginFailed { get; internal set; } public string OverridePassword { get; internal set; } internal decimal GetTemperature() { return nUD_TempField_Celsius.Value; } public bool Failed { get; internal set; } private string idText = ""; public string Id { get { return idText; } internal set { idText = value; UpdateLbl(l_PcbId, idText); setSerialNumbersVisible(!string.IsNullOrEmpty(idText)); } } private string srn = ""; public string Srn { get { return srn; } internal set { srn = value; UpdateLbl(L_Srnr, srn); setSerialNumbersVisible(!string.IsNullOrEmpty(Srn)); } } public String OverridePcbId { get; internal set; } private void setSerialNumbersVisible(bool vis) { if (vis && !IsEnabled) { vis = false; } UpdateVisControl(l_PcbId, vis); UpdateVisControl(L_Srnr, vis); } private void setTempinputVisible(bool vis) { UpdateVisControl(l_TempField_Celsius, vis); UpdateVisControl(nUD_TempField_Celsius, vis); UpdateEnableControl(nUD_TempField_Celsius, vis); } internal void StopTempWatch() { watchActiv = false; } public class CordonelTempLut { public int Id { get; set; } public int PcbId { get; set; } public double RefTempC { get; set; } public double AvgTof { get; set; } public bool Active { get; set; } } public TempMode MeterTempMode; private List> TempFromTofLUT; internal void StartTempWatch(TempMode tempMode = TempMode.Hand) { try { Meter.WriteLog($"StartTempWatch with {tempMode}"); Meter.logAmpTest = true; if (tempMode == TempMode.CalcTof) { TempFromTofLUT = new List>(); var pcbid = ""; if (OverridePcbId != null) { pcbid = OverridePcbId; } else { pcbid = Meter.GetPcbId(); } try { //if (Meter.Slot == 11) //{ // pcbid = "193400024"; // OverridePassword = "10C16DF46E6C"; // Meter.WriteLog($"Fake pcbid {pcbid}"); //} //else if (Meter.Slot == 12) //{ // pcbid = "193400261"; // OverridePassword = "BF8AC70AB27E"; // Meter.WriteLog($"Fake pcbid {pcbid}"); //} Meter.Login(); Meter.WriteRegister(Register.Genesisflow.TriggerIdle, 0); Meter.WriteRegister(Register.Genesisflow.LedMode, 6); Meter.WriteRegister(Register.Genesisflow.SampleRate, 10); var resp = LocalWebRequest.GetRequest($"http://10.49.40.25/MeterProcessState/api/TempFlange/GetLut?PcbId={pcbid}", 50000); var cordonelTempLut = JsonConvert.DeserializeObject>(resp); TempFromTofLUT = new List>(); foreach (var item in cordonelTempLut.OrderBy(a => a.RefTempC)) { TempFromTofLUT.Add(new Tuple(item.AvgTof, item.RefTempC)); } var sb = new StringBuilder(); foreach (var t in TempFromTofLUT) { sb.Append("Tof:"); sb.Append(t.Item1); sb.Append("=Temp:"); sb.Append(t.Item2); sb.Append(","); } Meter.WriteLog($"Load LUT { sb.ToString() } for meter {pcbid}"); } catch (Exception ex) { Meter.WriteLog($"StartTempWatch with LUT faild for meter {pcbid} with ex{ex.Message}"); } } watchActiv = true; MeterTempMode = tempMode; } catch (Exception ex) { Log("StartTempWatch" + ex.Message); } } public enum TempMode { Hand, Meter, CalcTof } private void WatchTmrOnTick(Object sender, EventArgs e) { //var t = new Task(() => { RunWatchActions(); }); //t.Start(); } internal void DisableTemperatureinput(bool v) { UpdateEnableControl(nUD_TempField_Celsius, !v); } public void SetTemperature(decimal temp, bool setControls = true) { if (nUD_TempField_Celsius.InvokeRequired) { Invoke((Action)SetTemperature, temp, setControls); return; } if (setControls) { if (!nUD_TempField_Celsius.Visible) { setTempinputVisible(true); } } nUD_TempField_Celsius.Value = temp; } public void changedTempreture(decimal newValue) { OnTempretureChangedHandler?.Invoke(this, new EventArgsDecimal(newValue)); } private void UpdateLbl(Label lbl, string text) { if (lbl.InvokeRequired) { Invoke((Action)UpdateLbl, lbl, text); return; } lbl.Text = text; } private void UpdateVisControl(Control lbl, bool vis) { if (lbl.InvokeRequired) { Invoke((Action)UpdateVisControl, lbl, vis); return; } lbl.Visible = vis; } private void UpdateEnableControl(Control ctl, bool enab) { if (ctl.InvokeRequired) { Invoke((Action)UpdateEnableControl, ctl, enab); return; } if (ctl is NumericUpDown) { ((NumericUpDown)ctl).ReadOnly = !enab; } ctl.Enabled = enab; } internal void Log(string v) { logSb?.AppendLine(v); Meter?.WriteLog(v); } public string GetLog() { if (logSb == null) { return ""; } return logSb.ToString(); } private void cB_ZeroFlowCal_EnableMeter_CheckedChanged(object sender, EventArgs e) { IsEnabled = ((CheckBox)sender).Checked; } internal void SetChecked(bool v) { if (cB_ZeroFlowCal_EnableMeter.InvokeRequired) { Invoke((Action)SetChecked, v); return; } cB_ZeroFlowCal_EnableMeter.Checked = v; } internal void SetUi(bool v = false) { if (p_ZeroFlowCal_Meter.InvokeRequired) { Invoke((Action)SetUi, true); return; } if (SetToUnknownStatus || (!IsEnabled && !Failed)) { p_ZeroFlowCal_Meter.BackColor = Color.Cornsilk; return; } if (Ok && !Failed) { p_ZeroFlowCal_Meter.BackColor = Color.LightGreen; //pB_Meter.Image = GenesisZeroFlow._GenesisZeroFlow.pB_AvailableImages.ErrorImage; } else { p_ZeroFlowCal_Meter.BackColor = Color.LightPink; } } private void numericUpDown1_EnabledChanged(object sender, EventArgs e) { } private void timBlink_Tick(object sender, EventArgs e) { } private bool watchActiv = false; private Color failedBackgroundColor = Color.OrangeRed; private void timWatch_Tick(object sender, EventArgs e) { try { if (IsEnabled && watchActiv) { var t = new Task(() => { RunWatchActions(); }); t.Start(); if (watcherFailed) { var tmp = p_ZeroFlowCal_Meter.BackColor; p_ZeroFlowCal_Meter.BackColor = failedBackgroundColor; failedBackgroundColor = tmp; } } else { if (watchActiv) { Log("watcher activ but ctl is disabled!"); } } } catch (Exception ex) { Log(ex.Message); } } internal void SetDisableForRetry() { IsEnabled = false; IsDisabeldForRetry = true; } internal void SetEnableAfterRetry() { if (IsDisabeldForRetry) { IsEnabled = true; } } internal void EnabeldBoxEnabel(bool v) { UpdateEnableControl(cB_ZeroFlowCal_EnableMeter, v); } private void pB_Meter_Click(object sender, EventArgs e) { OnRequestDetails?.Invoke(this, e); } private void l_TempField_Celsius_Click(object sender, EventArgs e) { Log("Click"); } } }