Aller au contenu

Questions de débutant en Quick Apps sur HC3


Messages recommandés

Posté(e)

#5 Question 5 : appeler une fonction B et attendre son résultat pour l'utiliser au sein d'une fonction A avant de continuer la suite du code du QA

 

Dans une fonction A dans un QA j'appelle une autre fonction B, mais j'ai besoin d'attendre le résultat de cette autre fonction B avant de continuer à dérouler le reste de la fonction A.

Comment coder "proprement" pour que la ligne de 17 attende l'exécution et le résultat d'une fonction appelée à la ligne de code 16 ?

Dans mes premiers essais la ligne après l'appel de la fonction B se déroule avant d'avoir terminé la fonction B et de connaître son résultat dont j'ai besoin pour continuer :wacko:

 

Par exemple :

function QuickApp:onInit()
	self:debug("onInit")
	jsonTableCurrent = {}
end

function currentData()
	print("This function is checking regularly current meteo")
	local http = net.HTTPClient()
	--blabla
	jsonTableCurrent = json.decode(response.data)
end

function mainCode(self)
	self:debug("This function is checking regularly the meteo for prevision")
	currentData()
	self:debug(jsonTableCurrent.name)
end

Dans cet exemple, dans mainCode(self), la ligne "self:debug(jsonTableCurrent.name)" s'exécute avant d'avoir terminé d'exécuter la fonction "currentData()" de la ligne précédente.

 

Donc comment faire pour ne pas exécuter "self:debug(jsonTableCurrent.name)" tant que "currentData()" n'est pas terminé ? :blink:

J'ai bien pensé et essayé un setTimeout d'1s (et ça fonctionne très bien) :

function mainCode(self)
	self:debug("This function is checking regularly the meteo for prevision")
	currentData()
	fibaro.setTimeout(1000, function() self:debug(jsonTableCurrent.name) end)
end

mais je ne trouve pas cela propre. En plus si ma fonction"currentData()" devait exceptionnellement prendre plus de temps que d'habitude et dépasser ma valeur dans setTimeout, mon QA planterait.

Je préfèrerais une solution permettant simplement d'attendre réellement la fin de "currentData()" avant de passer à la ligne suivante :P

C'est peut-être tout bête, mais je n'ai pas trouvé après relu plusieurs doc :D

 

Posté(e)

Bienvenue dans le monde merveilleux de l'asynchronisme :D

 

Il faut utiliser une fonction de rappel (callback) :

function QuickApp:onInit()
	self:debug("onInit")
end

local function currentData(callback)
	print("This function is checking regularly current meteo")
	local http = net.HTTPClient()
	http:request("http://...", {
		success = function()
			--blabla
			local jsonTableCurrent = json.decode(response.data)
			callback(true, jsonTableCurrent)
		end,
		error = function(msg)
			--blabla
			callback(false, msg)
		end,
	}
end

function mainCode(self)
	self:debug("This function is checking regularly the meteo for prevision")
	currentData(
		function(success, data)
			if success then
				self:debug(data.name)
			else
				self:error("ça s'est pas bien passé :", data)
			end
		end
	)
end

Tu constates qu'il y a une première fonction de rappel lors du retour de http:request..... celle-ci en appelant une seconde, la tienne.

C'est ultra puissant, mais pas évident à maitriser au début.

 

Maintenant tu peux aller approfondir avec le sujet suivant :

 

Et aussi celui-ci qui va prendre de l'importance à mesure que tu utilises des fonctions réputées pour planter de temps en temps (httprequest et json.decode) :

 

 

Remarque : définir http à chaque passage de boucle n'est pas judicieux.

Il vaut mieux le définir une seule fois à l'initialisation du QA, donc dans onInit, et l'utiliser par la suite.

A ce sujet, voir la page 2 de 1er tuto dont j'ai donné le lien ci-dessus, on a abordé cette problématique.

  • Like 1
Posté(e)
il y a 35 minutes, Lazer a dit :

Bienvenue dans le monde merveilleux de l'asynchronisme :D

 

Il faut utiliser une fonction de rappel (callback) :

Purée ça fonctionne  :13: Merci ;)

Pas encore tout compris, mais ça fonctionne :D

 

 

il y a 35 minutes, Lazer a dit :

