Mon premier script Lua dans Domoticz : La mise en oeuvre

Cet article fait suite à deux autres permettant de poser les bases du langage Lua dans Domoticz.

Le premier  (https://easydomoticz.com/point-scripts-lua/)  décrivait quels étaient les principes de fonctionnement des script Lua.

Le second donnait quelques notions de langage.

Ici pour faire suite nous allons prendre un exemple que nous allons dérouler et complexifier étape par étape.

L’exemple que je souhaite détailler ici part du fait que je possède un capteur de luminosité, des volets roulants. Je voudrais que lorsque la luminosité descend en dessous de 170 et que il est plus de 17h30, fermer tous les volets automatiquement. 😯

fenetres_maison

N.B :Pour simplifier j’ai rassemblés tous (!) mes volets roulants au sein d’un groupe (une scène au sens Domoticz)  pour pouvoir les commander tous ensemble.

Dans un pseudo langage on pourrait écrire :

  • A chaque fois que la valeur de mon capteur de luminosité change

je regarde si il est plus de 17H30

ET si

elle est inférieure a 170

ALORS

je passe le groupe des volets à ON

Ce qui signifie qu’il nous faut un script basé sur les devices puisque je cherche à déclencher tout cela lorsque la luminosité change, il faudra récupérer la valeur de notre capteur , la comparer à un seuil, aller chercher l’heure actuelle la comparer à un seuil horaire, puis passer le groupe de volets à ON.

N.B : il y a un petit bug de conception car une fois que les volets vont être fermés, si j’allume puis éteint la lumière de mon salon, la luminosité va changer, il sera plus de 17h30 et on tentera de fermer les volets en permanence alors qu’ils le sont déjà.

En pratique

On se connecte via putty à notre Raspberry, puis on va dans le répertoire des scripts Lua

cd domoticz/scripts/lua

Créons un fichier dont les premiers caractères sont script_device_ et la fin .lua afin d’avoir un script basé sur le changement d’état d’un périphérique.

(N’oubliez pas que les script_device_ se déclenchent TOUS dés que N’IMPORTE quel périphérique change de valeur)

Je nomme mon script script_device_gestiondesvolets.lua.

N’oubliez pas que le nom après les device_ n’a aucune espèce d’importance, toutefois nommez le de façon la plus claire possible pour vous y retrouver dans quelques temps.

sudo pico script_device_gestiondesvolets.lua

Si vous travaillez depuis Windows™ attention d’écrire votre fichier en UTF8, sans BOM

Il est de bon ton de documenter son programme afin d’en faciliter la lecture et la compréhension. Prenez l’habitude de placer quelques lignes en haut de vos production qui indiquent en français le rôle de ce programme, les valeurs utilisées, la date …

Nous avons vu plus haut que pour les commentaires la ligne débute par —

-- Gestion des volets roulants en fonction
-- de la luminosite et d l'heure
-- le capteur utilisé est celui du salon nommé 'Lumière',
-- le groupe Volets est basculé si on est inf a 170 Lux et 
-- qu'il est plus de 17h30
--
-- 13/11/15 : Version 1 : Redaction initiale

Nous avions vu dans le chapitre précédent que tout script doit contenir les blocs

commandArray = {}
 nos instructions ici 
return commandArray

Nous avions dit ici : https://easydomoticz.com/point-scripts-lua/

que TOUS les script d’un même type se lancent dés que un événement survient et qu’il faut TOUJOURS commencer un script par un test sur l’état du  périphérique  afin d’abandonner le script au plus vite et passer au script suivant.

Lors de la création de mon capteur de luminosité je l’ai appelé Lumière (avé l’accent).

Le script continuera donc par un

commandArray = {}
if (devicechanged['Lumière']) then
    ......... 
end
return commandArray

Ce script ne continuera à exécuter les instructions entre le then et le end QUE SI ET SEULEMENT SI la valeur ou l’état du capteur nommé Lumière à changé.

Ici une précision  s’impose :

Le devicechanged[‘device’] est valide dès lors que le device à été mis à jour, même si la valeur n’a pas changé.

EX:

  • Pour un capteur, si on à exactement la même valeur que précédemment, (la valeur n’a pas changé), il y a eu toutefois une mise à jour de l’état dans Domoticz , donc le script se déclenche.
  • Si j’ai un script qui se lance lorsque j’allume ma lampe, si j’appuie 2 fois sur On, le script se lancera 2 fois..
commandArray = {}
si mon device ['Lumière']) à changé de valeur alors
     fais tout ce qui est marqué ici 
