/// /// Copyright (c) 2021 Sensus Slovensko a.s. /// using System; using System.Reflection; using System.Text; using System.Windows.Forms; using Common; using log4net; using TBF.Rig.GenericDevices; namespace TBF.Rig.ControlBoard.Uni { public class StandingStartStopTestOp : IOperation { private static readonly ILog log = LogManager.GetLogger(typeof(StandingStartStopTestOp)); public override string ToString() { return string.Format("StandingStartStopTestOp()"); } /// /// Set by the constructor /// readonly UniCB uniCB; readonly object flowMeter; readonly TBF.Rig.Uni.FlowMetersInParallel.FlowMeter flowMeterInParallel; readonly TBF.Rig.Uni.Diverter.Diverter diverter; readonly int pulsesCount; /// Number of reference pulses for a complete test readonly bool withDiverter; /// Test with diverter (and scale) private DateTime startTimeForSimulation; private bool simulationTimerStarted = false; /// /// Internal state of this operation /// enum OpState { StartingTest, TestInProgress, TestCompleted, } OpState opState; /// /// Operation for a Standing start-stop test (constructor) /// /// Events: OpArgumentError .... invalid arguments, test cannot be started /// StartingTest ....... starting a test /// TestInProgress ..... test was successfully started, test is running /// TestCompleted ...... test was successfully completed /// Error .............. unspecified error while running a test /// /// Control board component /// Components used by the test /// Flow lower limit /// Flow upper limit /// Test duration - number of reference flow meter pulses public StandingStartStopTestOp(UniCB cb, OutputPath devices, int pulsesCount, bool withDiverter) { this.uniCB = cb; try { flowMeter = devices.FlowMeter as TBF.Rig.Uni.FlowMeter.FlowMeter; if(flowMeter == null) flowMeter = devices.FlowMeter as TBF.Rig.Uni.FlowMetersInParallel.FlowMeter; if (flowMeter == null) throw new ArgumentNullException("Invalid flow meter"); } catch (Exception ex) { string deviceInfo = GetAllDevicesInfo(devices); string flowMeterStatus = devices.FlowMeter == null ? "devices.FlowMeter je NULL" : $"devices.FlowMeter je typu: {devices.FlowMeter.GetType().FullName}"; MessageBox.Show( $"Chyba počas zastavenia regulácie prietoku, v ramci StandingStartStopTestOp() pre flowMeter:\n" + $"{ex.Message}\n\n" + $"Diagnostika:\n{flowMeterStatus}\n\n" + $"{deviceInfo}\n\n" + $"Stack trace:\n{ex.StackTrace}", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error ); throw; } this.pulsesCount = pulsesCount; this.withDiverter = withDiverter; if (withDiverter) { try { diverter = devices.Diverter as TBF.Rig.Uni.Diverter.Diverter; if (diverter == null) throw new ArgumentNullException("Invalid diverter"); } catch (Exception ex) { string deviceInfo = GetAllDevicesInfo(devices); MessageBox.Show( $"Chyba počas zastavenia regulácie prietoku, v ramci StandingStartStopTestOp() pre diverter:\n" + $"{ex.Message}\n\n{deviceInfo}\n\nStack trace:\n{ex.StackTrace}", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error ); throw; } } log.Debug(this.ToString()); } string GetAllDevicesInfo(object obj) { if (obj == null) return "devices objekt je null."; StringBuilder sb = new StringBuilder(); sb.AppendLine("Zoznam zariadení v devices:"); var props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in props) { try { object value = prop.GetValue(obj); string valueStr = value != null ? value.ToString() : "null"; sb.AppendLine($"{prop.Name}: {valueStr}"); } catch (Exception ex) { sb.AppendLine($"{prop.Name}: [Chyba pri načítaní - {ex.Message}]"); } } return sb.ToString(); } /// /// Start this operation /// public void Start() { if (flowMeter is TBF.Rig.Uni.FlowMeter.FlowMeter) { log.InfoFormat("Start() Et#={0} pulses={1} withDiverter={2}", ((TBF.Rig.Uni.FlowMeter.FlowMeter)flowMeter).Idx1, pulsesCount, withDiverter); /// Start the test (and the flow measurement) if (withDiverter) { uniCB.DivResolution = diverter.Resolution; } uniCB.SetActivity(Activity.StandingStartStopTest); uniCB.StartTest(false, ((TBF.Rig.Uni.FlowMeter.FlowMeter)flowMeter).Idx1, (withDiverter ? diverter.DiverterNr : 0), 0, false, withDiverter, false, true, false, pulsesCount); opState = OpState.StartingTest; } else if (flowMeter is TBF.Rig.Uni.FlowMetersInParallel.FlowMeter) { log.InfoFormat("Start() Et#={0} pulses={1} withDiverter={2}", ((TBF.Rig.Uni.FlowMetersInParallel.FlowMeter)flowMeter).Idx1, pulsesCount, withDiverter); /// Start the test (and the flow measurement) if (withDiverter) { uniCB.DivResolution = diverter.Resolution; } uniCB.SetActivity(Activity.StandingStartStopTest); uniCB.StartTest(false, ((TBF.Rig.Uni.FlowMetersInParallel.FlowMeter)flowMeter).Idx1, (withDiverter ? diverter.DiverterNr : 0), 0, false, withDiverter, false, true, false, pulsesCount); opState = OpState.StartingTest; } } /// /// Run this operation /// /// /// Event.OpArgumentError .... invalid arguments, test cannot be started /// Event.StartingTest ....... starting a test /// Event.TestInProgress ..... test was successfully started, test is running /// Event.TestCompleted ...... test was successfully completed /// Event.Error .............. unspecified error while running a test /// public Event Run() { log.DebugFormat("Run() opState={0}", opState); //Simulation of processing time 25 seconds if (uniCB.DebugLevel == DebugMode.Simulate) { if (opState == OpState.StartingTest) { startTimeForSimulation = DateTime.Now; simulationTimerStarted = false; } if (opState == OpState.TestInProgress) { if (!simulationTimerStarted) { startTimeForSimulation = DateTime.Now; simulationTimerStarted = true; } else if (DateTime.Now - startTimeForSimulation > TimeSpan.FromSeconds(25)) { return Event.TestCompleted; } } } switch (opState) { case OpState.StartingTest: opState = OpState.TestInProgress; return Event.TestInProgress; case OpState.TestInProgress: if (uniCB.RefPulses < pulsesCount) { return Event.TestInProgress; /// Test was not completed yet } opState = OpState.TestCompleted; return Event.TestCompleted; case OpState.TestCompleted: default: return Event.TestCompleted; } } /// /// Stop this operation /// public void Stop() { log.Info("Stop()"); uniCB.SetActivity((opState == OpState.TestCompleted) ? Activity.TestCompleted : Activity.Idle); uniCB.StopAll(false); } } }