Tu constates qu'il y a une première fonction de rappel lors du retour de http:request..... celle-ci en appelant une seconde, la tienne.

C'est ultra puissant, mais pas évident à maitriser au début.

Oui, je viens de relire au moins 10 fois, et je continue :D

 

 

il y a 35 minutes, Lazer a dit :

Maintenant tu peux aller approfondir avec le sujet suivant :

 

Et aussi celui-ci qui va prendre de l'importance à mesure que tu utilises des fonctions réputées pour planter de temps en temps (httprequest et json.decode) :

 

OK merci beaucoup. Je vais prendre le temps de lire ces 2 sujets à tête reposée ce soir ;)

 

 

il y a 35 minutes, Lazer a dit :

Remarque : définir http à chaque passage de boucle n'est pas judicieux.

Il vaut mieux le définir une seule fois à l'initialisation du QA, donc dans onInit, et l'utiliser par la suite.

A ce sujet, voir la page 2 de 1er tuto dont j'ai donné le lien ci-dessus, on a abordé cette problématique.

Compris, je viens de regarder. Pour ne pas polluer ce topic et mélanger tous les sujets, dans ce cas si besoin je questionnerai directement sur l'autre sujet :P

 

Posté(e)

En fait le principe de base est relativement simple, puisque ça consiste à appeler une fonction en lui donnant un paramètre, ce paramètre est une variable de type "function" (pour rappel en LUA, les fonctions sont des variables au même titre que les autres type : string, table, number, etc)

 

La fonction appelée s'exécute... puis à un moment elle va exécuter la fonction qui lui a été donnée en paramètre (le paramètre que j'ai appelé "callback" dans mon exemple)

 

Une fois que tu as compris ça, il n'y a plus de limite, tu peux enchainer les rappels de fonctions à volonté.

Posté(e)

Ca y est ! A force de relire et faire des exercices cérébraux pour comprendre la dynamique et ton message, je viens d'être éclairé, ou plutôt Laserifié :2:

 

Maintenant que j'ai compris sa lecture, on verra si j'arrive à le réutiliser dans une autre situation ou un autre QA en écriture seul comme un grand :P

Posté(e) (modifié)

@Lazer pour continuer de creuser/philosopher un peu plus les appels de fonction, avec 2 appels http et donc 2 callback, que penses-tu du code ci-dessous (en retirant la plupart des commentaires pour plus de lisibilité:

 

function currentData(self, callback1, callback2)
	self.http:request("blabla1" {
		success = function(response)
			if response.status == 200
			then
				self:debug("Success: status = "..tostring(response.status))
				local jsonTable = json.decode(response.data)
				callback1(true, jsonTable)
			else
				self:warning("Error: status = " ..tostring(response.status))
			end
		end,
		error = function(err)
			callback1(false, err)
			self:warning("Error: " ..err)
		end
	})
	self.http:request("blabla2" {
		success = function(response)
			if response.status == 200
			then
				self:debug("Success: status = "..tostring(response.status))
				local jsonTable = json.decode(response.data)
				callback2(true, jsonTable)
			else
				self:warning("Error: status = " ..tostring(response.status))
			end
		end,
		error = function(err)
			callback2(false, err)
			self:warning("Error: " ..err)
		end
	})
end

function mainCode(self)
	currentData(self,
		function(success1, datajsonTable1)
			if success1
			then self:debug(datajsonTable1.name1)
			else self:error("ça ne s'est pas bien passé :", datajsonTable1)
			end
		end,
		function(success2, datajsonTable2)
			if success2
			then self:debug(datajsonTable2.name2)
			else self:error("ça ne s'est pas bien passé :", datajsonTable2)
			end
		end
	)
end

 

Modifié par Fredmas
Posté(e)
function currentData(self, callback)
  self.http:request("http://worldtimeapi.org/api/timezone/Europe/Stockholm", {
      success = function(response)
        if response.status == 200
        then
          self:debug("Success: status = "..tostring(response.status))
          local jsonTable = json.decode(response.data)
          callback(true, jsonTable)
        else
          self:warning("Error: status = " ..tostring(response.status))
        end
      end,
      error = function(err)
        callback(false, err)
        self:warning("Error: " ..err)
      end
    })
end

function mainCode(self)
  currentData(self,
    function(success1, datajsonTable1)
      if success1
      then self:debug("1",datajsonTable1.datetime)
        currentData(self,function(success2, datajsonTable2)
            if success2
            then self:debug("2",datajsonTable2.datetime)
            else self:error("ça ne s'est pas bien passé :", datajsonTable2)
            end
          end)
      else 
        self:error("ça ne s'est pas bien passé :", datajsonTable1)
      end
    end
  )
end

function QuickApp:onInit()
  self.http = net.HTTPClient()
  mainCode(self)
end

 

Posté(e)

...and you see that currentData(...) becomes a generic http get function...

function httpGet(self, url, callback)
  self.http:request(url, {
      success = function(response)
        if response.status == 200
        then
          self:debug("Success: status = "..tostring(response.status))
          local jsonTable = json.decode(response.data)
          callback(true, jsonTable)
        else
          self:warning("Error: status = " ..tostring(response.status))
        end
      end,
      error = function(err)
        callback(false, err)
        self:warning("Error: " ..err)
      end
    })
end

function mainCode(self)
  httpGet(self,"http://worldtimeapi.org/api/timezone/Europe/Stockholm",
    function(success1, datajsonTable1)
      if success1
      then self:debug("1",datajsonTable1.datetime)
        httpGet(self,"http://worldtimeapi.org/api/timezone/America/New_York",
          function(success2, datajsonTable2)
            if success2
            then self:debug("2",datajsonTable2.datetime)
            else self:error("ça ne s'est pas bien passé :", datajsonTable2)
            end
          end)
      else 
        self:error("ça ne s'est pas bien passé :", datajsonTable1)
      end
    end
  )
end

function QuickApp:onInit()
  self.http = net.HTTPClient()
  mainCode(self)
end

 

  • Like 1
Posté(e)

Good, thank you :D

In your 2 examples, as the 2 functions are not called in parallel but one after the other, do I need to keep success1/datajsonTable1 and success2/datajsonTable2, etc., or can I rename all of them to simply success/datajsonTable

Posté(e)

No absolutely not, I prefer one after the other like in your proposal.

 

My question was just about name of success1, success2, etc.

Posté(e)

I think it's best to serialize http requests, as @jang suggested.

 

You can use the same name for success() arguments, the LUA compiler will use the last one.

But it can be dangerous because it can lead to confusion. A best practice is to use different names.

Posté(e)
il y a 5 minutes, Lazer a dit :

I think it's best to serialize http requests, as @jang suggested.

Yes for sure, it was my purpose :P and for this reason we are talking about callback since yesterday ;)

 

 

il y a 5 minutes, Lazer a dit :

You can use the same name for success() arguments, the LUA compiler will use the last one.

But it can be dangerous because it can lead to confusion. A best practice is to use different names.

Clear, thank you. This was my question, and I understand your answer: yes I can (technically speaking), but I will not  :D

 

 

Posté(e) (modifié)
Il y a 11 heures, Fredmas a dit :

Yes for sure, it was my purpose : Pand for this reason we are talking about callback since yesterday;)

 

 

Clear, thank you. This was my question, and I understand your answer: yes I can (technically speaking), but I will not  : D

 

 

 

Well, the local variables just shadow each other - it will work with same name - I choose different ones just for clarity. ...and clarity is good!

 

Here you have 3 versions.

  1. Parallell - all request run and handled in parallell.
  2. Sequential - one request after another, handled in sequence. 
  3. Parallell_join - The request run in parallell and the response collected in a common result that is sent to the callback when all results are ready. The advantage of sequential with the performance of parallell :-) 
function httpGet(self, url, callback)
  self.http:request(url, {
      success = function(response)
        if response.status < 400 then
          callback(true, url, response.data)
        else
          callback(false, url, response.status)
        end
      end,
      error = function(err)
        callback(false, url, err)
      end
    })
end

local urls2call = {
  "https://www.apple.com",
  "https://www.google.com",
  "https://www.amazon.com",
  "https://www.facebook.com",
}

function parallell(self, urls ,handler)         -- call all urls in parallell, handle asynchronous
  for _,url in ipairs(urls) do 
    httpGet(self, url, handler)
  end
end

