[Résolu] - Fixer la valeur d'un capteur virtuel en LUA

Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
vinchz31
Messages : 312
Inscription : 21 nov. 2016, 07:51

[Résolu] - Fixer la valeur d'un capteur virtuel en LUA

Message par vinchz31 »

Bonjour à tous,

Je débute sur Domoticz et suis en train d'essayer de fixer la valeur d'un capteur virtuel en LUA.
J'ai créé un capteur de type switch et là, pas de soucis avec un commandArray['MonSwitchVirtuel']='On'

En revanche, si je créée autre chose comme capteur virtuel, rien n'y fait je ne parviens pas à effectuer de modification (exemple: capteur virtuel type température ou plus simplement texte pour être sûr du format à envoyer avant de repasser au test température).

J'ai vu que plusieurs personnes avaient eu le même souci sur le forum (et que la solution consistait alors à passer en JSON), mais je voulais savoir si une l'origine du souci avait au final été identifiée sous LUA et si une solution LUA était possible.

L'idée pour moi est simple: faire un capteur virtuel "hygrométre" qui prendrait la moyenne de mes capteurs d'hygrométrie dans la maison pour piloter ma VMC (NB: aucun souci pour récupérer en LUA ces valeurs et faire la moyenne, ça fonctionne parfaitement).

Merci d'avance pour votre aide !
Dernière modification par vinchz31 le 22 nov. 2016, 08:03, modifié 2 fois.
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par deennoo »

Voici un script que j'utilise pour mettre a jour un virtuel de temperature :

Code : Tout sélectionner


--ce script calcule la difference de temperature entre l'exterieur et l'interieur
--149 est le numero idx de mon virtuel de temperature
commandArray = {}
        if (devicechanged['Exterieur'])
        then
           if (otherdevices_temperature['Exterieur'] - otherdevices_temperature['Salon'] >= 0)
           then
             commandArray['UpdateDevice'] = 149 .. '|0|'.. tostring(otherdevices_temperature['Exterieur'] - otherdevices_temperature['Salon'])
	   elseif (otherdevices_temperature['Exterieur'] - otherdevices_temperature['Salon'] <= 0)
           then
             commandArray['UpdateDevice'] = 149 .. '|0|'.. tostring(otherdevices_temperature['Exterieur'] - otherdevices_temperature['Salon'])
           end
        end
        return commandArray
la commande est

Code : Tout sélectionner

commandArray[tempDeviceIdx] = { ['UpdateDevice'] = tempDeviceIdx..'|0|'..temp }
pour la temperature.

si il n'y a pas cette commande pour l'humidité je ferais un capteur Temperature/humidité, la commande pour le mettre a jour est celle ci :

Code : Tout sélectionner

commandArray[tempHumDevIdx] = { ['UpdateDevice'] = tempHumDevIdx..'|0|'.. temp ..';'.. hum ..';'.. hum_stat }
L'interet est le hum_stat qui est defini ainsi :

Code : Tout sélectionner

Humidity_status can be one of:
0=Normal
1=Comfortable
2=Dry
3=Wet
Toujours en script, tu peux definir que si ta moyenne de % d'humidité est dans des valeurs que tu as defini :

Code : Tout sélectionner

normal de x% a y%
comfortable de w% a x%
dry de v% a w%
wet de y% a z%
tu peux faire afficher ce statut a ton capteur et ainsi t'en servir pour definir la regle de ta vmc.

Si tu peux partager ton script pour les moyenne de temperature et humidité je suis prenneur stp.
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
vinchz31
Messages : 312
Inscription : 21 nov. 2016, 07:51

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par vinchz31 »

Bonjour deenoo,

Merci beaucoup pour le retour.

J'ai du mal à saisir deux choses si tu peux m'aider :

Dans ton script tu positionnes :
commandArray['UpdateDevice'] = 149 .. '|0|'.. tostring(otherdevices_temperature['Exterieur'] - otherdevices_temperature['Salon'])

Et tu indiques que la commande est :
commandArray[tempDeviceIdx] = { ['UpdateDevice'] = tempDeviceIdx..'|0|'..temp }

