Page 1 sur 1

[LUA] message erreur global 'uservariables'

Publié : 23 août 2022, 14:11
par GIC
Bonjour à tous,

Tout d'abord, je débute ! Alors merci de votre patience.
J'ai fait de la programmation dans mon jeune temps mais c'était du C, du C++. Mais je pense ne pas être trop mal cablé pour comprendre le LUA !

Je commence mon premier ecript LUA en me référent à quelques lectures sur internet ainsi que sur les 3 articles de ce site sur LUA. Mais je sens qu'il me manque beaucoup de connaissances pour avancer. Et je ne trouve pas de tuto plus complets sur le LUA dans Domoticz et ça me parait surprenant.

Avant toute chose, je passe par LUA parce que c'est ce qui me semble le plus logique mais peut-être allez-vous me conseiller autre chose. Je suis ouvert !

Mon projet n'est pas un sujet nouveau mais je m'en sers surtout pour comprendre les scripts.

A ce stade, je souhaite savoir si j'ai assez d'eau dans une cuve pour lancer un arrosage.
J'ai créé :
Arrosage_Actif : device fictif de type swith On/Off qui me permet de définir si je veux lancer les programmes d'arrosage ou non.
Water_Tank_Hauteur : device réel qui récupère la hauteur d'eau dans ma cuve (via capteur ultra son)

water_tank : user variable de type string qui contiendra OK ou KO selon qu'il y a assez d'eau pour un arrosage ou pas
water_tank_hauteur_courante de type float qui récupèrera la valeur du device Water_Tank_Hauteur (ça fait peut-être doublon)
water_tank_hauteur_mini de type float qui contient la hauteur mini en deça de laquelle je ne veut pas arroser

Dans mon premier script, je souhaite initialiser la variable utilisateur water_tank à OK ou KO.
Si water_tank_hauteur_courante>water_tank_hauteur_mini alors water_tank = OK sinon water_tank = KO

Ca ne me semble pas compliqué mais pourtant...

Voilà mon script :
// A noter que je teste provisoirement la valeur du device 'Arrosage_Actif' pour tester mon script. A terme, je testerai le changement de Water_Tank_Hauteur .

// J'ai également mis des print partout pour le debogage

Code : Tout sélectionner

print('Entrée dans la script Water_Tank_OK')
commandArray = {}
if (devicechanged['Arrosage_Actif']) then
     print('if 1') 	       		 
     commandArray['Variable:water_tank_hauteur_courante']=tostring((otherdevices_svalues['Water_Tank_Hauteur']))
     if (uservariables['water_tank_hauteur_courante'])>(uservariables['water_tank_hauteur_mini']) then
                print('if 2')
                uservariables['water_tank']=OK
                print("Hauteur de cuve = "..(otherdevices_svalues['Water_Tank_Hauteur']))
                print("valeur water_tank = "..tonumber(uservariables('water_tank')))
     else
                print('else 2')
                uservariables["water_tank"]=KO
                print("Hauteur de cuve = "..tonumber((otherdevices_svalues['Water_Tank_Hauteur'])))
                print("valeur water_tank = "..tonumber(uservariables('water_tank')))
     end
else
     print('pas de changement detecté')
end
return commandArray
Je récupère le message suivant dans mon log
EventSystem: in /home/pi/domoticz/scripts/lua/script_device_water_tank_ok.lua: .../pi/domoticz/scripts/lua/script_device_water_tank_ok.lua:16: attempt to call a table value (global 'uservariables')
Cela correspond au code

Code : Tout sélectionner

               print("valeur water_tank = "..tonumber((uservariables('water_tank'))))
J'ai essayé de retirer le tonumber mais ça ne change rien.

A noter par la même occasion que même en retirant le code "print" générant cette erreur, ma variable utilisateur water_tank_hauteur_courante n'et pas initialisée par mon device Water_Tank_Hauteur comme le voudrait la commande

Code : Tout sélectionner

commandArray['Variable:water_tank_hauteur_courante']=tostring((otherdevices_svalues['Water_Tank_Hauteur']))
De bonnes âmes pour m'aider ? Je suis preneur de toutes vos remarques !

Re: [LUA] message erreur global 'uservariables'

Publié : 23 août 2022, 14:40
par Keros
Tu débutes très bien : le code est clair, il y a du débogage > bravo ;)

Si tu veux quelques infos sur la programmation, j'ai écris des petits guides : regarde les liens dans ma signature.

Tu vas avoir un petit souci :

Code : Tout sélectionner

if (devicechanged['Arrosage_Actif']) then
    .... ton code...
else
     print('pas de changement detecté')
