triossrf Posté(e) le 24 novembre 2021 Signaler Posté(e) le 24 novembre 2021 Bonsoir à tous. J'aimerai savoir si il y' a d'autre méthode dans un Q.A mise à part le settimeout? je m'explique: Ce soir j'ai fais un bout de code qui est le suivant: local Volet = fibaro.getValue(Walli, "value") function QuickApp:ActiveWalli() if Volet == 0 then self:setVariable("EtatVolet", "Fermé") fibaro.call(Walli, 'setRingOnColor', "green") fibaro.call(Walli, 'setRingOffColor', "blue") self:debug("Volet fermé") else self:setVariable("EtatVolet", "Ouvert") fibaro.call(Walli, 'setRingOnColor', "none") fibaro.call(Walli, 'setRingOffColor', "none") self:debug("Volet ouvert") end end Est-ce qu'il n'y a pas possibilité de faire une lecture instantanée des variables lors d'un changement d'état du volet par exemple? J'ai bien pensé à faire un self:ActiveWalli(), mais tout logiquement il me Lit la variable à l'infini tant qu'il n'y a pas de changement d'état. Si jamais il y a des méthodes plus pertinentes que le settimeout. Je suis preneur. Merci.
Fredmas Posté(e) le 24 novembre 2021 Signaler Posté(e) le 24 novembre 2021 Pour être sûr de bien comprendre, tu aimerais (par exemple) : - que lorsque tu bouges ton volet à la main (interrupteur ou autre automatisme) - ton QA soit au courant ? Franchement à part demander à ton QA de surveiller (donc tourner en boucle), je n'ai qu'une seule idée que je ne trouve pas du tout intéressante : - avoir une scène avec comme trigger ton module de volet, qui ensuite appelle l'exécution de ton QA en cas de changement d'état. Maintenant je te réponds en live sans trop y avoir réfléchis longuement, mais c'est ce qu'il me vient à l'esprit. Car sans boucle dans ton QA, de lui-même il ne surveillera pas ce qu'il se passe. Soit il tourne en continue, soit tu as quelque chose qui le prévient volontairement. A défaut du setTimeout il y a bien setInterval, mais d'un point de vue boucle temporelle qui check ce qu'il se passe, tu ne seras pas plus avancé avec ça. Question : pourquoi veux-tu trouver une autre solution qu'un QA qui boucle pour vérifier ce qu'il se passe ? Le fait que ce ne soit pas quasiment instantané ? 1
triossrf Posté(e) le 24 novembre 2021 Auteur Signaler Posté(e) le 24 novembre 2021 Effectivement tu as mit le doigt dessus! Il y'a plusieurs raison à cela. 1- Pour éviter de solliciter la box pour rien. Si mon volet change 4 fois max d'état par jours je trouve cela dommage de faire une boucle toute les 30 secondes pour vérifier l'état. 2- Effectivement, j'aurai bien aimé qu'il y ai un peu d'instantanéité à la fin de la lecture de la fonction. Il n'y a donc pas possibilité de détecter instantanément un changement de variable (local ou global) ? Cela pourrait permettre de résoudre mon problème.
Fredmas Posté(e) le 24 novembre 2021 Signaler Posté(e) le 24 novembre 2021 Si, selon moi avec un trigger dans une scène ou ton QA qui vérifie toutes x secondes. En dehors de ça je ne vois pas, mais je ne suis pas le plus fort en LUA ou QA. Après si ton QA n’est pas gargantuesque, quel est le problème à le faire tourner. Ton contrôleur Fibaro en est capable facilement
Fredmas Posté(e) le 24 novembre 2021 Signaler Posté(e) le 24 novembre 2021 Même si je comprends complètement ton raisonnement 1. de ne pas vouloir « solliciter » ta box que pour ça…
triossrf Posté(e) le 25 novembre 2021 Auteur Signaler Posté(e) le 25 novembre 2021 Bah disons qu'au lieu de faire une boucle toutes les 10 secondes, j aurais une fonction qui prenne en compte en temps réel et qu'une seul fois un changement d état du volet sa éviterai à la machine de tourner pour rien. Après, si il n y a aucun impact sur la machine autant faire cela puisque ça marche. Je m étai dis que si il y a 20 Q.A qui ont des settimeout toutes les 10 secondes sa doit tirer sur la machine. ( je n ai pas de recul suffisant pour savoir ce que peut supporter la hc3) .
jang Posté(e) le 25 novembre 2021 Signaler Posté(e) le 25 novembre 2021 It's not the setTimeout - it's what you do inside the setTimeouts... Here I start 1 million setTimeouts in parallell. local t = os.time() for i=1,1000000 do -- Start a million setTimeouts fibaro.setTimeout(1,function() end) end fibaro.setTimeout(30,function() print("OK2") print(os.time()-t) end) The last setTimeout with 30ms timer will not be allowed to run until all the 1 million have completed (that's how we time it). It takes 41s on the HC3 [27.05.2021] [12:07:13] [DEBUG] [SCENE24]: OK2 [27.05.2021] [12:07:13] [DEBUG] [SCENE24]: 41 That's actually quite ok. The trick with polling for state changes is not to do it with a setTimeout loop doing fibaro.getValue. It's to do http:requests to the /refreshStates api as the http request will hang if there are no events and not consume any cpu during that time. When an event is available the http request will return immediately. Granted is that you will get all kinds of events and need an efficient way to filter for events that you look for (devices changing state or globals changing value) - but that is easy to do with a table lookup. I have a ready made library 'fibaroExtra.lua' that implements an event/sourceTrigger callback function that is as efficient as it gets. 1
Lazer Posté(e) le 25 novembre 2021 Signaler Posté(e) le 25 novembre 2021 En complément... j'avais fait des tests de charge avec l'API refreshStates, et il s'avère que l'impact sur la charge CPU est relativement minime : Perso j'ai plusieurs QA qui exploitent cette API en parallèle. Actuellement 4 je crois : Il y a notamment GEA, mais aussi Evénements, la gestion de ma porte de garage, et d'un Velux. 2
Fredmas Posté(e) le 25 novembre 2021 Signaler Posté(e) le 25 novembre 2021 Merci @jang et @Lazer Bon il ne reste plus qu'à investiguer l'utilisation de cette API Bonnes soirées de lecture et de cerveau qui brule en perspective, on ne s'ennuie jamais ici 1
jang Posté(e) le 25 novembre 2021 Signaler Posté(e) le 25 novembre 2021 (modifié) Try to install this QA TriggerQA.fqa v1.21 and then create another QA: function QuickApp:subscribeTrigger(event) local s = self:getVariable('TRIGGER_SUB') if s == nil or s == "" then s = {} end s[#s+1]=event self:setVariable('TRIGGER_SUB',s) end function QuickApp:sourceTrigger(tr) self:debug(json.encode(tr)) end function QuickApp:onInit() self:debug("onInit") self:subscribeTrigger({type='device'}) end This will call QuickApp: sourceTrigger with the trigger as soon as it happens. You can be more specific and do self:subscribeTrigger({type='device', id=88}) self:subscribeTrigger({type='device', id=99}) to only get triggers from deviceId 88 and 99 etc. Inside QuickApp: sourceTrigger you need to look at the trigger to see what trigger it is if you subscribe to different triggers. If you don't need super optimized trigger handling (then you run your own / refreshStates loop) then the TriggerQA is a simple helper that makes it easy for other QAs to receive sourceTrigger with very little overhead - similar to how scenes gets them - and it scales very well. Modifié le 2 décembre 2021 par jang 3 1
triossrf Posté(e) le 28 novembre 2021 Auteur Signaler Posté(e) le 28 novembre 2021 Merci pour vos réponses, je vais essayer tout cela prochainement
jang Posté(e) le 2 décembre 2021 Signaler Posté(e) le 2 décembre 2021 (modifié) Updated TriggerQA to v1.21 Supported triggers {type='alarm', property='armed', id=<id>, value=<value>} {type='alarm', property='breached', id=<id>, value=<value>} {type='alarm', property='homeArmed', value=<value>} {type='alarm', property='homeBreached', value=<value>} {type='alarm', property='activated', id=<id>, seconds=<seconds>} {type='weather', property=<prop>, value=<value>, old=<value>} {type='global-variable', property=<name>, value=<value>, old=<value>} {type='quickvar', id=<id>, name=<name>, value=<value>; old=<old>} {type='device', id=<id>, property=<property>, value=<value>, old=<value>} {type='device', id=<id>, property='centralSceneEvent', value={keyId=<value>, keyAttribute=<value>}} {type='device', id=<id>, property='accessControlEvent', value=<value>} {type='profile', property='activeProfile', value=<value>, old=<value>} {type='custom-event', name=<name>} {type='deviceEvent', id=<id>, value='removed'} {type='deviceEvent', id=<id>, value='changedRoom'} {type='deviceEvent', id=<id>, value='created'} {type='deviceEvent', id=<id>, value='modified'} {type='sceneEvent', id=<id>, value='started'} {type='sceneEvent', id=<id>, value='finished'} {type='sceneEvent', id=<id<, value='instance', instance=<number>} {type='sceneEvent', id=<id>, value='removed'} {type='sceneEvent', id=<id>, value='modified'} {type='sceneEvent', id=<id>, value='created'} {type='onlineEvent', value=<boolean>} {type='room', id=<id>, value='created'} {type='room', id=<id>, value='removed'} {type='room', id=<id>, value='modified'} {type='section', id=<id>, value='created'} {type='section', id=<id>, value='removede'} {type='section', id=<id>, value='modified'} {type='location',id=<userid>,property=<locationid>,value=<geofenceaction>,timestamp=<number>} {type='ClimateZone',...} {type='ClimateZoneSetpoint',...} It also supports time/cron events Time subscription: {type='cron', time=<cronString>, tag=<string>} cron string format: "<min> <hour> <day> <month> <wday> <year>" min: 0-59 hour: 0-23 day: 1-31 month: 1-12 wday: 1-7 1=sunday year: YYYY Ex. "0 * * * * *" Every hour "0/15 * * * * *" Every 15 minutes "0,20 * * * * *" At even hour and 20min past "0 * * 1-3 * *" Every hour, January to March "0 7 lastw-last * 1 *" 7:00, every sunday in the last week of the month "sunset -10 lastw-last * 1 *" 10min before sunset every sunday in the last week of the month Ex. self:subscribeTrigger({type='cron', time="0/15 * * * * *", tag="Quarter"}) will send back a source trigger ever 15min in the format {type='cron', time="0/15 * * * * *", tag="Quarter"} 'tag' can be useful to match timers to actions... This gives more or less the same or more functionality than what you get from Scene conditions. Modifié le 2 décembre 2021 par jang 2 2
Messages recommandés