triossrf Posté(e) le 10 août 2021 Signaler Posté(e) le 10 août 2021 Bonjour la communauté. J'ai besoin de vos savoirs pour une question de rafraîchissement d'icône. Je m'explique : J'ai deux capteurs magnétiques pour ma porte de garage. Un en bas (pour m'indiquer que le portail est fermé). Un en haut (pour m'indiquer que le portail est ouvert). Quand il n'est ni en haut ni en bas il est ouvert a moitié pour faire un passage au chien. Pour avoir une bonne lisibilité sur le tableau de bord, les icones changent selon l'état des capteurs. J'ai mis un "setTimeout" toutes les 30 secondes afin de voir les icones changer. J'aurais aimé qu'il s'actualise automatiquement et instantanément dés lors qu'un capteur change d'état, et donc sans passer par un setTimeout Je vous mets le code, si cela peut vous aider. Merci d'avance. function QuickApp:onInit() __TAG = "QA_"..plugin.mainDeviceId.."_Portail_Garage" self:debug("onInit") self:Etat() self:Loop() end ---Ouverture du Chien function QuickApp:Massaye() fibaro.call(171,"turnOn") fibaro.sleep(6000) fibaro.call(171,"turnOn") end function QuickApp:OnOff() fibaro.call(171,"turnOn") end function QuickApp:Etat() local EtatValBas = fibaro.getValue(375, "value") local EtatValHaut = fibaro.getValue(376, "value") if EtatValBas == false then self:updateProperty("deviceIcon", 1054) self:updateProperty("log", "Portail Fermé") end if EtatValHaut == false then self:updateProperty("deviceIcon", 1055) self:updateProperty("log", "Portail Ouvert") end if EtatValBas == true and EtatValHaut == true then self:updateProperty("deviceIcon", 1053) self:updateProperty("log", "Portail Massaye") end function QuickApp:Loop() self:Etat() fibaro.setTimeout(30000, function() self:Loop() end) self:debug("Refraichissement") end end
Lazer Posté(e) le 10 août 2021 Signaler Posté(e) le 10 août 2021 Il faut utiliser /api/refreshStates Il y a une discussion sur ce sujet sur le forum, sur comment le mettre en œuvre, et son impact (très modéré) sur les performances. Il se trouve que j'ai un QuickApp qui fait exactement pareil, de type rollerShutter, et qui surveille 2 contacts d'ouverture haut et bas, comme toi. Je ne l'ai pas partagé parce que je pensais être le seul dans ce cas de figure. Voici le code, il faut mettre les ID des 2 détecteurs dans l'onglet Variables du QA. Ce QA fait une double vérification de l'état de la porte (c'est critique... sécurité oblige) : boucle avec setTimeout, et détection instantané avec refreshStates : ---------------------------------------------------------------------------------------------------- -- QuickApp : Porte garage -- Author : Lazer -- Version : 1.00 -- Date : May 2021 ---------------------------------------------------------------------------------------------------- -- -- System variables -- __TAG = "QA_PORTEGARAGE_" .. plugin.mainDeviceId QuickApp.version = 1.00 QuickApp._VERSION = "1.00" local id_bas, id_haut local garbageExecTime local intervalLoop -- -- Constructor -- function QuickApp:onInit() -- Initialize self:trace("") self:trace("QuickApp Porte de garage - Initialisation") self:trace("") -- Check if QuickApp device is enabled if not api.get("/devices/"..tostring(self.id)).enabled then self:updateProperty("log", "Désactivé") self:warning("Le module", self.name, "est désactivé => QuickApp arrêté") return end -- Get QuickApp variables id_bas = tonumber(self:getVariable("ID_Bas")) id_haut = tonumber(self:getVariable("ID_Haut")) if not id_bas or not id_haut then self:error("ID haut ou bas invalide") self:updateProperty("log", "Erreur") return end local refreshInterval = tonumber(self:getVariable("Refresh")) or 60 -- Update main device properties self:updateProperty("manufacturer", "Lazer") self:updateProperty("model", "Porte garage") self:updateProperty("log", "") -- Display debug information self:debug("<font color=teal>Capteur porte basse : #<b>" .. tostring(id_bas), fibaro.getName(id_bas), "</b> =>", fibaro.getType(id_bas), "</font>") self:debug("<font color=teal>Capteur porte haute : #<b>" .. tostring(id_haut), fibaro.getName(id_haut), "</b> =>", fibaro.getType(id_haut), "</font>") self:debug("<font color=teal>Intervalle de rafraîchissement : <b>" .. tostring(refreshInterval) .. "</b> secondes", "</font>") -- Initialize internal variables local lastRefresh = 0 -- Performance optimization local http = net.HTTPClient() local http_request = http.request local json_decode = json.decode local pcall = pcall local type = type local setTimeout = setTimeout -- -- Boucle d'attente d'événements instantanés -- local function instantLoop() local status, err = pcall(function() local stat, res = http_request(http, "http://127.0.0.1:11111/api/refreshStates?last=" .. lastRefresh, { success = function(res) local status, states = pcall(function() return json_decode(res.data) end) if status then if type(states) == "table" then lastRefresh = states.last or 0 local events = states.events local nbEvents = #(events or {}) for i = 1, nbEvents do local event = events[i] if event.type == "DevicePropertyUpdatedEvent" then local data = event.data if data and data.property == "value" then local id = data.id if id == id_bas then if data.newValue then self:trace("Porte basse", data.newValue and "ouverte" or "fermée", "=> Porte ouverte à 50 %") self:updateProperty("value", 50) else self:trace("Porte basse", data.newValue and "ouverte" or "fermée", "=> Porte ouverte à 0 %") self:updateProperty("value", 0) end elseif id == id_haut then if data.newValue then self:trace("Porte haute", data.newValue and "ouverte" or "fermée", "=> Porte ouverte à 99 %") self:updateProperty("value", 99) else self:trace("Porte haute", data.newValue and "ouverte" or "fermée", "=> Porte ouverte à 50 %") self:updateProperty("value", 50) end end end end end else self:error("Invalid states :", type(states)) end else self:error(states or "json.decode() failed") end setTimeout(instantLoop, 250) end, error = function(res) self:error("Error : API refreshStates :", res) setTimeout(instantLoop, 5000) end, }) end) if not status then self:error(err) setTimeout(instantLoop, 5000) end end -- Start both loops fibaro.setTimeout(1000, function() intervalLoop(self, refreshInterval) end) fibaro.setTimeout(1500, instantLoop) end -- -- Main loop -- intervalLoop = function(self, refreshInterval) -- Display LUA memory consumption every 5 minutes if not garbageExecTime then garbageExecTime = os.time() else local elapsedTime = os.difftime(os.time(), garbageExecTime or 0) if elapsedTime >= 300 then self:debug(string.format("<font color=gray>Total memory in use by Lua : %.2f KB</font>", collectgarbage("count"))) garbageExecTime = os.time() end end -- Check local newValue if fibaro.getValue(id_haut, "value") then newValue = 99 elseif not fibaro.getValue(id_bas, "value") then newValue = 0 else newValue = 50 end if newValue ~= self.properties.value then self:warning("Porte ouverte à", newValue, "%") self:updateProperty("value", newValue) end -- Wait if refreshInterval and refreshInterval > 0 then fibaro.setTimeout(math.floor(refreshInterval*1000), function() intervalLoop(self, refreshInterval) end) end end -- -- Actions -- function QuickApp:open() self:setValue(99) end function QuickApp:close() self:setValue(0) end function QuickApp:stop() end -- Value is type of integer (0-99) function QuickApp:setValue(value) -- TODO -- Gestion du double clic -- Appel de l'API GCE IPX800 et du FGS --self:trace("Ouverture porte à", value, "%") --self:updateProperty("value", value) end On constate tout en cas que j'ai prévu les actions open, close, et setValue, auxquelles doit pouvoir réagir un QA de type RollerShutter. Sauf que je n'ai pas encore câblé cela sur la porte de garage, donc pour l'instant c'est inactif. 1 1
triossrf Posté(e) le 10 août 2021 Auteur Signaler Posté(e) le 10 août 2021 (modifié) @Lazer Merci pour ta réponse rapide, je vais alors fouiner sur le forum pour trouver le fameux /api/refreshStates voir si je peu peaufiner le Q-A et je vais me pencher également sur ton Q-A qui m'a l'air bien plus poussé que le mien . Du coup tu n'es plus seul avec tes deux capteurs . Pour ma part je ne peu pas utiliser le même code que toi car il ne s'agit pas d'un RollerShutter pour mon portail mais d'un FGS-224 On/Off. Modifié le 10 août 2021 par triossrf
Lazer Posté(e) le 10 août 2021 Signaler Posté(e) le 10 août 2021 (modifié) Mais justement, tu n'as pas saisis l'intérêt du QuickApp Évidemment que je n'utilise pas non plus un Roller Shutter pour piloter ma porte de garage, puisqu'aucune porte de garage ne peut être pilotée avec un FGR. C'est toujours du contact sec. J'utilise un contact d'un IPX800 en série avec un FGS (double sécurité, je ne veux pas que la porte s'ouvre toute seule... bon malgré tout ce n'est toujours pas câblé comme dis précédemment). Mais avec un FGS-224 comme le tient ça serait pareil. C'est le QA qui est de type Roller Shutter, pour apparaitre proprement dans l'interface Fibaro (web et mobile). Et laisser la box gérer les icônes toutes seules, selon son pourcentage d'ouverture. Dans la pratique, comme j'ai 2 capteurs (bas et haut), je peux déterminer 3 positions (complètement fermé, complètement ouvert, et intermédiaire). Comme toi. Donc dans la propriété value du QA RollerShutter, ça se traduit par 0, 50 et 99, comme tu peux le voir dans le code LUA. Bref, vu le code ci-dessus, ça permet de remonter l'état de la porte de garage dans la box. Et il reste à écrire les lignes dans la fonction QuickApp:setValue(value) pour agir sur la porte. EDIT: Modifié le 10 août 2021 par Lazer 1 1
triossrf Posté(e) le 11 août 2021 Auteur Signaler Posté(e) le 11 août 2021 Ahhh j'avais pas compris la subtilité avec le roller shutter je vais essayer ton Q.A de ce pas. merci a toi.
jjacques68 Posté(e) le 12 août 2021 Signaler Posté(e) le 12 août 2021 Le 10/08/2021 à 10:47, Lazer a dit : Il faut utiliser /api/refreshStates rien à voir avec le sujet, désolé, mais @Lazer, tu as donc la boucle d'interrogation du refreshstate dans GEA et dans ce QA ? tu interroges cette API donc à plusieurs endroit différent ? Pas de soucis de performances alors ?
Lazer Posté(e) le 12 août 2021 Signaler Posté(e) le 12 août 2021 Mais justement @jjacques68 j'avais longuement détaillé mes expériences sur l'autre sujet. Aucun souci de performance. Pour l'instant j'ai 3 QA (GEA, Velux, Porte garage) sur ma box de production qui exploitent cette API, et ça tourne nickel depuis 2 mois. Je pense même en ajouter un 4ème prochainement, quand j'aurai le temps de m'y mettre (réécrire le QA Evénements pour utiliser /refreshStates à la place de /events/history)
jjacques68 Posté(e) le 12 août 2021 Signaler Posté(e) le 12 août 2021 il y a 23 minutes, Lazer a dit : j'avais longuement détaillé mes expériences sur l'autre sujet. Exacte, je me rappelle maintenant que tu le dis, je viens de retrouver le sujet
Messages recommandés