end
Le principe des scripts LUA est qu'ils sont tous exécutés en fonction des triggers (All, Device, Time). C'est à l'intérieur des scripts qu'il faut limiter les actions sur seulement les triggers que l'on souhaite. Dans ton cas, devicechanged['Arrosage_Actif'] est très bien, par contre, faire un else print(), là par contre, tu va te retrouver avec plein de print dés qu'un device va mettre à jour sa valeur :o

Concernant ton souci de Uservariable, les scripts ne sont pas exécutés ligne après ligne : tout est fait à la fin. Si tu mets à jour ta uservariable, tu ne peux pas réutiliser sa valeur plus bas dans le script. Il vaut mieux rester avec une variable interne au script.

Pour le print de ta valeur, le tonumber() n'est pas utile. Peut-être un tostring().

Tu as vraiment besoin de stocker ta valeur limite dans une uservariable ? Tu ne peux la pas stocker dans une variable en début de script ?


Si tu préfères la programmation orienté objet, tu peux regarder le DzVents. C'est aussi du LUA mais orienté objet pour DomoticZ ;)

Re: [LUA] message erreur global 'uservariables'

Publié : 23 août 2022, 18:07
par GIC
Tout d'abord merci beaucoup pour cette réponse rapide et tes encouragements. Il faut être persévérant et c'est vrai que l'absence de documentation complète n'aide pas beaucoup... On a vraiment l'impression d'aller à la pêche !

Je suis tes reco et simplifie le code pour le recompléxifier au fur et à mesure. J'ai également lu tes différents posts, très instructifs. Notament l'éditeur lua intégré à Domoticz ! Très pratique comparé à celui de putty...

Pour répondre à tes 2 commentaires, j'ai bien prévu de supprimer le print inutile à la fin, il est juste là pour le debugage initial.
Pour water_tank_hauteur_mini, je trouve plus pratique de l'avoir en variable changeable facilement.
Pour tout dire, je travaille sur ce projet pour gérer l'arrosage sur un site isolé avec une cuve remplie par une pompe de forage fonctionnant au fil du soleil. Et selon les arrosages, je veux être certain d'avoir assez d'eau. Cette valeur pourra donc varier dans le temps et je trouve ça plus élégant de pouvoir la changer directement sans passer par une modification du script !

Avant d'aller plus loin, iy a une question à laquelle je n'arrive pas à répondre.
A quoi sert le "commandArray" ? Je ne parle pas de celui qu'on utilise en début de script et qui se termine par return commandArray mais celui qui est suivi d'une variable ou d'un device ?

Par ailleurs, je pense que mon principal problème pour le moment, c'est de comprendre la syntaxe et la manipulation des différents types de données...

Re: [LUA] message erreur global 'uservariables'

Publié : 23 août 2022, 18:38
par Keros
Avec l'éditeur intégré avec DomoticZ, regarde le menu déroulant avec le + : tu auras une proposition de plusieurs exemples en fonctions des triggers. C'est aussi une source d'infos.
Pour info également, les scripts générés dans l'éditeur de DomoticZ sont enregistrés dans la base de données de DomoticZ et donc sauvegardés en même temps que DomoticZ. Les scripts gérés via le système de fichiers ne sont pas sauvegardés avec DomoticZ.

Par contre, je viens de voir que tu devrais avoir une erreur sur tes lignes : uservariables['water_tank']=OK
  • Le OK, il ne va essayer de trouver une variable OK ... Je pense qu'il faut que tu rentres une chaine de caractères.
  • Il manque quelque chose pour dire qu'il faut écrire cette donnée dans DomoticZ ... C'est la réponse à ta dernière question ;)
Perso, je n'ai en Uservariable que des infos que j'utilise sur plusieurs scripts. Tous mes paramètres sont dans mes différents scripts. Je trouve aussi simple d'aller dans les scripts (via l'éditeur de DomoticZ) que d'aller dans la liste des Uservariables. Surtout quelle peut vite devenir longue. Maintenant, si tu n'as qu'un script pour gérer ta pompe et ta cuve, tu devrais t'y retrouver.

Re: [LUA] message erreur global 'uservariables'

Publié : 23 août 2022, 18:52
par GIC
Pour compléter mon message précédent, j'ai réécrit des passages, intégré des variables locales et je n'ai plus d'erreurs de syntaxe.
Par contre, le déroulement de ma comparaison dans le if n'est pas bon.

Code : Tout sélectionner

        if (otherdevices_svalues['Water_Tank_Hauteur']>'Variable:water_tank_hauteur_mini') then
Mon device Water_Tank_Hauteur a une valeur de 123.4 cm
Ma uservariable water_tank_hauteur_mini vaut 10
et la comparaison renvoie FAUX

