diff --git a/TBF/BenchControl/StateMachine.cs b/TBF/BenchControl/StateMachine.cs
deleted file mode 100644
index db7c3c54f..000000000
--- a/TBF/BenchControl/StateMachine.cs
+++ /dev/null
@@ -1,857 +0,0 @@
-///
-/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
-///
-using System;
-using System.Text;
-using System.Threading;
-using System.Collections.Generic;
-using log4net;
-using NHibernate;
-using Common;
-using Config.Entities;
-using TBF.BenchControl.Generic;
-using TBF.BenchControl.GenericDevices;
-using TBF.BenchControl.Sequences;
-using Dirichlet.Numerics;
-using TBF.Resources;
-
-namespace TBF.BenchControl
-{
- public enum MachineState
- {
- Undefined = 0,
- Disabled,
- StartingUp, /// Start-up: Initialize() of all devices + start of the worker thread
- FailedToStart, /// Most likely Initialize() of any device thrown an exception
- Running, /// RunDeviceBefore() and RunDeviceAfter() of all devices, Start()/Run()/Stop() of operations
- ShuttingDown, /// Shutdown: StopDevice() and StopDevice2() of all devices
- Off, /// Off after the shutdown
- }
-
-
- ///
- /// This class controls real test bench behavior.
- /// It is based on a state machine
- ///
- public static class StateMachine
- {
- private static readonly ILog log = LogManager.GetLogger(typeof(StateMachine));
- private static readonly ILog wlog = LogManager.GetLogger(typeof(StateMachine));
-
- /// Private devices and components
- static IList components; /// list of all components
- static IList devices; /// list of devices
- ///
- /// Bench paths
- static IList feedingPaths;
- static IList benchPaths;
- static IList outputPaths;
- static IList metersPaths;
- static IList heatMetersPaths;
- public static IList TransitionSequences;
- public static IList TransitionSteps;
-
- /// Public components
- public static Elde.ControlBoardDev ControlBoard;
- public static GenericDevices.IAmbient Ambient;
- public static IOperation BenchWaitingOp;
- public static IOperation BenchErrorOp;
- public static GenericDevices.IScaleOrTank Tank1;
- public static GenericDevices.IScaleOrTank Tank2;
- public static GenericDevices.IScaleOrTank Tank3;
- public static GenericDevices.IValve DrainValve1;
- public static GenericDevices.IValve DrainValve2;
- public static GenericDevices.IValve DrainValve3;
- public static IList MasterValves; /// list of directly controlled valves
- public static IList CoupledValves; /// list of coupled valves
- public static IList ExtendedValves; /// list of extended valves
-
- public static IList LoopStartNames;
- public static IList LoopEndNames;
-
- /// Time and synchronization
-#if TURA_IPERL || TURA_IPERL_NEW
- public const int Period = 2; /// State machine period in sec.
-#else
- public const int Period = 1; /// State machine period in sec.
-#endif
-
- static DateTime startDateTime; /// DateTime of time instance when the state machine worker thread starts
- static int currentTimeSec; /// Time from the start of the state machine in seconds
-
- public static MachineState MachineState; /// see enum MachineState for explanation
-
- /// Worker thread and database session
- static Thread workerThread;
-
- static IList states; /// list of states
-
- public static DateTime CycleStartTimeStamp;
-
- public static IList DefaultValvesOpen
- {
- get
- {
- return GenericDevices.ValveBase.Merge(
- Utils.ValvesOpen((feedingPaths != null && feedingPaths.Count > 0) ? feedingPaths[0] : null),
- Utils.ValvesOpen((benchPaths != null && benchPaths.Count > 0) ? benchPaths[0] : null),
- Utils.ValvesOpen((outputPaths != null && outputPaths.Count > 0) ? outputPaths[0] : null)
- );
- }
- }
-
- public static IList DefaultValvesClose
- {
- get
- {
- return GenericDevices.ValveBase.Merge(
- Utils.ValvesClose((feedingPaths != null && feedingPaths.Count > 0) ? feedingPaths[0] : null),
- Utils.ValvesClose((benchPaths != null && benchPaths.Count > 0) ? benchPaths[0] : null),
- Utils.ValvesClose((outputPaths != null && outputPaths.Count > 0) ? outputPaths[0] : null)
- );
- }
- }
-
- ///
- /// Loaded by LoadProcedure() or IOperation LoadProcedureOp(...)
- ///
- public static Procedure Procedure; /// Procedure
- public static TestInstance[] TestInstances; /// Tests
- public static bool IsRemoteProcedure;
-
-
- /// Hardware devices connected to the PC controlling the bench.
- public static IList Components { get { return components; } }
- public static IList Devices { get { return devices; } }
-
- ///
- /// DateTime of time instance when the state machine worker thread starts
- ///
- public static DateTime StartDateTime { get { return startDateTime; } }
-
- ///
- /// Current state name
- ///
- public static int Time
- {
- get { return currentTimeSec; }
- set { currentTimeSec = value; }
- }
-
- ///
- /// Constructor
- ///
- static StateMachine()
- {
- devices = new List();
- states = new List();
- currentTimeSec = 0;
- }
-
- ///
- /// Add a device to the state machine.
- ///
- /// Device
- public static void AddDevice(IDevice device)
- {
- if (device != null && !devices.Contains(device)) devices.Add(device);
- }
-
- ///
- /// Add a state to the state machine.
- /// In this way a sequence can be created programtically.
- ///
- /// State
- public static void AddState(State state)
- {
- if (state != null && !states.Contains(state)) states.Add(state);
- }
-
- ///
- /// Remove the state from the state machine.
- ///
- /// State
- public static void RemoveState(State state)
- {
- if (state != null && state != State.CurrentState && states.Contains(state)) states.Remove(state);
- }
-
- ///
- /// Get a state from a label
- ///
- ///
- /// The matching state or null
- static State GetStateFromLabel(string label)
- {
- if (label == null) return null;
-
- foreach (State state in states)
- {
- if (state.Label != null && state.Label.Equals(label)) return state;
- }
- return null;
- }
-
- ///
- /// Start the state machine in the state 'label' in a desired mode of operation.
- /// This method is called in the UI thread and creates a new state machine thread.
- /// This method call should be embedded in: try { StateMachine.Start(...); } catch { }
- /// to handle configuration problems. Calls CreateDevices(mode) and CreateStates().
- ///
- /// Mode of operation
- /// A copy of bench data used by the state machine
- /// Identifies the initial state
-#if DN100
- public static void InitializeBoardEtc(ControlCom2VB.ControlCom2panel ctrlBrdComponent)
-#elif FUZHOU_150 || MUNICH
- public static void InitializeBoardEtc(ControlComponent3Munich.UserControl1 ctrlBrdComponent)
-#elif FUZHOU_300
- public static void InitializeBoardEtc(ControlComponent3F300.UserControl1 ctrlBrdComponent)
-#elif BERLIN || GELSENWASSER || GENESIS || IZRAEL_200 || PETERSBURG_200 || PUCHONG_200 || SLM_150
- public static void InitializeBoardEtc(ControlComponent_Izrael2014.UserControl1 ctrlBrdComponent)
-#else /// all newer benches
- public static void InitializeBoardEtc(ControlComponent_Torino2015.UserControl1 ctrlBrdComponent)
-#endif
- {
- /// Load the list of components (entities) from the database.
- /// Then create the components (derived from IComponent).
- components = BenchControl.TbfComponents.LoadComponentsFromDB(TBF.DB.CreateSession(Common.DBKind.Config));
- MasterValves = GenericDevices.ValveBase.MasterValves(components);
- CoupledValves = GenericDevices.ValveBase.CoupledValves(components);
- ExtendedValves = GenericDevices.ValveBase.ExtendedValves(components);
-
- /// Find all balances (to initialize tank capacities in the control board)
- /// Find the control board
- IList tanks = new List();
- ProcessData.IperlHeads = new List();
- SequenceBase.FlowMeters = new List();
- SequenceBase.RegulValves = new List();
- SequenceBase.FeedingRegulValves = new List();
- SequenceBase.OutputRegulValves = new List();
- SequenceBase.PumpsWithFM = new List();
- SequenceBase.WaterMeters = new List();
- SequenceBase.Cameras = new List();
- LoopStartNames = new List();
- LoopEndNames = new List();
- UInt128 valvesToInvert = 0;
- foreach (var cmpnt in components)
- {
- if (cmpnt is Elde.ControlBoardDev) ControlBoard = cmpnt as Elde.ControlBoardDev;
- if (cmpnt is IBenchInfo) ProcessData.BenchInfo = cmpnt as IBenchInfo;
- if (cmpnt is IErrorFlags) ProcessData.ErrorFlagsComp = cmpnt as IErrorFlags;
- if (cmpnt is IStatisticsMonitoring) ProcessData.StatisticsMonitoringComp = cmpnt as IStatisticsMonitoring;
-
- if ((cmpnt is Output.DB.SensusOracle.Database) && (ProcessData.OracleDB == null))
- {
- /// The 1st Oracle database component found --> store the reference
- ProcessData.OracleDB = cmpnt as Output.DB.SensusOracle.Database;
- }
- if ((cmpnt is Output.DB.ProductionTracing.Tracing) && (ProcessData.TracingDB == null))
- {
- /// The 1st production tracing database component found --> store the reference
- ProcessData.TracingDB = cmpnt as Output.DB.ProductionTracing.Tracing;
- }
-
- if (cmpnt is TestMethods.iPerlCommunication.iPerlHead.IperlHead)
- {
- ProcessData.IperlHeads.Add(cmpnt as TestMethods.iPerlCommunication.iPerlHead.IperlHead);
- }
- if (cmpnt is IFlowMeter) SequenceBase.FlowMeters.Add(cmpnt as IFlowMeter);
- if ((cmpnt is IRegValve) && !(cmpnt is BenchControl.Elde.RegulValveTandem.RegulValveTandem))
- {
- IRegValve rv = cmpnt as IRegValve;
- SequenceBase.RegulValves.Add(rv);
- if (rv.Category == ValveCategory.Feeding) SequenceBase.FeedingRegulValves.Add(rv);
- if (rv.Category == ValveCategory.Output) SequenceBase.OutputRegulValves.Add(rv);
- }
- if (cmpnt is IPumpFM && !(cmpnt is Elde.PumpTandem.Pump))
- {
- SequenceBase.PumpsWithFM.Add(cmpnt as IPumpFM);
- }
- if (cmpnt is IWaterMeter) SequenceBase.WaterMeters.Add(cmpnt as IWaterMeter);
- if (cmpnt is ICamera) SequenceBase.Cameras.Add(cmpnt as ICamera);
- if (cmpnt is GenericDevices.IAmbient) Ambient = cmpnt as GenericDevices.IAmbient;
-
- if (cmpnt is GenericDevices.IParallelOutput && cmpnt.Name.ToLower().Contains("tower"))
- {
- BenchWaitingOp = (cmpnt as GenericDevices.IParallelOutput).ShowBenchWaitingOp();
- BenchErrorOp = (cmpnt as GenericDevices.IParallelOutput).ShowBenchErrorOp();
- }
-
- if (cmpnt is ITestMethod && cmpnt.ClassName == "TestMethods.OuterLoop.Start") LoopStartNames.Add(cmpnt.Name);
- if (cmpnt is ITestMethod && cmpnt.ClassName == "TestMethods.OuterLoop.End") LoopEndNames.Add(cmpnt.Name);
-
- if (cmpnt is IScaleOrTank)
- {
- IScaleOrTank tank = cmpnt as IScaleOrTank;
- tanks.Add(tank);
- if (Tank1 == null) Tank1 = tank;
- else if (Tank2 == null) Tank2 = tank;
- else if (Tank3 == null) Tank3 = tank;
- }
-
- Elde.Valve.Valve eldeValve = (cmpnt as Elde.Valve.Valve);
- if ((eldeValve != null) && eldeValve.Inverted) valvesToInvert |= eldeValve.Mask;
- }
-
- /// Pre-initialize the control board (= buffer the arguments ctrlBrdComponent, tankCapacities)
- if (ControlBoard != null)
- {
- /// Create an array with tank capacities from 'tanks' list
- double[] tankCapacities = new double[tanks.Count];
- for (int i = 0; i < tankCapacities.Length; i++) tankCapacities[i] = tanks[i].Capacity;
-
- ControlBoard.InitializeEldeComponent(ctrlBrdComponent, valvesToInvert, tankCapacities);
- }
- else
- {
- throw new Exception("Control board component is missing");
- }
- }
-
-
- public static string CurrentlyInitializedComponentName;
- ///
- public static string InitializeComponents()
- {
- CurrentlyInitializedComponentName = "-";
-
- bool anyComponentIsInSimulMode = false;
- StringBuilder inSimulMode = new StringBuilder();
-
- /// Add all devices to the state machine and initialize them
- foreach (var cmpnt in components)
- {
- if (cmpnt.DebugLevel == DebugMode.Simulate)
- {
- inSimulMode.AppendFormat("{0}{1}", anyComponentIsInSimulMode ? ", " : "", cmpnt.Name);
- anyComponentIsInSimulMode = true;
- }
-
- if (cmpnt is IDevice)
- {
- devices.Add(cmpnt as IDevice); /// Only components that were initialized are added
- UiBridge.Bridge.OnActivity(null, cmpnt.Name); /// Info
- }
-
- CurrentlyInitializedComponentName = cmpnt.Name;
- cmpnt.Initialize();
- cmpnt.StartChangeHandler(); /// Start handling parameter change events
- }
-
- CurrentlyInitializedComponentName = "---";
-
- ///
- /// (1) Propagate debug levels from parents to children when necessary
- /// (2) Set drain valves DrainValve1, DrainValve2 and DrainValve3
- ///
- foreach (var cmpnt in components)
- {
- if (cmpnt.Cfg is IChildComponentCfg && !string.IsNullOrEmpty(cmpnt.Cfg.ParentName) &&
- (cmpnt.Cfg.DebugLevel == DebugMode.Inherit || cmpnt.Cfg.DebugLevel == DebugMode.AutoDetect))
- {
- foreach (var par in components)
- {
- if (par.Cfg.Name.Equals(cmpnt.Cfg.ParentName)) { cmpnt.Cfg.DebugLevel = par.Cfg.DebugLevel; break; }
- }
- }
-
- if (cmpnt is IScaleOrTank)
- {
- IScaleOrTank tank = cmpnt as IScaleOrTank;
-
- if (tank == Tank1 && DrainValve1 == null)
- {
- DrainValve1 = tank.DrainValve;
- log.WarnFormat("InitializeComponents() ... Scale1={0} DrainValve1={1}",
- tank.Name, (DrainValve1 != null) ? DrainValve1.Name : "---");
- }
- else if (tank == Tank2 && DrainValve2 == null)
- {
- DrainValve2 = tank.DrainValve;
- log.WarnFormat("InitializeComponents() ... Scale2={0} DrainValve2={1}",
- tank.Name, (DrainValve2 != null) ? DrainValve2.Name : "---");
- }
- else if (tank == Tank3 && DrainValve3 == null)
- {
- DrainValve3 = tank.DrainValve;
- log.WarnFormat("InitializeComponents() ... Scale3={0} DrainValve3={1}",
- tank.Name, (DrainValve3 != null) ? DrainValve3.Name : "---");
- }
- }
- }
-
- if (anyComponentIsInSimulMode)
- return inSimulMode.ToString();
- else
- return null;
- }
-
- ///
- /// Stop devices that were started by InitializeDevices().
- /// Works correctly also after exeption from InitializeDevices() as only ...
- /// ... correctly started devices were added in 'devices' list.
- ///
- public static void StopDevices()
- {
- for (int i = devices.Count - 1; i >= 0; i--)
- {
- var dev = devices[i];
- UiBridge.Bridge.OnActivity(null, string.Format("1. {0}", dev.Name)); /// Info
- dev.StopDevice();
- }
- }
-
- ///
- /// Stop devices that were started by InitializeDevices().
- /// Works correctly also after exeption from InitializeDevices() as only ...
- /// ... correctly started devices were added in 'devices' list.
- ///
- public static void StopDevices2()
- {
- for (int i = devices.Count - 1; i >= 0; i--)
- {
- var dev = devices[i];
- UiBridge.Bridge.OnActivity(null, string.Format("2. {0}", dev.Name)); /// Info
- dev.StopDevice2();
- }
- }
-
- ///
- /// Checks remote and local configuration DB paths and transitions for compatibility
- ///
- /// true when DB-s are compatible
- public static bool IsRemoteDBCompatible(out string message)
- {
- IList remoteFeedingPaths;
- IList remoteBenchPaths;
- IList remoteOutputPaths;
- IList remoteMetersPaths;
- IList remoteTransitions;
-
- try
- {
- ISession remoteSession = TBF.DB.CreateSession(Common.DBKind.RemoteConfig);
- remoteFeedingPaths = remoteSession.QueryOver().List();
- remoteBenchPaths = remoteSession.QueryOver().List();
- remoteOutputPaths = remoteSession.QueryOver().List();
- remoteMetersPaths = remoteSession.QueryOver().List();
- remoteTransitions = remoteSession.QueryOver().List();
- }
- catch (Exception)
- {
- message = "Cannot open remote database";
- return false;
- }
-
- ISession localSession = TBF.DB.CreateSession(Common.DBKind.Config);
- var localFeedingPaths = localSession.QueryOver().List();
- var localBenchPaths = localSession.QueryOver().List();
- var localOutputPaths = localSession.QueryOver().List();
- var localMetersPaths = localSession.QueryOver().List();
- var localTransitions = localSession.QueryOver().List();
-
- string subMsg;
- if (!IsCompatible(localFeedingPaths, remoteFeedingPaths, out subMsg))
- {
- message = string.Format("Feeding: {0}", subMsg);
- return false;
- }
-
- if (!IsCompatible(localBenchPaths, remoteBenchPaths, out subMsg))
- {
- message = string.Format("Bench: {0}", subMsg);
- return false;
- }
-
- if (!IsCompatible(localOutputPaths, remoteOutputPaths, out subMsg))
- {
- message = string.Format("Output: {0}", subMsg);
- return false;
- }
-
- if (!IsCompatible(localMetersPaths, remoteMetersPaths, out subMsg))
- {
- message = string.Format("Sensors: {0}", subMsg);
- return false;
- }
-
- if (!IsCompatible(localTransitions, remoteTransitions, out subMsg))
- {
- message = string.Format("Transitions: {0}", subMsg);
- return false;
- }
-
- message = string.Empty;
- return true;
- }
-
- ///
- ///
- ///
- /// FeedingPath, BenchPath, OutputPath, MetersPath or TransitionSequence
- /// Local list of paths or transitions
- /// Remote list of paths or transitions
- /// Message specifying a cause of incompatibility
- /// true when lists are compatible, otherwise false
- private static bool IsCompatible(IList localList, IList remoteList, out string message)
- {
- message = "Local list is empty";
- if ((localList == null) || (localList.Count == 0) || !(localList[0] is IHasName)) return false;
-
- message = "Remote list is empty";
- if ((remoteList == null) || (remoteList.Count == 0) || !(remoteList[0] is IHasName)) return false;
-
- ///
- /// Each path or transition on a remote list must exist on a local list
- ///
- foreach (var rItem in remoteList)
- {
- bool exists = false;
- foreach (var lItem in localList)
- {
- if ((rItem as IHasName).Name == (lItem as IHasName).Name)
- {
- exists = true;
- break;
- }
- }
-
- if (!exists)
- {
- message = string.Format("Remote item {0} does not exist on a local list", (rItem as IHasName).Name);
- return false;
- }
- }
-
- message = string.Empty;
- return true;
- }
-
-
- ///
- /// Start the state machine
- ///
- public static void Start()
- {
- if (MachineState != MachineState.StartingUp)
- {
- /// Unexpected MachineState (not MachineState.StartingUp) --> prevent worker thread from starting
- ///
- MachineState = MachineState.FailedToStart;
- return;
- }
-
- workerThread = new Thread(Worker);
- workerThread.CurrentCulture = Thread.CurrentThread.CurrentCulture;
- workerThread.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
- workerThread.Start();
- }
-
- ///
- /// Loads all paths and transitions from the DB.
- /// Updates StatMachine.feedingPaths ... StatMachine.meterPaths, StatMachine.TransitionSequences
- ///
- public static void LoadPathsAndTransitions(ISession session)
- {
- feedingPaths = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
- benchPaths = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
- outputPaths = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
- metersPaths = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
- TransitionSequences = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
- TransitionSteps = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
-#if HEAT_METERS
- heatMetersPaths = session.QueryOver().OrderBy(x => x.ItemNr).Asc.List();
-#endif
- }
-
- ///
- /// Loads selected procedure from the DB.
- /// Updates StateMachine.Procedure and StateMachine.Tests
- ///
- public static bool LoadProcedure(ISession session, string procedureName, bool isRemote, IList autoTests = null)
- {
- Procedure = null;
-
- IList selectedProcs = session.QueryOver()
- .Where(x => (x.ProcedureState == Common.ProcedureState.Active))
- .And(x => (x.Name == procedureName))
- .List();
- if (selectedProcs.Count == 1)
- {
- IsRemoteProcedure = isRemote;
- Procedure = selectedProcs[0];
- TestInstances = selectedProcs[0].UpdateTestInstances(LoopStartNames, LoopEndNames, autoTests);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- public static void LoadProcedureParams(Procedure procedure)
- {
- foreach (var cmpnt in components)
- {
- cmpnt.Cfg.LoadProcedureParamsFromDB(procedure);
- }
- }
-
- public static void LoadTestParams(Test test)
- {
- foreach (var cmpnt in components)
- {
- cmpnt.Cfg.LoadTestParamsFromDB(test);
- }
- }
-
- ///
- /// Called from the sequence to update paths based on the selected test
- ///
- /// Selected test
- ///
- ///
- ///
- ///
- /// Transition sequence entity
- /// Transition sequence entity
- /// Error message in case of incorrect configuration
- /// true when loaded configuration is correct (all four paths are defined !=null, etc.)
- public static bool GetPaths(Test test,
- bool heatMetersPathRequired,
- out FeedingPath pfeed,
- out BenchPath pben,
- out OutputPath pout,
- out MetersPath pmtrs,
- out HeatMetersPath phmtrs,
- out TransitionSequence transitionBefore,
- out TransitionSequence transitionBetween,
- out TransitionSequence transitionAfter,
- out string errorMsg)
- {
- ITestMethod tm = TbfComponents.FindComponent(test.Method) as ITestMethod;
- bool isHydroTest = (tm != null) ? tm.DoTransitions() : false;
-
- pfeed = null;
- pben = null;
- pout = null;
- phmtrs = null;
- transitionBefore = null;
- transitionBetween = null;
- transitionAfter = null;
-
- foreach (var path in feedingPaths)
- {
- if (test.FeedingPath == path.Name) { pfeed = new FeedingPath(path, components); break; }
- }
-
- foreach (var path in benchPaths)
- {
- if (test.BenchPath == path.Name) { pben = new BenchPath(path, components); break; }
- }
-
- foreach (var path in outputPaths)
- {
- if (test.OutputPath == path.Name) { pout = new OutputPath(path, components); break; }
- }
-
- pmtrs = GetMetersPath(test);
-
- if (isHydroTest && (pfeed == null)) errorMsg = Strings.Cannot_load_feeding_path;
- else if (isHydroTest && (pben == null)) errorMsg = Strings.Cannot_load_bench_path;
- else if (isHydroTest && (pout == null)) errorMsg = Strings.Cannot_load_output_path;
- else if (pmtrs == null) errorMsg = Strings.Cannot_load_sensor_path;
- else errorMsg = string.Empty;
- if ((isHydroTest && (pfeed == null || pben == null || pout == null)) || (pmtrs == null))
- {
- log.ErrorFormat("GetPaths({0},...) returns false, wrong configuration", test.Name);
- return false;
- }
-
-#if HEAT_METERS
- foreach (var path in heatMetersPaths)
- {
- if (test.HeatMetersPath == path.Name) { phmtrs = new HeatMetersPath(path, components); break; }
- }
-#endif
- if (heatMetersPathRequired && phmtrs == null)
- {
- log.ErrorFormat("GetPaths({0},...) returns false, missing heat meters sensors", test.Name);
- errorMsg = "Cannot load heat meters sensors";
- return false;
- }
-
- foreach (var tr in TransitionSequences)
- {
- if (tr.Name == test.TransBefore) transitionBefore = tr;
- if (tr.Name == test.TransBetween) transitionBetween = tr;
- if (tr.Name == test.TransAfter) transitionAfter = tr;
- }
-
- if (isHydroTest && pout.Scale == null)
- {
- log.ErrorFormat("GetPaths({0},...) returns false, missing scales in output path {1}", test.Name, test.OutputPath);
- errorMsg = string.Format("No balance specified in path {0}", test.OutputPath);
- return false;
- }
-
- if (Config.Formulas.RealDensity() < 500.0f || Config.Formulas.RealDensity() > 2000.0f)
- {
- log.ErrorFormat("GetPaths({0},...) returns false, density was not specified", test.Name);
- errorMsg = string.Format("Density was not specified");
- return false;
- }
-
- log.WarnFormat("GetPaths({0},...) returns true, paths loaded OK, isHydroTest={1}", test.Name, isHydroTest);
- errorMsg = string.Empty;
- return true;
- }
-
-
- ///
- /// Updates paths based on the selected test
- ///
- public static MetersPath GetMetersPath(Test test)
- {
- MetersPath pmtrs = null;
- foreach (var path in metersPaths)
- {
- if (test.MetersPath == path.Name) { pmtrs = new MetersPath(path, components); break; }
- }
- if (pmtrs != null)
- {
- int count = Math.Min(TBF.Data.WMsCount, pmtrs.RegisterReaders.Length);
- for (int i = 0; i < count; i++)
- {
- if ((pmtrs.RegisterReaders[i] != null) &&
- (pmtrs.RegisterReaders[i].Cfg.DebugLevel == DebugMode.DetectedOff))
- {
- pmtrs.RegisterReaders[i] = null;
- }
- }
- }
- return pmtrs;
- }
-
-
- /*
- * This is and example sequence of RunDeviceBefore() / RunOperations() / RunDeviceAfter() calls
- * as they are executed during normal run from the progran start to the end.
- *
- foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in StateMachine.Worker()
- State.Create(...).AddOperation(...).AddOperation(...).EnterState() . . in the sequence in Execute(...)
-
- foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
- WaitNextTick() (may throw QuitStateMachineException) . . . . . . . . in WaitRunDevsRunOps()
- foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in WaitRunDevsRunOps()
- IList events = State.RunOperations(); . . . . . . . . . . . . . in WaitRunDevsRunOps()
-
- foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
- WaitNextTick() (may throw QuitStateMachineException) . . . . . . . . in WaitRunDevsRunOps()
- foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in WaitRunDevsRunOps()
- IList events = State.RunOperations(); . . . . . . . . . . . . . in WaitRunDevsRunOps()
-
- State.Create(...).AddOperation(...).AddOperation(...).EnterState() . . in the sequence in Execute(...)
-
- foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
- WaitNextTick() (may throw QuitStateMachineException) . . . . . . . . in WaitRunDevsRunOps()
- foreach (var device in devices) device.RunDeviceBefore(); . . . . . . in WaitRunDevsRunOps()
- IList events = State.RunOperations(); . . . . . . . . . . . . . in WaitRunDevsRunOps()
-
- foreach (var device in devices) device.RunDeviceAfter(); . . . . . . . in WaitRunDevsRunOps()
- WaitNextTick() (assume QuitStateMachineException thrown) . . . . . . in WaitRunDevsRunOps()
- State.StopOperations(); . . . . . . . . . . . . . . . . . . . . . . . in StateMachine.Worker() catch()
- foreach (var device in devices) device.StopDevice(); . . . . . . . . . in StateMachine.Worker() catch()
- */
-
- ///
- /// Worker thread: calls Start(), Run() and Stop() methods of operations.
- /// It uses 'currentState', 'nextState' and 'quitStateMachine' static fields.
- ///
- static void Worker()
- {
- MachineState = MachineState.Running;
- startDateTime = DateTime.Now;
- CycleStartTimeStamp = startDateTime; /// Do not leave CycleStartTimeStamp uninitialized
- wlog.InfoFormat(" currentTime = {0}s startDateTime = {1}", currentTimeSec.ToString(), startDateTime.ToString());
-
- /// Run all devices for the first time
- foreach (var device in devices) device.RunDeviceBefore();
-
- SequenceBase.ReferenceFlowmetersCount = SequenceBase.FlowMeters.Count;
- SequenceBase.CalibratedLtrPerRefPulse = new double[SequenceBase.ReferenceFlowmetersCount];
- foreach (var flowmtr in SequenceBase.FlowMeters)
- {
- int ix = flowmtr.Idx1;
- if (ix > 0 && ix <= SequenceBase.ReferenceFlowmetersCount)
- {
- SequenceBase.CalibratedLtrPerRefPulse[ix - 1] = flowmtr.NominalFlow / 7200.0;
- }
- }
-
- ///
- /// Run the main sequence
- ///
- (new Sequences.MainSeq()).Execute();
-
- StateMachine.MachineState = MachineState.Off; /// Update StateMachine.MachineState
- TBF.UiBridge.Bridge.Bench2UI(TBF.UiBridge.ButtonsEtc.Shutdown); /// Let UI know the state machine is shut down now
- }
-
-
- ///
- /// Do stuff that is repeated in the state execution loops most often
- ///
- /// List of Event-s returned from the state operations, null == quit
- public static IList WaitRunDevsRunOps(bool lastTime = false)
- {
- Thread.Sleep(100); /// Insert 1/10 sec.delay between RunOperations() and RunDeviceAfter()
-
- for (int i = devices.Count - 1; i >= 0; i-- )
- {
- devices[i].RunDeviceAfter();
- }
-
- WaitNextTick();
-
- if (lastTime)
- {
- ///
- /// Executed when the state machine is being stopped
- ///
- State.StopOperations();
- return null;
- }
-
- foreach (var device in devices)
- {
- device.RunDeviceBefore();
- }
-
- Thread.Sleep(100); /// Insert 1/10 sec.delay between RunDeviceBefore() and RunOperations()
-
- return State.RunOperations(); /// Returns events from all running operations
- /// This is followed by a state change in the sequence
- }
-
-
- ///
- /// Wait time period - synchronize
- ///
- /// true when interrupted by 'quitStateMachine', otherwise false
- public static void WaitNextTick()
- {
- int currentTimeSecFromClock = Convert.ToInt32(Math.Round((DateTime.Now - startDateTime).TotalSeconds - 0.2));
-
- currentTimeSec = Math.Max(currentTimeSec, currentTimeSecFromClock) + Period;
-
- DateTime nextTickDateTime = startDateTime + TimeSpan.FromSeconds(currentTimeSec);
-
- while (DateTime.Now < nextTickDateTime)
- {
- Thread.Sleep(100);
- }
- }
- }
-}
diff --git a/TBF/Rig/Sequences/ProcessData.cs b/TBF/Rig/Sequences/ProcessData.cs
index a93fd6dc9..749b30019 100644
--- a/TBF/Rig/Sequences/ProcessData.cs
+++ b/TBF/Rig/Sequences/ProcessData.cs
@@ -30,6 +30,13 @@ namespace TBF.Rig.Sequences
public static int LinesCount { get { return TBF.Data.WMsCount / TBF.Data.LineSize; } }
public static int LineSize { get { return TBF.Data.LineSize; } }
public static int CompoundWMsCount { get { return TBF.Data.CompoundWMsCount; } }
+ ///
+ public static Unit VolumeUnit { get { return BenchInfo != null ? BenchInfo.VolumeUnit : Unit.l; } }
+ public static Unit FlowUnit { get { return BenchInfo != null ? BenchInfo.FlowUnit : Unit.m3ph; } }
+ public static Unit MassUnit { get { return BenchInfo != null ? BenchInfo.MassUnit : Unit.kg; } }
+ public static Unit TempUnit { get { return BenchInfo != null ? BenchInfo.TempUnit : Unit.C; } }
+ public static Unit PressUnit { get { return BenchInfo != null ? BenchInfo.PressUnit : Unit.bar; } }
+ public static Unit LengthUnit { get { return BenchInfo != null ? BenchInfo.LengthUnit : Unit.mm; } }
///
/// Procedure related state variables