fin 
return commandArray

ifthenelse2

Remarquez que pour une lecture plus facile les instructions entre then et end sont décalées d’un ou plusieurs espace vers la droite.

Maintenant que nous sommes sur que la valeur de notre capteur à changé, nous devons aussi nous assurer qu’il est plus de 17h30, récupérons tout d’abord l’heure actuelle par un

Heure_Actuelle=os.date("%X")
print (Heure_Actuelle)

La commande os.date() , sans le « %X » renvoie le nombres de secondes écoulées depuis le 1/01/1970 soit 1447450200, super mais pas pratique !

Avec %X on reçoit dans la variable nommée Heure_Actuelle la vraie heure « 23:12:32″ que l’on pourra comparer avec notre horaire butoir

Créons une variable Seuil_Heure= »17:30:00 » et comparons les deux, à savoir que si l’heure actuelle est plus grande que notre heure.

Nous créerons une variable nommée Seuil_Lux et lui donnerons 170 comme valeur.

Notre script devient :

-- Gestion des volets roulants en fonction
-- de la luminosite et d l'heure
-- le capteur utilisé est celui du salon nommé 'Lumière',
-- le groupe Volets est basculé si on est inf a 170 Lux et 
-- qu'il est plus de 17h30
--
-- 13/11/15 : Version 1 : Redaction initiale

--------------------
-- les variables de seuil.
Seuil_Heure="17:30:00"
Seuil_Lux=170
-------------------

commandArray = {}
 if (devicechanged['Lumière'])then
     Heure_Actuelle=os.date("%X")
     print (Heure_Actuelle)
     if Heure_Actuelle > Seuil_Heure then
         print ("c'est l'heure")
     end   
 end 

return commandArray

En enregistrant ce script par CTRL O, nous devrions voir dans les logs de Domoticz lorsque la valeur de Lumière à changé, l’heure actuelle s’afficher grâce au print (Heure_Actuelle) puis si l’horaire est dépassé le message « c’est l’heure ».

Puisque c’est  l’heure, obtenons maintenant la valeur de notre capteur de luminosité et rangeons la valeur dans la variable valeur_lux.

L’instruction otherdevices_svalues[‘nom du capteur’] nous donne la dernière mesure stockée par Domoticz pour ce capteur.

Il se trouve que la valeur renvoyé par cette instruction doit être transformée en nombres par l’instruction tonumber

valeur_lux = (otherdevices_svalues['Lumière'])
valeur_lux=tonumber(valeur_lux)
print("lum = "..valeur_lux)

Puis nous écrivons ensuite dans le log lum= la valeur de la variable mesurée.

un

valeur_lux = tonumber((otherdevices_svalues['Lumière']))

aurait été possible.

Nous comparerons cette valeur à notre seuil puis déclenchons la scène si la valeur est plus petite que notre seuil avec la commande Scene:Nomdelascene=’On’.

Remarquez au passage que l’on peut mettre autant de commandArray que l’on veut dans un script.

 

Chaque fois que nous testons une condition avec un if , il faut qu’il y ait un then et end associé, le décalage des instructions est donc important pour améliorer la lisibilité.

 if valeur_lux < Seuil_Lux then
     print("Declencher la scene")
     commandArray['Scene:Volets']='On'
 end

ifthenelse

surtout quant il y en a beaucoup de if

