Verwarming concept in stapjes

Hieronder een zo compleet mogelijke uitleg van hoe ik de structuur heb opgebouwd rond de sturing van mijn verwarming. Ik begin met de meest eenvoudige stapjes en voeg dan stilletjes zaken toe om te komen tot de uiteindelijke programmatie.

img093

Een basis kamer met een radiator en een schema.

Stel, je hebt een kamer met 1 radiator. Nu wil je een tijdsafhankelijke sturing, zodat je bijvoorbeeld het volgende kan instellen:

  • tussen 8u en 10u: 21°C
  • tussen 10u en 15u: 19°C
  • tussen 15u en 22u: 20°C
  • tussen 22u en 8u: 18°C

Om dit volgens een LUA sturing handig op te splitsen moet je een stapje ervoor toevoegen en het laatste stapje opsplitsen:

  • 00:00 tot 08:00 : 18°C
  • 08:01 tot 10:00 : 21°C
  • 10:01 tot 15:00 : 19°C
  • 15:01 tot 22:00 : 20°C
  • 22:01 tot 23:59 : 18°C

Dit schema vertaalt zich in de finale LUA in een structuur:

local schema_x={
  {00,00,08,00,18},
  {08,01,10,00,21},
  {10,01,15,00,19},
  {15,01,22,00,20},
  {22,01,23,59,18}
  }

En dan heb je nog de code die de temperatuur hieruit haalt die nodig is op dat moment:

local parsetemp=schema_x

local time=tonumber(os.date("%H"))*60+tonumber(os.date("%M"))  --huidige tijd
local setlevel=errortemp -- errortemp wanneer er iets misgaat (18°C)
local levelttl=0 -- hoe lang de temperatuur geldig is
local logtotime="--:--" -- voor de log

for i=1,#parsetemp do
  local mintime=parsetemp[i][1]*60+parsetemp[i][2]
  local maxtime=parsetemp[i][3]*60+parsetemp[i][4]
  if ((time>=mintime) and (time<maxtime)) then
    setlevel=parsetemp[i][5]
    levelttl=(maxtime-time-1)
    logtotime=parsetemp[i][3]..":"..parsetemp[i][4]
  end
end

Een kamer met meerdere schema’s.

In sommige kamers wil je misschien meerdere schema’s gebruiken. Eentje voor als het een weekdag is, en een ander voor wanneer het een dag in het weekend is. Naar analogie met hierboven krijg je dan verschillende local’s (hieronder ingekort weergegeven)

local thuisweekdag ={
    {00,00,08,00,18},
    {08,01,22,00,20},
    {22,01,23,59,18}
    }

local thuisweekenddag = {
    {00,00,09,00,18},
    {09,01,23,00,21},
    {23,01,23,59,18}
    }

En de code om het juiste schema te selecteren:

local parsetemp=nil
local schemaName=""

if ((tonumber(os.date("%w"))~=0) and (tonumber(os.date("%w"))~=6)) then
  parsetemp=thuisweekdag
  schemaName="thuisweekdag"
else
  parsetemp=thuisweekenddag
  schemaName="thuisweekenddag"
end

Toevoeging: niemand-thuis schema

Wanneer er niemand thuis is, kan je de verwarming best een graadje lager schakelen. Dit bestaat dus uit twee zaken, enerzijds een soort van “schakelaar” of alarmsysteem-codepaneel waarmee je aan de HC2 kan laten weten of er iemand thuis is of niet, anderzijds een schema specifiek voor de radiator dat geselecteerd moet worden wanneer er niemand thuis is.

Bij mij is dit bepaald door de globale variabele “G_IemandThuis”.

local nietthuis={
  {0,0,23,59,18}
  }

En de selectiecode:

local iemandthuis=tonumber(fibaro:getGlobalValue("G_IemandThuis"))
local parsetemp=nietthuis
local schemaName="nietthuis"

if (iemandthuis==0) then
  parsetemp=nietthuis
  schemaName="nietthuis"
elseif ((tonumber(os.date("%w"))~=0) and (tonumber(os.date("%w"))~=6)) then
  parsetemp=thuisweekdag
  schemaName="thuisweekdag"
