Après une première partie technique, voici la partie gestion de la pompe piscine en fonction de sa température. Désolé cet article est un peu long, mais je pense que cela en vaut le coup.
Je suis parti sur un certain nombres d’informations (il y en peut-être d’autres, à vous d’adapter en fonction des besoins).
Il est toujours bon de savoir ce que l’on veut faire…
Pour le moment cette régulation n’est dédiée qu’à un fonctionnement d’été. Nous avons besoin des éléments suivant:
- un capteur 1-wire connecté à un serveur OW-SERVER : 1-Wire to Ethernet Server de la marque EDS lui même géré par la Vera. Mais il est possible d’utiliser tout autres dispositifs qui mesure la température dans le doigt,
- Pour piloter la pompe j’utilise un interrupteur zwave qui commande le contacteur de la pompe,
- A ceci il faut ajouter un plugin « variables container » qui nous permettra de stocker les variables nécessaires.
Le temps de régulation est dépendant de la température piscine. La règle utilisée est la « température / 2 » qui nous donne le temps de fonctionnement de la pompe piscine.
Normalement si la température excède les 28°C, il faut un fonctionnement en continu. Pour ma part j’ai choisi 27°C par sécurité.
Bref, tous les discours ne valent pas une bonne programmation expliquée:
J’utilise deux scènes sur la vera pour effectuer cette régulation. Une qui sert de déclencheur, et une autre qui effectue un certain nombres d’actions.
Voici donc la scène de commande dans son intégralité. Elle démarre à 8h et effectue un contrôle toute les heures.
--avoid pump automation if needed automation_pump = luup.variable_get("urn:upnp-org:serviceId:VSwitch1","Status",49) if(automation_pump=="0")then return false end --function that detect if pump is "on" or "off", if "off" then set to "on", if on let in "on state" function test_pump() local test_pump_on = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1","Status", pump_device) if (test_pump_on == "0") then luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = "1"}, 11) -- add a sleep time to have a good temp measure. end end --function to launch a scene function launch_scene() luup.call_action("urn:micasaverde-com:serviceId:HomeAutomationGateway1", "RunScene", {SceneNum = "23"}, 0) end local t = os.date('*t') local current_time_hour = t.hour local current_time_minute = t.min current_time = (current_time_hour + (current_time_minute / 60)) current_time = tonumber(current_time) if (current_time >= 8) and (current_time <= 9) then --set to "0" the flag luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable4","0",51) test_pump() --sleep 5 minutes luup.call_delay('launch_scene', 300) end if (current_time >= 12) and (current_time <= 18) then launch_scene() end if (current_time >= 21) and (current_time <= 23) then launch_scene() end if (current_time >= 0) and (current_time < 8) then --do nothing end
et l’explication du code:
Ce code sert a empêcher la régulation de s’effectuer, si vous avez besoin de manipuler votre pompe ou si vous désirez passer en mode manuel. Pour que cela soit opérationnel, il vous faut installer un plugin virtual switch et remplacer le numéro 49 par votre numéro de device virtuel.
--avoid pump automation if needed automation_pump = luup.variable_get("urn:upnp-org:serviceId:VSwitch1","Status",49) if(automation_pump=="0")then return false end
La fonction test_pump permet de tester si la pompe est allumée ou éteinte, en fonction du résultat la pompe sera allumée.
--function that detect if pump is "on" or "off", if "off" then set to "on", if "on" let in "on state" function test_pump() local test_pump_on = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1","Status", pump_device) if (test_pump_on == "0") then luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = "1"}, 11) end end
J’aime bien travailler avec des fonctions (ou méthodes), celle-ci à pour but de lancer la scène qui va effectuer le travail de régulation quand elle sera appelée. A la place du chiffre 23 veuillez mettre le numéro de votre scène correspondante.
--function to launch a scene function launch_scene() luup.call_action("urn:micasaverde-com:serviceId:HomeAutomationGateway1", "RunScene", {SceneNum = "23"}, 0) end
Ce code permet de manipuler le temps, pour effectuer des actions dans le temps imparti.
local t = os.date('*t') local current_time_hour = t.hour local current_time_minute = t.min current_time = (current_time_hour + (current_time_minute / 60)) --heure en decimale current_time = tonumber(current_time)
Nous verrons en détail la régulation, mais ce code permet de déclencher à l’heure désirée, l’acquisition de l’heure de début de la régulation et d’autres paramètres. Comme la pompe n’est pas censée être en fonctionnement la fonction test_pump entre en jeux puis il faut attendre environ 5 minutes pour avoir une information de température fiable.
if (current_time >= 8) and (current_time <= 9) then --set to "0" the flag luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable4","0",51) test_pump() --sleep 5 minutes luup.call_delay('launch_scene', 300) end
Vérification de la température entre 12 et 18 heure.
if (current_time >= 12) and (current_time <= 18) then launch_scene() end
Idem mais entre deux heures ou la pompe devrait s’arrêter si la température est inférieure à 27 °C.
if (current_time >= 21) and (current_time <= 23) then launch_scene() end
En ne faisant rien entre minuit et 8h du matin, cela laisse la possibilité de ne pas arrêter la pompe selon la dernière régulation exécutée.
if (current_time >= 0) and (current_time < 8) then --do nothing end
Passons à la deuxième scène qui est le cœur de la régulation.
Elle est morcelée en plusieurs fonctions, Voici le code intégrale:
--avoid pump automation if needed automation_pump = luup.variable_get("urn:upnp-org:serviceId:VSwitch1","Status",49) if(automation_pump=="0")then return false end --devices declaration water_temp_device = 53 notification_device = 39 var_container_device = 51 pump_device = 11 --function notification function notif(text) luup.call_action( "urn:upnp-gilles-com:serviceId:XFD1", "SendNotification", { message = text }, notification_device ) end --function that change the state of the pump function setPoolPump(newValue) luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = newValue}, pump_device) end --function that detect if pump is "on" or "off", if "off" then set to "on", if on let in "on state" function test_pump() local test_pump_on = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1","Status", pump_device) if (test_pump_on == "0") then luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = "1"}, 11) -- add a sleep time to have a good temp measure. end end --function that get all variables function get_pool_variables() local t = os.date('*t') local current_time_hour = t.hour local current_time_minute = t.min current_time = (current_time_hour + (current_time_minute / 60)) current_time = tonumber(current_time) --notif("current_time="..current_time) local flag = luup.variable_get("urn:upnp-org:serviceId:VContainer1","Variable4",var_container_device) flag = tonumber(flag) if ( flag == 0 ) then local first_time = current_time --first_time = tonumber (first_time) flag = 1 luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable4",flag,var_container_device) --set first hour time luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable1",first_time,var_container_device) end first_time = luup.variable_get("urn:upnp-org:serviceId:VContainer1","Variable1",var_container_device) first_time = tonumber(first_time) --set last time measure local last_time = current_time_hour .. "h" .. current_time_minute luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable2",last_time,var_container_device) --get water temp water_temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature",water_temp_device) water_temp = tonumber(water_temp) --compare if actual water_temp is greater than older local old_water_temp = luup.variable_get("urn:upnp-org:serviceId:VContainer1","Variable3",var_container_device) old_water_temp = tonumber(old_water_temp) if ((current_time > 14) and (current_time < 18)) then if (water_temp < old_water_temp) then notif("temp_water%20egal%20old") water_temp = old_water_temp end end --set last temperature measure luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable3",water_temp,var_container_device) --calculate brass_time variable brass_time = water_temp / 2 brass_time = tonumber(brass_time) --notif("brass_time="..brass_time) --set estimated end time estimated_time = brass_time + first_time estimated_time = tonumber(estimated_time) --notif("estimated_time="..estimated_time) luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable5",estimated_time,var_container_device) end --function that test if it's time to stop the pump with an offset delay function program_stop_pump() if (current_time > estimated_time) and ( water_temp < 27 ) then notif("arret%20pompe") setPoolPump("0") end end --sequence to regulate notif("regul.%20pompe") test_pump() get_pool_variables() program_stop_pump()
Et maintenant l’explication:
Comme vu plus haut, si l’on veut desactiver l’automatisme mettre en place ces lignes et changer le numéro du device.
--avoid pump automation if needed automation_pump = luup.variable_get("urn:upnp-org:serviceId:VSwitch1","Status",49) if(automation_pump=="0")then return false end
Déclaration des devices utilisés:
--devices declaration water_temp_device = 53 notification_device = 39 var_container_device = 51 pump_device = 11
Une fonction de notification à vous d’adapter votre solution, j’utilise un plugin maison, il y a beaucoup d’autres solutions …
--function notification function notif(text) luup.call_action( "urn:upnp-gilles-com:serviceId:XFD1", "SendNotification", { message = text }, notification_device ) end
Une fonction pour changer le statut de la pompe:
--function that change the state of the pump function setPoolPump(newValue) luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = newValue}, pump_device) end
Comme vu plus haut là aussi, changement d’état de la pompe si la pompe est éteinte sinon ne rien faire:
--function that detect if pump is "on" or "off", if "off" then set to "on", if on let in "on state" function test_pump() local test_pump_on = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1","Status", pump_device) if (test_pump_on == "0") then luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = "1"}, 11) -- add a sleep time to have a good temp measure. end end
Une fonction d’acquisition des variables et de paramétrage de celles-ci:
Tout d’abord récupération de l’heure courante en heure décimale dans « current_time ».
--function that get all variables function get_pool_variables() local t = os.date('*t') local current_time_hour = t.hour local current_time_minute = t.min current_time = (current_time_hour + (current_time_minute / 60)) current_time = tonumber(current_time)
Récupération du flag permettant de savoir si c’est la première mesure de la journée.
local flag = luup.variable_get("urn:upnp-org:serviceId:VContainer1","Variable4",var_container_device) flag = tonumber(flag)
Si le flag est à « 0 » alors récupérer la première heure, et la stocker dans la variable1 du plugin variable container et mettre le flag à « 1 ». En le mettant à « 1 » cela permettra d’éviter une réecriture du flag lors des prochaines mesures.
if ( flag == 0 ) then local first_time = current_time --first_time = tonumber (first_time) flag = 1 luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable4",flag,var_container_device) --set first hour time luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable1",first_time,var_container_device) end
Stockage de la première heure.
first_time = luup.variable_get("urn:upnp-org:serviceId:VContainer1","Variable1",var_container_device) first_time = tonumber(first_time)
Stockage de l’heure la dernière mesure dans la variable2 du plugin variable container.
--set last time measure local last_time = current_time_hour .. "h" .. current_time_minute luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable2",last_time,var_container_device)
Acquisition de la température de l’eau piscine.
--get water temp water_temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature",water_temp_device) water_temp = tonumber(water_temp)
Stockage de la température de l’eau la plus élevée entre 14 et 18h.
--compare if actual water_temp is greater than older local old_water_temp = luup.variable_get("urn:upnp-org:serviceId:VContainer1","Variable3",var_container_device) old_water_temp = tonumber(old_water_temp) if ((current_time > 14) and (current_time < 18)) then if (water_temp < old_water_temp) then notif("temp_water%20egal%20old") water_temp = old_water_temp end end
Stockage de la dernière température corrigée par la condition ci-dessus.
--set last temperature measure luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable3",water_temp,var_container_device)
Calcul du temps de filtration.
--calculate brass_time variable brass_time = water_temp / 2 brass_time = tonumber(brass_time) --notif("brass_time="..brass_time)
Estimation de l’heure d’arrêt de la pompe.
--set estimated end time estimated_time = brass_time + first_time estimated_time = tonumber(estimated_time) --notif("estimated_time="..estimated_time) luup.variable_set("urn:upnp-org:serviceId:VContainer1","Variable5",estimated_time,var_container_device) end
Une fonction qui va arrêter la pompe sur certaines conditions qui sont le temps estimé de filtration et la température inférieure à 27 °C.
--function that test if it's time to stop the pump with an offset delay function program_stop_pump() local offset = 0.5 --offset will help brass 1 more hour. offset = tonumber (offset) --current_time = tonumber(current_time) if (current_time > estimated_time) and ( water_temp < 27 ) then notif("arret%20pompe") setPoolPump("0") end end --function that test if it's time to stop the pump with an offset delay function program_stop_pump() local offset = 0.5 --offset will help brass 1 more hour. offset = tonumber (offset) --current_time = tonumber(current_time) if (current_time > estimated_time) and ( water_temp < 27 ) then notif("arret%20pompe") setPoolPump("0") end end
Le corps du programme:
--sequence to regulate notif("regul.%20pompe") test_pump() get_pool_variables() program_stop_pump()
Voilà nous sommes arrivés au bout de cette régulation par une Vera, comme je l’ai indiqué c’est un peu long mais très fonctionel.
Il reste des choses à améliorer comme la gestion hiver/été et des temps de pause pour la pompe, je ne manquerai pas de publier mes modifications.
Bonne Baignade …