Aller au contenu

Recommended Posts

CODER UN BOUTON FONCTIONNANT UNIQUEMENT SUR DOUBLE-CLIQUE

 

 

Les boutons des modules virtuels ne permettent malheureusement pas grand chose d'autre que de cliquer dessus. Il arrive même parfois que nous cliquions sur un bouton par inadvertance.

 

Dans la plus part des cas cela n'est pas grave mais pour certaines opérations sensibles, il serait judicieux de pouvoir valider notre clique.

 

L'idée (soumise par @Moicphil) est de déclencher l'action uniquement lors d'un double-clique sur le bouton.

 

Pour réaliser cela, il nous faut :

  • Un bouton
  • Un label

Le label va nous servir à  avertir l'utilisateur qu'un double-clique est nécessaire, mais il va surtout nous servir à  savoir si un clique précédent a été effectuer.

 

527205DbClick.png

 

Au premier clique, le système affiche le message pendant un temps limité. Si pendant ce temps, l'utilisateur ré appuie sur le bouton, l'action est confirmée, sinon on retire le message et la confirmation est annulée.

 

Voici donc le code a implémenter derrière votre bouton :

-- ----------------------------
-- Ne pas toucher --
-- ----------------------------
function confirm(msg, labelId, secondes)
    local current = fibaro:getValue(fibaro:getSelfId(), "ui."..labelId..".value")
    if (current == msg) then
        fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value", " ")
    	return true
    else
        fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value", msg)
        fibaro:sleep(secondes*1000)
        fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value","")
	return fibaro:getValue(fibaro:getSelfId(), "ui."..labelId..".value") == " "
    end
end

-- ----------------------------
-- A vous de jouer ---
-- ----------------------------
local message = "Ré-appuyer pour confirmer" -- le message de confirmation
local label_id = "lblMessage"               -- l'ID du label qui recevra le message
local duree = 1                             -- la durée max entre 2 clique (en seconde)

if ( confirm(message, label_id, duree) ) then
      fibaro:log("Confirmé") 
      -- votre code ici en cas de confirmation
else 
      fibaro:log("Annulé")  
      -- votre code ici en cas d'annulation
end

Le code n'est pas si compliqué et la partie qui vous intéresse début à  la ligne 21.

 

Voilà , j'espère que cela puisse vous éviter quelque catastrophe :)

 

 

P.S. Il y a aussi moyen d'utiliser une variable global à  la place du label mais l'insertion d'une valeur dans une variable globale est trop lente pour être viable.

  • Upvote 11

Partager ce message


Lien à poster
Partager sur d’autres sites

Au top Steven...

Pourquoi chui pas chez moi pour tester... Trop injuste. :-(

Envoyé de mon C6603 en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Salut Steven,

 

On a pas la possibilité de changer le label du bouton à  la volée afin que l'utilisateur clique sur le bouton, obtienne la demande de confirmation, re-clique (ou pas selon son choix) sur le bouton ?

 

Merci d'avance de ton retour

@+

Partager ce message


Lien à poster
Partager sur d’autres sites

Malheureusement ce n'est pas possible 😞

Envoyé de mon GT-I9192 en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

@Steven, juste pour compléter: il est possible de mettre àjour àla volée le label d'un bouton mais le label lui n'est rafraîchi qu'après un rechargement de page, donc inutile notre cas ;)

Variable globale trop lente àêtre mise àjour ? Peux tu m'en dire plus ?

Sinon, merci pour ce code .

Envoyé de mon iPhone àl'aide de Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

C'est ce qu'il me semblait mais je préférais faire valider par deux grosses stars ;-)

 

@Krikroff : j'avais vu un de test posts pour le changement à  la volée où tu avais indiqué qu'il fallait refaire un load de la page, chose qui dans ce cas comme tu dis fais pas notre beurre... Je me suis dit qu'avec les updates de notre HC2 entre temps ça avait peut être changé...

 

@Steven : oui, merci pour le code, très utile: typiquement, j'ai installé un store banne piloté via un module fibaro et que selon les données météo je referme (pluie, vent, rafales, ...). J'ai créé un module virtuel qui permet de basculer en mode automatique/manuel et une confirmation est très intéressante, donc merci :-) Egalement intéressé sur l'utilisation de la variable globale si tu as un peu de temps pour expliquer.

