Mesurer la température de sa piscine avec un doigt de gant (Partie 2/2)

regulation piscine partie 2Aprè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 …

 

A propos Gilles

Voulant "domotiser" ma maison avec un coût raisonnable, j'ai cherché sur le net ce qui se faisait. Etant a l'époque sur windows, les possibilités étaient assez maigre et surtout payante. Tout ceci à eu pour effet de me faire basculer dans le monde formidable de "Linux", sa puissance, sa fiabilité et sa liberté. Tout ceci cumulé à du zwave et android, nous voilà prêt pour découvrir ce qui peut être réalisé ....

A voir aussi

Gestion complète du refroidissement d'un ordinateur avec Z-UNO

Concours Z-UNO – Projet de Lilian

Premier projet domotique : Desk by Gameinfotech Mon premier projet domotique fut le projet Desk …

4 commentaires

  1. Bonjour,
    Article intéressant que je souhaiterais metter en pratique. Cependant, une chose que je n’ai pas comprise. Comment est paramétré l’intervalle de temps de la 1ère scène dans l’onglet « horaires » ?

  2. Depuis cette date, pas eu d’autres modifs ?

  3. Si, des corrections pour la gestion de la pompe et les notifications,
    Justement j’avais idée de faire un article pour quelques modifications et confirmer qu’en hiver cela fonctionne aussi.

    Donc a bienôt.

  4. Beaucoup plus facile avec la app PLEC pour Vera….

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *