Afgelopen week heb je een artikel kunnen lezen hoe je de mechanische ventilatie vanuit Domoticz kunt bedieningen. Nu gaan we een stapje verder: het ventilatie-systeem moet automatisch aan gaan, zodra de luchtvochtigheid binnen een enkele minuten een paar procent omhoog gaat: humidity control. Dit is bijvoorbeeld het geval tijdens het douchen. Hiervoor moeten we een temperatuur- /luchtvochtigheidssensor in de badkamer plaatsen.
Benodigdheden
- Raspberry Pi
- Raspbian software
- Domoticz software
- RFXCom interface
- KlikAanKlikUit ACM3500-3
- Temperatuur/luchtvochtigheidssensor
Vochtigheidssensor
We gaan een LUA-script gebruiken welke hoeveel het percentage van de luchtvochtigheid is gestegen in een bepaalde periode. Uiteraard hebben we daar een temperatuursensor voor nodig die ook de luchtvochtigheid aangeeft én compatible is met RFXCom. De sensor hoeft niet geijkt te zijn, aangezien het werkelijke percentage niet van belang is: voor het douchen is de luchtvochtigheid X, tijdens het douchen loopt dat op naar Y en uiteindelijk moet het script ervoor zorgen dat de luchtvochtigheid weer zo snel mogelijk X is. Deze sensor van een euro of 7 voldoet prima!
User Variables
Allereerst dienen we een aantal gebruikersvariabelen aan te maken: SETPU > MORE OPTIONS > USER VARIABLES. Maak onderstaande variabelen aan (wijzig de naam niet en zet de waarde op “0” !).
- humCounter (type=integer, value=0)
- humidityTmin5 (type=integer, value=0)
- humidityTmin10 (type=integer, value=0)
- targetFanOffHumidity (type=integer, value=0)
- fanMaxTimer (type=integer, value=0)
- fanFollowsProgram (type=integer, value=0)
Humidity control script
Hieronder vind je het script dat we gaan gebruiken. Sla dit script op met de naam script_time_humidity.lua
in de folder /home/pi/domoticz/scripts/lua/
. Het script zal nu automatisch iedere minuut draaien. In regel 11 zet je de switch-naam van jouw ventilatie systeem en in regel 12 de naam van de temperatuur-/luchtvochtigheidssensor.
Werking van het script: Iedere 5 minuten wordt de luchtvochtigheid gemeten. De laatste twee meting worden in de gebruikersvariabelen (humidityTmin5 en humidityTmin10) opgeslagen. De metingen van de laatste 10 minuten zijn dus bekend. Vervolgens wordt de laagste van de twee waarden vergeleken met de nieuwste meting en wordt het verschil berekend. Indien het verschil 3 of meer is dan zal het ventilatiesysteem aangezet worden het het ‘luchtvochtigheidsdoel’ berekend worden. Vanaf nu wordt iedere 5 minuten de huidige luchtvochtigheid vergeleken met het doel. Zodra dit doel bereikt wordt zal het ventilatiesysteem weer uitgaan.
Uiteraard is het mogelijk dat het doel nooit gehaald wordt (bv. als het buiten gaat regenen). Daarvoor zit er een failsafe (FAN_MAX_TIME) ingebouwd, het ventilatiesysteem zal na deze tijd automatisch uitgaan. Ook zal het script zien wanneer het ventilatiesysteem handmatig is aangezet, voordat het programma start of als het uitgezet wordt tijdens het programma.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
commandArray = {} -- declare some constants -- adjust to your specific situation SAMPLE_INTERVAL = 5 -- time in minutes when a the script logic will happen FAN_DELTA_TRIGGER = 3 -- rise in humidity that will trigger the fan FAN_MAX_TIME = 24 -- maximum amount of sample cycles the fan can be on, -- in case we never reach the target humidity TARGET_OFFSET = 2 -- ventilator goes off if target+offset is reached -- (maybe it takes too long to reach the true target due to wet towels etc) FAN_NAME = 'FAN3' -- exact device name of the switch turning on/off the ventilator SENSOR_NAME = 'Luchtv. Badkamer' -- exact device name of the humidity sensor TEST_MODE = false -- when true TEST_MODE_HUMVAR is used instead of the real sensor TEST_MODE_HUMVAR = 'testHumidity' -- fake humidity value, give it a test value in domoticz/uservars PRINT_MODE = false -- when true wil print output to log and send notifications if PRINT_MODE == true then print('Fan control') end -- get the global variables: -- this script runs every minute, humCounter is used to create SAMPLE_INTERVAL periods humCounter = tonumber(uservariables['humCounter']) humidityTmin5 = tonumber(uservariables['humidityTmin5']) -- youngest reading humidityTmin10 = tonumber(uservariables['humidityTmin10']) -- oldest reading targetFanOffHumidity = tonumber(uservariables['targetFanOffHumidity']) -- target humidity fanMaxTimer = tonumber(uservariables['fanMaxTimer']) fanFollowsProgram = tonumber(uservariables['fanFollowsProgram']) -- marker indicating that the -- decrease program is started target = 0 -- will hold the target humidity when the program starts -- get the current humidity value if (TEST_MODE) then current = tonumber(uservariables[TEST_MODE_HUMVAR]) else current = otherdevices_humidity[SENSOR_NAME] end -- check if the sensor is on or has some weird reading if (current == 0 or current == nil) then print('current is 0 or nil. Skipping this reading') return commandArray end if PRINT_MODE == true then print('Current humidity:' .. current) print('targetFanOffHumidity:' .. targetFanOffHumidity) print('humidityTmin5: ' .. humidityTmin5) print('humidityTmin10: ' .. humidityTmin10) print('fanMaxTimer: ' .. fanMaxTimer) print('humCounter:' .. humCounter) print('fanFollowsProgram:' .. fanFollowsProgram) end -- increase cycle counter humCounter = humCounter + 1 if (humCounter >= SAMPLE_INTERVAL) then if (humidityTmin5 == 0) then -- initialization, assume this is the first time humidityTmin5 = current humidityTmin10 = current end humCounter = 0 -- reset the cycle counter -- pick the lowest history value to calculate the delta -- this also makes sure that two relative small deltas in the past 2*interval minutes are treated as one larger rise -- and therefore will still trigger the ventilator -- I do not want to use a longer interval instead because I want the ventilator to start as soon as possible -- so rather after 5 minutes instead of after 15 minutes because the mirrors in the bathroom become kinda useless <img draggable="false" class="emoji" alt="😉" src="https://s.w.org/images/core/emoji/11/svg/1f609.svg"> delta = current - math.min(humidityTmin10, humidityTmin5) if PRINT_MODE == true then print('Delta: ' .. delta) end -- pick the lowest history value target = math.min(humidityTmin10, humidityTmin5) + TARGET_OFFSET -- shift the previous measurements humidityTmin10 = humidityTmin5 -- and store the current humidityTmin5 = current if (otherdevices[FAN_NAME]=='Off' or (otherdevices[FAN_NAME]=='On' and fanFollowsProgram==0)) then -- either the fan is off or it is on but the decrease program has not started -- in that latter case we start the program anyway. This could happen if someone turns on the ventilator -- manually because he/she is about to take a shower and doesn't like damp mirrors. -- I don't do this because the ventilator removes heat from the bathroom and I want this to happen -- as late as possible <img draggable="false" class="emoji" alt="😉" src="https://s.w.org/images/core/emoji/11/svg/1f609.svg"> if (fanFollowsProgram == 1 and otherdevices[FAN_NAME]=='Off') then -- likely someone turned off the ventilator while the program was running fanFollowsProgram = 0 end -- see if we have to turn it on if (delta >= FAN_DELTA_TRIGGER) then -- time to start the fan commandArray[FAN_NAME] = 'On' targetFanOffHumidity = target if (fanFollowsProgram == 1) then print('Ventilator was already on but we start the de-humidifying program') end fanFollowsProgram = 1 -- set the safety stop fanMaxTimer = FAN_MAX_TIME if PRINT_MODE == true then print('Rise in humidity. Turning on the vents. Delta: ' .. delta) print('Target humidity for turning the ventilator: ' ..targetFanOffHumidity) commandArray['SendNotification'] = 'Ventilator is on#The ventilator was activated at humidity level ' .. current .. '#0' end end else if (fanMaxTimer > 0) then -- possible that someone started the ventialator manually fanMaxTimer = fanMaxTimer - 1 end if (fanFollowsProgram == 1) then -- not manually started if (delta >= FAN_DELTA_TRIGGER) then -- ok, there is another FAN_DELTA_TRIGGER rise in humidity -- when this happen we reset the fanMaxTimer to a new count down -- because we have to ventilate a bit longer due to the extra humidity if PRINT_MODE == true then print('Another large increase detected, resetting max timer. Delta: ' .. delta) end fanMaxTimer = FAN_MAX_TIME end -- first see if it can be turned off if (current <= targetFanOffHumidity or fanMaxTimer==0) then commandArray[FAN_NAME] = 'Off' msg = '' if (fanMaxTimer == 0 and current > targetFanOffHumidity) then msg = 'Target not reached but safety time-out is triggered.' if PRINT_MODE == true then print(msg) end else msg = 'Target humidity reached' if PRINT_MODE == true then print(msg) end end if PRINT_MODE == true then print('Turning off the ventilator') msg = msg .. '\nTurning off the ventilator' end targetFanOffHumidity = 0 fanMaxTimer = 0 fanFollowsProgram = 0 -- reset history in this case.. we start all over -- Tmin10 is still in the 'ventilator=On'-zone humidityTmin10 = humidityTmin5 if PRINT_MODE == true then commandArray['SendNotification'] = 'Ventilator is off#' .. msg .. '#0' end else -- we haven't reached the target yet if PRINT_MODE == true then print('Humidity delta: ' .. delta) end end end end if PRINT_MODE == true then print('New values >>>>>>>>>>>') print('humidityTmin5: ' .. humidityTmin5) print('humidityTmin10: ' .. humidityTmin10) print('fanMaxTimer: ' .. fanMaxTimer) print('humCounter:' .. humCounter) print('fanFollowsProgram:' .. fanFollowsProgram) print('------ target: ' .. targetFanOffHumidity) end end -- save the globals commandArray['Variable:humCounter'] = tostring(humCounter) commandArray['Variable:humidityTmin10'] = tostring(humidityTmin10) commandArray['Variable:humidityTmin5'] = tostring(humidityTmin5) commandArray['Variable:targetFanOffHumidity'] = tostring(targetFanOffHumidity) commandArray['Variable:fanMaxTimer'] = tostring(fanMaxTimer) commandArray['Variable:fanFollowsProgram'] = tostring(fanFollowsProgram) return commandArray |