-- ======================
-- Description
-- ======================
--
-- Logika sterująca rekuperatorem.
--
-- Osobny wentylator nawiewny i wywiewny, każdy sterowany proporcjonalnie. Dowolna ilość nastawialnych poziomów wentylacji.
--
-- Obsługa okapu.
--
-- Obsługa trybu override (obejście).
--
-- Obsługa bypassu. Sterowanie bypassem polega na przepływie powietrza przez wymiennik (odbiór ciepła lub chłodu z powietrza wywiewanego)
-- lub pomijając go (powietrze nawiewane wprost z powietrza wchodzącego na rekuperator). System ustawia tak bypass aby powietrze
-- nawiewane miało wyższe parametry (ogrzewanie pasywne) lub niższe parametry (chłodzenie pasywne).
--
-- Tryb ogrzewania i chłodzenia przez wentylację.
--
-- W okresie zimowym jest możliwe tylko ogrzewanie pasywne.
--
-- W okresie letnim jest możliwe chłodzenie pasywne lub ogrzewanie pasywne. Jeżeli temperatura wewnętrzna jest powyżej temperatury
-- minimalnej to następuje chłodzenie pasywne. Jeżeli temperatura wewnętrzna jest poniżej temperatury minimalnej to zaprzestawane
-- jest chłodzenie pasywne a bypass jest wysterowany tak aby podczas wentylacji wybierać cieplejsze źródło.
--
--
-- ======================
-- Parameters
-- ======================
--
-- SubLogic supports following variables:
--
-- input.inside.t.value
-- input.inside.t.err - temperatura wewnętrzna
--
-- input.vent.in.t.value
-- input.vent.in.t.err - temperatura powietrza wejścia na rekuperator (z GWC lub czerpni)
--
-- input.vent.exhaust.t.value
-- input.vent.exhaust.t.err - temperatura powietrza wywiewanego
--
-- input.outdoor.t.value
-- input.outdoor.t.err - temperatura zewnętrzna
--
-- input.season - 0 - winter, 1 - summer [0..1]
--
-- input.override - sygnał tymczasowego obejścia wentylacji [0 - brak sygnału; różne od 0 - jest sygnał]
--
-- input.hood - sygnał z okapu (1 - ma być realizowana funkcja okapu) [0 - brak sygnału; różne od 0 - jest sygnał]
--
-- output.fan.supply - wentylator nawiewny [0..100]
--
-- output.fan.exhaust - wentylator wywiewny [0..100]
--
-- output.hood.airdamper - przepustnica okapu (0 - wyciąg normalnie; 1 - wyciąg z okapu) [0..1]
--
-- output.bypass.airdamper - by-pass wymiennika (0 - przez wymiennik; 1 - przez by-pass) [0..1]
--
-- setting.inside.t.max - maksymalna temperatura wewnętrzna zimą, powyżej której nie jest realizowane
-- ogrzewanie przez wentylację
--
-- setting.inside.t.min - minimalna temperatura wewnętrzna latem, poniżej której wybierane jest włączane
-- ogrzewanie pasywne (bypass)
--
-- setting.inside.t.hyst - histereza załączania/zmiany biegu wentylatora w funkcji różnicy temperatury
-- zadanej a panującej
--
-- setting.inside.dt.on
-- setting.inside.dt.off - wymagana różnica temperatury między powietrzem wewnętrznym i zewnętrznym
-- do obsługi ogrzewania lub chłodzenia przez wentylację
--
-- setting.fan.level.demand - aktualnie wymagany bieg wentylacji
--
-- setting.heating.enabled - ogrzewanie przez wentylację (freeheating) (0 - nieaktywne; 1 - aktywne). [0..1]
-- Ogrzewanie przez wentylacje jest realizowane:
-- - tylko zimą
-- - tylko gdy nie ma błędu temperatury wewnętrzne i zewnętrznej (counter.alert.t.state)
-- - jeżeli w pomieszczeniu jest poniżej maksymalnej wewnętrznej (counter.inside.t.max.status = 0)
-- - temperatura zewnętrzna jest wyższa niż wewnętrzna (counter.alert.inside.dt.t.state = 1)
--
-- setting.cooling.enabled - chłodzenie przez wentylację (freecooling) (0 - nieaktywne; 1 - aktywne). [0..1]
-- Chłodzenie przez wentylacje jest realizowane
-- - tylko latem
-- - tylko gdy nie ma błędu temperatury wewnętrzne i zewnętrznej (counter.alert.t.state)
-- - jeżeli w pomieszczeniu jest powyżej minimalnej wewnętrznej (counter.inside.t.min.status = 0)
-- - temperatura zewnętrzna jest niższa niż wewnętrzna (counter.alert.inside.dt.t.state = 1)
--
-- setting.heating.fan.level - poziom wentylacji przy ogrzewaniu pasywnym (freeheating)
--
-- setting.cooling.fan.level - poziom wentylacji przy chłodzeniu pasywnym (freecooling)
--
-- setting.hood.fan.supply - wartość wentylatora nawiewnego przy aktywnym okapie [0..100]
--
-- setting.hood.fan.exhaust - wartość wentylatora wywiewnego przy aktywnym okapie [0..100]
--
-- setting.bypass.dt.on
-- setting.bypass.dt.off - wymagana różnica temperatury między powietrzem nawiewanym a wywiewanym do obsługi bypass'u
--
-- setting.fan.level.supply - lista wartości wentylatora nawiewnego na danym biegu [0..100]
--
-- setting.fan.level.exhaust - lista wartości wentylatora wywiewnego na danym biegu [0..100]
--
-- setting.override.fan.level - poziom wentylacji w trybie override
--
-- counter.inside.t.min.status - flaga: czy warunek minimalna temperatury wewnętrznej latem, poniżej której
-- zaprzestawane jest chłodzenie przez wentylację a podczas normalnej wentylacji
-- wybierane jest cieplejsze źródła ciepła (sterowanie bypass'em).
-- Zimą wartość zawsze 1. [0..1]
--
-- counter.inside.t.max.status - flaga: czy warunek maksymalnej temperatury wewnętrznej zimą, powyżej której
-- zaprzestawane jest ogrzewanie przez wentylację. Latem wartość zawsze 0. [0..1]
--
-- counter.bypass.heating.dt.status - flaga: czy warunek dt bypassu dla ogrzewania jest spełniony [0..1]
-- (dt temperatury wejścia na rekuperator i wyciągu) [0..1]
--
-- counter.bypass.cooling.dt.status - flaga: czy warunek dt bypassu dla chłodzenia jest spełniony
-- (dt temperatury wyciągu i wejścia na rekuperator) [0..1]
--
-- counter.inside.heating.dt.status - flaga: czy warunek dt dla ogrzewania przez wentylację jest spełniony (freeheating)
-- (dt temperatury wewnętrznej i zewnętrznej). Latem zawsze 0. [0..1]
--
-- counter.inside.cooling.dt.status - flaga: czy warunek dt dla chłodzenia przez wentylację jest spełniony (freecooling)
-- (dt temperatury wewnętrznej i zewnętrznej). Zimą zawsze 0. [0..1]
--
-- counter.inside.cooling.status - flaga: czy aktualnie jest realizowany proces chłodzenia przez wentylację (freecooling)
--
-- counter.inside.heating.status - flaga: czy aktualnie jest realizowany proces ogrzewania przez wentylację (freeheating)
--
-- counter.fan.levels.count - ilość biegów wentylacji
--
-- counter.alert.bypass.t.state - jeżeli któryś z czujników, niezbędny do obsługi bypassu jest uszkodzony to ta flaga
-- jest ustawiana na 1. W takim przypadku bypass jest zawsze zamknięty [0..1]
--
-- counter.alert.inside.dt.t.state - jeżeli któryś z czujników, niezbędny do obsługi ogrzewania lub chłodzenia przez
-- wentylacje jest uszkodzony to ta flaga jest ustawiana na 1. W takim przypadku
-- nie jest realizowane ogrzewanie i chłodzenie przez wentylację [0..1]
--
-- 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.2.5
--
-- # zmiana nazwy parametru outside -> outdoor
--
-- 2019-06-04 ver 0.1.4
--
-- + dodanie flag freecooling i freeheating
--
-- 2018-07-07 ver 0.0.3
--
-- # zabezpieczenie delt
--
-- 2017-07-26 ver 0.0.2
--
-- # input.override, input.hood - sygnał załączenia >0
--
-- 2017-06-07 ver 0.0.1
--
-- # obsługa automatycznego build'a
-- # opis logiki
--
-- 2017-06-05 ver 0.0.0
--
-- # First release
--
--
-- 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_outputFanSupply = nil;
g_outputFanExhaust = nil;
g_outputHoodAirdamper = nil;
g_outputBypassAirdamper = nil;
g_counterInsideTMinStatus = nil;
g_counterInsideTMaxStatus = nil;
g_counterBypassHeatingDtStatus = nil;
g_counterBypassCoolingDtStatus = nil;
g_counterInsideHeatingDtStatus = nil;
g_counterInsideCoolingDtStatus = nil;
g_settingInsideDtOn = nil;
g_settingInsideDtOff = nil;
g_settingBypassDtOn = nil;
g_settingBypassDtOff = nil;
SUPPORTED_SUBLOGIC_TYPE = "Recu01";
SUPPORTED_SUBLOGIC_VERSION = "1.2.5";
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 inputInsideTValue = getLogicValue("input.inside.t.value");
local inputInsideTErr = getLogicValue("input.inside.t.err");
local inputVentInTValue = getLogicValue("input.vent.in.t.value");
local inputVentInTErr = getLogicValue("input.vent.in.t.err");
local inputVentExhaustTValue = getLogicValue("input.vent.exhaust.t.value");
local inputVentExhaustTErr = getLogicValue("input.vent.exhaust.t.err");
local inputOutdoorTValue = getLogicValue("input.outdoor.t.value");
local inputOutdoorTErr = getLogicValue("input.outdoor.t.err");
local inputSeason = getLogicValue("input.season");
local inputOverride = getLogicValue("input.override");
local inputHood = getLogicValue("input.hood");
local settingInsideTMax = getLogicValue("setting.inside.t.max");
local settingInsideTMin = getLogicValue("setting.inside.t.min");
local settingInsideTHyst = getLogicValue("setting.inside.t.hyst");
local settingInsideDtOn = getLogicValue("setting.inside.dt.on");
local settingInsideDtOff = getLogicValue("setting.inside.dt.off");
local settingFanLevelDemand = getLogicValue("setting.fan.level.demand");
local settingHeatingEnabled = getLogicValue("setting.heating.enabled");
local settingCoolingEnabled = getLogicValue("setting.cooling.enabled");
local settingHeatingFanLevel = getLogicValue("setting.heating.fan.level");
local settingCoolingFanLevel = getLogicValue("setting.cooling.fan.level");
local settingHoodFanSupply = getLogicValue("setting.hood.fan.supply");
local settingHoodFanExhaust = getLogicValue("setting.hood.fan.exhaust");
local settingBypassDtOn = getLogicValue("setting.bypass.dt.on");
local settingBypassDtOff = getLogicValue("setting.bypass.dt.off");
local settingFanLevelSupplyList = getVarList("setting.fan.level.supply");
local settingFanLevelExhaustList = getVarList("setting.fan.level.exhaust");
local settingOverrideFanLevel = getLogicValue("setting.override.fan.level");
local counterFanLevelsCount = 0;
local counterAlertBypassTState = 0;
local counterAlertInsideDtTState = 0;
local counterInsideCoolingStatus = 0;
local counterInsideHeatingStatus = 0;
local FanLevelSupplyList = {};
local FanLevelExhaust = {};
-- states
if g_outputFanSupply == nil or firstCall then
g_outputFanSupply = State.create(0, 0, 100, true);
end
g_outputFanSupply:call();
if g_outputFanExhaust == nil or firstCall then
g_outputFanExhaust = State.create(0, 0, 100, true);
end
g_outputFanExhaust:call();
if g_outputHoodAirdamper == nil or firstCall then
g_outputHoodAirdamper = State.create(0, 0, 1, true);
end
g_outputHoodAirdamper:call();
if g_outputBypassAirdamper == nil or firstCall then
g_outputBypassAirdamper = State.create(0, 0, 1, true);
end
g_outputBypassAirdamper:call();
if g_counterInsideTMinStatus == nil or firstCall then
g_counterInsideTMinStatus = State.create(0, 0, 1, true);
end
g_counterInsideTMinStatus:call();
if g_counterInsideTMaxStatus == nil or firstCall then
g_counterInsideTMaxStatus = State.create(0, 0, 1, true);
end
g_counterInsideTMaxStatus:call();
if g_counterBypassHeatingDtStatus == nil or firstCall then
g_counterBypassHeatingDtStatus = State.create(0, 0, 1, true);
end
g_counterBypassHeatingDtStatus:call();
if g_counterBypassCoolingDtStatus == nil or firstCall then
g_counterBypassCoolingDtStatus = State.create(0, 0, 1, true);
end
g_counterBypassCoolingDtStatus:call();
if g_counterInsideHeatingDtStatus == nil or firstCall then
g_counterInsideHeatingDtStatus = State.create(0, 0, 1, true);
end
g_counterInsideHeatingDtStatus:call();
if g_counterInsideCoolingDtStatus == nil or firstCall then
g_counterInsideCoolingDtStatus = State.create(0, 0, 1, true);
end
g_counterInsideCoolingDtStatus:call();
-- zabezpieczenie delt
--InsideDt
if g_settingInsideDtOn == nil or firstCall then
g_settingInsideDtOn = settingInsideDtOn;
end
if g_settingInsideDtOff == nil or firstCall then
g_settingInsideDtOff = settingInsideDtOff;
end
if (g_settingInsideDtOn ~= settingInsideDtOn) then
if (settingInsideDtOn <= settingInsideDtOff) then
settingInsideDtOn = settingInsideDtOff + 1;
setLogicValue("setting.inside.dt.on", settingInsideDtOn);
end
end
if (g_settingInsideDtOff ~= settingInsideDtOff) then
if (settingInsideDtOff >= settingInsideDtOn) then
settingInsideDtOff = settingInsideDtOn - 1;
setLogicValue("setting.inside.dt.off", settingInsideDtOff);
end
end
-- w przypadku pozostałości ze storage
if (settingInsideDtOn <= settingInsideDtOff) then
settingInsideDtOn = settingInsideDtOff + 1;
setLogicValue("setting.inside.dt.on", settingInsideDtOn);
end
g_settingInsideDtOn = settingInsideDtOn;
g_settingInsideDtOff = settingInsideDtOff;
--BypassDt
if g_settingBypassDtOn == nil or firstCall then
g_settingBypassDtOn = settingBypassDtOn;
end
if g_settingBypassDtOff == nil or firstCall then
g_settingBypassDtOff = settingBypassDtOff;
end
if (g_settingBypassDtOn ~= settingBypassDtOn) then
if (settingBypassDtOn <= settingBypassDtOff) then
settingBypassDtOn = settingBypassDtOff + 1;
setLogicValue("setting.bypass.dt.on", settingBypassDtOn);
end
end
if (g_settingBypassDtOff ~= settingBypassDtOff) then
if (settingBypassDtOff >= settingBypassDtOn) then
settingBypassDtOff = settingBypassDtOn - 1;
setLogicValue("setting.bypass.dt.off", settingBypassDtOff);
end
end
-- w przypadku pozostałości ze storage
if (settingBypassDtOn <= settingBypassDtOff) then
settingBypassDtOn = settingBypassDtOff + 1;
setLogicValue("setting.bypass.dt.on", settingBypassDtOn);
end
g_settingBypassDtOn = settingBypassDtOn;
g_settingBypassDtOff = settingBypassDtOff;
-- obsługa alarmowa
if ((inputInsideTErr ~= 0) or (inputVentInTErr ~= 0) or (inputVentExhaustTErr ~= 0)) then
counterAlertBypassTState = 1;
g_counterInsideTMinStatus:setValue(0);
g_counterBypassCoolingDtStatus:setValue(0);
g_counterBypassHeatingDtStatus:setValue(0);
g_outputBypassAirdamper:setValue(0);
end
if ((inputInsideTErr ~= 0) or (inputOutdoorTErr ~= 0)) then
counterAlertInsideDtTState = 1;
g_counterInsideHeatingDtStatus:setValue(0);
g_counterInsideCoolingDtStatus:setValue(0);
end
-- demand temperatures states
if (inputSeason == 0) then
g_counterInsideTMinStatus:setValue(0);
g_counterInsideTMaxStatus:set1IfHigherThan(inputInsideTValue, settingInsideTMax, settingInsideTHyst);
g_counterInsideHeatingDtStatus:setIfDelta(inputOutdoorTValue, inputInsideTValue, settingInsideDtOn, settingInsideDtOff);
g_counterInsideCoolingDtStatus:setValue(0);
g_counterBypassCoolingDtStatus:setValue(0);
g_counterBypassHeatingDtStatus:setIfDelta(inputVentInTValue, inputVentExhaustTValue, settingBypassDtOn, settingBypassDtOff);
else
g_counterInsideTMinStatus:set1IfLowerThan(inputInsideTValue, settingInsideTMin, settingInsideTHyst);
g_counterInsideTMaxStatus:setValue(0);
g_counterInsideHeatingDtStatus:setValue(0);
g_counterInsideCoolingDtStatus:setIfDelta(inputInsideTValue, inputOutdoorTValue, settingInsideDtOn, settingInsideDtOff);
if (g_counterInsideTMinStatus:getValue() == 0) then
g_counterBypassCoolingDtStatus:setIfDelta(inputVentExhaustTValue, inputVentInTValue, settingBypassDtOn, settingBypassDtOff);
g_counterBypassHeatingDtStatus:setValue(0);
else
g_counterBypassCoolingDtStatus:setValue(0);
g_counterBypassHeatingDtStatus:setIfDelta(inputVentInTValue, inputVentExhaustTValue, settingBypassDtOn, settingBypassDtOff);
end
end
-- sterowanie bypassem
if (g_counterBypassHeatingDtStatus:getValue() == 1) or (g_counterBypassCoolingDtStatus:getValue() == 1) then
g_outputBypassAirdamper:setValue(1);
else
g_outputBypassAirdamper:setValue(0);
end
-- sterowanie okapem
if (inputHood ~= 0) then
g_outputHoodAirdamper:setValue(1);
g_outputFanSupply:setValue(settingHoodFanSupply);
g_outputFanExhaust:setValue(settingHoodFanExhaust);
else
g_outputHoodAirdamper:setValue(0);
end
-- tablica wartości wentylacji na podstawie ustawień
if settingFanLevelSupplyList ~= nil then
for var, value in pairs(settingFanLevelSupplyList) do
FanLevelSupplyList[var] = value;
counterFanLevelsCount = counterFanLevelsCount + 1;
end
end
if settingFanLevelExhaustList ~= nil then
for var, value in pairs(settingFanLevelExhaustList) do
FanLevelExhaust[var] = value;
end
end
-- zabezpieczenie przed zbyt wysokimi biegami nastaw
if (settingFanLevelDemand >= counterFanLevelsCount) then
settingFanLevelDemand = counterFanLevelsCount - 1;
setLogicValue("setting.fan.level.demand", settingFanLevelDemand);
end
if (settingOverrideFanLevel >= counterFanLevelsCount) then
settingOverrideFanLevel = counterFanLevelsCount - 1;
setLogicValue("setting.override.fan.level", settingOverrideFanLevel);
end
if (settingCoolingFanLevel >= counterFanLevelsCount) then
settingCoolingFanLevel = counterFanLevelsCount - 1;
setLogicValue("setting.cooling.fan.level", settingCoolingFanLevel);
end
-- tryb override
if (inputOverride ~= 0) then
g_outputFanSupply:setValue(FanLevelSupplyList['' .. settingOverrideFanLevel]);
g_outputFanExhaust:setValue(FanLevelExhaust['' .. settingOverrideFanLevel]);
end
-- tryb ogrzewania przez wentylację
if (settingHeatingEnabled == 1) and (g_counterInsideHeatingDtStatus:getValue() == 1) and (g_counterInsideTMaxStatus:getValue() == 0) then
g_outputFanSupply:setValue(FanLevelSupplyList['' .. settingHeatingFanLevel]);
g_outputFanExhaust:setValue(FanLevelExhaust['' .. settingHeatingFanLevel]);
counterInsideHeatingStatus = 1;
end
-- tryb chłodzenia przez wentylację
if (settingCoolingEnabled == 1) and (g_counterInsideCoolingDtStatus:getValue() == 1) and (g_counterInsideTMinStatus:getValue() == 0) then
g_outputFanSupply:setValue(FanLevelSupplyList['' .. settingCoolingFanLevel]);
g_outputFanExhaust:setValue(FanLevelExhaust['' .. settingCoolingFanLevel]);
counterInsideCoolingStatus = 1;
end
-- sterowanie normalną pracą wentylacji
g_outputFanSupply:setValue(FanLevelSupplyList['' .. settingFanLevelDemand]);
g_outputFanExhaust:setValue(FanLevelExhaust['' .. settingFanLevelDemand]);
-- send logic variables to ibmanager
setLogicValue("output.fan.supply", g_outputFanSupply:getValue());
setLogicValue("output.fan.exhaust", g_outputFanExhaust:getValue());
setLogicValue("output.hood.airdamper", g_outputHoodAirdamper:getValue());
setLogicValue("output.bypass.airdamper", g_outputBypassAirdamper:getValue());
setLogicValue("counter.inside.t.min.status", g_counterInsideTMinStatus:getValue());
setLogicValue("counter.inside.t.max.status", g_counterInsideTMaxStatus:getValue());
setLogicValue("counter.bypass.heating.dt.status", g_counterBypassHeatingDtStatus:getValue());
setLogicValue("counter.bypass.cooling.dt.status", g_counterBypassCoolingDtStatus:getValue());
setLogicValue("counter.inside.heating.dt.status", g_counterInsideHeatingDtStatus:getValue());
setLogicValue("counter.inside.cooling.dt.status", g_counterInsideCoolingDtStatus:getValue());
setLogicValue("counter.inside.cooling.status", counterInsideCoolingStatus);
setLogicValue("counter.inside.heating.status", counterInsideHeatingStatus);
setLogicValue("counter.fan.levels.count", counterFanLevelsCount);
setLogicValue("counter.alert.bypass.t.state", counterAlertBypassTState);
setLogicValue("counter.alert.inside.dt.t.state", counterAlertInsideDtTState);
end