- Sur la première partie de la commande tu indiques "commandArray[tempDeviceIdx] = { ['UpdateDevice']...." qu'est ce que ça signifie ? (que je peux soit mettre "commandArray[149] = ..." ou "commandArray['UpdateDevice'] = 149...." ?
- Sur la deuxième partie, je comprends qu'il faut fixer la valeur sur l'ID du capteur virtuel et pas sur son nom comme je le fais, passer un |0| puis la température. A quoi sert le |0| au milieu dans cette syntaxe ?

En te remerciant par avance pour ton aide et tes explications.
Très bonne journée !
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par deennoo »

vinchz31 a écrit :Bonjour deenoo,

Merci beaucoup pour le retour.
Mais de rien

vinchz31 a écrit : Dans ton script tu positionnes :
commandArray['UpdateDevice'] = 149 .. '|0|'.. tostring(otherdevices_temperature['Exterieur'] - otherdevices_temperature['Salon'])

Et tu indiques que la commande est :
commandArray[tempDeviceIdx] = { ['UpdateDevice'] = tempDeviceIdx..'|0|'..temp }
C'est vrai c'est un peu contradictoire, honnetement ce que j'ai dans le script fonctionne, mais pas essayer la commande qui vient du wiki, donc j'ai envie de dire : fait comme dans le script, cela fonctionne !
vinchz31 a écrit : - Sur la première partie de la commande tu indiques "commandArray[tempDeviceIdx] = { ['UpdateDevice']...." qu'est ce que ça signifie ? (que je peux soit mettre "commandArray[149] = ..." ou "commandArray['UpdateDevice'] = 149...." ?

Code : Tout sélectionner

commandArray['UpdateDevice'] = 149 .. '|0|'..valeur
fonctionne, donc on reste ainsi non ?
vinchz31 a écrit : - Sur la deuxième partie, je comprends qu'il faut fixer la valeur sur l'ID du capteur virtuel et pas sur son nom comme je le fais, passer un |0| puis la température. A quoi sert le |0| au milieu dans cette syntaxe ?
Je ne sais pas, c'est ecrit ainsi dans le wiki des events : https://www.domoticz.com/wiki/Events (au 2/3 de pages) si le chef dit que c'est ainsi, on fait ainsi, peute a creuser dans la doc LUA.
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
vinchz31
Messages : 312
Inscription : 21 nov. 2016, 07:51

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par vinchz31 »

Super, merci encore une fois.
Je teste ce soir et je vous fais le retour pour mettre le post à résolu.
Très bonne journée !
Neutrino
Messages : 2662
Inscription : 10 juil. 2015, 15:42
Localisation : Les Herbiers(85)

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par Neutrino »

Bonjour,
En fait, commandArray est un tableau.
Tu peux donc y mettre plein de chose.
commandArray['le nom de l interupteur']='On'
ou commandArray['SendNotification']='subject#body#0'
et pour la température
commandArray[tempDeviceIdx] = { ['UpdateDevice'] = tempDeviceIdx..'|0|'..temp }

Attention a ne pas écraser une valeur.
commandArray['OpenURL']='www.premierurl.fr'
commandArray['OpenURL']='www.secondurl.fr'
seul le secondurl.fr sera appelé.
J'ai remarqué aussi qu'un
commandArray['UpdateDevice'] = idxSwitch.. '|0|'..'Off'
met à jour le switch (il passe à Off) mais ne déclenche pas de devicechanged.
Cela évite les boucles.
Comme l'a dit Deennoo, tout est décrit ici : https://www.domoticz.com/wiki/Events
Ma maison à plein d'IP ! :mrgreen:
SAV Bonjour. Vous avez vidé le cache ?
vinchz31
Messages : 312
Inscription : 21 nov. 2016, 07:51

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par vinchz31 »

Bonjour Neutrino,

Merci, je vais aller faire un tour sur le lien envoyé pour essayer de comprendre tout ça.
Très bonne journée !
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Fixer la valeur d'un capteur virtuel en LUA

Message par deennoo »

Comme cette histoire de moyenne m'amusait a faire j'ai un peu bosser dessus, j'ai bien reussit a cree une moyenne de temperature par etage, + moyenne d'humidité + etat d'humidité avec ce script adapter aux pieces de chaque etage :

Code : Tout sélectionner


