tbf/TestBenchFramework/BenchControl/Modbus/TankSelector/TankSelector.cs
2017-03-10 12:54:18 +01:00

278 lines
10 KiB
C#

///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.Generic;
using TBF.BenchControl.GenericDevices;
using TBF.Boxes;
using TBF.Resources;
namespace TBF.BenchControl.Modbus.TankSelector
{
/// <summary> Enumeration of water tanks </summary>
public enum TankId
{
None,
Cold,
Warm,
Hot,
}
/// <summary> Enumeration of water tanks activities</summary>
public enum Activity
{
Unknown,
Idle,
Selected_Waiting1min,
Selected,
Unselected_WaitingLevel,
}
/// <summary> TankSelector state </summary>
public enum State
{
Unknown, /// Initial state after program startup
NoTankSelected,
ColdTankSelected_Waiting1min,
ColdTankSelected,
ColdTankUnselected_WaitingLevel,
WarmTankSelected_Waiting1min,
WarmTankSelected,
WarmTankUnselected_WaitingLevel,
HotTankSelected_Waiting1min,
HotTankSelected,
HotTankUnselected_WaitingLevel,
}
/// <summary> Quido digital out board outputs assignment </summary>
public enum QuidoOutputs : ushort
{
None = 0,
SelectColdTank = 0x0001, /// Quido out 1
SelectWarmTank = 0x0002, /// Quido out 2
SelectHotTank = 0x0004, /// Quido out 3
PumpToColdTank = 0x0008, /// Quido out 4
PumpToWarmTank = 0x0010, /// Quido out 5
PumpToHotTank = 0x0020, /// Quido out 6
Mixing = 0x0040, /// Quido out 7
HeatingHotTank = 0x0080, /// Quido out 8
HeatingWarmTank = 0x0100, /// Quido out 9
CoolingHotTank = 0x0200, /// Quido out 10
CoolingWarmTank = 0x0400, /// Quido out 11
CoolingColdTank = 0x0800, /// Quido out 12
}
public class TankSelector : ComponentBase, ISequenceCondition, IDevice
{
private static readonly ILog log = LogManager.GetLogger(typeof(TankSelector));
public override string ToString() { return string.Format("TankSelector({0})", Cfg.ToString(1)); }
readonly TankSelectorCfg tankSelectorCfg;
readonly TBF.BenchControl.Modbus.QuidoRS.QuidoRS quidoRS;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm hotHeating;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm hotCooling;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm warmHeating;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm warmCooling;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm coldCooling;
public State State;
public TankId CurrentTank { get { return GetTankIdFromState(State); } }
public Activity CurrentActivity { get { return GetActivityFromState(State); } }
public TankId GetTankIdFromState(State state)
{
switch (state)
{
case State.ColdTankSelected_Waiting1min:
case State.ColdTankSelected:
case State.ColdTankUnselected_WaitingLevel:
return TankId.Cold;
case State.WarmTankSelected_Waiting1min:
case State.WarmTankSelected:
case State.WarmTankUnselected_WaitingLevel:
return TankId.Warm;
case State.HotTankSelected_Waiting1min:
case State.HotTankSelected:
case State.HotTankUnselected_WaitingLevel:
return TankId.Hot;
default:
return TankId.None;
}
}
public Activity GetActivityFromState(State state)
{
switch (state)
{
case State.NoTankSelected:
return Activity.Idle;
case State.ColdTankSelected_Waiting1min:
case State.WarmTankSelected_Waiting1min:
case State.HotTankSelected_Waiting1min:
return Activity.Selected_Waiting1min;
case State.ColdTankSelected:
case State.WarmTankSelected:
case State.HotTankSelected:
return Activity.Selected;
case State.ColdTankUnselected_WaitingLevel:
case State.WarmTankUnselected_WaitingLevel:
case State.HotTankUnselected_WaitingLevel:
return Activity.Unselected_WaitingLevel;
default:
return Activity.Unknown;
}
}
public TankSelector()
{
CreateConditions(false);
}
public TankSelector(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
tankSelectorCfg = cfg as TankSelectorCfg;
quidoRS = (TBF.BenchControl.Modbus.QuidoRS.QuidoRS)TbfComponents.FindComponent(cfg.ParentName, components);
if (quidoRS == null) throw new Exception(string.Format("Cannot find parent '{0}' of the component {1}", cfg.ParentName, Name));
hotHeating = (TBF.BenchControl.Modbus.Easytherm.Easytherm)TbfComponents.FindComponent(tankSelectorCfg.HotWaterHeating, components);
hotCooling = (TBF.BenchControl.Modbus.Easytherm.Easytherm)TbfComponents.FindComponent(tankSelectorCfg.HotWaterCooling, components);
warmHeating = (TBF.BenchControl.Modbus.Easytherm.Easytherm)TbfComponents.FindComponent(tankSelectorCfg.WarmWaterHeating, components);
warmCooling = (TBF.BenchControl.Modbus.Easytherm.Easytherm)TbfComponents.FindComponent(tankSelectorCfg.WarmWaterCooling, components);
coldCooling = (TBF.BenchControl.Modbus.Easytherm.Easytherm)TbfComponents.FindComponent(tankSelectorCfg.ColdWaterCooling, components);
if (hotHeating == null) throw new Exception(string.Format("Component '{0}' cannot find temperature controller '{1}'", Name, tankSelectorCfg.HotWaterHeating));
if (hotCooling == null) throw new Exception(string.Format("Component '{0}' cannot find temperature controller '{1}'", Name, tankSelectorCfg.HotWaterCooling));
if (warmHeating == null) throw new Exception(string.Format("Component '{0}' cannot find temperature controller '{1}'", Name, tankSelectorCfg.WarmWaterHeating));
if (warmCooling == null) throw new Exception(string.Format("Component '{0}' cannot find temperature controller '{1}'", Name, tankSelectorCfg.WarmWaterCooling));
if (coldCooling == null) throw new Exception(string.Format("Component '{0}' cannot find temperature controller '{1}'", Name, tankSelectorCfg.ColdWaterCooling));
CreateConditions(true);
State = State.Unknown;
log.Debug(this.ToString());
}
///
/// IDevice interface implementation
///
public void Initialize()
{
SetOutputs(0);
}
public void RunDeviceBefore()
{
}
public void RunDeviceAfter() {}
public void StopDevice() {}
///
/// Quido wrappers
///
public void SetOutputs(ushort outputs) { quidoRS.SetOutputs(outputs); }
public void SetBit(ushort bitMask) { quidoRS.SetBit(bitMask); }
public void ResetBit(ushort bitMask) { quidoRS.ResetBit(bitMask); }
///
/// ISequenceCondition interface implementation (conditions in transition sequences)
///
IList<string> sequenceConditionNames;
IList<IOperation> 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<string>();
sequenceConditions = new List<IOperation>();
}
void AddCondition(string conditionName, bool createOperation, IOperation conditionOperation)
{
sequenceConditionNames.Add(conditionName);
if (createOperation) sequenceConditions.Add(conditionOperation);
}
/// <summary>
/// Create a list of conditions
/// </summary>
/// <param name="createOps">true = create names and condition operations, false = create names only</param>
void CreateConditions(bool createOps)
{
ClearConditions();
AddCondition(Strings.Select_COLD_tank, createOps, new SelectTankOp(this, TankId.Cold));
AddCondition(Strings.Select_WARM_tank, createOps, new SelectTankOp(this, TankId.Warm));
AddCondition(Strings.Select_HOT_tank, createOps, new SelectTankOp(this, TankId.Hot));
AddCondition(Strings.Unselect_current_tank, createOps, new UnselectTankOp(this));
AddCondition(Strings.Set_hot_water_heating_temperature, createOps, hotHeating.SetRequiredTemperatureOp());
AddCondition(Strings.Set_hot_water_cooling_temperature, createOps, hotCooling.SetRequiredTemperatureOp());
AddCondition(Strings.Set_warm_water_heating_temperature, createOps, warmHeating.SetRequiredTemperatureOp());
AddCondition(Strings.Set_warm_water_cooling_temperature, createOps, warmCooling.SetRequiredTemperatureOp());
AddCondition(Strings.Set_cold_water_cooling_temperature, createOps, coldCooling.SetRequiredTemperatureOp());
AddCondition("Start heating hot water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.HeatingHotTank, true));
AddCondition("Stop heating hot water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.HeatingHotTank, false));
AddCondition("Start cooling hot water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.CoolingHotTank, true));
AddCondition("Stop cooling hot water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.CoolingHotTank, false));
AddCondition("Start heating warm water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.HeatingWarmTank, true));
AddCondition("Stop heating warm water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.HeatingWarmTank, false));
AddCondition("Start cooling warm water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.CoolingWarmTank, true));
AddCondition("Stop cooling warm water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.CoolingWarmTank, false));
AddCondition("Start cooling cold water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.CoolingColdTank, true));
AddCondition("Stop cooling cold water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.CoolingColdTank, false));
AddCondition("Start mixing water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.Mixing, true));
AddCondition("Stop mixing water", createOps, new SetQuidoBitOp(quidoRS, QuidoOutputs.Mixing, false));
}
}
}