else
  parsetemp=thuisweekenddag
  schemaName="thuisweekenddag"
end

Toevoeging: schema afhankelijk van de buitentemperatuur

Wanneer het buiten meer dan 18 graden is, hoef je eigenlijk binnen geen verwarming meer op te zetten vind ik. Vandaar dat ik een schema hiervoor heb toegevoegd.

local buitenwarm={
  {0,0,23,59,16}
  }

En de selectie hier is weer gebaseerd op een globale variabele, die ingevuld wordt vanuit een buitenweerstation of bijvoorbeeld vanuit Yahoo Weather.

local buitenwarmtemp=16 --temperatuur buiten zonder verwarming

local tempbuiten=tonumber(fibaro:getGlobalValue("G_TempBuiten"))

if (tempbuiten>=buitenwarmtemp) then
  parsetemp=buitenwarm
  schemaName="buitenwarm"
elseif (iemandthuis==0) then
  parsetemp=nietthuis
  schemaName="nietthuis"
elseif ((tonumber(os.date("%w"))~=0) and (tonumber(os.date("%w"))~=6)) then
  parsetemp=thuisweekdag
  schemaName="thuisweekdag"
else
  parsetemp=thuisweekenddag
  schemaName="thuisweekenddag"
end




Een kamer met een radiator en een temperatuur sensor (en dus ook aansturing van de warmtevraag naar de ketel)

Wanneer je een sensor hebt hangen in de kamer, die de actuele temperatuur meet, kan je uit het verschil met de ingestelde waarde in de thermostaatkop bepalen of de ketel warmte moet produceren of niet. In mijn opstelling zet ik op voorhand een globale variabele op 0, ga ik alle radiator-LUA-settings schema’s af en als nadien die globale variabele op 1 staat, betekent dit dat er ergens een kamer warmte nodig heeft.

Enerzijds betekent dit een toevoeging in de scene om de radiatorkop in te stellen

local exttemp=74  --id van de externe temperatuursensor

if (exttemp~=0) then
  if (setlevel>tonumber(fibaro:getValue(exttemp,"value"))) then
    fibaro:setGlobal("G_KetelWarmte",1)
    fibaro:debug("Demanding Boiler Heat: "..setlevel.." requested "..fibaro:getValue(exttemp,"value").." measured")
    fibaro:sleep(100)
  end
end

Anderzijds dus ook een aparte scene die alle 5 minuten loopt en alle scenes van de radiatoren afloopt en daarna de ketel al dan niet om warmte vraagt.

--[[
%% properties
%% autostart
%% events
%% globals
--]]

local heatsetids={30,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48}
-- de id's van alle set-scenes van de Danfoss Radiatorkoppen
local nestDevice=196
local ketelHeating=0

while true do
  fibaro:debug("Running scene at: "..os.date())
  local setp=tonumber(fibaro:getValue(nestDevice,"ui.settemp.value"))
  local curlivtmp=tonumber(fibaro:getValue(nestDevice,"ui.curtemp.value"))  
  fibaro:debug("SetPoint: "..setp.."  -  Current: "..curlivtmp)
  if (setp>curlivtmp) then
    ketelHeating=1
  else
    ketelHeating=0
  end
  fibaro:setGlobal("G_KetelWarmte",0)
  for i=1,#heatsetids do
    fibaro:startScene(heatsetids[i])
  end
  fibaro:sleep(10*1000)
  if (tonumber(fibaro:getGlobalValue("G_KetelWarmte"))==1) then
    fibaro:debug("Outcome: G_Ketelwarmte=1")
    if (ketelHeating==1) then
      if (setp>curlivtmp) then
        fibaro:debug("Boiler Heat requested - boiler still active")
      else
        fibaro:debug("Boiler Heat requested - boiler still active - updating temp")
	    fibaro:call(nestDevice,"setProperty", "ui.setpoint.value", curlivtmp+1)
      end  
    else
      fibaro:call(nestDevice,"setProperty", "ui.setpoint.value", curlivtmp+1)
      fibaro:debug("Boiler Heat requested - Activating boiler setting temp to: "..curlivtmp+1)
      fibaro:sleep(100)
    end
  else
    fibaro:debug("Outcome: G_Ketelwarmte=0")
    if (ketelHeating==0) then
      if (setp<curlivtmp) then
        fibaro:debug("Not Requesting Boiler Heat - boiler still inactive")
      else
	    fibaro:call(nestDevice,"setProperty", "ui.setpoint.value", curlivtmp-1)
        fibaro:debug("Not Requesting Boiler Heat - boiler still inactive - updating temp")
        fibaro:sleep(1000)
      end
      --check for temp and adjust not heating temp
    else
      fibaro:call(nestDevice,"setProperty", "ui.setpoint.value", curlivtmp-1)
      fibaro:sleep(1000)
      fibaro:debug("Not Requesting Boiler Heat - Deactivating boiler setting temp to: "..curlivtmp-1)
    end
  end
  fibaro:sleep(4*60*1000) -- slaap 4 minuten