-- //!\\ il faut cree une variable utilisateur de type entier avec 0 en valeur pour jouer avec le hum_statut

-- Fonction Arrondir à deux décimales
function arrondir(num, dec)
   if num == 0 then
      return 0
   else
      local mult = 10^(dec or 0)
      return math.floor(num * mult + 0.5) / mult
end
end

--moyenne de temperature et humidité rdc
stu, stuh = otherdevices_svalues['Studio']:match("([^;]+);([^;]+)")
stu = tonumber(stu)
stuh = tonumber(stuh)

loi, loih = otherdevices_svalues['Piece Loisir']:match("([^;]+);([^;]+)")
loi = tonumber(loi)
loih = tonumber(loih)

ent = otherdevices_svalues['Entree']:match("([^;]+)")
ent = tonumber(ent)

atm = otherdevices_svalues['Atelier Mel']:match("([^;]+)")
atm = tonumber(atm)

bur, burh = otherdevices_svalues['Bureau Nico']:match("([^;]+);([^;]+)")
bur = tonumber(bur)
burh = tonumber(burh)

-- moyenne de temperature
moytrdc = arrondir(((stu + loi + ent + atm + bur) / 5),1) --on arrondi le resultat a 1 decimal
moytrdc = tonumber(moytrdc)

-- moyenne d' humidite
moyhrdc = arrondir(((stuh + loih + burh) / 3),1) --on arrondi le resultat a 1 decimal
moyhrdc = tonumber(moyhrdc)


commandArray = {}

   

        if (devicechanged['Piece Loisir'] or devicechanged['Bureau Nico'] or devicechanged['Studio'] or devicechanged['Entree'] or devicechanged['Atelier Mel'])
        then
            print('moyenne temp rdc : '..moytrdc)
            print('moyenne hum rdc : '..moyhrdc)
            
            -- on dertermine le niveau de confort
            if moyhrdc < 45 then
                commandArray['Variable:hum_statut_rdc']='2'
            elseif moyhrdc >= 45 and moyhrdc <= 65 then
                commandArray['Variable:hum_statut_rdc']='1'
            elseif moyhrdc > 65 then
                commandArray['Variable:hum_statut_rdc']='3'
            end 
            
            -- on recupere la variable hum_statut
            hum_statrdc = tonumber(uservariables['hum_statut_rdc'])
            
            --mise jour du capteur virtuel
        --commandArray['UpdateDevice'] = 2336 ..'|0|'.. moytrdc ..';'.. moyhrdc ..';'.. hum_statrdc
        commandArray[2336] = { ['UpdateDevice'] = 2336 ..'|0|'.. moytrdc ..';'.. moyhrdc ..';'.. hum_statrdc }

end
return commandArray

ou 2336 est un virtuel Temp/Hum

J'ai ensuite voulue faire une moyenne de la maison total (moyenne etage + moyenne rdc)/2 : raté !

impossible de faire executé le script de moyenne maison, si je me sert des deux virtuels en 'declancheur', il aura fallut utiliser une sonde "reel" de l'etage et une sonde "reel" du RDC pour que ce script s'execute.

J'ai essayé les deux technique de mise a jour :

Code : Tout sélectionner

commandArray['UpdateDevice'] = 2336 
et

Code : Tout sélectionner