Partager ce message


Lien à poster
Partager sur d’autres sites

Imaginons que j'ai une variable globale à1. Si je fait un setGlobal(..., 2) et de suite un getGlobal, j'ai 1 en retour. Par contre, si je temporise avec un sleep entre deux c"est tout bon.

Ce qui me semble normal vu que les variables globales doivent être stockées ce qui nécessite un temps de traitement un peu plus lent. Traitement qui semble être effectué en asynchrone.

Est-ce que vous avez le même comportement ?

Envoyé de mon GT-I9192 en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Non pas de latence (Pourtant ma HC2 est chargée comme une mule ;)), je viens de faire encore le test:

fibaro:debug("switch global to 2");
fibaro:setGlobal("test", 2);
fibaro:debug(fibaro:getGlobalValue("test"));
--etc...
[DEBUG] 00:32:03: switch global to 2
[DEBUG] 00:32:03: 2
[DEBUG] 00:32:04: switch global to 1
[DEBUG] 00:32:04: 1
[DEBUG] 00:32:05: switch global to 2
[DEBUG] 00:32:05: 2

 
De plus un setProperty sur un label persiste la valeur en bd exactement comme un setGlobal et le getValue sur un label est exactement la même chose qu'un getGlobalValue, donc si effectivement tu as des problèmes de latences avec tes variables globales, tu auras exactement les mêmes avec la mise à  jour de tes label un jour ou l'autre :huh:.

Partager ce message


Lien à poster
Partager sur d’autres sites

Ok merci pour tes tests, je vais refaire des tests après un bon reboot, on ne sait jamais. ;-)

Pour la persistance des labels, pourquoi c'est persister puisque ce n'est pas récupérer après un simple enregistrement du VD. Tu parles bien de la valeur d'un label et non pas du label lui-même ?

Envoyé de mon GT-I9192 en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Logiquement même après un reboot tes labels reprennent leurs valeurs, enfin c'était comme ça avant ! Après dans tous les cas ta solution evite l'utilisation d'une variable globale je trouve cela bien ;) .

 

Je suis curieux de savoir si le reboot va arranger les choses...

Partager ce message


Lien à poster
Partager sur d’autres sites

Après 1h30 de test :

 

Je suis surpris en bien .. je n'ai PAS rebooter ma box.

 

J'ai créer un VD avec un label, un slider et deux boutons. Un bouton pour setter la valeur du label et du slider et un bouton pour gérer le double clique avec une variable globale (voir code ci-dessous)

 

Une fois la valeur du label et du slider setter .. la valeur reste bien, même après un reboot ... PARFAIT

J'ai cliquer un million de fois sur mon bouton ... la variable globale a toujours répondu parfaitement ... PARFAIT.

 

Sur ces deux points ... J'avais tord et pourtant, je suis convaincu d'avoir vu des choses bizarres.

 

Code correct du double-clique avec une variable globale

if (tonumber(fibaro:getGlobalValue("Capsule")) >= 2) then
	fibaro:log("Confirmé")
  	fibaro:setGlobal("Capsule", 3)
else
  	fibaro:log("Encore...")
	fibaro:setGlobal("Capsule", 2)
end

fibaro:sleep(1000)
fibaro:setGlobal("Capsule", 1)
fibaro:log("")

J'ai donc poussé mes tests plus loin en mettant le code ci-dessous dans un main-loop

fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Slider1.value",50)
fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Label1.value",fibaro:getValue(fibaro:getSelfId(), "ui.Slider1.value"))

Le code est simple, je met 50 dans le slider et la label affiche la valeur du slider.

Résultat, je devrais TOUJOURS avoir 50 dans le label puisque qu'il affiche TOUJOURS la valeur du slider qui est TOUJOURS de 50

 

et ben non

 

si on bouge manuellement le slider sur 85 ou une autre valeur, on va voir que le main loop repasse bien le slider à  50 mais par contre le label affiche la valeur de 85... il faudra attendre les 3 secondes pour qu'il affiche 50