function sequential(self, urls, handler)          -- call all urls in sequence
  local i = 1
  local function callback(success, url, result)
    handler(success, url, result)
    i=i+1
    if i  <= #urls then
      httpGet(self,urls[i], callback)
    end
  end
  httpGet(self, urls[i], callback)             
end

function parallell_join(self, urls, handler)        -- call all urls in parallel, call join
  local  result = {n=0,responses={}}
  for _,url in ipairs(urls) do 
    httpGet(self, url,
      function(success, url, response)
        result.responses[#result.responses+1]={url=url,success=success,response=response}
        result.n = result.n+1
        if result.n == #urls then handler(true, nil, result.responses) end
      end)
  end
end


function QuickApp:onInit()
  self.http = net.HTTPClient()

--  parallell(self,urls2call,
--    function(success, url, result) self:debug("Success "..tostring(success).." "..url) end
--  )
--  sequential(self,urls2call,
--    function(success, url, result) self:debug("Success "..tostring(success).." "..url) end
--  )
  parallell_join(self,urls2call,
    function(success, url, result)
      for _,r in ipairs(result) do
        self:debug("Success "..tostring(r.success).." "..r.url) 
      end
    end
  )
end

 

Modifié par jang
  • Like 1
Posté(e)

Guys I like you :P

More we talk, more you have ideas to share and to propose :D

As @Lazer said several times in the past, building codes the main limit is knowledge and creativity :unsure:

  • 4 semaines après...
Posté(e)
Le 11/06/2021 à 15:57, Lazer a dit :

#1 Réponse 1 : choix du type lors de la création d'un QA

 

C'est un super QA que tu nous fait là :D

 

Sérieusement, j'ai aussi ce type de QA, notamment un qui s'appelle "Gestion Maison" et effectue des actions globales : éteindre toutes les lumières, baisser le chauffage, passer la maison en mode vacances, etc.

Du coup, aucun des types "simples" ne lui convient (ou plus exactement, aucun des type correspondant à des modules Z-Wave)

Dans ce cas, le type "Generic device" est tout indiqué.

Ou bien "Device Conroller" s'il aura des enfants (d'ailleurs les enfants peuvent être typés avec un type utile : temperature, etc).

 

En fait ça revient à faire un QA avec une certaine similitude à ce qu'étaient les Virtual Devices sur HC2.

 

Les types Generic et Device Controller n'auront pas d'action associé au clic sur leur icône, ils n'afficheront rien sous leur icône. Il faut les ouvrir (pour afficher leur vue et accéder aux boutons sliders et labels)

Par ailleurs, aussi étrange que cela puisse paraitre, on ne peut pas (encore ?) changer leur icône... sauf à utiliser le hack assez simple déjà partagé plusieurs fois sur le forum.

 

image.png.9d2a1d7c6e16c74026b362696fc360c0.png

 

Rappel : évidemment, autant que possible, il faut utiliser un des types qui correspond à un module Z-Wave (lumière, température, etc) afin de respecter la logique Fibaro, et surtout en bénéficier : à l'usage un QA correctement typé s'utilise exactement de la même façon qu'un module Z-Wave dans la box ou sur l'application mobile. Très pratique.

 

Dernier point : une fois affecté, un module ne peut pas changer de type.

Astuce de contournement : il faut exporter le QA, modifier son type à la main avec un éditeur de texte dans le JSON, puis le réimporter.

 

salut

 

j'ai ouvert mon fichier avec un éditeur et je vois bien effectivement le type de mon QA :

 

"type":"com.fibaro.clima"

 

Est-ce bien cela qu'il faut modifier pour pouvoir après ajouter les icônes au bon vouloir ?

 

Quel type que je dois remplacer ?

 

 

 

 

 

Posté(e) (modifié)

j'ai crée mon tout premier QA il permet QA sur HC3 , il fonction mai c'est un peut l'usine à gaz :D

 

C'est dernier fonctionne grâce à un module infrarouge IP d'envoyer des codes à une clim

 

 il fonctionne surtout grâce à GEA 

 

 

Question d'apprendre j'aurais souhaité de l'aide pour faire la même chose mais uniquement dans le QA 

 

Là où j'ai pris plus de gaz, c'est avec la Tampo de 4 heures et 2 heures.

 

