More TankSelector modifications, ver. 2.12.491

This commit is contained in:
Milan Hanajik 2017-03-10 09:49:05 +01:00
parent d2bed417f1
commit 20fce538de
8 changed files with 306 additions and 185 deletions

View File

@ -1,37 +1,93 @@

///
/// Copyright (c) 2017 Sensus Metering Systems
///
namespace TBF.BenchControl.Modbus.TankSelector
{
public class SelectTankOp : IOperation
{
TankSelector tankSelector;
int tankNo;
TankId tankId;
ushort bitMask;
ushort unselectBitMask;
bool alreadySet;
bool unselectedWaitLevel;
bool doUnselect;
int time;
public SelectTankOp(TankSelector tankSelector, int tankNo)
public SelectTankOp(TankSelector tankSelector, TankId tankId)
{
this.tankSelector = tankSelector;
this.tankNo = tankNo;
this.bitMask = (ushort)((tankNo == 1) ? 1 : ((tankNo == 2) ? 2 : ((tankNo == 3) ? 4 : 0)));
this.tankId = tankId; /// tankId is always TankId.Cold, TankId.Warm or TankId.Hot
this.bitMask = (ushort)((tankId == TankId.Cold) ? QuidoOutputs.SelectColdTank
: (tankId == TankId.Warm) ? QuidoOutputs.SelectWarmTank
: QuidoOutputs.SelectHotTank);
}
/// <summary>Start this operation</summary>
public void Start()
{
if (tankSelector.CurrentlySelectedTankValid && (tankNo == tankSelector.CurrentlySelectedTank))
if (tankSelector.CurrentActivity == Activity.Selected && tankSelector.CurrentTank == tankId)
{
alreadySet = true;
alreadySet = true; /// Nothing to be done in Run()
unselectedWaitLevel = false;
doUnselect = false;
}
else
else if (tankSelector.CurrentActivity == Activity.Selected_Waiting1min && tankSelector.CurrentTank == tankId)
{
tankSelector.CurrentlySelectedTank = tankNo;
tankSelector.CurrentlySelectedTankValid = true;
alreadySet = false;
time = 0;
tankSelector.QuidoRS.SetBit(bitMask);
unselectedWaitLevel = false;
doUnselect = false;
time = 1; /// Skip resetting button bit in Run(), wait 1 min.
}
else if (tankSelector.CurrentActivity == Activity.Idle ||
tankSelector.CurrentActivity == Activity.Unknown)
{
SelectTankFromIdleState();
}
else if (tankSelector.CurrentActivity == Activity.Unselected_WaitingLevel)
{
alreadySet = false;
unselectedWaitLevel = true;
doUnselect = false;
}
else if (tankSelector.CurrentActivity == Activity.Selected ||
tankSelector.CurrentActivity == Activity.Selected_Waiting1min)
{
///
/// it follows that (tankSelector.CurrentTank != tankId) => unselect the tank first
///
alreadySet = false;
unselectedWaitLevel = false;
doUnselect = true;
TankId selectedTankId = tankSelector.CurrentTank;
unselectBitMask = (ushort)((selectedTankId == TankId.Cold) ? QuidoOutputs.PumpToColdTank
: (selectedTankId == TankId.Warm) ? QuidoOutputs.PumpToWarmTank
: QuidoOutputs.PumpToHotTank);
tankSelector.State = (selectedTankId == TankId.Cold) ? State.ColdTankUnselected_WaitingLevel
: (selectedTankId == TankId.Warm) ? State.WarmTankUnselected_WaitingLevel
: State.HotTankUnselected_WaitingLevel;
tankSelector.ResetBit(unselectBitMask);
}
}
void SelectTankFromIdleState()
{
/// tankId is always TankId.Cold, TankId.Warm or TankId.Hot
tankSelector.State = (tankId == TankId.Cold) ? State.ColdTankSelected_Waiting1min
: (tankId == TankId.Warm) ? State.WarmTankSelected_Waiting1min
: State.HotTankSelected_Waiting1min;
alreadySet = false;
unselectedWaitLevel = false;
doUnselect = false;
time = 0; /// Reset button bit in Run(), wait 1 min.
tankSelector.SetBit(bitMask);
}
/// <summary>Run this operation</summary>
@ -41,9 +97,24 @@ namespace TBF.BenchControl.Modbus.TankSelector
{
return Event.ConditionMet;
}
else if (doUnselect)
{
tankSelector.ResetBit(unselectBitMask);
doUnselect = false;
unselectedWaitLevel = true;
return Event.ConditionNotMet;
}
else if (unselectedWaitLevel)
{
if (tankSelector.CurrentActivity == Activity.Idle)
{
SelectTankFromIdleState();
}
return Event.ConditionNotMet;
}
else if (time == 0)
{
tankSelector.QuidoRS.ResetBit(bitMask);
tankSelector.ResetBit(bitMask);
time++;
return Event.ConditionNotMet;
}

View File

@ -16,7 +16,7 @@ namespace TBF.BenchControl.Modbus.TankSelector
readonly Event eventDone;
public SetQuidoBitOp(TBF.BenchControl.Modbus.QuidoRS.QuidoRS quidoRS, TankSelector.QuidoOutputs bitMask, bool set)
public SetQuidoBitOp(TBF.BenchControl.Modbus.QuidoRS.QuidoRS quidoRS, QuidoOutputs bitMask, bool set)
: this(quidoRS, (ushort)bitMask, set, Event.ConditionMet)
{
}

View File

@ -11,6 +11,60 @@ 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));
@ -18,7 +72,7 @@ namespace TBF.BenchControl.Modbus.TankSelector
readonly TankSelectorCfg tankSelectorCfg;
public readonly TBF.BenchControl.Modbus.QuidoRS.QuidoRS QuidoRS;
readonly TBF.BenchControl.Modbus.QuidoRS.QuidoRS quidoRS;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm hotHeating;
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm hotCooling;
@ -27,31 +81,60 @@ namespace TBF.BenchControl.Modbus.TankSelector
readonly TBF.BenchControl.Modbus.Easytherm.Easytherm coldCooling;
IList<string> sequenceConditionNames;
IList<IOperation> sequenceConditions;
public State State;
public TankId CurrentTank { get { return GetTankIdFromState(State); } }
public Activity CurrentActivity { get { return GetActivityFromState(State); } }
public int CurrentlySelectedTank;
public bool CurrentlySelectedTankValid;
/// <summary>
/// Quido digital out board outputs assignment
/// </summary>
public enum QuidoOutputs : ushort
public TankId GetTankIdFromState(State state)
{
None = 0,
SelectColdTank = 0x0001,
SelectWarmTank = 0x0002,
SelectHotTank = 0x0004,
PumpToColdTank = 0x0008,
PumpToWarmTank = 0x0010,
PumpToHotTank = 0x0020,
Mixing = 0x0040,
HeatingHotTank = 0x0080,
HeatingWarmTank = 0x0100,
CoolingHotTank = 0x0200,
CoolingWarmTank = 0x0400,
CoolingColdTank = 0x0800,
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;
}
}
@ -65,8 +148,8 @@ namespace TBF.BenchControl.Modbus.TankSelector
{
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));
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);
@ -82,113 +165,48 @@ namespace TBF.BenchControl.Modbus.TankSelector
CreateConditions(true);
CurrentlySelectedTankValid = false;
State = State.Unknown;
log.Debug(this.ToString());
}
///
/// IDevice interface implementation
///
public void Initialize()
{
SetOutputs(0);
}
public void RunDeviceBefore() {}
public void RunDeviceBefore()
{
}
public void RunDeviceAfter() {}
public void StopDevice() {}
void CreateConditions(bool createAll)
{
sequenceConditionNames = new List<string>();
sequenceConditions = new List<IOperation>();
sequenceConditionNames.Add(Strings.Select_COLD_tank);
if (createAll) sequenceConditions.Add(new SelectTankOp(this, 1));
sequenceConditionNames.Add(Strings.Select_WARM_tank);
if (createAll) sequenceConditions.Add(new SelectTankOp(this, 2));
sequenceConditionNames.Add(Strings.Select_HOT_tank);
if (createAll) sequenceConditions.Add(new SelectTankOp(this, 3));
sequenceConditionNames.Add(Strings.Unselect_COLD_tank);
if (createAll) sequenceConditions.Add(new UnselectTankOp(this, 1));
sequenceConditionNames.Add(Strings.Unselect_WARM_tank);
if (createAll) sequenceConditions.Add(new UnselectTankOp(this, 2));
sequenceConditionNames.Add(Strings.Unselect_HOT_tank);
if (createAll) sequenceConditions.Add(new UnselectTankOp(this, 3));
sequenceConditionNames.Add(Strings.Set_hot_water_heating_temperature);
if (createAll) sequenceConditions.Add(hotHeating.SetRequiredTemperatureOp());
sequenceConditionNames.Add(Strings.Set_hot_water_cooling_temperature);
if (createAll) sequenceConditions.Add(hotCooling.SetRequiredTemperatureOp());
sequenceConditionNames.Add(Strings.Set_warm_water_heating_temperature);
if (createAll) sequenceConditions.Add(warmHeating.SetRequiredTemperatureOp());
sequenceConditionNames.Add(Strings.Set_warm_water_cooling_temperature);
if (createAll) sequenceConditions.Add(warmCooling.SetRequiredTemperatureOp());
sequenceConditionNames.Add(Strings.Set_cold_water_cooling_temperature);
if (createAll) sequenceConditions.Add(coldCooling.SetRequiredTemperatureOp());
sequenceConditionNames.Add("Start heating hot water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.HeatingHotTank, true));
sequenceConditionNames.Add("Stop heating hot water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.HeatingHotTank, false));
sequenceConditionNames.Add("Start cooling hot water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.CoolingHotTank, true));
sequenceConditionNames.Add("Stop cooling hot water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.CoolingHotTank, false));
sequenceConditionNames.Add("Start heating warm water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.HeatingWarmTank, true));
sequenceConditionNames.Add("Stop heating warm water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.HeatingWarmTank, false));
sequenceConditionNames.Add("Start cooling warm water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.CoolingWarmTank, true));
sequenceConditionNames.Add("Stop cooling warm water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.CoolingWarmTank, false));
sequenceConditionNames.Add("Start cooling cold water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.CoolingColdTank, true));
sequenceConditionNames.Add("Stop cooling cold water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.CoolingColdTank, false));
sequenceConditionNames.Add("Start mixing water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.Mixing, true));
sequenceConditionNames.Add("Stop mixing water");
if (createAll) sequenceConditions.Add(new SetQuidoBitOp(QuidoRS, QuidoOutputs.Mixing, false));
}
///
/// 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); }
/// <summary>
/// Set outputs of QuidoRS board
/// </summary>
/// <param name="outputs">output value</param>
public void SetOutputs(uint outputs)
{
QuidoRS.SetOutputs((ushort)outputs);
}
///
/// ISequenceCondition interface implementation (conditions in transition sequences)
///
IList<string> sequenceConditionNames;
IList<IOperation> sequenceConditions;
public int ConditionsCount { get { return sequenceConditions != null ? sequenceConditions.Count : 0; } }
/// Returned strings are added to the combo-box
/// 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)
@ -201,6 +219,7 @@ namespace TBF.BenchControl.Modbus.TankSelector
}
}
/// Operations are executed as a part of a transition sequence
public IOperation ConditionOp(int i)
{
if (sequenceConditions != null && i < sequenceConditions.Count && i >= 0)
@ -212,5 +231,47 @@ namespace TBF.BenchControl.Modbus.TankSelector
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));
}
}
}

View File

@ -1,55 +1,68 @@

///
/// Copyright (c) 2017 Sensus Metering Systems
///
namespace TBF.BenchControl.Modbus.TankSelector
{
public class UnselectTankOp : IOperation
{
TankSelector tankSelector;
int tankNo;
ushort bitMask;
bool alreadyUnselected;
TankId tankId;
ushort unselectBitMask;
bool doUnselect;
bool unselectedWaitLevel;
int time;
public UnselectTankOp(TankSelector tankSelector, int tankNo)
public UnselectTankOp(TankSelector tankSelector)
{
this.tankSelector = tankSelector;
this.tankNo = tankNo;
this.bitMask = (ushort)((tankNo == 1) ? 8 : ((tankNo == 2) ? 0x10 : ((tankNo == 3) ? 0x20 : 0)));
}
/// <summary>Start this operation</summary>
public void Start()
{
if (tankSelector.CurrentlySelectedTankValid && (tankNo == 0))
if (tankSelector.CurrentActivity == Activity.Selected ||
tankSelector.CurrentActivity == Activity.Selected_Waiting1min)
{
alreadyUnselected = true;
}
else
{
tankSelector.CurrentlySelectedTank = tankNo;
tankSelector.CurrentlySelectedTankValid = true;
alreadyUnselected = false;
time = 0;
tankId = tankSelector.CurrentTank;
unselectBitMask = (ushort)((tankId == TankId.Cold) ? QuidoOutputs.PumpToColdTank
: (tankId == TankId.Warm) ? QuidoOutputs.PumpToWarmTank
: QuidoOutputs.PumpToHotTank);
doUnselect = true;
unselectedWaitLevel = false;
tankSelector.QuidoRS.SetBit(bitMask);
tankSelector.SetBit(unselectBitMask);
}
else if (tankSelector.CurrentActivity == Activity.Unselected_WaitingLevel)
{
tankId = tankSelector.CurrentTank;
doUnselect = false;
unselectedWaitLevel = true;
}
else /// tankSelector.CurrentActivity == Activity.Idle or Activity.Uknown
{
doUnselect = false;
unselectedWaitLevel = false;
}
}
/// <summary>Run this operation</summary>
public Event Run()
{
if (alreadyUnselected)
if (doUnselect)
{
return Event.ConditionMet;
}
else if (time == 0)
{
tankSelector.QuidoRS.ResetBit(bitMask);
time++;
tankSelector.ResetBit(unselectBitMask);
doUnselect = false;
unselectedWaitLevel = true;
return Event.ConditionNotMet;
}
else if (time <= 60)
else if (unselectedWaitLevel)
{
time++;
if (tankSelector.CurrentActivity == Activity.Idle)
{
unselectedWaitLevel = false;
return Event.ConditionMet;
}
return Event.ConditionNotMet;
}
else

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
/// Copyright (c) 2013-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;

View File

@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.12.490.1")]
[assembly: AssemblyFileVersion("2.12.490.1")]
[assembly: AssemblyVersion("2.12.491.1")]
[assembly: AssemblyFileVersion("2.12.491.1")]

View File

@ -4447,29 +4447,11 @@ namespace TBF.Resources {
}
/// <summary>
/// Looks up a localized string similar to Unselect COLD water.
/// Looks up a localized string similar to Unselect current tank.
/// </summary>
internal static string Unselect_COLD_tank {
internal static string Unselect_current_tank {
get {
return ResourceManager.GetString("Unselect_COLD_tank", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unselect HOT water.
/// </summary>
internal static string Unselect_HOT_tank {
get {
return ResourceManager.GetString("Unselect_HOT_tank", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unselect WARM water.
/// </summary>
internal static string Unselect_WARM_tank {
get {
return ResourceManager.GetString("Unselect_WARM_tank", resourceCulture);
return ResourceManager.GetString("Unselect_current_tank", resourceCulture);
}
}

View File

@ -1642,14 +1642,8 @@
<data name="Select_WARM_tank" xml:space="preserve">
<value>Select WARM water</value>
</data>
<data name="Unselect_COLD_tank" xml:space="preserve">
<value>Unselect COLD water</value>
</data>
<data name="Unselect_HOT_tank" xml:space="preserve">
<value>Unselect HOT water</value>
</data>
<data name="Unselect_WARM_tank" xml:space="preserve">
<value>Unselect WARM water</value>
<data name="Unselect_current_tank" xml:space="preserve">
<value>Unselect current tank</value>
</data>
<data name="T_cold_cooling" xml:space="preserve">
<value>T cold cooling</value>