Inkew Posté(e) le 31 août 2021 Signaler Posté(e) le 31 août 2021 Bonjour, rapide question : peut-on mettre à jour la valeur d'un QA2 depuis un code se trouvant dans un QA1, et si oui quel est le code? Ex. J'ai le QA "Indicateur Solaire" qui met à jour sa valeur Azimut, la hauteur du soleil est calculée et mise à jour dans un Label de ce QA. Je souhaiterai que cette hauteur soit la valeur d'un autre QA : Citation --------------------------------- -- Script de collecte de quelques indicateurs solaire -- Auteur : Sébastien Joly -- Date : 29 août 2015 -- Eléments de calculs : -- http://www.plevenon-meteo.info/technique/theorie/enso/ensoleillement.html -- http://herve.silve.pagesperso-orange.fr/solaire.htm -- adpaté par Jean-Jacques NEFF pour la HC3 le 24/03/2020 --------------------------------- function QuickApp:onInit() __TAG = "QA_"..plugin.mainDeviceId.."_Indicateur Solaire" self:debug("onInit") self.offset = -0 self:Main() end --------------------------------- -- Fonction déterminant si année bissextile --------------------------------- function QuickApp:AnneeBissextile(annee) return annee%4==0 and (annee%100~=0 or annee%400==0) end --------------------------------- -- Fonction Arrondir --------------------------------- function QuickApp: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 local location = api.get("/settings/location") local Ville = location.city local Latitude = location.latitude local Longitude = location.longitude local Altitude = 53 --Vendegies --------------------------------- -- MAIN --------------------------------- function QuickApp:Main() -- Début debug self:trace("=====================================") self:trace(os.date("%Y-%m-%d %H:%M:%S", os.time())) self:trace(Ville .. ", " .. Latitude .. ", " .. Longitude) self:trace("Altitude = " .. tostring(Altitude) .. " m") local NiemeJourDeLAnnee = os.date("%j") --------------------------------- -- Vitesse angulaire = Combien de degrés par jour --------------------------------- VitesseAngulaire = 360/365.25 ----JourDansLAnnee -- ou approximativement 365.25 self:trace("Vitesse angulaire = " .. VitesseAngulaire .. " par jour") --------------------------------- -- Formule Declinaison = ArcSin(0,3978 x Sin(Va x (j - (81 - 2 x Sin(Va� x (j - 2)))))) --------------------------------- local Declinaison = math.deg(math.asin(0.3978 * math.sin(math.rad(VitesseAngulaire) *(NiemeJourDeLAnnee - (81 - 2 * math.sin((math.rad(VitesseAngulaire) * (NiemeJourDeLAnnee - 2)))))))) self:trace("La déclinaison = " .. Declinaison .. "°") --------------------------------- -- Temps universel décimal (UTC) --------------------------------- TempsDecimal = (os.date("!%H") + os.date("!%M") / 60) self:trace("Temps universel decimal (UTC)".. TempsDecimal .." H.dd") --------------------------------- -- Temps solaire --------------------------------- HeureSolaire = TempsDecimal + (4 * Longitude / 60 ) self:trace("Temps solaire ".. HeureSolaire .." H.dd") --------------------------------- -- Angle horaire du soleil --------------------------------- AngleHoraire = 15 * ( 12 - HeureSolaire ) self:trace("Angle Horaire = ".. AngleHoraire .. "°") --------------------------------- -- La hauteur du soleil (Elévation ou altitude) --------------------------------- HauteurSoleil = math.deg(math.asin(math.sin(math.rad(Latitude))* math.sin(math.rad(Declinaison)) + math.cos(math.rad(Latitude)) * math.cos(math.rad(Declinaison)) * math.cos(math.rad(AngleHoraire)))) self:trace("Hauteur du soleil = " .. HauteurSoleil .. "°") self:updateView("LBL_Hauteur", "text", "Hauteur = "..tostring(self:arrondir(HauteurSoleil,0)) .. "°") ---- -- Renseigne la global variable du nom --- fibaro.setGlobalVariable("toto", tostring(self:arrondir(HauteurSoleil,0))) local Azimut = math.acos((math.sin(math.rad(Declinaison)) - math.sin(math.rad(Latitude)) * math.sin(math.rad(HauteurSoleil))) / (math.cos(math.rad(Latitude)) * math.cos(math.rad(HauteurSoleil) ))) * 180 / math.pi local SinAzimut = (math.cos(math.rad(Declinaison)) * math.sin(math.rad(AngleHoraire))) / math.cos(math.rad(HauteurSoleil)) if (SinAzimut<0) then Azimut=360-Azimut end self:trace("Azimut du soleil = " .. Azimut .. "°") --affichage sans offset self:updateView("LBL_Azimut", "text", "Azimut = "..tostring(self:arrondir(Azimut,0)+self.offset).."°") self:updateProperty("value", self:arrondir(Azimut,0)+self.offset) self:updateProperty("unit", " °") self:updateView("LBL_Update", "text", os.date("%d/%m/%Y %H:%M:%S",os.time())) self:trace("=====================================") --bouclage toutes les minutes fibaro.setTimeout(60*1000, function() self:Main() end) end
Lazer Posté(e) le 31 août 2021 Signaler Posté(e) le 31 août 2021 Il faut appeler la méthode updateProperty (la même que tu utilises pour mettre à jour le QA lui-même), sauf qu'au lieu d'utiliser self, il faut utiliser fibaro.call() avec l'IP du QA cible. Par exemple pour mettre à jour la propriété "value" : fibaro.call(ID, "updateProperty", "value", value) 1
Fredmas Posté(e) le 1 septembre 2021 Signaler Posté(e) le 1 septembre 2021 Le 31/08/2021 à 13:40, Lazer a dit : Il faut appeler la méthode updateProperty (la même que tu utilises pour mettre à jour le QA lui-même), sauf qu'au lieu d'utiliser self, il faut utiliser fibaro.call() avec l'IP du QA cible. Par exemple pour mettre à jour la propriété "value" : fibaro.call(ID, "updateProperty", "value", value) Du coup, si on veut mettre à jour la variable locale "toto" avec la valeur "1" du QA2 (destinataire ID2), via le QA1 (émetteur ID1) , comment écrire dans le QA1 ? Ca ça marche ??? fibaro.call(2, "updateProperty", "toto", 1)
Lazer Posté(e) le 1 septembre 2021 Signaler Posté(e) le 1 septembre 2021 Non, avec updateProperty tu ne peux modifier que les propriétés, c'est à dire les valeurs qui sont dans la sous-table properties du JSON du module (visible via /api/devices/ID) Si la variable est "locale", c'est qu'elle est dans la mémoire (pile) du code LUA en cours d'exécution, donc elle n'est absolument pas accessible depuis un autre QA. C'est l'isolation élémentaire des espaces mémoires des programmes informatiques. Encore heureux... encore que des bugs/failles existent, ce qui mène aux plantages ou piratages qu'on voit parfois passer... En revanche, tu peux modifier les variables de QA (celles qui sont dans l'onglet Variables de l'interface Wzb), puisqu'elles sont stockées dans les properties du QA. Mais attention, le format est un peu spécifique, c'est une sous-table qui liste toutes les variables et leurs valeurs, cela n'est donc pas modifiable avec updateProperty, il faut passer par l'API directement.... ou plus simplement appeler la méthode setVariable du QA cible : fibaro.call(ID, "setVariable", "ma_variable", "ma_valeur") je l'ai déjà dit plusieurs fois sur le forum, mais toutes les méthodes (= fonctions) d'un QuickApp sont automatiquement exposées, elles peuvent donc être exécutées depuis un autre QA, ou bien depuis n'importe où dans le monde en passant par l'API HTTP de la box. Cela inclue donc des fonctions aussi élémentaires que self:debug() ===> fibaro.call(ID, "debug", "Injection d'un message dans le log du QA cible") Cela étant dit, tu peux créer une fonction dans un QA, qui permet de modifier une variable locale. Exemple tout simple : function QuickApp:onInit() self.mavariable = "Hello" end function QuickApp:ModifyVariable(value) self.mavariable = value end Il suffit d'appeler depuis un autre QA : fibaro.call(ID, "ModifyVariable", "Goodbye") 1
Fredmas Posté(e) le 1 septembre 2021 Signaler Posté(e) le 1 septembre 2021 Merci d’avoir pris le temps de m’expliquer et pardon si je t’ai fait répéter Même si j’essaie de suivre un max de sujets, on en oublie parfois Ta réponse m’éclaire tel un laser dans l’obscurité 1
Fredmas Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 @Lazer dans le doute je viens d'aller relire d'autres sujets avant de poser la question pour essayer de me répondre tout seul, mais je ne suis pas sûr d'avoir trouvé la réponse. Par curiosité j'ai aussi testé cette écriture et ça fonctionne également : function QuickApp:onInit() mavariable = "Hello" end function QuickApp:ModifyVariable(value) mavariable = value end En gros, sans le self. devant la variable. Quelle est la différence avec l'écriture que tu as proposé qui fonctionne évidemment ?
Lazer Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 Dans mon exemple, mavariable est affectée à l'objet self, c'est à dire l'objet QuickApp, cette variable n'est donc accessible que depuis l'une des fonctions membres de QuickApp (avant de me faire reprendre par les experts : en pratique on peut y accéder d'ailleurs, mais chut, on va pas compliquer inutilement pour l'instant) Dans ton dernier exemple, mavariable est une variable globale dans le code LUA de ton QA. C'est qui n'est pas idéal, car une bonne pratique c'est toujours de limiter la portée d'une variable au strict nécessaire. C'est un sujet qui a été abordé plusieurs fois sur le forum, mais l'information étant diluée ça et là au fil des discussions, c'est pas évident à retrouver. On pourrait transformer ta variable globale en variable locale en l'écrivant ainsi : local mavariable function QuickApp:onInit() mavariable = "Hello" end function QuickApp:ModifyVariable(value) mavariable = value end En revanche attention ce code est faux, car la variable serait alors locale uniquement à la fonction onInit() et ne serait donc pas accessible depuis la fonction ModifyVariable (qui créerait alors une autre variable, globale cette fois-ci, portant le même nom) function QuickApp:onInit() local mavariable = "Hello" end function QuickApp:ModifyVariable(value) mavariable = value end Quelques bonnes lectures : 1
Fredmas Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 Merci pour cette explication très claire, comme souvent Comme discuté ensemble dans un autre sujet il y a quelques temps, j'étais justement en train de virer presque toutes mes variables globales "persistantes" pour utiliser un maximum de variables locales dans mes QA Purée j'étais tout content d'y être arrivé cette semaine, mais ton explication éclairée vient à l'instant de me faire comprendre que je me suis planté, comme le décrit mon exemple précédent. Car je n'ai pas précisé soit self. ou soit local suivant le besoin que tu décris Donc sans le vouloir j'ai créé pléthore de nouvelles variables globales... Bon ben je retourne lire et modifier ma manière de déclarer mes variables dans mes QA
Lazer Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 (modifié) Attention de ne pas confondre : les variables LUA (qui existent dans le code LUA, qu'elles soient locales, globales, ou attribuées à un objet via self) => elles résident uniquement en RAM, elle sont créées à chaque démarrage du QuickApp, et perdues lors de son arrêt les variables persistantes de la box (globales, de QuickApp, ou de Scène) => elles sont stockées dans la DB, donc conservées à chaque redémarrage du QA ou reboot de la box. Modifié le 3 septembre 2021 par Lazer
Fredmas Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 Bon pardon pour le hors-sujet à force... Si tu souhaites supprimer/déplacer, ce serait normal, mais du travail pour toi. Mais du coup bien que tu l'aies déjà répété, j'ai mélangé les notions de variables "persistantes" écrites dans l'onglet Général/Variables ou dans l'onglet Variables d'un QA, avec la notion de leur portée dans le code LUA... #1 Donc finalement j'ai bien limité au maximum l'écriture en dur des variables en les supprimant de ces onglets. Bon point pour l'usure du contrôleur et la vitesse de calcul, car c'était mon premier objectif #2 Par contre j'ai créé beaucoup de variables à portée globales dans mes QA (sans préciser local ou self), ce qui n'est pas catastrophique dans mon usage mais pas le mieux d'un point de vue calcul et risque d'erreur en réutilisation. Je peux donc encore améliorer mes codes en réduisant la portée des variables si nécessaire. Quand Lazer dit : "Reprenons :" Le 25/07/2021 à 13:06, Lazer a dit : -- Cette fonction est membre de la classe QuickApp. Elle est donc automatiquement publiée et accessible depuis l extérieur du QA function QuickApp:test() self:debug("hello") end -- Cette fonction est "globale" (par défaut), c'est à dire accessible dans tous les fichiers du QA : function test(self) self:debug("hello") end -- Cette fonction est locale (car spécifié) donc accessible uniquement dans le fichier en cours (ou bloc de code en cours si la fonction a été définie à l'intérieur d'une autre fonction/boucle/etc) : local function test(self) self:debug("hello") end
Lazer Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 Ah voilà tu as retrouvé où on en a parlé il y a quelques temps Outre les problématiques de portée et de risque d'erreur de réutilisation, précisons, au sujet des performances, qu'il est plus rapide d'utiliser des variables locales que des variables globales (en LUA, ce n'est pas le cas avec d'autres langages) En effet, en LUA, accéder à une variable globale requiert de parcourir la table super-globale _G (une table qui contient toutes les variables globales, les fonctions, etc), ce qui prend des cycles CPU à chaque accès. Mais on parle là de micro-optimisations. Il n'y aura un gain sensible à ce niveau que pour un algorithme très lourd, avec une boucle qui effectue des millions d'accès à la même variable. Cela n'a rien à voir avec la différence de performance lors de l'accès à une variable persistante en DB, pour laquelle la différence de performance est considérable.
Fredmas Posté(e) le 3 septembre 2021 Signaler Posté(e) le 3 septembre 2021 Yes C'est pour ça que de mon côté aidé par le forum comme la première étape est majoritairement atteinte : DB quasi vide, scènes remplacées par QA, et ça tourne de manière stable, je laisse désormais fonctionner quelques jours/semaines pour essayer de piéger d'éventuels cas de vie oubliés dans mes validations et apporter quelques corrections ou nouvelles idées de fonctionnement (sachant qu'il y a quelques temps, je venais de 6,5 ans de HCL avec pleins de scènes blocs, des VG et des VD). Pour l'optimisation de la portée de variables et des gains de perf (encore négligeables dans mon usage), je le ferai par principe, mais dans un second temps dans le cadre de l'amélioration continue durant les longues journées pluvieuses d’automne
Messages recommandés