commandArray[2336] = { ['UpdateDevice'] = 2336 ..'|0|'.
Reste a voir cette fonction d'arrondi a 1 dixieme, parce que la moyenne peut etre longue :
Capture.PNG
Capture.PNG (66.9 Kio) Consulté 13971 fois
cela ce passe ici : viewtopic.php?f=10&t=2820


Edit : Fonction arrondir ajouté et commenté
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
vinchz31
Messages : 312
Inscription : 21 nov. 2016, 07:51

Re: [Rséolu] - Fixer la valeur d'un capteur virtuel en LUA

Message par vinchz31 »

Bonjour,

J'ai testé très rapidement la mise à jour du capteur virtuel hier avec la méthode donnée.
Ca fonctionne parfaitement.

J'ai commencé par récupérer l'IDx de mon capteur virtuel dans les dispositifs :
Domoticz6.jpg
Domoticz6.jpg (126.49 Kio) Consulté 13939 fois
NB1: j'ai créé un capteur virtuel Température mais également un texte pour tester les deux.
NB2: attention, il faut bien récupérer l'IDx (ici 6 et 8) et non l'ID qui sont ici 00082006 et 14058.
Une fois récupéré, j'ai testé le mise à jour dans un script time :

-----------------------------------------------------------------------

commandArray = {}


-- récupération de la température et hygro de la première sonde
temperatureL, hygroL, etatL = otherdevices_svalues['Sonde l']:match("([^;]+);([^;]+);([^;]+)")

-- récupération de la température et hygro de la première sonde
temperatureParents, hygroParents, etatParents = otherdevices_svalues['Sonde SdB Parents']:match("([^;]+);([^;]+);([^;]+)")

-- calcul de la moyenne
Moyenne_Temp = (temperatureL + temperatureParents)/2

-- Affichage pour contrôle dans la log Domoticz
print( temperatureL .. " " .. hygroLea .. " " .. etatLea)
print( temperatureP .. " " .. hygroParents .. " " .. etatParents)
print ( Moyenne_Temp )


-- Fixation de la valeur du capteur de température vituel
commandArray['UpdateDevice'] = 8 .. '|0|'.. tostring(Moyenne_Temp)

-- Fixation de la valeur du texte virtuel
commandArray['UpdateDevice'] = 6 .. '|0|'.. "Ca fonctionne !!!"


-- Je déclenche un moteur extracteur (connecté sur un module on/off) si la moyenne relevé est supérieur à une température définie dans une variable (TEMPDECLENCHEMENT)

if Moyenne_Temp > uservariables["TEMPDECLENCHEMENT"] then
commandArray['On/off extracteur']='On'
print ( "La temperature moyenne (" .. Moyenne_Temp .. ") est supérieure à la température fixée (" .. uservariables["TEMPDECLENCHEMENT"] .. " : déclenchement" )
else
commandArray['On/off extracteur']='Off'
print ( "La temperature moyenne (" .. Moyenne_Temp .. ") est inférieure à la température fixée (" .. uservariables["TEMPDECLENCHEMENT"] .. " : arrêt" )
end


return commandArray

-----------------------------------------------------------------------

Le tout fonctionne parfaitement :
- le capteur texte reçoit bien la valeur "Ca fonctionne !!!" dans Domoticz
- le capteur virtuel de température se met bien à jour avec la moyenne des températures dans Domoticz
- mon moteur déclenche bien en fonction de la température moyenne

Deux remarques :
- Ce que je ne m'explique cependant pas c'est pourquoi certains dispositifs peuvent être mis à jour directement avec leur nom, exemple : commandArray['On/off extracteur']='On' (qui fonctionne très bien et me met bien en marche ou arrête mon moteur), et pourquoi pour d'autres il faut passer par la syntaxe commandArray['UpdateDevice'] = Idx .. '|0|'.. valeur. J'ai m'impression que tous les dispositifs virtuels nécessitent cette deuxième syntaxe
- concernant la question que j'ai posé sur la présence du |0|, après recherche il correspond au nvalue :
"To modify an otherdevice value, you should use commandArray['UpdateDevice']='idx|nValue|sValue' where idx is the device index, nValue and sValue the values to modify (see json page for details - Domoticz API/JSON URL's) "
Le Svalue représente la valeur que l'on souhaite attribuer mais je n'ai pas trouvé la signification du nvalue.
Sur cette page : https://easydomoticz.com/les-tables-domoticz/ il est effectivement indiqué qu'elle est souvent à 0 (ce qui correspond au cas ci-dessus). A priori il existe des tables pour préciser quel doit être le nvalue pour chaque dispositif ("You can have a look at the database for the nValue/sValue, or the .cpp code") mais je ne sais pas ou trouver cette information...

Je n'ai plus qu'à faire ça avec la partie Hygro pour gérer ma VMC. Sujet résolu !
Très bonne journée et merci pour votre aide !
vinchz31
Messages : 312
Inscription : 21 nov. 2016, 07:51

Re: [Résolu] - Fixer la valeur d'un capteur virtuel en LUA

Message par vinchz31 »

J'ai testé hier la moyenne Hygro en créant un capteur virtuel humidité.
Et là... la mise à jour du capteur virtuel ne fonctionnait plus avec la méthode utilisée pour le texte et la température (CF post ci-dessus):
La commande " commandArray['UpdateDevice'] = 5 .. '|0|'.. tostring(Moyenne_Hygro) " ne mettait pas à jour mon capteur virtuel (ou 5 est l'IDx de mon capteur virtuel d'humidité).

Comme j'avais vu que le nvalue (ici 0) pouvait des fois valoir 1 (CF post ci-dessus), j'ai tenté le coup en mettant
commandArray['UpdateDevice'] = 5 .. '|1|'.. tostring(Moyenne_Hygro)

Le script passe... ...et mon humidité passe à 1%
Si je mets 38 à la place de 1 dans le commandArray, elle passe à 38%

J'ai donc testé en mettant uniquement : commandArray['UpdateDevice'] = 5 .. '|10|'
pour voir si la syntaxe suffisait et faisait passer mon capteur à 10%

Et bien non !
J'ai donc testé en mettant uniquement : commandArray['UpdateDevice'] = 5 .. '|10|' .. 0
Ca fonctionne.
Si on ne complète pas en positionnant une Svalue quelle qu'elle soit (3ème valeur dans la commande), le capteur n'est pas mis à jour.

J'ai donc essayé la commande suivante pour que mon Hygro calculée soit positionnée :
commandArray['UpdateDevice'] = 5 .. tostring(Moyenne_Hygro) .. 0

Pas de mise à jour !!!
J'ai fini par réussir à faire fonctionner en positionnant :
commandArray['UpdateDevice'] = 5 .. '|' .. tostring(Moyenne_Hygro) ..'|' .. 0
...et là miracle, mon capteur est bien mis à jour :D

Il faut donc dans la syntaxe :
- le nvalue soit positionné impérativement entre "|" pour que ça fonctionne (normal sinon il n'y a rien qui délimite la nvalue de la svalue)
- que le nvalue comme le svalue soient impérativement renseignés
Pour le capteur virtuel d'humidité, seul le nvalue est utilisé (on peut mettre n'importe quelle valeur dans le svalue cela n'apporte aucun changement visible).

J'en déduis donc que l'on doit systématiquement passer un nvalue et un svalue pour mettre à jour un dispositif et qu'il s'agit simplement de deux valeurs utilisées ou non par les dispositifs (ex: la température n'utilise pas le nvalue mais utilise le svalue alors que l'humidité utilise le nvalue mais n'utilise pas le svalue).
Ceci expliquerait peut-être pourquoi :
- pour une sonde virtuelle (ou un dispositif un peu poussé) la seule commande commandArray['MaSondeVirtuelle'] = 10 ne marche pas (on passe au capteur virtuel d'humidité une seule valeur alors que le dispositif en exige deux, CF ci-dessus lorsqu'on ne met pas de Svalue)
- la commande commandArray['On/off extracteur']='On' fonctionne car il s'agit d'un interrupteur on/off qui ne requiert qu'une seule valeur (on ou off)

Voici donc un petit bout du script en exemple qui me permet de calculer mon humidité moyenne dans la maison pour piloter ensuite ma VMC en déclenchant celle-ci sur la valeur du capteur d'humidité virtuel :

--------------------------------------
commandArray = {}

temperatureL, hygroL, etatL = otherdevices_svalues['SondeL']:match("([^;]+);([^;]+);([^;]+)")
temperatureS, hygroS, etatS = otherdevices_svalues['SondeS']:match("([^;]+);([^;]+);([^;]+)")

Moyenne_Hygro = (hygroL+ hygroS) / 2
commandArray['UpdateDevice'] = 5 .. '|' .. tostring(Moyenne_Hygro) ..'|' .. 0

return commandArray

-----------------------------------
NB: il faudrait peut-être essayer en ne positionnant pas le dernier "|" (qui indique normalement une séparation avec une valeur suivante) ni la svalue (dernière valeur) voir si ça fonctionne. Exemple : commandArray['UpdateDevice'] = 5 .. '|' .. tostring(Moyenne_Hygro). Je tenterai et vous dirai ce que ça donne...

J'espère que ça pourra en aider certain...
Très bonne journée !
Répondre