J'ai essayé de mettre un tonumber( devant chacun des termes comme ça :

Code : Tout sélectionner

if (tonumber(otherdevices_svalues['Water_Tank_Hauteur'])>tonumber('Variable:water_tank_hauteur_mini'))
mais dans ce cas j'ai une erreur
EventSystem: in water_tank_ok: [string "--..."]:45: attempt to compare nil with number
Je pense que dans mon 1er cas, il essaye de comparer des chaines de texte mais je ne comprends pas pourquoi il interprète tonumber('Variable:water_tank_hauteur_mini') en NIL. C'est la syntaxe qui n'est pas bonne ?

Re: [LUA] message erreur global 'uservariables'

Publié : 23 août 2022, 20:31
par Keros
Dans ce cas, pour déboguer, tu peux mettre un print juste avant la ligne en erreur pour comprendre quelle sont les valeurs que tu essayes de comparer.

Le message d'erreur "nil" indique une valeur vide.

C'est ta syntaxe pour récupérer la uservariable qui n'est pas bonne. Voici un lexique qui pourrait t'aider.

Re: [LUA] message erreur global 'uservariables'

Publié : 24 août 2022, 09:57
par GIC
On progresse... Top !!
J'ai compris et résolu mon problème avec uservariables Effectivement, mauvaise syntaxe !

Et en plus, si je ne trompe pas dans la casse de mes device, je récupère les bonnes valeurs !!! :evil: :o :lol:

Juste un point, c'est étrange que lorsque je fais référence à un device avec la mauvaise orthographe, il ne me retorune pas une erreur d'exécution du genre "device inconnu"...

Re: [LUA] message erreur global 'uservariables'

Publié : 24 août 2022, 12:05
par Keros
Super !

Ce sont les charmes de la programmation :mrgreen: Soit ça plante, soit tu as un truc vide.

Bonne continuation

Re: [LUA] message erreur global 'uservariables'

Publié : 24 août 2022, 13:59
par GIC
Je viens de créer un nouveau script pour déclencher les arrosages.
Même s'il est très simple, il marche !! (OK, après quelques tatonnement.... :mrgreen: )

Pour le debugage, j'ai ajouté 2 print (que je supprimerai après) juste après le commandArray{} et avant le 1er if, 1 pour me dire qu'on rentre dans le script en question, et l'autre pour me renvoyer la valeur du device que je surveille (Plan_Ag).

Par contre, quand je regarde mon log, je vois que ces 2 lignes s'éxécutent 2 fois. 1 fois avant de rentrer dans la boucle if (devicechanged['Plan_Ag']) et une fois après.

Code : Tout sélectionner

commandArray = {}
print('Exécution script Arrosage Agrumes')
print('valeur de Plan_Ag '..(otherdevices['Plan_Ag']))
if (devicechanged['Plan_Ag']) then
        print('Changement dans planning agrumes')
        if (otherdevices['Plan_Ag']=='On' and uservariables['water_tank']=='OK') then
           commandArray['Dombus - [311.2] RL2 - Agrumes']='On' 
            print('Arrosage Agrumes ON')
        else
            commandArray['Dombus - [311.2] RL2 - Agrumes']='Off' 
            print('Arrosage Agrumes OFF')
        end    
end

return commandArray
2022-08-24 13:56:52.460 Status: User: Admin (IP: 192.168.1.110) initiated a switch command (64/Plan_Ag/Off)
2022-08-24 13:56:52.496 Status: LUA: Exécution script Arrosage Agrumes
2022-08-24 13:56:52.496 Status: LUA: valeur de Plan_Ag Off

2022-08-24 13:56:52.496 Status: LUA: Changement dans planning agrumes
2022-08-24 13:56:52.496 Status: LUA: Arrosage Agrumes OFF
2022-08-24 13:56:52.500 Status: EventSystem: Script event triggered: Arrosage_Agrumes
2022-08-24 13:56:52.617 Status: LUA: Exécution script Arrosage Agrumes
2022-08-24 13:56:52.617 Status: LUA: valeur de Plan_Ag Off
C'est normal ?
Est-ce parce que le script s'éxécute en boucle et ne sort que lorsque le if (devicechanged['Plan_Ag']) n'est plus valable ?

Re: [LUA] message erreur global 'uservariables'

Publié : 24 août 2022, 15:44
par Keros
Oui, c'est normal. Le Trigger de ton script doit être All ou Device : il est déclenché à chaque fois qu'un device change de valeur.
C'est avec le Devicechange qu'on limite la portion de code à exécuter lorsque le device souhaité change de valeur.

Tes prints étant à l'extérieur du if devicechange, ils sont exécutés à chaque déclenchement du script.