Si on appuie sur 4H le décompte avant le OFF mais si entre-temps j'appuie sur 2H il faut qu'il stoppe le décompte du 4H

Le Reset permet de stopper le 4H ou 2H

 

 

 

 

ci-dessous le QA:

qa.pdf

 

948737632_Capturedcran2021-10-1410_22_35.thumb.png.51dc9b025557339eb4b76b80e3c9a268.png

 

Modifié par 971jmd
  • 5 semaines après...
Posté(e)
Le 11/06/2021 à 21:57, Lazer a dit :

C'est un super QA que tu nous fait là :D

Le 12/06/2021 à 08:12, Fredmas a dit :

:2: super QA ça je ne sais pas, mais comme dit ailleurs maintenant que j'ai fait quelques trucs (probablement basiques pour les spécialistes) en LUA, je commence l'apprentissage des QA.

 

Le 03/07/2021 à 14:08, Lazer a dit :

@Fredmas en fait tu es en train de réinventer la roue ;)

 

Ce que tu cherches à faire, c'est exactement ce que fait déjà GEA, ou l'exemple de @jang

 

GEA fait bien plus évidemment, mais ça fonction de base c'est de surveiller à intervalle régulier l'état de plusieurs conditions, et agir (ou pas) en conséquence.

Maintenant si tu veux juste apprendre pour le plaisir de coder en LUA, dans ce cas tu peux effectivement écrire ta propre boucle, comme dans l'exemple intervalRunner(), qui sera plus efficace (plus précis) que GEA (qui est précis à 30 secondes près). Dans l'esprit, cela ressemble beaucoup au Scheduler qui existait sur HC2 v3.

Le 03/07/2021 à 15:34, Fredmas a dit :

Oui tu as raison @Lazer, je m'étais fait la remarque d'ailleurs.

Mais comme tu as compris que j'aime bien comprendre ce que je fais, tu as raison c'est aussi un peu par plaisir d'apprendre et de coder mon truc que j'essaie de faire des QA.

J'ai bien pensé prendre ta version HC3 de GEA, mais bon dans un premier temps voir ma phrase précédente :P

Alors j'essaie d'évoluer petits bouts par petits bouts de temps en temps le week-end, et en partageant mes questions/réponses dans ce topic au cas où cela aiderait d'autres membres (évidemment ce n'est pas toi ou @jang que ça va aider vu votre niveau élevé en QA :lol: )

 

 

 

Salut @Lazer (@jang et les autres), bon ben juste pour te dire que tu avais raison. A un niveau technique certainement bien différent, sans trop m'en rendre compte j'ai réinventé mon propre GEA (nommé autrement), qui me permet de contrôler régulièrement ce qui se passe et d'agir en fonction de. Grâce à votre aide j'ai commencé avec ce petit QA par le lever/coucher du soleil et la gestion des volets, et y ajoute de temps en temps d'autres automatismes :P, et depuis complété avec un autre QA qui contrôle régulièrement la météo et envoie des informations au QA principal ;)

Bon au moins je comprends chaque ligne de code qui y figure dans ce QA :D

Difficile d'imaginer/comprendre la puissance du système avant de s'y mettre, mais maintenant je ne reviendrais pas en arrière avec mes dizaines de scènes bloc et variables globales :lol:

 

  • Like 2
Posté(e)
Le 14/10/2021 à 11:20, 971jmd a dit :

j'ai crée mon tout premier QA il permet QA sur HC3 , il fonction mai c'est un peut l'usine à gaz :D

 

C'est dernier fonctionne grâce à un module infrarouge IP d'envoyer des codes à une clim

 

 il fonctionne surtout grâce à GEA 

 

 

Question d'apprendre j'aurais souhaité de l'aide pour faire la même chose mais uniquement dans le QA 

 

Là où j'ai pris plus de gaz, c'est avec la Tampo de 4 heures et 2 heures.

 

Si on appuie sur 4H le décompte avant le OFF mais si entre-temps j'appuie sur 2H il faut qu'il stoppe le décompte du 4H

Le Reset permet de stopper le 4H ou 2H

 

 

 

 

ci-dessous le QA:

qa.pdf

 

948737632_Capturedcran2021-10-1410_22_35.thumb.png.51dc9b025557339eb4b76b80e3c9a268.png

 

