diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.cs index a5bc1e99..d3b04416 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Config/FM2014Config.cs @@ -32,6 +32,7 @@ */ using System; +using System.Collections.Generic; using System.IO; using Newtonsoft.Json; using Xylem.Common.CommonCore.Consts; @@ -63,10 +64,21 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config /// public Int32? TolerancePercent { get; set; } + /// + /// Address of the FM2014 + /// + public List IndividualTolerancePercent { get; set; } + + /// /// Serial baudrate for FM2014 serial bus /// - public static Int32 Baudrate { get; set; } = 1200; + public Int32 Baudrate { get; set; } = 1200; + + /// + /// Serial baudrate for FM2014 serial bus + /// + public List SlotIsSelected { get; set; } #endregion @@ -77,6 +89,9 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config /// /// - Initial. /// + /// + /// - Support multiple FM2014 with shared port but slot selected and individual tolerance. + /// public Boolean ReadFM2014Config() { // Check for AppRoaming @@ -92,6 +107,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config SerialPort = null; Address = null; TolerancePercent = null; + SlotIsSelected = null; + IndividualTolerancePercent = null; return false; } } @@ -102,6 +119,9 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config SerialPort = fm2014Setup.SerialPort; Address = fm2014Setup.Address; TolerancePercent = fm2014Setup.TolerancePercent; + Baudrate = fm2014Setup.Baudrate; + IndividualTolerancePercent = fm2014Setup.IndividualTolerancePercent; + SlotIsSelected = fm2014Setup.SlotIsSelected; } return true; @@ -124,7 +144,6 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config var configFile = Path.Combine(path, ProgramConfig.FM2014ConfigFileName); File.WriteAllText(configFile, JsonConvert.SerializeObject(this)); - File.WriteAllText(ProgramConfig.FM2014ConfigFileName, JsonConvert.SerializeObject(this)); } #endregion } diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs index 40dc27aa..46b1f90e 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs @@ -69,39 +69,44 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// 'W' - 'REF pulses per volume'! The REF pulses/cm can then be restored using /// 'Ref_pulses_per_cm = Dut_pulses_per_cm * RefToDutScale_norm' /// - private const UInt32 RefPulsesPerVolumeRegulationSetupInvalidMarker = 1; + private const UInt32 REF_PULSES_PER_VOLUME_INVALID_MARKER = 1; /// /// fm2014 is the minimum value which can be stored to the FM2014 with commands /// 'V' - 'DUT pulses per volume' and 'W' - 'REF pulses per volume'! /// - private const UInt32 PulsesPerVolumeRegulationSetupMin = 1; + private const UInt32 PULSES_PER_CM_REGULATION_SETUP_MIN = 1; /// /// This is the maximum value which can be stored to the FM2014 with command /// 'V' - 'DUT pulses per volume'! /// - private const UInt32 PulsesPerVolumeRegulationSetupMax = 9999; + private const UInt32 PULSES_PER_CM_REGULATION_SETUP_MAX = 9999; /// /// This is the maximum input value for the REF which CANNOT be stored to FM2014 /// but will be used to calculate the 'RefToDutScale_norm'. /// - private const UInt32 RefPulsesPerCmRegulationInputLimitMax = 100000000; + private const UInt32 REF_PULSES_PER_CM_REGULATION_INPUT_MAX = 100000000; /// /// Publish the FM2014 minimum REF to DUT scale for error display. /// - public const Double RefToDutScaleMin = 0.0001; + public const Double REF_TO_DUT_SCALE_MIN = 0.0001; /// /// Publish the FM2014 maximum REF to DUT scale for error display. /// - public const Double RefToDutScaleMax = 999.9; + public const Double REF_TO_DUT_SCALE_MAX = 999.9; /// /// The mantissa for the scale value has to be in the range from 1000 to 9999. /// - private const UInt16 MantissaScaleMin = 1000; + private const UInt16 MANTISSA_SCALE_MIN = 1000; + + /// + /// Default tolerance if not properly setup. + /// + public const Int32 DEFAULT_TOLERANCE_percent = 3; #endregion ---------------------------------------- constants ------------------------------------------------- @@ -204,7 +209,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// Private tolerance percentage /// - private Int32 _tolerance_percent = 3; + private Int32 _tolerance_percent = DEFAULT_TOLERANCE_percent; + /// /// Actual tolerance scale to convert raw value from FM2014 to percent /// @@ -222,7 +228,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core // Limit input to discrete setting of 3 or 5 %, // internally those values are going to be scaled to 3.3 or 5.5 Single percentage; - if (value == 3) + if (value == DEFAULT_TOLERANCE_percent) percentage = 3.3f; else if (value == 5) percentage = 5.5f; @@ -296,8 +302,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core set { // Check limits and equality - if (value < PulsesPerVolumeRegulationSetupMin || - value > RefPulsesPerCmRegulationInputLimitMax || + if (value < PULSES_PER_CM_REGULATION_SETUP_MIN || + value > REF_PULSES_PER_CM_REGULATION_INPUT_MAX || value == _ref_pulse_per_cm) return; @@ -318,8 +324,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { // Check limits and equality, the DUT max input is 9999 as this will be // directly stored to FM2014'V' - 'DUT pulses per volume' - if (value < PulsesPerVolumeRegulationSetupMin || - value > PulsesPerVolumeRegulationSetupMax || + if (value < PULSES_PER_CM_REGULATION_SETUP_MIN || + value > PULSES_PER_CM_REGULATION_SETUP_MAX || value == _dut_pulse_per_cm) return; @@ -358,7 +364,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core get => _refToDutScale_norm; private set { - if (value > RefToDutScaleMax || value < RefToDutScaleMin) + if (value > REF_TO_DUT_SCALE_MAX || value < REF_TO_DUT_SCALE_MIN) return; _refToDutScale_norm = value; @@ -370,7 +376,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core number *= 10.0; mantissa = (UInt16)(number + 0.5); exponent--; - } while (mantissa < MantissaScaleMin); + } while (mantissa < MANTISSA_SCALE_MIN); // The pre-generated string will be used to send it to the FM2014 directly _refToDutScaleStr = $"{mantissa}{GetCmdStr(CmdName.CMD_REF_SET_SCALE)}{exponent}"; @@ -422,22 +428,22 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// Number of processing steps for this actual process progress /// - private Int32 MaxActualProcessProgress { get; set; } + private static Int32 MaxActualProcessProgress { get; set; } /// /// Progress of actual process converted to percent /// - private Double _actualProcessProgress_percent; + private static Double _actualProcessProgress_percent; /// /// Progress of actual process /// - private Int32 _actualProcessProgress; + private static Int32 _actualProcessProgress; /// /// Actual process progress of subroutine /// - private Int32 ActualProcessProgress + private static Int32 ActualProcessProgress { get => _actualProcessProgress; set @@ -454,12 +460,51 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core #region ------------------------------------------- static methods -------------------------------------------- /// - /// Executes all StoreConfiguration and StoreCalibration for each application. + /// Executes all StoreConfiguration and StoreCalibration for each FM2014 which is logged on. /// /// true if all configurations are stored + /// + /// - Initial. + /// public static Boolean StoreAllConfigurations() { - return false; + if (SharedCyclicMeasSequ == CyclicMeasSequ.IDLE) + return false; + + var retVal = true; + InitActualProcessProgress(); + + foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn)) + { + retVal &= fm2014.SaveStandAloneMeasurement(); + ActualProcessProgress++; + } + + return retVal; + } + + /// + /// Common routine to set up the counter for max process progress based on connected + /// and logged in devices and set the actual process progress to zero. + /// + /// + /// - Initial. + /// + private static void InitActualProcessProgress(Int32? maxInitProcesses = null) + { + MaxActualProcessProgress = 0; + ActualProcessProgress = 0; + + if (maxInitProcesses != null) + { + MaxActualProcessProgress = (Int32)maxInitProcesses; + return; + } + + foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn)) + { + MaxActualProcessProgress++; + } } /// @@ -776,7 +821,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// - REF and DUT counters together using the synchronized backup. /// - Each FM2014 can use a different REF and/or DUT setting as the REF is parallel for all FM2014s. /// Preconditions: - /// - The has to be executed in advance. + /// - The has to be executed in advance. /// Initial setup: /// - Starts the pulse counter measurement of REF and/or DUT. /// Cyclic: @@ -956,7 +1001,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// The regulation measurement compares the DUT to REF tolerance: /// Preconditions: - /// - The has to be executed in advance, + /// - The has to be executed in advance, /// - The REF pulses per cubic meter has to be preset, /// - The DUT pulses per cubic meter has to be preset, /// - The Scale for REF to DUT pulses has to be preset. @@ -983,8 +1028,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { if (Ref_pulse_per_cm == 0 || Dut_pulse_per_cm == 0 || - RefToDutScale_norm < RefToDutScaleMin || - RefToDutScale_norm > RefToDutScaleMax || + RefToDutScale_norm < REF_TO_DUT_SCALE_MIN || + RefToDutScale_norm > REF_TO_DUT_SCALE_MAX || !IsLoggedOn) { return false; @@ -1001,7 +1046,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core var cmdName = CmdName.CMD_NA; var measurementInfo = Resources.StrMeasMsgRegulation; - + InitActualProcessProgress(3); // Prepare regulation measurement try { @@ -1010,18 +1055,19 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { return false; } + ActualProcessProgress++; cmdName = CmdName.CMD_MEAS_SET_ATTN; if (!Write(cmdName, this, Attenuation)) { return false; } + ActualProcessProgress++; cmdName = CmdName.CMD_REF_SET_SCALE; if (!Write(cmdName, this, _refToDutScaleStr)) { return false; } - - + ActualProcessProgress++; } catch (Exception e) { @@ -1039,6 +1085,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core do { + InitActualProcessProgress(); foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn)) { try @@ -1218,8 +1265,8 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core { // Set to zero if it doesn't fit to the limit which can be stored as indicator for invalid value // which should be recovered by 'Ref_pulses_per_cm = Dut_pulses_per_cm * RefToDutScale_norm' - var limitedRefPulsesPerCm = Ref_pulse_per_cm <= PulsesPerVolumeRegulationSetupMax ? - Ref_pulse_per_cm : RefPulsesPerVolumeRegulationSetupInvalidMarker; + var limitedRefPulsesPerCm = Ref_pulse_per_cm <= PULSES_PER_CM_REGULATION_SETUP_MAX ? + Ref_pulse_per_cm : REF_PULSES_PER_VOLUME_INVALID_MARKER; var retVal = Write(cmdName, this, (UInt16)limitedRefPulsesPerCm); if (retVal) @@ -1422,11 +1469,12 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// - Support for multiple FM2014s. /// - public Boolean ResetMeasurementAllDevices() + public Boolean ResetHardwareAllDevices() { if (SharedCyclicMeasSequ == CyclicMeasSequ.IDLE) return true; + InitActualProcessProgress(); // Exit tasks SharedCyclicMeasSequ = CyclicMeasSequ.IDLE; @@ -1445,7 +1493,6 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core var resetDelayCtr_ms = 4000; const Int32 loopTime_ms = 500; MaxActualProcessProgress = resetDelayCtr_ms / loopTime_ms; - ActualProcessProgress = 0; do { // Change the SI unit to ms instead of seconds @@ -1457,7 +1504,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core specificInfoObj: response)); Thread.Sleep(loopTime_ms); resetDelayCtr_ms -= loopTime_ms; - ActualProcessProgress += 1; + ActualProcessProgress++; } while (resetDelayCtr_ms >= 0); }, SharedCancellationToken); @@ -1480,27 +1527,27 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// /// Forcing to reset all measurements before the start of a new one: /// - This will enable to keep the measurements and NOT clear those in the reset method, - /// as this should be used to prepare the hardware for + /// as this should be used to prepare the hardware for /// the new measurement after it being able to start the new measurement immediately! /// private static void ClearMeasurementResultsForAllDevices() { } - + /// /// Connect to individual FM2014: /// - This is initially used to assign and set up the SharedSerialPort which will be shared upon /// all devices. - /// - Additionally, it is going to log in to the individual device for early detection which one is - /// connected to the SharedSerialPort. + /// - Additionally, it is going to read out the individual device information for early detection + /// which one is responsive on the SharedSerialPort. /// /// /// /// /// - Support for multiple FM2014s. /// - /// + /// /// - ´Login to individual FM2014. /// public Boolean Connect(String comPort) @@ -1565,12 +1612,6 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core RegisteredFm2014s.Add(this); - // Reset pulse ratios to force a preset with 'standalone' settings from - // FM2014 wit '%D@' - Read 'Default Measurement Setup' - _ref_pulse_per_cm = 0; - _dut_pulse_per_cm = 0; - SharedCmdTypeReminderLastCmd = CmdType.NOT_INITIALIZED; - return IsLoggedOn; } @@ -1598,7 +1639,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core public void Dispose() { Logout(); - ResetMeasurementAllDevices(); + ResetHardwareAllDevices(); RegisteredFm2014s?.Clear(); RegisteredFm2014s = null; SharedSerialPort?.Dispose(); diff --git a/FM2014TestApp/Ui/FM2014TestBenchWinFrms/FrmFm2014TestApp.cs b/FM2014TestApp/Ui/FM2014TestBenchWinFrms/FrmFm2014TestApp.cs index e01cf4fb..41cedd3f 100644 --- a/FM2014TestApp/Ui/FM2014TestBenchWinFrms/FrmFm2014TestApp.cs +++ b/FM2014TestApp/Ui/FM2014TestBenchWinFrms/FrmFm2014TestApp.cs @@ -622,10 +622,10 @@ namespace Sensus.Ui.FM2014TestApp // Display error if scale doesn't fit var tempRefToDutScale_norm = (Double)Fm2014.Ref_pulse_per_cm / Fm2014.Dut_pulse_per_cm; - if (tempRefToDutScale_norm < FM2014.RefToDutScaleMin || - tempRefToDutScale_norm > FM2014.RefToDutScaleMax || - Fm2014.RefToDutScale_norm < FM2014.RefToDutScaleMin || - Fm2014.RefToDutScale_norm > FM2014.RefToDutScaleMax) + if (tempRefToDutScale_norm < FM2014.REF_TO_DUT_SCALE_MIN || + tempRefToDutScale_norm > FM2014.REF_TO_DUT_SCALE_MAX || + Fm2014.RefToDutScale_norm < FM2014.REF_TO_DUT_SCALE_MIN || + Fm2014.RefToDutScale_norm > FM2014.REF_TO_DUT_SCALE_MAX) { tbxScaleRefToDut.BackColor = ColorProcessFailed; tbxScaleRefToDut.Text = Resources.StrError; @@ -788,7 +788,7 @@ namespace Sensus.Ui.FM2014TestApp _autoProgressBar = false; // Deactivate the button temporary to avoid repeated execution as the reset takes a certain time btnDutToRefRegulation.Enabled = false; - Fm2014.ResetMeasurementAllDevices(); + Fm2014.ResetHardwareAllDevices(); ActionControl(false); btnDutToRefRegulation.Text = Resources.StrBtnStartRegulation; } @@ -839,7 +839,7 @@ namespace Sensus.Ui.FM2014TestApp _autoProgressBar = false; // Deactivate the button temporary to avoid repeated execution as the reset takes a certain time btnManualRefCalibration.Enabled = false; - Fm2014.ResetMeasurementAllDevices(); + Fm2014.ResetHardwareAllDevices(); ActionControl(false); btnManualRefCalibration.Text = Resources.StrBtnStartCalibration; } diff --git a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml index 0d7005f2..91384c38 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml +++ b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml @@ -16,9 +16,12 @@ - - - + + + + + + /// /// new UserControl or null to remove it - private void SetNewUserControl(StackPanel sp, UserControl uc = null) + private void SetNewUserControl(StackPanel sp, UserControl uc) { sp.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => @@ -363,11 +362,18 @@ namespace Sensus.Ui.FM2014TestBench /// Clear object lists, initialize and assign all objects: /// - 10 x FM2014 objects including address assignment based on the panel number, /// - 10 x FM2014 user controls, - /// - Assign a common receive handler. + /// - Assign a common receive handler, + /// - Load configuration: + /// - ComPort, + /// - Slot selections, + /// - Individual hardware tolerance selection. /// /// /// - Initial. /// + /// + /// - Initial. + /// private void Init() { ActionControl(false); @@ -381,7 +387,9 @@ namespace Sensus.Ui.FM2014TestBench } _autoProgressBar = false; - _regulationSetupHasChanged = false; + + // Load the configuration from the local file stored in AppData\FM2014 + _fm2014Config.ReadFM2014Config(); // Clear and dispose all FM2014 objects if (Fm2014s.Count != 0) @@ -389,7 +397,7 @@ namespace Sensus.Ui.FM2014TestBench for (var ctr = 0; ctr < Fm2014s.Count; ctr++) { // Remove objects from user control panel - SetNewUserControl(PanelsForUcFM2014s[ctr]); + SetNewUserControl(PanelsForUcFM2014s[ctr], null); // Kill FM2014 Fm2014s[ctr].OnRawRecordReceived -= DataReceived_Handler; @@ -410,24 +418,29 @@ namespace Sensus.Ui.FM2014TestBench fm2014.OnRawRecordReceived += DataReceived_Handler; Fm2014s.Add(fm2014); - var userControl = new UcFM2014Device(fm2014); + var userControl = new UcFM2014Device(fm2014, StoreFM2014Settings); UcFM2014s.Add(userControl); SetNewUserControl(PanelsForUcFM2014s[ctr], UcFM2014s[ctr]); + if (_fm2014Config?.SlotIsSelected?[ctr] != null && + _fm2014Config.SlotIsSelected.Count == MaxFm2014s && + SlotSelections.Count == MaxFm2014s) + SlotSelections[ctr].IsChecked = _fm2014Config?.SlotIsSelected[ctr] ?? false; + if (_fm2014Config?.IndividualTolerancePercent?[ctr] != null && + _fm2014Config.IndividualTolerancePercent.Count == MaxFm2014s) + fm2014.Tolerance_percent = _fm2014Config?.IndividualTolerancePercent[ctr] ?? + FM2014.DEFAULT_TOLERANCE_percent; } //grpBoxDebug.Visible = false; //gbxDutToRefRegulation.Visible = true; //gbxRegulationSetup.Visible = true; - // Load the configuration from the local file stored in AppData\FM2014 - _fm2014Config.ReadFM2014Config(); - // Display actual com-port, if not assigned use the '?'. This will be placed on Items[0] - if (_fm2014Config.SerialPort != null && !cbxFM2014ComPort.Items.Contains(_fm2014Config.SerialPort)) + if (_fm2014Config?.SerialPort != null && !cbxFM2014ComPort.Items.Contains(_fm2014Config.SerialPort)) { cbxFM2014ComPort.Items.Add(_fm2014Config.SerialPort); } - else if (_fm2014Config.SerialPort == null && !cbxFM2014ComPort.Items.Contains("?")) + else if (_fm2014Config?.SerialPort == null && !cbxFM2014ComPort.Items.Contains("?")) { cbxFM2014ComPort.Items.Add("?"); } @@ -440,16 +453,6 @@ namespace Sensus.Ui.FM2014TestBench cbxFM2014ComPort.Text = cbxFM2014ComPort.Items[_comPortIdx]?.ToString(); - //itemContent = _fm2014Config?.TolerancePercent ?? 3; - //for (var idx = 0; idx < cbxFM2014TolerancePercent.MaxDropDownItems; idx++) - //{ - // if (!cbxFM2014TolerancePercent.Items[idx].ToString().Equals(itemContent.ToString())) continue; - - // _toleranceIdx = idx; - // cbxFM2014TolerancePercent.SelectedItem = cbxFM2014TolerancePercent.Items[idx]; - // break; - //} - //// FM2014 group box //lblConnectionStatus.Text = Resources.StrLblFM2014NotConnected; //lblConnectionStatus.ForeColor = ColorProcessFailed; @@ -504,7 +507,7 @@ namespace Sensus.Ui.FM2014TestBench } /// - /// Store the settings adjusted by the UI + /// Store the settings adjusted by the UI or the UcFM2014Device /// /// /// - Initial. @@ -512,17 +515,33 @@ namespace Sensus.Ui.FM2014TestBench /// /// - Update FM2014 properties. /// + /// + /// - Store individual tolerances and test bench slot selections. + /// private void StoreFM2014Settings() { + if (_fm2014Config == null) + return; + + _setupHasChanged = false; + _fm2014Config.IndividualTolerancePercent?.Clear(); + _fm2014Config.IndividualTolerancePercent = null; + _fm2014Config.IndividualTolerancePercent = new List(); + + _fm2014Config.SlotIsSelected?.Clear(); + _fm2014Config.SlotIsSelected = null; + _fm2014Config.SlotIsSelected = new List(); + _fm2014Config.SerialPort = cbxFM2014ComPort.Text; - //if (int.TryParse(cbxFM2014TolerancePercent.SelectedItem.ToString(), out var tolerancePercent) - // && (tolerancePercent == 3 || tolerancePercent == 5)) - //{ - // _fm2014Config.TolerancePercent = tolerancePercent; - // if (Fm2014 != null) - // Fm2014.Tolerance_percent = tolerancePercent; - //} + for (var ctr = 0; ctr < MaxFm2014s; ctr++) + { + var fm2014 = Fm2014s[ctr]; + if (fm2014 == null) + return; + _fm2014Config.IndividualTolerancePercent.Add(fm2014.Tolerance_percent); + _fm2014Config.SlotIsSelected.Add(SlotSelections[ctr].IsChecked); + } _fm2014Config.Update(); } @@ -536,6 +555,9 @@ namespace Sensus.Ui.FM2014TestBench { try { + if (_setupHasChanged) + StoreFM2014Settings(); + Init(); if (string.IsNullOrEmpty(cbxFM2014ComPort?.SelectedItem?.ToString()) || cbxFM2014ComPort.SelectedItem.ToString().Equals("?")) @@ -877,6 +899,158 @@ namespace Sensus.Ui.FM2014TestBench SetFM2014AccessEnabled(); } #endregion ---------------------------------------- ActivationControls ---------------------------------------- + #region ------------------------------------------- Event handler --------------------------------------------- + /// + /// Feedback from FM2014being parsed to GUI + /// + /// + /// - Initial. + /// + private void DataReceived_Handler(Object sender, ProcessExecEventArgs e) + { + //var address = 0; + //if (sender is FM2014 fm2014) + //{ + // address = fm2014.Address; + //} + // Progress info section + if (e.ActualProcessMessage != null) + { + UpdateContentControl(lblSingleProgressText, e.ActualProcessMessage); + } + + if (e.ActualProcessPercent != null && !_autoProgressBar) + { + pbSubProgress.Dispatcher.Invoke(DispatcherPriority.Normal, + new Action(() => + { + pbSubProgress.Value = (Int32)e.ActualProcessPercent; + UpdateContentControl(lblTotalProgressValue, $@"{e.ActualProcessPercent:##0.0} %"); + } + )); + } + if (e.OverallProcessMessage != null) + { + UpdateContentControl(lblSingleProgressText, e.OverallProcessMessage); + } + + if (e.OverallProcessPercent != null && !_autoProgressBar) + { + pbTotalProgress.Dispatcher.Invoke(DispatcherPriority.Normal, + new Action(() => + { + pbTotalProgress.Value = (Int32)e.OverallProcessPercent; + UpdateContentControl(lblTotalProgressValue, $@"{e.OverallProcessPercent:##0.0} %"); + } + )); + } + + SetTimeDisplay(); + + // Data dispatcher + var resp = (CmdResponse)e.SpecificInfoObj; + + if (e.StatusReturn == StatusReturn.Failed) + { + LogErrorText(resp.AnswerStr); + //ErrorHandler(resp.CmdName); + } + + else if (resp.IntValue == null && resp.DoubleValue == null) + { + LogText(resp.AnswerStr); + } + else if (resp.IntValue != null) + { + LogText($"{resp.AnswerStr}: {resp.IntValue:D} {resp.SiUnit}"); + //switch (resp.CmdName) + //{ + //case FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR: + //case FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR_BU: + // tbxMeasuredRefPulses.Text = $@"{resp.IntValue:D}"; + // break; + //case FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR: + //case FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR_BU: + // tbxMeasuredDutPulses.Text = $@"{resp.IntValue:D}"; + // break; + //case FM2014CmdDef.CmdName.CMD_REF_LPP_SCALE: + // tbxRefPulsePerCm.Text = $@"{resp.IntValue:D}"; + // break; + //case FM2014CmdDef.CmdName.CMD_DUT_LPP_SCALE: + // tbxDutPulsePerCm.Text = $@"{resp.IntValue:D}"; + // break; + //case FM2014CmdDef.CmdName.CMD_MEAS_SET_ATTN: + // var idx = cbxAttenuation.FindString($@"{resp.IntValue}"); + // cbxAttenuation.SelectedIndex = idx; + // break; + //case FM2014CmdDef.CmdName.CMD_GET_REF_FREQU: + // tbxRefFrequencyHz.Text = $@"{resp.IntValue:D}"; + // tbxRefFrequencyDirectHz.Text = $@"{resp.IntValue:D}"; + // if (resp.IntValue < 1 || resp.IntValue > 254) + // { + // tbxRefFrequencyHz.BackColor = ColorProcessFailed; + // tbxActualFlowRateCmPerHour.BackColor = ColorProcessFailed; + // } + // else + // { + // tbxRefFrequencyHz.BackColor = ColorStandardDisplayField; + // tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField; + // } + + // break; + //} + } + else if (resp.DoubleValue != null) + { + LogText($"{resp.AnswerStr}: {resp.DoubleValue:F2} {resp.SiUnit}"); + //switch (resp.CmdName) + //{ + // case FM2014CmdDef.CmdName.CMD_GET_UDTLC: + // case FM2014CmdDef.CmdName.CMD_GET_DTLC: + // tbxActualMeasuredToleranceDutToRef.Text = $@"{resp.DoubleValue:F2}"; + // if (resp.DoubleValue < -Fm2014.Tolerance_percent || + // resp.DoubleValue > Fm2014.Tolerance_percent) + // { + // tbxActualMeasuredToleranceDutToRef.BackColor = ColorProcessFailed; + // } + // else + // { + // tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField; + // } + + // break; + // case FM2014CmdDef.CmdName.CMD_REF_SET_SCALE: + // tbxScaleRefToDut.Text = $@"{resp.DoubleValue:F4}"; + // break; + // // DEBUG + // case FM2014CmdDef.CmdName.CMD_GET_REF_PERIOD: + // tbxRefPeriodMs.Text = $@"{resp.DoubleValue:F3}"; + // break; + // case FM2014CmdDef.CmdName.CMD_GET_DUT_PERIOD: + // tbxDutPeriodMs.Text = $@"{resp.DoubleValue:F3}"; + // break; + // case FM2014CmdDef.CmdName.CMD_CAL_FREQU_REF_PERIOD: + // tbxRefFrequencyFromRefPeriodHz.Text = $@"{resp.DoubleValue:F3}"; + // break; + // case FM2014CmdDef.CmdName.CMD_CAL_FREQU_DUT_PERIOD: + // tbxDutFrequencyFromDutPeriodHz.Text = $@"{resp.DoubleValue:F3}"; + // break; + // case FM2014CmdDef.CmdName.CMD_CAL_FLOW_REF_FREQU: + // tbxRefFlowRateFromRefFrequencyCmPerH.Text = $@"{resp.DoubleValue:F3}"; + // // TODO THW Check if the actual flow shall be taken based on 'REF Frequency' + // tbxActualFlowRateCmPerHour.Text = $@"{resp.DoubleValue:F3}"; + // break; + // case FM2014CmdDef.CmdName.CMD_CAL_FLOW_REF_PERIOD: + // tbxRefFlowRateFromRefPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}"; + // break; + // case FM2014CmdDef.CmdName.CMD_CAL_FLOW_DUT_PERIOD: + // tbxDutFlowRateFromDutPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}"; + // break; + //} + } + } + + #endregion ---------------------------------------- Event handler --------------------------------------------- #region ------------------------------------------- Buttons and Controls -------------------------------------- /// /// Establish connection to FM2014 with individual address and read out FM2014 info. @@ -994,15 +1168,11 @@ namespace Sensus.Ui.FM2014TestBench /// private void cbxFM2014BaseSettings_SelectedValueChanged(Object sender, EventArgs e) { - //if (_toleranceIdx != cbxFM2014TolerancePercent.SelectedIndex || - // _addressIdx != cbxFM2014Address.SelectedIndex || - // _comPortIdx != cbxFM2014ComPort.SelectedIndex) - //{ - // _toleranceIdx = cbxFM2014TolerancePercent.SelectedIndex; - // _addressIdx = cbxFM2014Address.SelectedIndex; - // _comPortIdx = cbxFM2014ComPort.SelectedIndex; - // StoreFM2014Settings(); - //} + if (_comPortIdx != cbxFM2014ComPort.SelectedIndex) + { + _comPortIdx = cbxFM2014ComPort.SelectedIndex; + StoreFM2014Settings(); + } } /// @@ -1341,22 +1511,6 @@ namespace Sensus.Ui.FM2014TestBench //} } - /// - /// Switch between DEBUG and regular operation - /// - /// - /// - private void picFM2014_Click(Object sender, EventArgs e) - { - //grpBoxDebug.Visible = !grpBoxDebug.Visible; - //if (Fm2014 != null) - // Fm2014.RequestDebugInformation = grpBoxDebug.Visible; - - ////gbxDutToRefRegulation.Visible = !grpBoxDebug.Visible; - //gbxRegulationSetup.Visible = !grpBoxDebug.Visible; - - } - /// /// Select next control on enter key pressed /// @@ -1369,159 +1523,12 @@ namespace Sensus.Ui.FM2014TestBench // SelectNextControl(ActiveControl, true, true, true, true); //} } - #endregion ---------------------------------------- Buttons and Controls -------------------------------------- - #region ------------------------------------------- Event handler --------------------------------------------- - /// - /// Feedback from FM2014being parsed to GUI - /// - /// - /// - Initial. - /// - private void DataReceived_Handler(Object sender, ProcessExecEventArgs e) + + private void cbxSlot1_Click(Object sender, RoutedEventArgs e) { - var address = 0; - if (sender is FM2014 fm2014) - { - address = fm2014.Address; - } - // Progress info section - if (e.ActualProcessMessage != null) - { - UpdateContentControl(lblSingleProgressText, e.ActualProcessMessage); - } - - if (e.ActualProcessPercent != null && !_autoProgressBar) - { - pbSubProgress.Dispatcher.Invoke(DispatcherPriority.Normal, - new Action(() => - { - pbSubProgress.Value = (Int32)e.ActualProcessPercent; - UpdateContentControl(lblTotalProgressValue, $@"{e.ActualProcessPercent:##0.0} %"); - } - )); - } - if (e.OverallProcessMessage != null) - { - UpdateContentControl(lblSingleProgressText, e.OverallProcessMessage); - } - - if (e.OverallProcessPercent != null && !_autoProgressBar) - { - pbTotalProgress.Dispatcher.Invoke(DispatcherPriority.Normal, - new Action(() => - { - pbTotalProgress.Value = (Int32)e.OverallProcessPercent; - UpdateContentControl(lblTotalProgressValue, $@"{e.OverallProcessPercent:##0.0} %"); - } - )); - } - - SetTimeDisplay(); - - // Data dispatcher - var resp = (FM2014CmdDef.CmdResponse)e.SpecificInfoObj; - - if (e.StatusReturn == StatusReturn.Failed) - { - LogErrorText(resp.AnswerStr); - //ErrorHandler(resp.CmdName); - } - - else if (resp.IntValue == null && resp.DoubleValue == null) - { - LogText(resp.AnswerStr); - } - else if (resp.IntValue != null) - { - LogText($"{resp.AnswerStr}: {resp.IntValue:D} {resp.SiUnit}"); - //switch (resp.CmdName) - //{ - //case FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR: - //case FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR_BU: - // tbxMeasuredRefPulses.Text = $@"{resp.IntValue:D}"; - // break; - //case FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR: - //case FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR_BU: - // tbxMeasuredDutPulses.Text = $@"{resp.IntValue:D}"; - // break; - //case FM2014CmdDef.CmdName.CMD_REF_LPP_SCALE: - // tbxRefPulsePerCm.Text = $@"{resp.IntValue:D}"; - // break; - //case FM2014CmdDef.CmdName.CMD_DUT_LPP_SCALE: - // tbxDutPulsePerCm.Text = $@"{resp.IntValue:D}"; - // break; - //case FM2014CmdDef.CmdName.CMD_MEAS_SET_ATTN: - // var idx = cbxAttenuation.FindString($@"{resp.IntValue}"); - // cbxAttenuation.SelectedIndex = idx; - // break; - //case FM2014CmdDef.CmdName.CMD_GET_REF_FREQU: - // tbxRefFrequencyHz.Text = $@"{resp.IntValue:D}"; - // tbxRefFrequencyDirectHz.Text = $@"{resp.IntValue:D}"; - // if (resp.IntValue < 1 || resp.IntValue > 254) - // { - // tbxRefFrequencyHz.BackColor = ColorProcessFailed; - // tbxActualFlowRateCmPerHour.BackColor = ColorProcessFailed; - // } - // else - // { - // tbxRefFrequencyHz.BackColor = ColorStandardDisplayField; - // tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField; - // } - - // break; - //} - } - else if (resp.DoubleValue != null) - { - LogText($"{resp.AnswerStr}: {resp.DoubleValue:F2} {resp.SiUnit}"); - //switch (resp.CmdName) - //{ - // case FM2014CmdDef.CmdName.CMD_GET_UDTLC: - // case FM2014CmdDef.CmdName.CMD_GET_DTLC: - // tbxActualMeasuredToleranceDutToRef.Text = $@"{resp.DoubleValue:F2}"; - // if (resp.DoubleValue < -Fm2014.Tolerance_percent || - // resp.DoubleValue > Fm2014.Tolerance_percent) - // { - // tbxActualMeasuredToleranceDutToRef.BackColor = ColorProcessFailed; - // } - // else - // { - // tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField; - // } - - // break; - // case FM2014CmdDef.CmdName.CMD_REF_SET_SCALE: - // tbxScaleRefToDut.Text = $@"{resp.DoubleValue:F4}"; - // break; - // // DEBUG - // case FM2014CmdDef.CmdName.CMD_GET_REF_PERIOD: - // tbxRefPeriodMs.Text = $@"{resp.DoubleValue:F3}"; - // break; - // case FM2014CmdDef.CmdName.CMD_GET_DUT_PERIOD: - // tbxDutPeriodMs.Text = $@"{resp.DoubleValue:F3}"; - // break; - // case FM2014CmdDef.CmdName.CMD_CAL_FREQU_REF_PERIOD: - // tbxRefFrequencyFromRefPeriodHz.Text = $@"{resp.DoubleValue:F3}"; - // break; - // case FM2014CmdDef.CmdName.CMD_CAL_FREQU_DUT_PERIOD: - // tbxDutFrequencyFromDutPeriodHz.Text = $@"{resp.DoubleValue:F3}"; - // break; - // case FM2014CmdDef.CmdName.CMD_CAL_FLOW_REF_FREQU: - // tbxRefFlowRateFromRefFrequencyCmPerH.Text = $@"{resp.DoubleValue:F3}"; - // // TODO THW Check if the actual flow shall be taken based on 'REF Frequency' - // tbxActualFlowRateCmPerHour.Text = $@"{resp.DoubleValue:F3}"; - // break; - // case FM2014CmdDef.CmdName.CMD_CAL_FLOW_REF_PERIOD: - // tbxRefFlowRateFromRefPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}"; - // break; - // case FM2014CmdDef.CmdName.CMD_CAL_FLOW_DUT_PERIOD: - // tbxDutFlowRateFromDutPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}"; - // break; - //} - } + _setupHasChanged = true; } - #endregion ---------------------------------------- Event handler --------------------------------------------- - + #endregion ---------------------------------------- Buttons and Controls -------------------------------------- } } \ No newline at end of file diff --git a/FM2014TestApp/Ui/Fm2014sTest/UserControls/UcFM2014Device.xaml.cs b/FM2014TestApp/Ui/Fm2014sTest/UserControls/UcFM2014Device.xaml.cs index 261fe36e..52e8b853 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/UserControls/UcFM2014Device.xaml.cs +++ b/FM2014TestApp/Ui/Fm2014sTest/UserControls/UcFM2014Device.xaml.cs @@ -26,18 +26,22 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls private readonly List MeasurementLabels; private readonly FM2014 _fM2014; + private readonly Action _selectedAction; + /// /// Ctor /// /// + /// kick off storage of changed setting to configuration file /// /// - Initial. /// - public UcFM2014Device(FM2014 fm2014) + public UcFM2014Device(FM2014 fm2014, Action setupHasChanged) { InitializeComponent(); _fM2014 = fm2014; + _selectedAction = setupHasChanged; MeasurementBorders = new List(); MeasurementLabels = new List(); MeasurementBorders.Add(brdMeasurement1); @@ -65,12 +69,66 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls HideMeasurements(); } + //TODO THW Setup device based on selections + //itemContent = fm2014.TolerancePercent ?? FM2014.DEFAULT_TOLERANCE_percent; + //for (var idx = 0; idx < cbxFM2014TolerancePercent.MaxDropDownItems; idx++) + //{ + // if (!cbxFM2014TolerancePercent.Items[idx].ToString().Equals(itemContent.ToString())) continue; + + // _toleranceIdx = idx; + // cbxFM2014TolerancePercent.SelectedItem = cbxFM2014TolerancePercent.Items[idx]; + // break; + //} + /// - /// Set a value to a label + /// Safe the settings to configuration file. /// - /// + /// + /// + /// + /// - Initial. + /// + private void btnSaveSettings_Click(Object sender, EventArgs e) + { + //TODO THW check if settings have changed before firing the event + //grpBoxDebug.Visible = !grpBoxDebug.Visible; + //if (Fm2014 != null) + // Fm2014.RequestDebugInformation = grpBoxDebug.Visible; + + ////gbxDutToRefRegulation.Visible = !grpBoxDebug.Visible; + //gbxRegulationSetup.Visible = !grpBoxDebug.Visible; + _selectedAction?.Invoke(); + } + + /// + /// Open the setting window + /// + /// + /// + /// + /// - Initial. + /// + private void picFM2014_Click(Object sender, EventArgs e) + { + //grpBoxDebug.Visible = !grpBoxDebug.Visible; + //if (Fm2014 != null) + // Fm2014.RequestDebugInformation = grpBoxDebug.Visible; + + ////gbxDutToRefRegulation.Visible = !grpBoxDebug.Visible; + //gbxRegulationSetup.Visible = !grpBoxDebug.Visible; + + } + + /// + /// Set a value to a label: + /// - Input values 1..7 ! + /// + /// 1 to 7 /// /// + /// + /// - Initial. + /// public Boolean SetValue(Int32 labelNumber, String valueStr) { var index = labelNumber - 1; @@ -215,6 +273,12 @@ namespace Sensus.Ui.Fm2014TestBench.UserControls /// /// /// + /// + /// - Initial + /// + /// + /// - Introduced multi line text with center alignment. + /// private static void UiElmEnable(UIElement elm, Boolean isEnabled, Boolean isVisible = true) { elm.Dispatcher.Invoke(DispatcherPriority.Normal,