end

In de scene hierboven zit ineens de integratie van mijn eigen gecreëerde NEST Thermostaat aansturing in. Zie daarvoor de specifieke pagina verderdoor.

Toevoeging: open/toe sensor(en)

Wanneer je een kamer aan het verluchten bent, is het niet nodig van de verwarming te laten opstaan. Als je een “open-toe sensor” op de raam installeert, kan je dit schema ook ineens mee verwerken in de scene voor de instelling van de radiatorkop. Ik heb ervoor gekozen om dan het “buitenwarm” schema toe te passen

local extopen=72  --id van de externe open deur/raam sensor

if (extopen~=0) then
  if (tonumber(fibaro:getValue(extopen,"value"))==1) then
    parsetemp=buitenwarm
    schemaName="verluchtingopen"
  end
end

Toevoeging: bewegingssensor

Indien er een kamer is waar een bewegingsdetector hangt, kan je bijvoorbeeld de temperatuur automatisch een graadje hoger zetten, wanneer er het afgelopen half uur nog beweging gedetecteerd is. Perfect om bijvoorbeeld de living op 20°C te zetten normaal gezien, en als er iemand aanwezig is net dat extra beetje gezellige warmte te creëren.

local extmotion=0  --id van de externe bewegingsdetector

if (extmotion~=0) then
  if ((os.time()-fibaro:getValue(extmotion, "lastBreached"))<1800) then
    setlevel=setlevel+1
  end
end

Toevoeging: extra warmte – knop

Wil je toch nog iets extra doen voor de mensen waarmee je samenwoont die het gemakkelijk kou hebben, kan je in een kamer een extra drukknop toevoegen zodat je manueel de temperatuur een graadje hoger kan schakelen.

local extmanplus=37 --id van een externe heat schakelaar +1 graden

if (extmanplus~=0) then
  if (tonumber(fibaro:getValue(extmanplus,"value"))==1) then
    setlevel=setlevel+1
  end
end

Finale LUA script voor de scene die de radiator instelt

Het finale LUA script ziet er dan zo uit:

--[[
%% properties
%% events
%% globals
--]]

local heaterid=133 --id van de thermostaatkop
local heaterfloor="gelijkvloers"
local heaterroom="living"

local extopen1=56  --id van de externe open deur/raam sensor
local extopen2=189  --id van de externe open deur/raam sensor
local extopen3=0  --id van de externe open deur/raam sensor
local exttemp=196  --id van de externe temperatuursensor
local extmotion=149  --id van de externe bewegingsdetector
local extmanplus=37 --id van een externe heat schakelaar +1 graden

local buitenwarmtemp=19 --temperatuur buiten zonder verwarming
local errortemp=18

local iemandthuis=tonumber(fibaro:getGlobalValue("G_IemandThuis"))
local tempbuiten=tonumber(fibaro:getGlobalValue("G_TempBuiten"))

--per "soort" een scrn : vanuut,vanminuut,totuur,totminuut,setvalue
-- voor een normale weekdag
local thuisweekdag={
  {0,0,6,0,18},
  {6,1,20,0,20},
  {20,1,22,0,21},
  {22,1,23,0,20},
  {23,1,23,59,18}
  }