Salut

 

Si on appuie sur 4H je lance la clime et au bout de quatre heures elle doit s’éteindre appuyer sur le bouton off

 

mais si entre-temps avant la fin des quatre heures j'appuie sur 2H il faut qu'il stoppe le décompte du 4H et commencer à décompter les deux heures. 
 

je n’arrive pas à le faire

 

Posté(e) (modifié)

Je pense avoir 1 ou 2 idées pour faire cela, soit en mode simple mais tu perds le fil si ta box plante entre temps, ou en boucle qui ne perd pas le fil en cas de redémarrage peu importe les raisons (box planté, électricité, etc.) ce qui à mon avis n'est peut-être pas utile car finalement tu t'en fiches si une ou deux fois par an ton tempo se perd à cause d'un redémarrage...

Par contre avant de partager les idées, je me rends compte que tu sembles utiliser GEA (ce que je ne fais pas, voir les messages précédents), du coup je me demande si tu ne pourrais pas intégrer cela et cette surveillance dans ton GEA, histoire de ne pas multiplier les boucles...

Modifié par Fredmas
  • Like 1
Posté(e)

Salut @Fredmas

 

alors oui pour le moment ça fonctionne mais avec GEA. 
 

mais je pense qu’il aurait été peut-être plus simple de passer directement par le Quick app. 
 

 

Posté(e) (modifié)

OK compris @971jmd

Il y a 21 heures, 971jmd a dit :

Si on appuie sur 4H je lance la clime et au bout de quatre heures elle doit s’éteindre appuyer sur le bouton off

mais si entre-temps avant la fin des quatre heures j'appuie sur 2H il faut qu'il stoppe le décompte du 4H et commencer à décompter les deux heures. 

je n’arrive pas à le faire

Alors pour un QA autonome, pas parfait mais très simple, tu pourrais faire un truc comme ci-dessous.

Mais attention, je rappelle que je suis également un débutant. Aussi ce serait pour chez moi je ne ferais pas comme ça car je fonctionne désormais avec mon propre QA de contrôle des évènements.

Et comme je ne sais pas comment sont tes codes, histoire de t'aiguiller dans ta réflexion, le truc suivant ultra simple devrait répondre à ta question :

function QuickApp:onInit()
  self:debug("onInit")
  timeoutClim = 0
  duration = 0
end

function QuickApp:buttonClim1()
  duration = 2*60*1000
  test()
end

function QuickApp:buttonClim2()
  duration = 4*60*1000
  test()
end

function test()
  print("test allumage")
  if timeoutClim > 0 then clearTimeout(timeoutClim) timeoutClim = 0 end
  timeoutClim = setTimeout(function() print("test extinction") end, duration)
end

Evidemment tu remplaces "test", "timeoutClim", "duration", "buttonClim1", "buttonClim2", et les "print" par les syntaxes qui te conviennent.

 

Ce serait pour moi, je fonctionnerais avec un QA qui boucle, et je surveillerais une incrémentation courte pour ne pas avoir à mettre en place des setTimeout si long.

Mais pas simple de conseiller, j'espère que ça répond à ton interrogation :P

 

Modifié par Fredmas
  • Like 1
Posté(e)

avant tout chose merci pour ton aide

si tu est debutant bin tu debut super bien :74:

 

 

je comprend certaine chose mai pas tout 

 

le code complet:

 

_Rebischung _IR.fqa

 

je suppose qui coler mon code HEX entre les parenthèses de test 

 

le bonton ON

function QuickApp:ON24_S1_C1(event)
self:send("sendir,1:3,1,36656,1,1,129,63,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,366,129,63,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,48,16,16,16,48,16,48,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,48,16,16,16,16,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,48,16,16,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,48,16,16,16,48,16,16,16,16,16,48,16,46920x0D0x0A",true)

et le OFF

 

---OFF
function QuickApp:OFF_S1_C1(event)
self:send("sendir,1:3,1,36656,1,1,129,63,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,366,129,63,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,48,16,16,16,48,16,48,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,48,16,16,16,16,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,48,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,16,16,48,16,16,16,16,16,16,16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,16,16,16,48,16,16,16,16,16,48,16,46920x0D0x0A",true)

 

 

 

×
×
  • Créer...