-- ======================
-- Description
-- ======================
--
-- Podwójne GWC bliźniacze. Każde GWC (oznaczone jako GWC1 i GWC2) jest sterowane przy pomocy siłownika z możliwością proporcjonalnego ustawienia. I odpowiednio oznacza:
--
-- 0% - przepustnica sterująca całkowicie zamknięta
-- 100% - przepustnica sterująca całkowicie otwarta
--
-- Definicje:
--
-- "Z czerpni" - oznacza przestawienie dwóch przepustnic do pozycji całkowicie otwartej (100%) i oznacza przepływ powietrza z czerpni wprost do budynku
--
-- "Z GWC" - oznacza przestawienie dwóch przepustnic do pozycji całkowicie zamkniętej (0%) i oznacza przepływ powietrza z czerpni przez GWC do budynku
--
-- "Regeneracja złoża" - oznacza cykliczne przestawienie przepustnic w/g zdefiniowanych pozycji. Do ustawienia powiązane następujące parametry:
--
-- - "pozycja 1" - wartość siłownika przepustnicy wyrażona w procentach. Zakres nastawy od 0% do 100% (np. 30%)
-- - "pozycja 2" - wartość siłownika przepustnicy wyrażona w procentach. Zakres nastawy od 0% do 100% (np. 0%)
-- - "pozycja 3" - wartość siłownika przepustnicy wyrażona w procentach. Zakres nastawy od 0% do 100% (np. 0%)
-- - "czas zmiany 1" - wyrażony w sekundach
-- - "czas zmiany 2" - wyrażony w sekundach
--
-- Jeżeli logika zdecyduje, że aktualnym trybem pracy ma być "regeneracja złoża" to oznacza to:
--
-- Faza 1:
-- - Ustawienie siłownika GWC1 w "pozycji 1" (zgodnie z przykładem 30%)
-- - Ustawienie siłownika GWC2 w "pozycji 2" (zgodnie z przykładem 0%)
-- - Po upłynięciu "czasu zmiany 1" następuje przejście do fazy 2
-- Faza 2:
-- - Ustawienie siłownika GWC1 w "pozycji 3" (zgodnie z przykładem 0%)
-- - Ustawienie siłownika GWC2 w "pozycji 3" (zgodnie z przykładem 0%)
-- - Po upłynięciu "czasu zmiany 2" następuje przejście do fazy 3
-- Faza 3:
-- - Ustawienie siłownika GWC1 w "pozycji 2" (zgodnie z przykładem 0%)
-- - Ustawienie siłownika GWC2 w "pozycji 1" (zgodnie z przykładem 30%)
-- - Po upłynięciu "czasu zmiany 1" następuje przejście do fazy 4
-- Faza 4:
-- - Ustawienie siłownika GWC1 w "pozycji 3" (zgodnie z przykładem 0%)
-- - Ustawienie siłownika GWC2 w "pozycji 3" (zgodnie z przykładem 0%)
-- - Po upłynięciu "czasu zmiany 2" następuje przejście do fazy 1
--
-- Właściwa logika działania:
--
-- W okresie letnim:
--
-- 1. Jeżeli temperatura zewnętrzna jest równa lub niższa od setting.summer.t.1.value (np. 20*C) z uwzględnieniem histerezy setting.t.1.hyst (np. 1*C) to następuje pobór powietrza "z czerpni".
-- 2. Jeżeli temperatura zewnętrzna jest równa lub większa od setting.summer.t.2.value (np. 30*C) z uwzględnieniem histerezy setting.t.2.hyst (np. 1*C) to następuje pobór powietrza "z GWC".
-- 3. Jeżeli temperatura zewnętrzna jest w zakresie pomiędzy setting.summer.t.1.value (np. 20*C) i setting.summer.t.2.value (np. 30*C) z uwzględnieniem histerezy to następuje "regeneracja złoża".
--
-- W okresie zimowym:
--
-- 1. Jeżeli temperatura zewnętrzna jest równa lub niższa od setting.winter.t.1.value (np. 0*C) z uwzględnieniem histerezy setting.t.1.hyst (np. 1*C) to następuje pobór powietrza "z GWC".
-- 2. Jeżeli temperatura zewnętrzna jest równa lub większa od setting.winter.t.2.value (np. 20*C) z uwzględnieniem histerezy setting.t.2.hyst (np. 1*C) to następuje pobór powietrza "z czerpni".
-- 3. Jeżeli temperatura zewnętrzna jest w zakresie pomiędzy setting.winter.t.1.value (np. 0*C) i setting.winter.t.2.value (np. 20*C) z uwzględnieniem histerezy to następuje "regeneracja złoża".
--
-- ======================
-- Parameters
-- ======================
--
-- SubLogic supports following variables:
--
-- input.outdoor.value
-- input.outdoor.err - temperatura zewnętrzna
--
-- input.season - 0 - zima, 1 - lato [0..1]
--
-- output.ghe.1 - wyjście określające stan przepustnicy dla GWC1
--
-- output.ghe.2 - wyjście określające stan przepustnicy dla GWC2
--
-- setting.reg.pos.1 - wartość siłownika przepustnicy wyrażona w procentach. "Pozycja 1" z definicji dla regeneracji złoża.
--
-- setting.reg.pos.2 - wartość siłownika przepustnicy wyrażona w procentach. "Pozycja 2" z definicji dla regeneracji złoża.
--
-- setting.reg.pos.3 - wartość siłownika przepustnicy wyrażona w procentach. "Pozycja 3" z definicji dla regeneracji złoża.
--
-- setting.reg.time.1 - "Czas zmiany 1" z definicji dla regeneracji złoża wyrażony w sekundach.
--
-- setting.reg.time.2 - "Czas zmiany 2" z definicji dla regeneracji złoża wyrażony w sekundach.
--
-- setting.alert.t.output.ghe.1 - wartość output.ghe.1 w przypadku błędu temperatury
--
-- setting.alert.t.output.ghe.2 - wartość output.ghe.2 w przypadku błędu temperatury
--
-- setting.summer.t.1.value - wartość temperatury t1 dla okresu letniego
-- Wartość musi być mniejsza od setting.summer.t.2.value minimum o setting.t.1.hyst / 2 + setting.t.2.hyst /2).
-- Jeżeli nie będzie zachowany ten warunek to wartość zostanie automatycznie skorygowana
--
-- setting.summer.t.2.value - wartość temperatury t2 dla okresu letniego.
-- Wartość musi być większa od setting.summer.t.1.value minimum o setting.t.1.hyst / 2 + setting.t.2.hyst /2).
-- Jeżeli nie będzie zachowany ten warunek to wartość zostanie automatycznie skorygowana
--
-- setting.winter.t.1.value - wartość temperatury t1 dla okresu zimowego
-- Wartość musi być mniejsza od setting.winter.t.2.value minimum o setting.t.1.hyst / 2 + setting.t.2.hyst /2).
-- Jeżeli nie będzie zachowany ten warunek to wartość zostanie automatycznie skorygowana
--
-- setting.winter.t.2.value - wartość temperatury t2 dla okresu zimowego
-- Wartość musi być większa od setting.winter.t.1.value minimum o setting.t.1.hyst / 2 + setting.t.2.hyst /2 ).
-- Jeżeli nie będzie zachowany ten warunek to wartość zostanie automatycznie skorygowana
--
-- setting.t.1.hyst - histereza powiązana z temperaturą t1
--
-- setting.t.2.hyst - histereza powiązana z temperaturą t2
--
-- counter.alert.t.state - jeżeli któryś z czujników jest uszkodzony to ta flaga jest ustawiana na 1.
--
-- counter.reg.phase.current - aktualna faza dla regeneracji złoża. 0 - nie jest realizowana funkcja regeneracji złoża.
--
-- counter.reg.phase.downcounter - pozostały czas do zmiany fazy regeneracji złoża
--
-- counter.t.1.value - aktualna wartość progu t1
--
-- counter.t.1.lower.status - czy temperatura zewnętrzna jest niższa od progu t1 z uwzględnieniem histerezy setting.t.1.hyst
--
-- counter.t.2.value - aktualna wartość progu t2
--
-- counter.t.2.higher.status - czy temperatura zewnętrzna jest wyższa od progu t2 z uwzględnieniem histerezy setting.t.2.hyst
--
-- Logic uses lua language to implement own behaviour
--
-- ======================
-- mandatory variables
-- ======================
--
-- Logic expects following mandatory variables:
--
-- reload.trigger - causes reloading lua script
--
-- memcnt - current amount of memory used by lua in bytes
--
-- Logic expects following kv settings:
--
-- LuaScriptPath - path to the lua script - must be absolute
--
-- ======================
-- ChangeLog
-- ======================
--
-- 2024-06-24 ver 1.0.0
--
-- # zmiana nazwy parametru outside -> outdoor
--
-- 2019-07-02 ver 0.0.0
--
-- # First release
--
-- user can use some functions provided by ibmanager.
-- user can use some functions provided by ibmanager.
-- ibmanager provides following functions to use:
--
-- function returns value of required ibmanager variable
-- @param fullName - string - variable name - name of variable of which value must be returned, for example "rs.0.id.255.input.t.0.value"
-- @return - string or integer - variable value or "nil" if variable not exist or is not readable
--
-- getValue(fullName)
-- function set value of given ibmanager variable
-- @param fullName - string - variable name - name of variable of which value we want to set, for example "rs.0.id.255.input.t.0.value"
-- @param value - string, int or boolean - value to set
-- @return - nothing
--
-- setValue(fullName, value)
-- function returns value of required ibmanager variable
-- @param key - placed in xml logic configuration file:
-- * as attribute: Name, in Var, RemoteVar and ImportVar elements in the case of stand alone variables
-- * as concatenation of two attributes: ListName.Postfix in VarListItem, RemoteVarListItem and ImportVarListItem elements
-- in the case of variables that are placed in lists
-- @return - string or integer - variable value or "nil" if variable not exist or is not readable
--
-- getLogicValue(key)
-- function set value of given ibmanager variable
-- @param key - placed in xml logic configuration file:
-- * as attribute: Name, in Var, RemoteVar and ImportVar elements in the case of stand alone variables
-- * as concatenation of two attributes: ListName.Postfix in VarListItem, RemoteVarListItem and ImportVarListItem elements
-- in the case of variables that are placed in lists
-- @param value - string, int or boolean - value to set
-- @return - nothing
--
-- setLogicValue(key, value)
-- function returns two sections of kvsettings from xml configuration file
-- returned value is two element table, each of these elements is table too.
-- indices of returned table are strings and equal "instance" and "global"
-- values of returned tables are tables and contain KVsettings for applicable section.
-- nested tables have form key = value, where key is index in nested table and value is value.
-- example: {"instance" = {"ikey1" = "ivalue1", "ikey2" = "gvalue2"}, "global" = {"gkey1" = "gvalue1", "gkey2" = "gvalue2", "gkey3" = "gvalue3"}}
-- @return - two dimensional array - kvsettings for global and instance sections
-- getKvSettings()
-- function schedules alert to send.
-- rules are defined in separated alert configuration files and are described in ibmanager instruction manual
-- @param id - alert identifier - must be defined in current logic configuration file in section: <Alert Id="any_identifier" ...
-- scheduleAlert(id)
-- function cancels alert sending, if was previously scheduled. if not then only wakes up alerts handling thread, so if there is no need to call this function, then do not call it.
-- rules are defined in separated alert configuration files and are described in ibmanager instruction manual
-- @param id - alert identifier - must be defined in current logic configuration file in section: <Alert Id="any_identifier" ...
-- cancelAlert(name)
-- function returns table, containing Variables that belongs to required list.
-- @param listName - Name attribute of VarList, RemoteVarList or ImportVarList elemetnst in configurationfile
-- @return array of key-value pairs. Key - variable postfix, Value - Variable value
-- getVarList(listName)
-- function returns monotonic system clock value, that elapsed since specific epoch
-- returned time is expressed in milliseconds.
-- getClock()
-- function logs message to file, if defined in configuration file log level is less than passed to this function
-- @param logLevel - one of:
-- LogLevel.TraceLo
-- LogLevel.Trace
-- LogLevel.TraceHi
-- LogLevel.DebugLo
-- LogLevel.Debug
-- LogLevel.DebugHi
-- LogLevel.Info
-- LogLevel.Notice
-- LogLevel.Warning
-- LogLevel.Error
-- LogLevel.Critical
-- @param logMessage - string to log
-- log(logLevel, logMessage)
-- ibmanager provides following global variables:
-- logic type, (in this case it will always be "Lua") - the same as in logic configuration file in section: <Logic Type="Lua" ...
-- LOGIC_TYPE
-- logic version, the same as in logic configuration file in section: <Logic ... Version="x.y.z" ...
-- LOGIC_VERSION
-- logic sub-type, the same as in logic configuration file in section: <Logic ... SubType="Hysteresis" ...
-- LOGIC_SUBTYPE
-- logic sub-version, the same as in logic configuration file in section: <Logic ... SubVersion="x.y.z" ...
-- LOGIC_SUBVERSION
-- logic instance name - the same as in logic configuration file, in section: <Instance Name="0">
-- LOGIC_INSTANCE_NAME
-- add script directory to package path
package.path = package.path .. ";./logic/scripts/utils/?.lua";
-- use script - without .lua extension - delta class
require("State");
require("DownCounter");
g_outputGhe1 = nil;
g_outputGhe2 = nil;
g_counterT1LowerStatus = nil;
g_counterT2HigherStatus = nil;
g_counterRegPhaseCurrent = 0;
g_counterRegPhaseDowncounter = nil;
g_settingSummerT2Value = nil;
g_settingSummerT1Value = nil;
g_settingWinterT2Value = nil;
g_settingWinterT1Value = nil;
SUPPORTED_SUBLOGIC_TYPE = "GHE02";
SUPPORTED_SUBLOGIC_VERSION = "1.0.0";
g_versionChecked = false;
-- entry point to the logic
-- @param firstCall - tells if logic is called first time
-- @return - nothing
function onLogicCall(firstCall)
if not g_versionChecked then
-- checking sublogic type and sublogic version
if LOGIC_SUBTYPE ~= SUPPORTED_SUBLOGIC_TYPE then
error("Wrong logic sub-type. expected " .. SUPPORTED_SUBLOGIC_TYPE .. " but used " .. LOGIC_SUBTYPE);
end
local versionWithoutBuild = string.match(LOGIC_SUBVERSION, "[0-9]+%.[0-9]+%.[0-9]+");
if versionWithoutBuild ~= SUPPORTED_SUBLOGIC_VERSION then
error("Wrong logic sub-version. expected " .. SUPPORTED_SUBLOGIC_VERSION .. " but used " .. LOGIC_SUBVERSION);
end
g_versionChecked = true;
end
local inputOutdoorValue = getLogicValue("input.outdoor.value");
local inputOutdoorErr = getLogicValue("input.outdoor.err");
local inputSeason = getLogicValue("input.season");
local settingRegPos1 = getLogicValue("setting.reg.pos.1");
local settingRegPos2 = getLogicValue("setting.reg.pos.2");
local settingRegPos3 = getLogicValue("setting.reg.pos.3");
local settingRegTime1 = getLogicValue("setting.reg.time.1");
local settingRegTime2 = getLogicValue("setting.reg.time.2");
local settingAlertTOutputGhe1 = getLogicValue("setting.alert.t.output.ghe.1");
local settingAlertTOutputGhe2 = getLogicValue("setting.alert.t.output.ghe.2");
local settingSummerT1Value = getLogicValue("setting.summer.t.1.value");
local settingSummerT2Value = getLogicValue("setting.summer.t.2.value");
local settingWinterT1Value = getLogicValue("setting.winter.t.1.value");
local settingWinterT2Value = getLogicValue("setting.winter.t.2.value");
local settingT1Hyst = getLogicValue("setting.t.1.hyst");
local settingT2Hyst = getLogicValue("setting.t.2.hyst");
local counterAlertTState = 0;
local counterRegPhaseDowncounter = 0;
local counterT1Value = 0;
local counterT2Value = 0;
-- states
if g_outputGhe1 == nil or firstCall then
g_outputGhe1 = State.create(0, 0, 100, true);
end
g_outputGhe1:call();
if g_outputGhe2 == nil or firstCall then
g_outputGhe2 = State.create(0, 0, 100, true);
end
g_outputGhe2:call();
if g_counterT1LowerStatus == nil or firstCall then
g_counterT1LowerStatus = State.create(0, 0, 1, true);
end
g_counterT1LowerStatus:call();
if g_counterT2HigherStatus == nil or firstCall then
g_counterT2HigherStatus = State.create(0, 0, 1, true);
end
g_counterT2HigherStatus:call();
-- timers
if g_counterRegPhaseDowncounter == nil or firstCall then
g_counterRegPhaseDowncounter = DownCounter.create();
end
-- wartość w zależności od fazy
if (g_counterRegPhaseCurrent == 0) then
g_counterRegPhaseDowncounter:updateParams(0);
g_counterRegPhaseDowncounter:reset();
elseif (g_counterRegPhaseCurrent == 1) or (g_counterRegPhaseCurrent == 3) then
g_counterRegPhaseDowncounter:updateParams(settingRegTime1 * 1000);
else
g_counterRegPhaseDowncounter:updateParams(settingRegTime2 * 1000);
end
-- if g_counterRegPhaseDowncounter:elapsed() then
-- g_counterRegPhaseDowncounter:reset();
-- end
counterRegPhaseDowncounter = g_counterRegPhaseDowncounter:timeTo0() / 1000;
counterRegPhaseDowncounter = (counterRegPhaseDowncounter < 0) and 0 or counterRegPhaseDowncounter;
-- obsługa alarmu temperatur
if (inputOutdoorErr ~= 0) then
counterAlertTState = 1;
end
if ((counterAlertTState ~= 0)) then
g_outputGhe1:setValue(settingAlertTOutputGhe1);
g_outputGhe2:setValue(settingAlertTOutputGhe2);
end
--zabezpieczenie wartości settingSummer
if g_settingSummerT2Value == nil or firstCall then
g_settingSummerT2Value = settingSummerT2Value;
end
if g_settingSummerT1Value == nil or firstCall then
g_settingSummerT1Value = settingSummerT1Value;
end
if (g_settingSummerT2Value ~= settingSummerT2Value) then
if (settingSummerT2Value <= settingSummerT1Value + settingT1Hyst / 2 + settingT2Hyst / 2) then
settingSummerT2Value = settingSummerT1Value + settingT1Hyst / 2 + settingT2Hyst / 2;
setLogicValue("setting.summer.t.2.value", settingSummerT2Value);
end
end
if (g_settingSummerT1Value ~= settingSummerT1Value) then
if (settingSummerT1Value >= settingSummerT2Value - settingT1Hyst / 2 - settingT2Hyst / 2) then
settingSummerT1Value = settingSummerT2Value - settingT1Hyst / 2 - settingT2Hyst / 2;
setLogicValue("setting.summer.t.1.value", settingSummerT1Value);
end
end
-- w przypadku pozostałości ze storage
if (settingSummerT2Value <= settingSummerT1Value + settingT1Hyst / 2 + settingT2Hyst / 2) then
settingSummerT2Value = settingSummerT1Value + settingT1Hyst / 2 + settingT2Hyst / 2;
setLogicValue("setting.summer.t.2.value", settingSummerT2Value);
end
g_settingSummerT2Value = settingSummerT2Value;
g_settingSummerT1Value = settingSummerT1Value;
--zabezpieczenie wartości settingWinter
if g_settingWinterT2Value == nil or firstCall then
g_settingWinterT2Value = settingWinterT2Value;
end
if g_settingWinterT1Value == nil or firstCall then
g_settingWinterT1Value = settingWinterT1Value;
end
if (g_settingWinterT2Value ~= settingWinterT2Value) then
if (settingWinterT2Value <= settingWinterT1Value + settingT1Hyst / 2 + settingT2Hyst / 2) then
settingWinterT2Value = settingWinterT1Value + settingT1Hyst / 2 + settingT2Hyst / 2;
setLogicValue("setting.winter.t.2.value", settingWinterT2Value);
end
end
if (g_settingWinterT1Value ~= settingWinterT1Value) then
if (settingWinterT1Value >= settingWinterT2Value - settingT1Hyst / 2 - settingT2Hyst / 2) then
settingWinterT1Value = settingWinterT2Value - settingT1Hyst / 2 - settingT2Hyst / 2;
setLogicValue("setting.winter.t.1.value", settingWinterT1Value);
end
end
-- w przypadku pozostałości ze storage
if (settingWinterT2Value <= settingWinterT1Value + settingT1Hyst / 2 + settingT2Hyst / 2) then
settingWinterT2Value = settingWinterT1Value + settingT1Hyst / 2 + settingT2Hyst / 2;
setLogicValue("setting.winter.t.2.value", settingWinterT2Value);
end
g_settingWinterT2Value = settingWinterT2Value;
g_settingWinterT1Value = settingWinterT1Value;
-- realizacja regeneracji złoża
if (g_counterRegPhaseCurrent ~= 0) then
if g_counterRegPhaseDowncounter:elapsed() then
g_counterRegPhaseCurrent = g_counterRegPhaseCurrent + 1;
if (g_counterRegPhaseCurrent == 5) then
g_counterRegPhaseCurrent = 1;
end
g_counterRegPhaseDowncounter:reset();
end
if (g_counterRegPhaseCurrent == 1) then
g_outputGhe1:setValue(settingRegPos1);
g_outputGhe2:setValue(settingRegPos2);
elseif (g_counterRegPhaseCurrent == 2) then
g_outputGhe1:setValue(settingRegPos3);
g_outputGhe2:setValue(settingRegPos3);
elseif (g_counterRegPhaseCurrent == 3) then
g_outputGhe1:setValue(settingRegPos2);
g_outputGhe2:setValue(settingRegPos1);
elseif (g_counterRegPhaseCurrent == 4) then
g_outputGhe1:setValue(settingRegPos3);
g_outputGhe2:setValue(settingRegPos3);
end
end
-- ustalenie temperatur t1 i t2 oraz sposób działania
if (inputSeason == 0) then
-- w sezonie zimowym
counterT1Value = settingWinterT1Value;
counterT2Value = settingWinterT2Value;
g_counterT1LowerStatus:set1IfLowerThan(inputOutdoorValue, counterT1Value, settingT1Hyst);
g_counterT2HigherStatus:set1IfHigherThan(inputOutdoorValue, counterT2Value, settingT2Hyst);
-- Jeżeli temperatura zewnętrzna jest równa lub niższa od setting.winter.t.1.value (np. 0*C) z uwzględnieniem histerezy setting.t.1.hyst (np. 1*C) to następuje pobór powietrza "z GWC".
if g_counterT1LowerStatus:getValue() == 1 then
g_outputGhe1:setValue(0);
g_outputGhe2:setValue(0);
g_counterRegPhaseCurrent = 0;
end
-- Jeżeli temperatura zewnętrzna jest równa lub większa od setting.winter.t.2.value (np. 20*C) z uwzględnieniem histerezy setting.t.2.hyst (np. 1*C) to następuje pobór powietrza "z czerpni".
if g_counterT2HigherStatus:getValue() == 1 then
g_outputGhe1:setValue(100);
g_outputGhe2:setValue(100);
g_counterRegPhaseCurrent = 0;
end
-- Jeżeli temperatura zewnętrzna jest w zakresie pomiędzy setting.winter.t.1.value (np. 0*C) i setting.winter.t.2.value (np. 20*C) z uwzględnieniem histerezy to następuje "regeneracja złoża".
if (g_counterT1LowerStatus:getValue() == 0) and (g_counterT2HigherStatus:getValue() == 0) and (g_counterRegPhaseCurrent == 0) then
g_counterRegPhaseCurrent = 1;
end
else
-- w sezonie letnim
counterT1Value = settingSummerT1Value;
counterT2Value = settingSummerT2Value;
g_counterT1LowerStatus:set1IfLowerThan(inputOutdoorValue, counterT1Value, settingT1Hyst);
g_counterT2HigherStatus:set1IfHigherThan(inputOutdoorValue, counterT2Value, settingT2Hyst);
-- Jeżeli temperatura zewnętrzna jest równa lub niższa od setting.summer.t.1.value (np. 20*C) z uwzględnieniem histerezy setting.t.1.hyst (np. 1*C) to następuje pobór powietrza "z czerpni".
if g_counterT1LowerStatus:getValue() == 1 then
g_outputGhe1:setValue(100);
g_outputGhe2:setValue(100);
g_counterRegPhaseCurrent = 0;
end
-- Jeżeli temperatura zewnętrzna jest równa lub większa od setting.summer.t.2.value (np. 30*C) z uwzględnieniem histerezy setting.t.2.hyst (np. 1*C) to następuje pobór powietrza "z GWC".
if g_counterT2HigherStatus:getValue() == 1 then
g_outputGhe1:setValue(0);
g_outputGhe2:setValue(0);
g_counterRegPhaseCurrent = 0;
end
-- Jeżeli temperatura zewnętrzna jest w zakresie pomiędzy setting.summer.t.1.value (np. 20*C) i setting.summer.t.2.value (np. 30*C) z uwzględnieniem histerezy to następuje "regeneracja złoża".
if (g_counterT1LowerStatus:getValue() == 0) and (g_counterT2HigherStatus:getValue() == 0) and (g_counterRegPhaseCurrent == 0) then
g_counterRegPhaseCurrent = 1;
end
end
-- send logic variables to ibmanager
setLogicValue("output.ghe.1", g_outputGhe1:getValue());
setLogicValue("output.ghe.2", g_outputGhe2:getValue());
setLogicValue("counter.alert.t.state", counterAlertTState);
setLogicValue("counter.reg.phase.current", g_counterRegPhaseCurrent);
setLogicValue("counter.reg.phase.downcounter", counterRegPhaseDowncounter);
setLogicValue("counter.t.1.value", counterT1Value);
setLogicValue("counter.t.1.lower.status", g_counterT1LowerStatus:getValue());
setLogicValue("counter.t.2.value", counterT2Value);
setLogicValue("counter.t.2.higher.status", g_counterT2HigherStatus:getValue());
end