Ce problème n’apparaît pas si j'exécute le même code dans un bouton. 

 

Krikroff, arrives-tu me confirmé cela stp ?

 

Et merci de m'avoir corrigé sur les points précédents. Il se peut que les soucis que j'ai cru voir seraient liés uniquement au main loop qui provoque dans ce cas des latences ( et encore, je vais attendre ta confirmation avant de juger trop vite ) 

Partager ce message


Lien à poster
Partager sur d’autres sites

Je confirme ton dernier test Steven, mais ce comportement me semble relativement logique et complétement dépendant du "design" du Main Loop et des 3 secondes de latence (minimum) avant un rafraichissement qui provoque un décalage entre la mise à  jour des variables "côté serveur" et du front (IHM)

 

Il ne faut pas oublier que nous sommes ici dans une configuration client/serveur non bidirectionnelle puisque la page web n'est mise à  jour que grâce a des requêtes (ajax) sur l'api du HC2.  D'ailleurs un Socket TCP c'est pourtant pas bien compliqué à  proposer :huh: pour les devs Fibaro, je demande cela depuis la V1.xx :angry: et puis les applications mobiles seraient beaucoup plus réactives :15:

Partager ce message


Lien à poster
Partager sur d’autres sites

Ok néanmoins cela provoque un comportement troublant et surtout incorrecte puisque le code est

a = 1

display (a)

Et que le résultat n'est pas 1.

Je travail en GWT Google Web Toolkit. En développement, l'éditeur Java et le navigateur discute grâce àun socket TCP alors que la version en exploitation est en ajax. En effet, le mode Socket est fréquemment bien plus réactif. Par contre je crois que cela ne fonctionne pas sous Safari et les navigateurs de plus petit gabarit.

Envoyé de mon GT-I9192 en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

C'est bien ce qui ce passe Steven ;) juste que les 3 secondes sont trompeuses. Avec ton code:

 

1 - Label + Slider sont à  50

2 - je bouge le slider, je relâche à  75 (a=75)

3 - entre 1 à  3 secondes après le Label passe à  75 (display(a)) et le slider lui passe de 75 à  50 logique puisque fixé par le mainloop donc a=50

4 - entre 1 à  3 secondes après le Label passe à  50 -> display(a)

 

J'ai testé 15 minutes et toujours le même comportement donc tout me semble ok même si le côté non réactif trouble le comportement.

 

Sinon aujourd'hui il me semble que seul opera mini ne supporte pas les WebSockets, Safari / ios safari c'est ok depuis la V6 :60:

Partager ce message


Lien à poster
Partager sur d’autres sites

J'ai enfin compris d'où venait ces soucis avec la réactivité des applications mobiles Je me demandais si du coup on arriverait pas àsur un virtual device faire demander le pin sur lancement d'un de ses boutons, dans le sens remplacer le double clique par une confirmation par code pin. Pas encore regardé si àmon niveau de connaissance c'est faisable ou pas.

razowski

Partager ce message


Lien à poster
Partager sur d’autres sites

super @Steven , ça marche très bien et c'est super utile  :60:

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

@Krikroff

Autre chose troublante ... quand un slider est mise à  jour via son API, sa valeur n'est pas stockée.

 

Exemple, j'ai un VD avec 15 sliders (passerelle Netatmo)

Mon script google via les appels API de Netatmo et de la HC2 met à  jour mes sliders.

Si je resauve le VD, tout les sliders repassent à  0 et il faut attendre les 5 mn que le scipt Google se ré-exécute.

Avant

mini_604898vdavant.png

Après enregistrement du VD.

mini_632137vdapres.png

Edit ... retour son le code précédent

1 - Label + Slider sont à  50

2 - je bouge le slider, je relâche à  75 (a=75)

3 - entre 1 à  3 secondes après le Label passe à  75 (display(a)) et le slider lui passe de 75 à  50 logique puisque fixé par le mainloop donc a=50

4 - entre 1 à  3 secondes après le Label passe à  50 -> display(a)

Cela est normal si tu affiche le label avant de repasser le slider à  50 mais dans le cas inverse, non.

Le code est le suivant :

