Aller au contenu
triossrf

setTimeout sur capteur?

Recommended Posts

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

 

Partager ce message


Lien à poster
Partager sur d’autres sites

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.

 

 

  • Like 1
  • Thanks 1

Partager ce message


Lien à poster
Partager sur d’autres sites

@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 :60:.

 

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é par triossrf

Partager ce message


Lien à poster
Partager sur d’autres sites

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é par Lazer
  • Like 1
  • Thanks 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Ahhh j'avais pas compris la subtilité avec le roller shutter je vais essayer ton Q.A de ce pas. 

merci a toi. 

Partager ce message


Lien à poster
Partager sur d’autres sites
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 ?

Partager ce message


Lien à poster
Partager sur d’autres sites

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)

Partager ce message


Lien à poster
Partager sur d’autres sites
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 -_-

 

Partager ce message


Lien à poster
Partager sur d’autres sites

×