local thuisweekenddag={
  {0,0,6,0,18},
  {6,1,23,0,20},
  {23,1,23,59,18}
  }

local nietthuis={
  {0,0,17,0,18},
  {17,1,18,0,19},
  {18,1,19,00,20},
  {19,01,23,59,18}
  }

local buitenwarm={
  {0,0,23,59,16}
  }

local parsetemp=nietthuis
local schemaName="nietthuis"

if (tempbuiten>=buitenwarmtemp) then
  parsetemp=buitenwarm
  schemaName="buitenwarm"
elseif (iemandthuis==0) then
  parsetemp=nietthuis
  schemaName="nietthuis"
elseif ((tonumber(os.date("%w"))~=0) and (tonumber(os.date("%w"))~=6)) then
  parsetemp=thuisweekdag
  schemaName="thuisweekdag"
else
  parsetemp=thuisweekenddag
  schemaName="thuisweekenddag"
end

if (extopen1~=0) then
  if (tonumber(fibaro:getValue(extopen1,"value"))==1) then
    parsetemp=buitenwarm
    schemaName="verluchtingopen"
  end
end
if (extopen2~=0) then
  if (tonumber(fibaro:getValue(extopen2,"value"))==1) then
    parsetemp=buitenwarm
    schemaName="verluchtingopen"
  end
end

fibaro:debug("T ext.:"..tempbuiten.."; Selected Schema: "..schemaName)

local time=tonumber(os.date("%H"))*60+tonumber(os.date("%M"))
local setlevel=errortemp
local levelttl=0
local logtotime="--:--"

for i=1,#parsetemp do
  local mintime=parsetemp[i][1]*60+parsetemp[i][2]
  local maxtime=parsetemp[i][3]*60+parsetemp[i][4]
  if ((time>=mintime) and (time<maxtime)) then
    setlevel=parsetemp[i][5]
    levelttl=(maxtime-time-1)
    logtotime=parsetemp[i][3]..":"..parsetemp[i][4]
  end
end

if (extmotion~=0) then
  if ((os.time()-fibaro:getValue(extmotion, "lastBreached"))<1800) then setlevel=setlevel+1 end end if (extmanplus~=0) then if (tonumber(fibaro:getValue(extmanplus,"value"))==1) then setlevel=setlevel+1 end end if (exttemp~=0) then if (setlevel>tonumber(fibaro:getValue(exttemp,"ui.curtemp.value"))) then
    fibaro:setGlobal("G_KetelWarmte",1)
    fibaro:debug("Demanding Boiler Heat: "..setlevel.." requested "..fibaro:getValue(exttemp,"ui.curtemp.value").." measured")
  end
end

fibaro:debug("Selected Temp: "..setlevel.." for: "..levelttl.." minutes until "..logtotime)

local currentlevel=tonumber(fibaro:getValue(heaterid,"value"))
if (currentlevel~=setlevel) then
  fibaro:call(heaterid,"setTargetLevel",setlevel)
  fibaro:debug("SETTING - Current setLevel: "..currentlevel.." new level: "..setlevel)
  fibaro:call(heaterid,"setTime",tonumber(os.time(t))+levelttl*60)
end

Aansturing van de ketel

Er zijn een paar mogelijkheden om je centrale verwarmingsketel aan te sturen, afhankelijk van het soort ketel dat je hebt. Wanneer er gewerkt wordt met een eenvoudige “Aan-Uit” thermostaat kan je hiervoor een Fibaro Relais gebruiken. Wat ook mogelijk is, is een intelligente thermostaat, voordeel hiervan is dat je indien je een OpenTherm compatibele thermostaat hebt, zoals ik, deze de ketelsturing ook nog intelligent moduleert. Ik heb hiervoor een NEST thermostaat gekozen. De aansturing daarvan is wel wat moeilijker, maar hiervoor heb ik een oplossing gemaakt.

img094

Voor de finale gedocumenteerde LUA zie de specifieke pagina

Een reactie achterlaten

Je e-mailadres zal niet getoond worden. Vereiste velden zijn gemarkeerd met *

Deze website gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.

Translate »