0) Je bouge le slider sur 75

le main loop s'active

1) Slider = 50

2) Label = valeur du slider (théroriquement cela devrait être 50)

3) Dodo pendant les 3 secondes su main loop

Donc a chaque exécution du main loop, le label devrait TOUJOURS avoir la valeur du slider qui vient d'être mis à  50.

Je comprend très bien les problèmes lié à  l'asynchrone mais là  c'est un bug car la valeur affichée n'est pas celle stockée.

Partager ce message


Lien à poster
Partager sur d’autres sites

@Razowsky, ça c'est pour toi :Dhttp://www.domotique-fibaro.fr/index.php/topic/1475-d%C3%A9clenchement-par-code-pin-et-clavier-virtuel/

 

@Steven, oui je comprends bien sauf que moi je suis incapable de dire quand le main loop s'active: avant que je bouge le slider, en même temps, juste après ... le résultat n'est pas le même selon le cas de figure. Pour moi la valeur affichée est bien celle stockée mais toujours avec un décalage indéterminé et non déterminable à  par peut-être par un Polonais après 1 bouteille de vodka :P. Bug peut-être mais je pense plus à  une faiblesse dans la conception venant s'ajouter à  un choix technique discutable, après le plus important c'est de bien cerner tout cela pour éviter les comportements étranges dans nos modules :60:

 

Merci pour l'info sur le slider, il faut que je test cela, sinon pourquoi utiliser des sliders pour ton affichage NetAtmo et pas des labels ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Je ne connais pas d'API Fibaro qui permet de mettre à  jour un label directement

 

Je n'ai vu que ceux là  :

Virtual Devices 
ID = device ID 
arg1 = button ID 
arg2 = slider value (only for slider) 
http://<HC2 ip address>/api/callAction?deviceID=15&name=pressButton&arg1=2 
http://<HC2 ip address>/api/callAction?deviceID=51&name=setSlider&arg1=8&arg2=30 

Donc mon Script Google manipule les sliders et ensuite dans mon main loop, je récupère ces valeurs et je mets à  jour mes labels.

 

Si tu as une solution plus simple, je suis preneur.

 

Ah, avant que j'oublie, Google Script est en https donc impossible d'appeler le script depuis la HC2 comme vous le faite en PHP. C'est donc le Script qui, toutes les 5 minutes, pousse l'information à  la HC2.

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour a tous,j'aurai besoins de vous.J'ai bien fais un boutons (pour effectuer un Reboot) et un label;j'ai mis le code que ma donner  Krikroff ci dessous et ensuite  le code pour confirmer est ce que cela est correct,j'ai mis un espace entre es deux.Merci

 
  1. local httpClient = Net.FHttp("127.0.0.1", 11111);
  2. local response, status, errorCode = httpClient:POST("/api/settings/reboot", "data=reboot");
  3. if errorCode == 0 then
  4. fibaro:debug("status:"..status);
  5. else
  6. fibaro:debug("Error code is "..errorCode..", response is ["..response..]");
  7. end

 

 

-- ----------------------------
-- Ne pas toucher --
-- ----------------------------
function confirm(msg, labelId, secondes)
    local current = fibaro:getValue(fibaro:getSelfId(), "ui."..labelId..".value")
    if (current == msg) then
        fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value", " ")
    	return true
    else
        fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value", msg)
        fibaro:sleep(secondes*1000)
        fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value","")
	return fibaro:getValue(fibaro:getSelfId(), "ui."..labelId..".value") == " "
    end
end

-- ----------------------------
-- A vous de jouer ---
-- ----------------------------
local message = "Ré-appuyer pour confirmer" -- le message de confirmation
local label_id = "lblMessage"               -- l'ID du label qui recevra le message
local duree = 1                             -- la durée max entre 2 clique (en seconde)

if ( confirm(message, label_id, duree) ) then
      fibaro:log("Confirmé") 
      -- votre code ici en cas de confirmation
else 
      fibaro:log("Annulé")  
      -- votre code ici en cas d'annulation
end

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Ton code (celui donnée par Krikroff) doit être inséré directement ou c'est marqué -- votre code ici en cas de confirmation.

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

×