diff --git a/TestBenchFramework/BenchControl/Elde/ControlBoardDev.cs b/TestBenchFramework/BenchControl/Elde/ControlBoardDev.cs index 978ce7ced..0822349f5 100644 --- a/TestBenchFramework/BenchControl/Elde/ControlBoardDev.cs +++ b/TestBenchFramework/BenchControl/Elde/ControlBoardDev.cs @@ -510,7 +510,7 @@ ControlComponent_Izrael2014.UserControl1 ctrlBrdComponent, /// Created operation public IOperation SetValvesOp(IValve valveOpen, IValve valveClose) { - return new Valve.SetValvesOp(this, valveOpen, valveClose); + return new SetValvesOp(this, valveOpen, valveClose); } /// @@ -522,7 +522,7 @@ ControlComponent_Izrael2014.UserControl1 ctrlBrdComponent, /// Created operation public IOperation SetValvesOp(IList valvesOpen, IList valvesClose) { - return new Valve.SetValvesOp(this, valvesOpen, valvesClose); + return new SetValvesOp(this, valvesOpen, valvesClose); } /// diff --git a/TestBenchFramework/BenchControl/Elde/Valve/SetValvesOp.cs b/TestBenchFramework/BenchControl/Elde/SetValvesOp.cs similarity index 82% rename from TestBenchFramework/BenchControl/Elde/Valve/SetValvesOp.cs rename to TestBenchFramework/BenchControl/Elde/SetValvesOp.cs index 883c675b8..9f1608e2a 100644 --- a/TestBenchFramework/BenchControl/Elde/Valve/SetValvesOp.cs +++ b/TestBenchFramework/BenchControl/Elde/SetValvesOp.cs @@ -1,5 +1,5 @@ /// -/// Copyright (c) 2013-2016 Sensus Metering Systems +/// Copyright (c) 2013-2017 Sensus Metering Systems /// using System; using System.Collections.Generic; @@ -7,7 +7,7 @@ using log4net; using TBF.BenchControl.GenericDevices; using Dirichlet.Numerics; -namespace TBF.BenchControl.Elde.Valve +namespace TBF.BenchControl.Elde { public class SetValvesOp : IOperation { @@ -21,8 +21,8 @@ namespace TBF.BenchControl.Elde.Valve public int TimeSec; /// Relative time in [s] from the start of the operation public IList VOpen; /// List of valves to open in this point of time public IList VClose; /// List of valves to close in this point of time - public UInt128 MasksOpen; /// OR-ed bitmasks of valves to open in this point of time - public UInt128 MasksClose; /// OR-ed bitmasks of valves to close in this point of time + public UInt128 MasksOpen; /// OR-ed bitmasks of valves to open in this point of time + public UInt128 MasksClose; /// OR-ed bitmasks of valves to close in this point of time public SwitchPoint(int time, IList vOpen, IList vClose) { @@ -42,9 +42,9 @@ namespace TBF.BenchControl.Elde.Valve foreach (var vlv in VOpen) { /// Skip the delay evaluation and update in case the valve/pump have not changed - if (vlv is Valve && ((vlv as Valve).Mask & changed) == 0) continue; - if (vlv is Pump.Pump && ((vlv as Pump.Pump).Mask & changed) == 0) continue; - if (vlv is PumpWithFM.Pump && ((vlv as PumpWithFM.Pump).Mask & changed) == 0) continue; + if (vlv is Valve.Valve && ((vlv as Valve.Valve).Mask & changed) == 0) continue; + if (vlv is Pump.Pump && ((vlv as Pump.Pump).Mask & changed) == 0) continue; + if (vlv is PumpWithFM.Pump && ((vlv as PumpWithFM.Pump).Mask & changed) == 0) continue; if (vlv is Danfoss.VLT2800.Pump && ((vlv as Danfoss.VLT2800.Pump).Mask & changed) == 0) continue; if ((vlv != null) && (vlv.Delay > max)) max = vlv.Delay; @@ -52,9 +52,9 @@ namespace TBF.BenchControl.Elde.Valve foreach (var vlv in VClose) { /// Skip the delay evaluation and update in case the valve/pump have not changed - if (vlv is Valve && ((vlv as Valve).Mask & changed) == 0) continue; - if (vlv is Pump.Pump && ((vlv as Pump.Pump).Mask & changed) == 0) continue; - if (vlv is PumpWithFM.Pump && ((vlv as PumpWithFM.Pump).Mask & changed) == 0) continue; + if (vlv is Valve.Valve && ((vlv as Valve.Valve).Mask & changed) == 0) continue; + if (vlv is Pump.Pump && ((vlv as Pump.Pump).Mask & changed) == 0) continue; + if (vlv is PumpWithFM.Pump && ((vlv as PumpWithFM.Pump).Mask & changed) == 0) continue; if (vlv is Danfoss.VLT2800.Pump && ((vlv as Danfoss.VLT2800.Pump).Mask & changed) == 0) continue; if ((vlv != null) && (vlv.Delay > max)) max = vlv.Delay; @@ -152,20 +152,20 @@ namespace TBF.BenchControl.Elde.Valve point.MasksOpen = 0; foreach (var valve in point.VOpen) { - if (valve is Valve) point.MasksOpen |= (valve as Valve).Mask; - if (valve is Pump.Pump) point.MasksOpen |= (valve as Pump.Pump).Mask; - if (valve is PumpWithFM.Pump) point.MasksOpen |= (valve as PumpWithFM.Pump).Mask; + if (valve is Valve.Valve) point.MasksOpen |= (valve as Valve.Valve).Mask; + if (valve is Pump.Pump) point.MasksOpen |= (valve as Pump.Pump).Mask; + if (valve is PumpWithFM.Pump) point.MasksOpen |= (valve as PumpWithFM.Pump).Mask; if (valve is Danfoss.VLT2800.Pump) point.MasksOpen |= (valve as Danfoss.VLT2800.Pump).Mask; - if (valve is PumpTandem.Pump) point.MasksOpen |= (valve as PumpTandem.Pump).Mask; + if (valve is PumpTandem.Pump) point.MasksOpen |= (valve as PumpTandem.Pump).Mask; } point.MasksClose = 0; foreach (var valve in point.VClose) { - if (valve is Valve) point.MasksClose |= (valve as Valve).Mask; - if (valve is Pump.Pump) point.MasksClose |= (valve as Pump.Pump).Mask; - if (valve is PumpWithFM.Pump) point.MasksClose |= (valve as PumpWithFM.Pump).Mask; + if (valve is Valve.Valve) point.MasksClose |= (valve as Valve.Valve).Mask; + if (valve is Pump.Pump) point.MasksClose |= (valve as Pump.Pump).Mask; + if (valve is PumpWithFM.Pump) point.MasksClose |= (valve as PumpWithFM.Pump).Mask; if (valve is Danfoss.VLT2800.Pump) point.MasksClose |= (valve as Danfoss.VLT2800.Pump).Mask; - if (valve is PumpTandem.Pump) point.MasksClose |= (valve as PumpTandem.Pump).Mask; + if (valve is PumpTandem.Pump) point.MasksClose |= (valve as PumpTandem.Pump).Mask; } point.TimeSec += timeShift; } diff --git a/TestBenchFramework/BenchControl/GenericDevices/ITankDraining.cs b/TestBenchFramework/BenchControl/GenericDevices/ITankDraining.cs index f1a6b8a71..854a1144a 100644 --- a/TestBenchFramework/BenchControl/GenericDevices/ITankDraining.cs +++ b/TestBenchFramework/BenchControl/GenericDevices/ITankDraining.cs @@ -8,7 +8,8 @@ using System.Text; namespace TBF.BenchControl.GenericDevices { - public interface ITankDraining + public interface ITankDraining : ISequenceCondition { + bool IsEmpty(); } } diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs index e9fa788d1..0816fc839 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs @@ -30,6 +30,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard protected readonly BalanceCfg balanceCfg; + GenericDevices.IValve drainValve; + /// /// Enumeration of balances via static fields and methods /// @@ -97,11 +99,15 @@ namespace TBF.BenchControl.MettlerToledo.Standard Balances[nextBalanceIdx - 1] = this; } + drainValve = TbfComponents.FindComponent(balanceCfg.DrainValve) as GenericDevices.IValve; + log.Debug(this.ToString()); } public void Initialize() { + base.Initalize(drainValve); + msrmntState = MsrmntState.Failed; /// Data not valid yet if (balanceCfg.DebugLevel == DebugMode.Simulate) return; @@ -115,7 +121,12 @@ namespace TBF.BenchControl.MettlerToledo.Standard log.FatalFormat("Successfully initialized device {0}", ToString()); } - public bool IsEmpty() + public override string GetName() + { + return Name; + } + + public override bool IsEmpty() { return (this.mass <= balanceCfg.Empty); } @@ -242,6 +253,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard /// public virtual void RunDeviceBefore() { + base.RunBefore(); + if (balanceCfg.DebugLevel == DebugMode.Simulate) { Masses[balanceNr] = TestBenchSim.GetSimMass(balanceNr); @@ -442,7 +455,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard /// Run this device public void RunDeviceAfter() { - } + base.RunAfter(); + } /// Stop this device public void StopDevice() diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceNewDev.cs b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceNewDev.cs index 9878e81c7..dca2635f4 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceNewDev.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceNewDev.cs @@ -67,6 +67,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard /// public override void RunDeviceBefore() { + base.RunBefore(); + if (balanceCfg.DebugLevel == DebugMode.Simulate) { mass = TestBenchSim.GetSimMass(balanceNr); diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceOld.cs b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceOld.cs index 3a8c8c61b..5e78bcb0f 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceOld.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceOld.cs @@ -61,6 +61,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard /// public override void RunDeviceBefore() { + base.RunBefore(); + if (balanceCfg.DebugLevel == DebugMode.Simulate) { mass = TestBenchSim.GetSimMass(balanceNr); diff --git a/TestBenchFramework/BenchControl/MettlerToledo/TankDraining.cs b/TestBenchFramework/BenchControl/MettlerToledo/TankDraining.cs index 639d2d0fb..8312ee619 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/TankDraining.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/TankDraining.cs @@ -2,25 +2,153 @@ /// Copyright (c) 2017 Sensus Metering Systems /// using System; +using System.Collections.Generic; +using log4net; +using TBF.BenchControl.GenericDevices; +using TBF.Resources; namespace TBF.BenchControl.MettlerToledo { - public class TankDraining : ComponentBase + public enum DrainState { - public GenericDevices.IValve DrainValve; + None, + OpeningDV_Start, + OpeningDV_Run, + OpeningDV_Stop, + Draining, + ClosingDV_Start, + ClosingDV_Run, + ClosingDV_Stop, + TankClosed, + } + + public class TankDraining : ComponentBase, ITankDraining + { + private static readonly ILog log = LogManager.GetLogger(typeof(TankDraining)); + + + readonly GenericDevices.ITankDrainingCfg tankDrainingCfg; + + private IValve drainValve; + private IOperation openDrainValveOp; + private IOperation closeDrainValveOp; + + + DrainState drainState; - GenericDevices.ITankDrainingCfg tankManagementCfg; public TankDraining() : base() { + CreateConditions(false); } public TankDraining(Generic.IComponentCfg cfg) : base(cfg) { - tankManagementCfg = cfg as GenericDevices.ITankDrainingCfg; - if (tankManagementCfg == null) throw new Exception(string.Format("Cannot create component {0}", cfg.Name)); + tankDrainingCfg = cfg as GenericDevices.ITankDrainingCfg; + if (tankDrainingCfg == null) throw new Exception(string.Format("Cannot create component {0}", cfg.Name)); + CreateConditions(true); + } + + protected void Initalize(IValve drainValve) + { + this.drainValve = drainValve; + openDrainValveOp = new Elde.SetValvesOp(StateMachine.ControlBoard, drainValve, null); + closeDrainValveOp = new Elde.SetValvesOp(StateMachine.ControlBoard, null, drainValve); + } + + protected void RunBefore() + { + switch (drainState) + { + case DrainState.OpeningDV_Start: + openDrainValveOp.Start(); + drainState = DrainState.OpeningDV_Run; + return; + + case DrainState.OpeningDV_Run: + if (openDrainValveOp.Run() == Event.ValvesSet) drainState = DrainState.OpeningDV_Stop; + return; + + case DrainState.OpeningDV_Stop: + openDrainValveOp.Stop(); + return; + + case DrainState.Draining: + if (IsEmpty()) drainState = DrainState.ClosingDV_Start; + return; + + case DrainState.ClosingDV_Start: + closeDrainValveOp.Start(); + drainState = DrainState.ClosingDV_Run; + return; + + case DrainState.ClosingDV_Run: + if (closeDrainValveOp.Run() == Event.ValvesSet) drainState = DrainState.ClosingDV_Stop; + return; + + case DrainState.ClosingDV_Stop: + closeDrainValveOp.Stop(); + return; + + default: + return; + } + } + + protected void RunAfter() { } /// Not used + + + public virtual string GetName() { return string.Empty; } + public virtual bool IsEmpty() { return false; } + + /// + /// ISequenceCondition interface implementation (conditions in transition sequences) + /// + IList sequenceConditionNames; + IList sequenceConditions; + + public int ConditionsCount { get { return sequenceConditions != null ? sequenceConditions.Count : 0; } } + + /// Strings are added to the combo-box for transition sequence condition selection + public string ConditionName(int i) + { + if (sequenceConditionNames != null && i < sequenceConditionNames.Count && i >= 0) + return sequenceConditionNames[i]; + else + return string.Empty; + } + + /// Operations are executed as a part of a transition sequence + public IOperation ConditionOp(int i) + { + if (sequenceConditions != null && i < sequenceConditions.Count && i >= 0) + return sequenceConditions[i]; + else + return null; + } + + void ClearConditions() + { + sequenceConditionNames = new List(); + sequenceConditions = new List(); + } + + void AddCondition(string conditionName, bool createOperation, IOperation conditionOperation) + { + sequenceConditionNames.Add(conditionName); + if (createOperation) sequenceConditions.Add(conditionOperation); + } + + /// + /// Create a list of conditions + /// + /// true = create names and condition operations, false = create names only + void CreateConditions(bool createOps) + { + ClearConditions(); + AddCondition(string.Format(Strings.Wait_until_0_tank_is_empty, GetName()), createOps, new WaitTankEmptyOp(this)); } } } diff --git a/TestBenchFramework/BenchControl/MettlerToledo/WaitTankEmptyOp.cs b/TestBenchFramework/BenchControl/MettlerToledo/WaitTankEmptyOp.cs new file mode 100644 index 000000000..9c770e667 --- /dev/null +++ b/TestBenchFramework/BenchControl/MettlerToledo/WaitTankEmptyOp.cs @@ -0,0 +1,50 @@ +/// +/// Copyright (c) 2017 Sensus Metering Systems +/// +using log4net; + +namespace TBF.BenchControl.MettlerToledo +{ + public class WaitTankEmptyOp : IOperation + { + private static readonly ILog log = LogManager.GetLogger(typeof(WaitTankEmptyOp)); + public override string ToString() { return string.Format("WaitTankEmptyOp()"); } + + readonly GenericDevices.ITankDraining tankDraining; + + bool conditionMet; + + /// + /// Events: ConditionMet, ConditionNotMet + /// + /// Tank draining (Balance device) instance + public WaitTankEmptyOp(GenericDevices.ITankDraining tankDraining) + { + this.tankDraining = tankDraining; + log.Debug(this.ToString()); + } + + /// Start this operation + public void Start() + { + conditionMet = tankDraining.IsEmpty(); + } + + /// Run this operation + /// + /// Event.ConditionMet . . . tank is empty + /// Event.ConditionNotMet . tank is not empty + /// + public Event Run() + { + conditionMet = conditionMet || tankDraining.IsEmpty(); + + return conditionMet ? Event.ConditionMet : Event.ConditionNotMet; + } + + /// Stop this operation + public void Stop() + { + } + } +} diff --git a/TestBenchFramework/BenchControl/Modbus/TankSelector/TankSelector.cs b/TestBenchFramework/BenchControl/Modbus/TankSelector/TankSelector.cs index 4082b1f08..7acbbb8a0 100644 --- a/TestBenchFramework/BenchControl/Modbus/TankSelector/TankSelector.cs +++ b/TestBenchFramework/BenchControl/Modbus/TankSelector/TankSelector.cs @@ -298,26 +298,18 @@ namespace TBF.BenchControl.Modbus.TankSelector public string ConditionName(int i) { if (sequenceConditionNames != null && i < sequenceConditionNames.Count && i >= 0) - { return sequenceConditionNames[i]; - } else - { return string.Empty; - } } /// Operations are executed as a part of a transition sequence public IOperation ConditionOp(int i) { if (sequenceConditions != null && i < sequenceConditions.Count && i >= 0) - { return sequenceConditions[i]; - } else - { return null; - } } void ClearConditions() diff --git a/TestBenchFramework/Resources/Strings.Designer.cs b/TestBenchFramework/Resources/Strings.Designer.cs index 032b3961a..3da3ea667 100644 --- a/TestBenchFramework/Resources/Strings.Designer.cs +++ b/TestBenchFramework/Resources/Strings.Designer.cs @@ -4662,6 +4662,15 @@ namespace TBF.Resources { } } + /// + /// Looks up a localized string similar to Wait until {0} tank is empty. + /// + internal static string Wait_until_0_tank_is_empty { + get { + return ResourceManager.GetString("Wait_until_0_tank_is_empty", resourceCulture); + } + } + /// /// Looks up a localized string similar to Warning. /// diff --git a/TestBenchFramework/Resources/Strings.de.resx b/TestBenchFramework/Resources/Strings.de.resx index 8ba9b581e..83d1c6a1a 100644 --- a/TestBenchFramework/Resources/Strings.de.resx +++ b/TestBenchFramework/Resources/Strings.de.resx @@ -1392,4 +1392,7 @@ Neue Q + + Warten bis {0} Behälter ist leer + \ No newline at end of file diff --git a/TestBenchFramework/Resources/Strings.resx b/TestBenchFramework/Resources/Strings.resx index 21c79a462..2219268b3 100644 --- a/TestBenchFramework/Resources/Strings.resx +++ b/TestBenchFramework/Resources/Strings.resx @@ -1693,4 +1693,7 @@ New Q + + Wait until {0} tank is empty + \ No newline at end of file diff --git a/TestBenchFramework/TBF.csproj b/TestBenchFramework/TBF.csproj index 51bc9601b..678414330 100644 --- a/TestBenchFramework/TBF.csproj +++ b/TestBenchFramework/TBF.csproj @@ -425,6 +425,7 @@ + @@ -507,6 +508,7 @@ + @@ -1341,7 +1343,6 @@ -