-- ======================
-- Description
-- ======================
--
-- Wodny grzebieniowy GWC, pojedynczy, bez recyrkulacji.
--
-- ======================
-- Parameters
-- ======================
--
-- SubLogic supports following variables:
--
-- input.t.outdoor.value
-- input.t.outdoor.value.mode
-- input.t.outdoor.err - temperatura zewnętrzna
--
-- input.t.vent.supply.value
-- input.t.vent.supply.value.mode
-- input.t.vent.supply.err - temperatura powietrza nawiewanego za GWC
--
-- input.t.ghe.inner.value
-- input.t.ghe.inner.value.mode
-- input.t.ghe.inner.err - temperatura złoża GWC
--
-- input.t.water.value
-- input.t.water.value.mode
-- input.t.water.err - temperatura wody zraszającej
--
-- input.water.level - czujnik poziomu wody (0 - OK; 1 - wysoki poziom wody)
-- input.water.level.mode - tryb pracy wyjścia (0 - AUTO; 1 - MANU)
--
-- input.water.pulse - aktualny przepływ wody zraszającej (impulsy)
--
-- input.output.water.valve.mode
-- input.output.signal.vent.disable.mode - tryb pracy wyjścia (0 - AUTO; 1 - MANU)
--
-- output.water.valve - elektrozawór polewania złoża wodą (0 - zamknięty; 1 - otwarty)
--
-- output.signal.vent.disable - sygnał wyłączenia nawiewu (ochrona przed zamarzaniem złoża zimą) (1 - wstrzymaj nawiew)
--
-- setting.logic.delay - czas zwłoki działania logiki. Dopiero po tym czasie logika zacznie pracować [s]
--
-- setting.kontrola_naw - czy ma być realizowana kontrola nawiewu (nastawa użytkownika) [0..1]
--
-- setting.kontrola_zlo - czy ma być realizowana kontrola złoża (nastawa użytkownika) [0..1]
--
-- setting.T_lato - od kiedy lato
--
-- setting.T_nawiew_lato - nawiew latem
--
-- setting.Nawiew_lato - czas pomiędzy zraszaniami lato [min]
--
-- setting.Zraszanie_lato - ilość wody do zraszania lato [l]
--
-- setting.Regeneracja_lato - ilość wody do regeneracji latem [l]
--
-- setting.T_upal - od kiedy upal
--
-- setting.T_nawiew_upal - nawiew jak upał
--
-- setting.Nawiew_upal - czas pomiędzy zraszaniami upał [min]
--
-- setting.Zraszanie_upal - ilość wody do zraszania upał [l]
--
-- setting.Regeneracja_upal - ilość wody do regeneracji upał [l]
--
-- setting.T_zima - od kiedy zima
--
-- setting.T_nawiew_zima - nawiew jak zima
--
-- setting.Nawiew_zima - czas pomiędzy zraszaniami zima [min]
--
-- setting.Zraszanie_zima - ilość wody do zraszania zimą [l]
--
-- setting.Regeneracja_zima - ilość wody do regeneracji zimą [l]
--
-- setting.T_mroz - od kiedy mróz
--
-- setting.T_nawiew_mroz - nawiew jak mróz
--
-- setting.Nawiew_mroz - czas pomiędzy zraszaniami mróz [min]
--
-- setting.Zraszanie_mroz - ilość wody do zraszania mróz [l]
--
-- setting.Regeneracja_mroz - ilość wody do regeneracji mróz [l]
--
-- setting.Histereza_mroz - histereza powiązana z odmrazaniem złoża [*C]
--
-- setting.T_zamarzaGWC - temperatura złoża poniżej której może zamarzać
--
-- setting.Pauza_zima - pauza po odmrażaniu przed włączeniem nawiewu [min]
--
-- setting.CzasMAX - po tym czasie alarm braku wody [min]
--
-- setting.Wsp_przeplywu - ile impulsów na jeden litr z przepływomierza [imp/l]
--
-- setting.reset.woda_zuzycie - resetuje licznik zużycia wody
--
-- setting.reset.alert.przeciek - resetuje alarm "alert.przeciek"
--
-- setting.reset.alert.historyczne_zalane_zloze - resetuje alarm "alert.historyczne_zalane_zloze"
--
-- setting.alert.woda_przeciek_max - maksymalna dopuszczalna wartość licznika "counter.woda_przeciek", powyżej aktywowany jest alarm "counter.alert.przeciek" [l]
--
-- counter.logic.delay - licznik czas zwłoki działania logiki. [s]
--
-- counter.aktualnySezon - aktualny sezon:
-- 0 - przejściowy
-- 1 - lato
-- 2 - upał
-- 3 - zima
-- 4 - mróz
--
-- counter.aktualnyTryb - aktualny tryb:
-- 0 - brak pracy
-- 1 - lato (cykl główny)
-- 2 - regeneracja lato
-- 3 - zraszanie lato
-- 4 - zima (cykl główny)
-- 5 - regeneracja zima
-- 6 - zraszanie zima
-- 7 - odmrażanie
-- 8 - pauza po odmrażaniu
--
-- counter.demand.t_kryt - wymagana temperatura nawiewu od której uruchomiamy regenerację - właściwy dla lato/upał/zima/mróz [min]
--
-- counter.demand.okres_nawiewu - wymagany czas nawiewu (bez zraszania) - właściwy dla lato/upał/zima/mróz [min]
--
-- counter.demand.zraszanie - wymagana ilość wody do zraszania [l] - właściwy dla lato/upał/zima/mróz [min]
--
-- counter.demand.regeneracja - wymagana ilość wody do regeneracji [l] - właściwy dla lato/upał/zima/mróz [min]
--
-- counter.regeneracja_dodatek - dodatkowa ilość wody dla regeneracji złoża (na podstawie temp. zewnętrznej) [l]
--
-- counter.czas_nawiewu - czas, który upłynął od rozpoczęcia nawiewu [min]
--
-- counter.czas_zawor - czas, który upłynął od włączenie elektrozaworu [min]
--
-- counter.woda_przeplyw_l - pomiar przepływu wody litry=impulsy / wsp. przepływu
--
-- counter.woda_cykl_zuzycie_imp - licznik zużycia wody w aktualnym cyklu (jeżeli zakończono cykl to w ostatnim cyklu) [impulsy]
--
-- counter.woda_cykl_zuzycie_l - licznik zużycia wody w aktualnym cyklu (jeżeli zakończono cykl to w ostatnim cyklu) [l]
--
-- counter.woda_zuzycie_imp - licznik zużycia wody (sumarycznie) [impulsy]
--
-- counter.woda_zuzycie_l - licznik zużycia wody (sumarycznie) [l]
--
-- counter.woda_przeciek_imp - licznik zużycia wody od ostatniego zamknięcia zaworu (wartość zerowana przy otwartym zaworze) [impulsy]
--
-- counter.woda_przeciek_l - licznik zużycia wody od ostatniego zamknięcia zaworu (wartość zerowana przy otwartym zaworze) [l]
--
-- counter.t.water - temperatura wody (uaktualniana tylko podczas przepływu wody)
--
-- counter.kontrola_naw - czy ma być realizowana kontrola nawiewu w bieżącym cyklu [0..1]
--
-- counter.kontrola_zlo - czy ma być realizowana kontrola złoża w bieżącym cyklu [0..1]
--
-- counter.Pauza_zima - licznik: pauza po odmrażaniu przed włączeniem nawiewu [min]
--
-- counter.alert.brak_wody - alarm aktywowany jeżeli po otwarciu zaworu przez "setting.CzasMAX" nie osiągnięto założonych parametrów
-- "Za mały przepływ wody! Przez czas [counter.czas_zawor] minut przepłynęło tylko [counter.woda_cykl_zuzycie_l] litrów wody. Sprawdź pompę i zasilanie wody."
--
-- counter.alert.przeciek - alarm "Nieszczelny zawór! Mimo zamkniętego zaworu przepłynęło [przeciek] litrów wody. Sprawdź działanie elektrozaworu."
--
-- counter.alert.brak_regeneracji_nawiew - alarm aktywowany jeżeli "counter.woda_cykl_zuzycie_l" jest większy niż "counter.demand.regeneracja"
-- oraz "input.t.vent.supply.value" nie osiągnęła wartości "setting.t_kryt"
-- Komunikat: "Słaba regeneracja złoża. Pomimo zroszenia złoża [counter.woda_cykl_zuzycie_l] litrami wody,
-- temperatura nawiewu [input.t.vent.supply.value] *C nie osiągnęła wymaganej [setting.t_kryt] *C."
--
-- counter.alert.odmrazanie_zloza - alarm nieudanego odmrażania złoża
-- Komunikat: "Bardzo słaba regeneracja złoża. Pomimo zroszenia złoża [counter.woda_cykl_zuzycie_l] litrami wody,
-- temperatura złoża GWC [input.t.ghe.inner.value] *C jest poniżej minimalnej [setting.T_zamarzaGWC] *C".
--
-- counter.alert.zalane_zloze - alarm "input.water.level" == 1: "Złoże GWC jest zalane wodą. Zbyt wolne wsiąkanie wody w grunt." (przerwanie pracy)
--
-- counter.alert.historyczne_zalane_zloze - wystąpił w przeszłości alarm "counter.alert.zalane_zloz".: "Złoże GWC było przez chwilę zalane wodą. Zbyt wolne wsiąkanie wody w grunt."
--
--
-- 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-05-11 ver 1.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 elements 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("Counter")
require("DownCounter");
-- elektrozawór polewania złoża wodą (0 - zamknięty; 1 - otwarty)
OUTPUTWATERVALVE = nil
-- sygnał wyłączenia nawiewu (ochrona przed zamarzaniem złoża zimą) (1 - wstrzymaj nawiew)
OUTPUTSIGNALVENTDISABLE = nil
-- aktualny sezon:
-- 0 - przejściowy
-- 1 - lato
-- 2 - upał
-- 3 - zima
-- 4 - mróz
COUNTERAKTUALNYSEZON = nil
-- aktualny tryb:
-- 0 - brak pracy
-- 1 - lato (cykl główny)
-- 2 - regeneracja lato
-- 3 - zraszanie lato
-- 4 - zima (cykl główny)
-- 5 - regeneracja zima
-- 6 - zraszanie zima
-- 7 - odmrażanie
-- 8 - pauza po odmrażaniu
COUNTERAKTUALNYTRYB = nil
-- licznik (downcounter) zwłoki do rpopoczęcia działania logiki [s]
DOWNCOUNTERLOGICDELAY = nil;
-- czas, który upłynął od rozpoczęcia nawiewu [s]
COUNTERCZASNAWIEWU = nil
-- czas, który upłynął od włączenie elektrozaworu [s]
COUNTERCZASZAWOR = nil
-- licznik zużycia wody w aktualnym cyklu (jeżeli zakończono cykl to w ostatnim cyklu) [impulsy]
COUNTERWODACYKLZUZYCIE_IMP = 0
-- licznik przecieków wody (przy zamkniętym zaworze) [impulsy]
COUNTERWODAPRZECIEK_IMP = 0
-- licznik (downcounter) 1s cyklu
DOWNCOUNTER_1S = nil
-- licznik (downcounter) pauzy po odmrażaniu przed włączeniem nawiewu [min]
DOWNCOUNTERPAUZAZIMA = nil
SUPPORTED_SUBLOGIC_TYPE = "GHE03"
SUPPORTED_SUBLOGIC_VERSION = "1.0.0"
VERSIONCHECKED = false
-- entry point to the logic
-- @param firstCall - tells if logic is called first time
-- @return - nothing
function onLogicCall(firstCall)
if not 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
VERSIONCHECKED = true
end
local inputTOutdoorValue = getLogicValue("input.t.outdoor.value")
local inputTOutdoorErr = getLogicValue("input.t.outdoor.err")
local inputTVentSupplyValue = getLogicValue("input.t.vent.supply.value")
local inputTVentSupplyErr = getLogicValue("input.t.vent.supply.err")
local inputTGheInnerValue = getLogicValue("input.t.ghe.inner.value")
local inputTGheInnerErr = getLogicValue("input.t.ghe.inner.err")
local inputTWaterValue = getLogicValue("input.t.water.value")
local inputTWaterErr = getLogicValue("input.t.water.err")
local inputWaterLevel = getLogicValue("input.water.level")
local inputWaterPulse = getLogicValue("input.water.pulse")
local settingLogicDelay = getLogicValue("setting.logic.delay");
local settingKontrolaNaw = getLogicValue("setting.kontrola_naw")
local settingKontrolaZlo = getLogicValue("setting.kontrola_zlo")
local settingTLato = getLogicValue("setting.T_lato")
local settingTNawiewLato = getLogicValue("setting.T_nawiew_lato")
local settingNawiewLato = getLogicValue("setting.Nawiew_lato")
local settingZraszanieLato = getLogicValue("setting.Zraszanie_lato")
local settingRegeneracjaLato = getLogicValue("setting.Regeneracja_lato")
local settingTUpal = getLogicValue("setting.T_upal")
local settingTNawiewUpal = getLogicValue("setting.T_nawiew_upal")
local settingNawiewUpal = getLogicValue("setting.Nawiew_upal")
local settingZraszanieUpal = getLogicValue("setting.Zraszanie_upal")
local settingRegeneracjaUpal = getLogicValue("setting.Regeneracja_upal")
local settingTZima = getLogicValue("setting.T_zima")
local settingTNawiewZima = getLogicValue("setting.T_nawiew_zima")
local settingNawiewZima = getLogicValue("setting.Nawiew_zima")
local settingZraszanieZima = getLogicValue("setting.Zraszanie_zima")
local settingRegeneracjaZima = getLogicValue("setting.Regeneracja_zima")
local settingTMroz = getLogicValue("setting.T_mroz")
local settingTNawiewMroz = getLogicValue("setting.T_nawiew_mroz")
local settingNawiewMroz = getLogicValue("setting.Nawiew_mroz")
local settingZraszanieMroz = getLogicValue("setting.Zraszanie_mroz")
local settingRegeneracjaMroz = getLogicValue("setting.Regeneracja_mroz")
local settingTZamarzaGWC = getLogicValue("setting.T_zamarzaGWC")
local settingHisterezaMroz = getLogicValue("setting.Histereza_mroz")
local settingPauzaZima = getLogicValue("setting.Pauza_zima")
local settingCzasMAX = getLogicValue("setting.CzasMAX")
local settingWspPrzeplywu = getLogicValue("setting.Wsp_przeplywu")
local settingResetWodaZuzycie = getLogicValue("setting.reset.woda_zuzycie")
local settingResetAlertPrzeciek = getLogicValue("setting.reset.alert.przeciek")
local settingResetAlertHistoryczneZalaneZloze = getLogicValue("setting.reset.alert.historyczne_zalane_zloze")
local settingAlertWodaPrzeciekMax = getLogicValue("setting.alert.woda_przeciek_max")
local counterWodaZuzycie_imp = getLogicValue("counter.woda_zuzycie_imp")
local counterDemandTKryt = 0
local counterDemandOkresNawiewu = 0
local counterDemandZraszanie = 0
local counterDemandRegeneracja = 0
local counterCzasNawiewu = 0
local counterCzasZawor = 0
local counterKontrolaNaw = 0
local counterKontrolaZlo = 0
local counterRegeneracjaDodatek = 0
local counterPauzaZima = 0
-- Test: 60 * 1000 to minuty; 1 * 1000 to sekundy
local globalTimerFactor = 60 * 1000
-- states
-- OUTPUTWATERVALVE - stan
if OUTPUTWATERVALVE == nil or firstCall then
OUTPUTWATERVALVE = State.create(0, 0, 1, true)
end
OUTPUTWATERVALVE:call()
-- OUTPUTSIGNALVENTDISABLE - stan
if OUTPUTSIGNALVENTDISABLE == nil or firstCall then
OUTPUTSIGNALVENTDISABLE = State.create(0, 0, 1, true)
end
OUTPUTSIGNALVENTDISABLE:call()
-- COUNTERAKTUALNYSEZON - stan
if COUNTERAKTUALNYSEZON == nil or firstCall then
COUNTERAKTUALNYSEZON = State.create(0, 0, 4, true)
end
COUNTERAKTUALNYSEZON:call()
-- COUNTERAKTUALNYTRYB - stan
if COUNTERAKTUALNYTRYB == nil or firstCall then
COUNTERAKTUALNYTRYB = State.create(0, 0, 8, true)
end
COUNTERAKTUALNYTRYB:call()
-- counters
-- DOWNCOUNTERLOGICDELAY - downcounter
if DOWNCOUNTERLOGICDELAY == nil or firstCall then
DOWNCOUNTERLOGICDELAY = DownCounter.create();
end
DOWNCOUNTERLOGICDELAY:updateParams(settingLogicDelay * 1000);
counterLogicDelay = DOWNCOUNTERLOGICDELAY:timeTo0() / 1000;
counterLogicDelay = (counterLogicDelay < 0) and 0 or counterLogicDelay;
if (counterLogicDelay == 0) then
-- COUNTERCZASNAWIEWU - counter
if COUNTERCZASNAWIEWU == nil or firstCall then
COUNTERCZASNAWIEWU = Counter:create();
end
counterCzasNawiewu = COUNTERCZASNAWIEWU:elapsed() / globalTimerFactor;
-- COUNTERCZASZAWOR - counter
if COUNTERCZASZAWOR == nil or firstCall then
COUNTERCZASZAWOR = Counter:create();
end
counterCzasZawor = COUNTERCZASZAWOR:elapsed() / globalTimerFactor;
-- DOWNCOUNTER_1S - downcounter
if DOWNCOUNTER_1S == nil or firstCall then
DOWNCOUNTER_1S = DownCounter.create();
DOWNCOUNTER_1S:updateParams(1000);
end
-- DOWNCOUNTERPAUZAZIMA - downcounter
if DOWNCOUNTERPAUZAZIMA == nil or firstCall then
DOWNCOUNTERPAUZAZIMA = DownCounter.create();
DOWNCOUNTERPAUZAZIMA:updateParams(0);
end
counterPauzaZima = DOWNCOUNTERPAUZAZIMA:timeTo0() / globalTimerFactor;
counterPauzaZima = (counterPauzaZima < 0) and 0 or counterPauzaZima;
-- resetowanie licznika zużycia wody
if settingResetWodaZuzycie == 1 then
counterWodaZuzycie_imp = 0
setLogicValue("setting.reset.woda_zuzycie", 0)
setLogicValue("counter.woda_zuzycie_imp", counterWodaZuzycie_imp);
end
-- resetowanie alarmu przecieku wody
if settingResetAlertPrzeciek == 1 then
setLogicValue("counter.alert.przeciek", 0)
setLogicValue("setting.reset.alert.przeciek", 0)
-- zeruj licznik ilości wody dla przecieku
COUNTERWODAPRZECIEK_IMP = 0
end
-- resetowanie alarmu historycznego zalane złoże
if settingResetAlertHistoryczneZalaneZloze == 1 then
setLogicValue("counter.alert.historyczne_zalane_zloze", 0)
setLogicValue("setting.reset.alert.historyczne_zalane_zloze", 0)
end
-- upływa licznik 1s
if DOWNCOUNTER_1S:elapsed() then
-- aktualizacja zużycia wody (sumarycznie)
counterWodaZuzycie_imp = counterWodaZuzycie_imp + inputWaterPulse;
-- zapisz zużycie wody (sumarycznie)
setLogicValue("counter.woda_zuzycie_imp", counterWodaZuzycie_imp);
-- aktualizacja przepływu wody (cykl)
if OUTPUTWATERVALVE:getValue() == 1 then
COUNTERWODACYKLZUZYCIE_IMP = COUNTERWODACYKLZUZYCIE_IMP + inputWaterPulse;
end
-- aktualizacja przepływu dla przecieku wody (przy zamkniętym zaworze)
if OUTPUTWATERVALVE:getValue() == 0 then
COUNTERWODAPRZECIEK_IMP = COUNTERWODAPRZECIEK_IMP + inputWaterPulse;
end
DOWNCOUNTER_1S:updateParams(1000);
DOWNCOUNTER_1S:reset();
end
-- aktualny przepływ wody z impulsów na litry
local counterWodaPrzeplywL = inputWaterPulse / settingWspPrzeplywu
-- zużycie wody w aktualnym cyklu z impulsów na litry
local counterWodaCyklZuzycie_l = COUNTERWODACYKLZUZYCIE_IMP / settingWspPrzeplywu
-- zużycie wody sumarycznie z impulsów na litry
local counterWodaZuzycie_l = counterWodaZuzycie_imp / settingWspPrzeplywu
-- zużycie przecieku wody z impulsów na litry
local counterWodaPrzeciek_l = COUNTERWODAPRZECIEK_IMP / settingWspPrzeplywu
-- jeżeli jakikolwiek błąd temperatury
if inputTOutdoorErr ~= 0 or inputTVentSupplyErr ~= 0 or inputTGheInnerErr ~= 0 or inputTWaterErr ~= 0 then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- włącz sygnał blokowania nawiewu
OUTPUTSIGNALVENTDISABLE:setValue(1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
-- alarm braku wody
if getLogicValue("counter.alert.brak_wody") == 1 then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- włącz sygnał blokowania nawiewu
OUTPUTSIGNALVENTDISABLE:setValue(1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
-- alarm przecieku wody
if counterWodaPrzeciek_l >= settingAlertWodaPrzeciekMax then
-- ustaw alarm przecieku wody
setLogicValue("counter.alert.przeciek", 1)
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- włącz sygnał blokowania nawiewu
OUTPUTSIGNALVENTDISABLE:setValue(1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
-- alarm odmrażania złoża
if getLogicValue("counter.alert.odmrazanie_zloza") == 1 then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- włącz sygnał blokowania nawiewu
OUTPUTSIGNALVENTDISABLE:setValue(1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
-- alarm zalane złoże
if inputWaterLevel == 1 then
-- ustaw alarm zalane złoże
setLogicValue("counter.alert.zalane_zloze", 1)
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- włącz sygnał blokowania nawiewu
OUTPUTSIGNALVENTDISABLE:setValue(1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
else
if getLogicValue("counter.alert.zalane_zloze") == 1 then
-- ustaw alarm historyczne zalane złoże
setLogicValue("counter.alert.historyczne_zalane_zloze", 1)
end
-- zresetuj alarm zalane złoże
setLogicValue("counter.alert.zalane_zloze", 0)
end
-- aktualizuj temperaturę wody (tylko podczas przepływu wody)
if inputWaterPulse > 0 then
setLogicValue("counter.t.water", inputTWaterValue)
end
-- jeżeli nastawa użytkownika "kontroli nawiewu" nieaktywna lub aktywny alarm braku regeneracji nawiew to nie kontroluj temperatury nawiewu
if settingKontrolaNaw == 0 or getLogicValue("counter.alert.brak_regeneracji_nawiew") == 1 then
counterKontrolaNaw = 0
else
counterKontrolaNaw = 1
end
-- jeżeli nastawa użytkownika "kontroli złoża" nieaktywna to nie kontroluj temperatury złoża
if settingKontrolaZlo == 0 then
counterKontrolaZlo = 0
else
counterKontrolaZlo = 1
end
-- ustalaj sezon tylko gdy aktualny tryb to: 0 - Brak pracy
if COUNTERAKTUALNYTRYB:getValue() == 0 then
-- ustalenie sezonu
if inputTOutdoorValue >= settingTLato then
if inputTOutdoorValue >= settingTUpal then
-- upał
COUNTERAKTUALNYSEZON:setValue(2)
else
-- lato
COUNTERAKTUALNYSEZON:setValue(1)
end
elseif inputTOutdoorValue < settingTZima then
if inputTOutdoorValue < settingTMroz then
-- mróz
COUNTERAKTUALNYSEZON:setValue(4)
else
-- zima
COUNTERAKTUALNYSEZON:setValue(3)
end
else
-- przejściowy
COUNTERAKTUALNYSEZON:setValue(0)
end
end
if COUNTERAKTUALNYSEZON:getValue() == 1 then
-- lato
counterDemandTKryt = settingTNawiewLato
counterDemandOkresNawiewu = settingNawiewLato
counterDemandZraszanie = settingZraszanieLato
counterDemandRegeneracja = settingRegeneracjaLato
elseif COUNTERAKTUALNYSEZON:getValue() == 2 then
-- upał
counterDemandTKryt = settingTNawiewUpal
counterDemandOkresNawiewu = settingNawiewUpal
counterDemandZraszanie = settingZraszanieUpal
counterDemandRegeneracja = settingRegeneracjaUpal
elseif COUNTERAKTUALNYSEZON:getValue() == 3 then
-- zima
counterDemandTKryt = settingTNawiewZima
counterDemandOkresNawiewu = settingNawiewZima
counterDemandZraszanie = settingZraszanieZima
-- dodatek do regeneracji złoża obliczany na podstawie temp. zewnętrznej
-- jeżeli temperatura powyżej 0*C to dodatek 0, jeżeli poniżej 0*C to dodatek = regeneracja*t_zew/10
if inputTOutdoorValue < 0 then
counterRegeneracjaDodatek = settingRegeneracjaZima * -(inputTOutdoorValue / 100)
else
counterRegeneracjaDodatek = 0
end
counterDemandRegeneracja = settingRegeneracjaZima + counterRegeneracjaDodatek
elseif COUNTERAKTUALNYSEZON:getValue() == 4 then
-- mróz
counterDemandTKryt = settingTNawiewMroz
counterDemandOkresNawiewu = settingNawiewMroz
counterDemandZraszanie = settingZraszanieMroz
-- dodatek do regeneracji złoża obliczany na podstawie temp. zewnętrznej
-- jeżeli temperatura powyżej 0*C to dodatek 0, jeżeli poniżej 0*C to dodatek = regeneracja*t_zew/10
if inputTOutdoorValue < 0 then
counterRegeneracjaDodatek = settingRegeneracjaMroz * -(inputTOutdoorValue / 100)
else
counterRegeneracjaDodatek = 0
end
counterDemandRegeneracja = settingRegeneracjaMroz + counterRegeneracjaDodatek
else
-- przejściowy
counterDemandTKryt = 0
counterDemandOkresNawiewu = 0
counterDemandZraszanie = 0
counterDemandRegeneracja = 0
end
-- jeżeli tryb to 0 - Brak pracy
if COUNTERAKTUALNYTRYB:getValue() == 0 then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- wyłącz sygnał blokowania nawiewu
OUTPUTSIGNALVENTDISABLE:setValue(0)
-- wyzeruj czas nawiewu
COUNTERCZASNAWIEWU:reset()
-- zresetuj licznik zużycia wody w aktualnym cyklu
COUNTERWODACYKLZUZYCIE_IMP = 0
-- jeżeli sezon to lato lub upał
if COUNTERAKTUALNYSEZON:getValue() == 1 or COUNTERAKTUALNYSEZON:getValue() == 2 then
-- zmień tryb na lato (cykl główny)
COUNTERAKTUALNYTRYB:setValue(1)
end
-- jeżeli sezon to zima lub mróz
if COUNTERAKTUALNYSEZON:getValue() == 3 or COUNTERAKTUALNYSEZON:getValue() == 4 then
-- zmień tryb na zima (cykl główny)
COUNTERAKTUALNYTRYB:setValue(4)
end
end
-- jeżeli tryb to 1 - lato (cykl główny)
if COUNTERAKTUALNYTRYB:getValue() == 1 then
-- jeżeli kontrola nawiewu w tym cyklu i temperatura nawiewu większa niż temperatura krytyczna to ustaw tryb na regeneracja lato
if counterKontrolaNaw == 1 and inputTVentSupplyValue >= counterDemandTKryt then
COUNTERAKTUALNYTRYB:setValue(2)
end
-- jeżeli czas nawiewu większy niż okres nawiewu to ustaw tryb na zraszanie lato
if counterCzasNawiewu >= counterDemandOkresNawiewu then
COUNTERAKTUALNYTRYB:setValue(3)
end
end
-- jeżeli tryb to 2 - regeneracja lato
if COUNTERAKTUALNYTRYB:getValue() == 2 then
-- otwórz zawór
OUTPUTWATERVALVE:setValue(1)
-- jeżeli zużycie wody w aktualnym cyklu większe niż wymagane do regeneracji
if counterWodaCyklZuzycie_l >= counterDemandRegeneracja then
-- jeżeli temperatura nawiewu spadła do wartości krytycznej lub niżej to zakończ regenerację
if inputTVentSupplyValue <= counterDemandTKryt then
-- skasuj alarm braku regeneracji nawiewu
setLogicValue("counter.alert.brak_regeneracji_nawiew", 0)
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zakończ regenerację, tyb na 1 - lato (cykl główny)
COUNTERAKTUALNYTRYB:setValue(1)
else
-- ustaw alarm braku regeneracji nawiew
setLogicValue("counter.alert.brak_regeneracji_nawiew", 1)
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zakończ regenerację, tyb na 1 - lato (cykl główny)
COUNTERAKTUALNYTRYB:setValue(1)
end
else
-- jeżeli zawór jest otwarty i upłynął czas większy niż czas maksymalny to ustaw alarm braku wody
if counterCzasZawor >= settingCzasMAX then
-- ustaw alarm braku wody
setLogicValue("counter.alert.brak_wody", 1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
end
end
-- jeżeli tryb to 3 - zraszanie lato
if COUNTERAKTUALNYTRYB:getValue() == 3 then
-- otwórz zawór
OUTPUTWATERVALVE:setValue(1)
-- jeżeli zroszono złoże odpowiednią ilością wody to zakończ zraszanie
if counterWodaCyklZuzycie_l >= counterDemandZraszanie then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zakończ zraszanie, tyb na 0 - brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
else
-- jeżeli zawór jest otwarty i upłynął czas większy niż czas maksymalny to ustaw alarm braku wody
if counterCzasZawor >= settingCzasMAX then
-- ustaw alarm braku wody
setLogicValue("counter.alert.brak_wody", 1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
end
end
-- jeżeli tryb to 4 - zima (cykl główny)
if COUNTERAKTUALNYTRYB:getValue() == 4 then
-- jeżeli kontrola złoża w tym cyklu i temperatura złoża mniejsza niż temperatura zamarzania to ustaw tryb na odmrażanie
if counterKontrolaZlo == 1 and inputTGheInnerValue <= settingTZamarzaGWC then
COUNTERAKTUALNYTRYB:setValue(7)
end
-- jeżeli kontrola nawiewu w tym cyklu i temperatura nawiewu większa niż temperatura krytyczna to ustaw tryb na regeneracja zima
if counterKontrolaNaw == 1 and inputTVentSupplyValue <= counterDemandTKryt then
COUNTERAKTUALNYTRYB:setValue(5)
end
-- jeżeli czas nawiewu większy niż okres nawiewu to ustaw tryb na zraszanie zima
if counterCzasNawiewu >= counterDemandOkresNawiewu then
COUNTERAKTUALNYTRYB:setValue(6)
end
end
-- jeżeli tryb to 5 - regeneracja zima
if COUNTERAKTUALNYTRYB:getValue() == 5 then
-- otwórz zawór
OUTPUTWATERVALVE:setValue(1)
-- jeżeli zużycie wody w aktualnym cyklu większe niż wymagane do regeneracji
if counterWodaCyklZuzycie_l >= counterDemandRegeneracja then
-- jeżeli temperatura nawiewu wzrosła powyżej wartości krytycznej to zakończ regenerację
if inputTVentSupplyValue >= counterDemandTKryt then
-- skasuj alarm braku regeneracji nawiewu
setLogicValue("counter.alert.brak_regeneracji_nawiew", 0)
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zakończ regenerację, tyb na 4 - zima (cykl główny)
COUNTERAKTUALNYTRYB:setValue(4)
else
-- ustaw alarm braku regeneracji nawiew
setLogicValue("counter.alert.brak_regeneracji_nawiew", 1)
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zakończ regenerację, tyb na 4 - zima (cykl główny)
COUNTERAKTUALNYTRYB:setValue(4)
end
else
-- jeżeli zawór jest otwarty i upłynął czas większy niż czas maksymalny to ustaw alarm braku wody
if counterCzasZawor >= settingCzasMAX then
-- ustaw alarm braku wody
setLogicValue("counter.alert.brak_wody", 1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
end
end
-- jeżeli tryb to 6 - zraszanie zima
if COUNTERAKTUALNYTRYB:getValue() == 6 then
-- otwórz zawór
OUTPUTWATERVALVE:setValue(1)
-- jeżeli zroszono złoże odpowiednią ilością wody to zakończ zraszanie
if counterWodaCyklZuzycie_l >= counterDemandZraszanie then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zakończ zraszanie, tyb na 0 - brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
else
-- jeżeli zawór jest otwarty i upłynął czas większy niż czas maksymalny to ustaw alarm braku wody
if counterCzasZawor >= settingCzasMAX then
-- ustaw alarm braku wody
setLogicValue("counter.alert.brak_wody", 1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
end
end
-- jeżeli tryb to 7 - odmrażanie
if COUNTERAKTUALNYTRYB:getValue() == 7 then
-- sygnał blokady wentylacji
OUTPUTSIGNALVENTDISABLE:setValue(1)
-- otwórz zawór
OUTPUTWATERVALVE:setValue(1)
-- jeżeli zawór jest otwarty i upłynął czas większy niż czas maksymalny to ustaw alarm braku wody
if counterCzasZawor >= settingCzasMAX then
-- ustaw alarm braku wody
setLogicValue("counter.alert.brak_wody", 1)
-- ustaw tryb na brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
-- jeżeli ilość wody w cyklu większa niż dwukrotność wymaganej do regeneracji to alarm odmrażania
if counterWodaCyklZuzycie_l >= counterDemandRegeneracja * 2 then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- ustaw alarm odmrażania
setLogicValue("counter.alert.odmrazanie_zloza", 1)
-- zakończ odmrażanie, tyb na 0 - brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
-- jeżeli temperatura złoża wzrosła powyżej wartości zamarzania z uwzględnieniem histerezy to zakończ odmrażanie
if inputTGheInnerValue >= settingTZamarzaGWC + settingHisterezaMroz then
-- zamknij zawór
OUTPUTWATERVALVE:setValue(0)
-- zresetuj licznik pauzy zimowej
DOWNCOUNTERPAUZAZIMA:updateParams(settingPauzaZima * globalTimerFactor);
DOWNCOUNTERPAUZAZIMA:reset();
-- zakończ odmrażanie, tyb na 8 - pauza po odmrażaniu
COUNTERAKTUALNYTRYB:setValue(8)
end
end
-- jeżeli tryb to 8 - pauza po odmrażaniu
if COUNTERAKTUALNYTRYB:getValue() == 8 then
-- jeżeli licznik pauzy zimowej zakończył odliczanie to
if DOWNCOUNTERPAUZAZIMA:elapsed() then
-- zresetuj licznik pauzy zimowej
DOWNCOUNTERPAUZAZIMA:updateParams(0);
DOWNCOUNTERPAUZAZIMA:reset();
-- wyłącz blokadę wentylacji
OUTPUTSIGNALVENTDISABLE:setValue(0)
-- zakończ pauzę po odmrażaniu, tyb na 0 - brak pracy
COUNTERAKTUALNYTRYB:setValue(0)
end
end
-- jeżeli zawór zamknięty to
if OUTPUTWATERVALVE:getValue() == 0 then
-- zresetuj licznik czasu zaworu
COUNTERCZASZAWOR:reset()
end
-- jeżeli stan zaworu uległ zmianie na otwarty to zresetuj licznik zużycia wody w aktualnym cyklu
if OUTPUTWATERVALVE:isChanged() == 1 and OUTPUTWATERVALVE:getValue() == 1 then
COUNTERWODACYKLZUZYCIE_IMP = 0
end
-- jeżeli stan zaworu uległ zmianie na otwarty to zresetuj licznik przecieku wody
if OUTPUTWATERVALVE:isChanged() == 1 and OUTPUTWATERVALVE:getValue() == 1 then
COUNTERWODAPRZECIEK_IMP = 0
end
-- wyłącz sygnał blokowania nawiewu jeżeli wcześniej nie został włączony
OUTPUTSIGNALVENTDISABLE:setValue(0)
-- send logic variables to ibmanager
setLogicValue("output.water.valve", OUTPUTWATERVALVE:getValue())
setLogicValue("output.signal.vent.disable", OUTPUTSIGNALVENTDISABLE:getValue())
setLogicValue("counter.aktualnySezon", COUNTERAKTUALNYSEZON:getValue())
setLogicValue("counter.aktualnyTryb", COUNTERAKTUALNYTRYB:getValue())
setLogicValue("counter.demand.t_kryt", counterDemandTKryt)
setLogicValue("counter.demand.okres_nawiewu", counterDemandOkresNawiewu)
setLogicValue("counter.demand.zraszanie", counterDemandZraszanie)
setLogicValue("counter.demand.regeneracja", counterDemandRegeneracja)
setLogicValue("counter.regeneracja_dodatek", counterRegeneracjaDodatek)
setLogicValue("counter.czas_nawiewu", counterCzasNawiewu)
setLogicValue("counter.czas_zawor", counterCzasZawor)
setLogicValue("counter.woda_przeplyw_l", counterWodaPrzeplywL)
setLogicValue("counter.woda_cykl_zuzycie_imp", COUNTERWODACYKLZUZYCIE_IMP)
setLogicValue("counter.woda_cykl_zuzycie_l", counterWodaCyklZuzycie_l)
setLogicValue("counter.woda_zuzycie_imp", counterWodaZuzycie_imp)
setLogicValue("counter.woda_zuzycie_l", counterWodaZuzycie_l)
setLogicValue("counter.woda_przeciek_imp", COUNTERWODAPRZECIEK_IMP)
setLogicValue("counter.woda_przeciek_l", counterWodaPrzeciek_l)
setLogicValue("counter.kontrola_naw", counterKontrolaNaw)
setLogicValue("counter.kontrola_zlo", counterKontrolaZlo)
setLogicValue("counter.Pauza_zima", counterPauzaZima)
end
setLogicValue("counter.logic.delay", counterLogicDelay);
end