-- Gestion des volets roulants en fonction
-- de la luminosite et d l'heure
-- le capteur utilisé est celui du salon nommé 'Lumière',
-- le groupe Volets est basculé si on est inf a 170 Lux et
-- qu'il est plus de 17h30
--
-- 13/11/15 : Version 1 : Redaction initiale

--------------------
-- les variables de seuil.
Seuil_Heure="17:30:00"
Seuil_Lux=170
-------------------

commandArray = {}
 if (devicechanged['CPU_Usage'])then
     Heure_Actuelle=os.date("%X")
     print (Heure_Actuelle)
     if Heure_Actuelle > Seuil_Heure then
          print ("c'est l'heure")
          valeur_lux = (otherdevices_svalues['Lumière'])
          valeur_lux=tonumber(valeur_lux)
          print("lum = "..valeur_lux)
          if valeur_lux < Seuil_Lux then
               print("Declencher la scene")
               commandArray['Scene:Volets']='On'
          end
      else
         print("pas l'heure")
      end
 end
return commandArray

Voila notre script doit fonctionner maintenant.

 

Ca marche pas !

  • Faites attention aux majuscules/minuscules dans les instructions Lua, dans vos variables.
  • Ajoutez des print() à des endroits stratégiques du script pour savoir d’où vient le problème.
  • Regardez la ligne d’erreur dans le log

script_device_gestiondesvolets.lua:1: unexpected symbol near ‘-

ici c’est la ligne 1 et cela me dit qu’il y a un symbole bizarre prés de –

  • Le log affiche ‘nil value’ : c’est que dans le truc que vous gérer il n’y a pas de valeur : vous avez mal orthographié le nom du matériel par exemple, vous appelez une table qui n’est pas gérée dans votre type de script…
  • Le log affiche ‘attempt to compare nil with number‘ vous avez récupéré qq chose que vous n’avez pas converti au format nombre : ajoutez un tonumber() résoudra votre problème.

A savoir :

Dans vos scripts utilisez des noms clairs : plutôt que a,b,c,d utilisez valeur_temperature, heure_courante , c’est quand même plus parlant

Dans un script_device les lignes suivantes

commandArray = {}
for i, v in pairs(devicechanged) do print(i, v) end
return commandArray

vous affichent les noms et valeurs de tous les périphériques dont la valeur vient de changer.

Des exemples se trouvent dans le répertoire scripts/lua, regardez les, inspirez vous en.

Vous avez des questions ?, une partie du forum est réservées aux questions Lua  https://easydomoticz.com/forum/viewforum.php?f=10

Une autre section https://easydomoticz.com/forum/viewforum.php?f=17 regroupe des exemples de scripts pour tous les usages  Inspirez vous des scripts  que vous y trouverez.

J’espère avoir donné envie aux débutants de se lancer dans la programmation Lua, sinon il nous reste le bon vieux Basic…

ecran_programmation

Pour toute question technique concernant cet article, veuillez utiliser les forum situés à https://easydomoticz.com/forum/
Posted in Débutants, Débuter Avec Domoticz et la Domotique, domoticz, scripts and tagged , , , , .

4 Comments

  1. Salut,

    Si je peux apporter une très légère correction, pas bien importante mais parfois ça peut aider..

    devicechanged[‘device’]

    Est valide dès lors que le device à été mis à jour, même si la valeur n’a pas changé.

    Si par exemple j’ai un script qui se lance lorsque j’allume ma lampe, si j’appuie 2 fois sur On, le script se lancera 2 fois..

  2. Bonsoir,

    Si je comprends bien votre script, tant que  »Seuil_Lux » sera inférieur à 170 et tant que nous serons dans la plage 17h30 – 23h59 nous donnerons l’ordre de fermer les volets ?

    Si oui, le système va lancer beaucoup d’ordres pour rien !

    Il faudrait intégrer une variable qui indique que l’ordre a déjà été exécuté puis remettre cette variable à 0 (non exécuté) dès que nous passons 23h59 ou 00h00.

    Bonne soirée.

     

Comments are closed.