Pour ceux qui connaissent HC2 mais débutent en HC3, voici des réponses aux principales questions que je me suis posées ces derniers jours. Rien de nouveau, tout est sur le forum (et en plusieurs exemplaires !) mais l'idée est de faire un post avec les principes de base et questions fréquentes (actualisé si besoin en fonction de vos commentaires/corrections), pour les débutants en HC3 qui comme moi sont très mauvais avec les moteurs de recherche.   Sources et liens essentiels: ils sont indiqués par @Lazer ici. Un grand merci à lui, beaucoup de mes apprentissages viennent de ses posts.     Qu'est-ce qu'un QuickApp (QA) ?   Un QA est 3 composants en 1 : Un script LUA, qui peut être organisé en plusieurs fichiers: par exemple un fichier pour votre programme principal ("main"), un fichier pour une librairie de tools, un fichier pour la config utilisateur, etc. Pour utiliser une fonction du fichier tools, il suffit de l'appeler par son nom dans l'onglet principal. Pour créer un nouveau fichier, cliquer sur l’icône Files dans la marge à gauche de l'interface UI. Un module virtuel (device). Contrairement aux VD de HC2, le module virtuel d'un QA simule un module physique (interrupteur, détecteur, sonde, etc.). C'est pour ça que chaque fois qu'on crée un QA il faut choisir le type de device associé. En fonction du type, vous aurez des propriétés ("lastBreached" pour un détecteur par exemple), des icônes, et une interface utilisateur spécifiques équivalentes à ce que vous auriez pour un QA physique du même type. L'idée est que ce module virtuel soit piloté par la HC3 de la même manière que s’il était réel, via des appels fibaro.get(), fibaro.getValue(), fibaro.call() et même via l’API. Le grand avantage est que vous pouvez personnaliser et modifier son « micro-programme » et son interface (UI), ce qui n'est pas possible pour un module réel. La liste des types disponibles et propriétés associées est ici (fichier excel à la fin du post). C'est aussi si besoin une interface (UI) avec des labels, boutons, sliders, comme un VD de HC2. Attention, l'interface par défaut dépend du type de device que vous sélectionnez à la création du QA (cf. ci-dessus).   Chaque composant est optionnel. Comme illustré ici il est possible d'avoir des modules QA qui fonctionnent sans une ligne de code (pilotés par des calls externes). Et inversement, si vous n'avez pas besoin de module virtuel, vous pouvez sélectionner l'option "Appareil désactivé" ("Device disabled") dans l'onglet "Avancé" du QA : le QA ne pourra plus être appelé par des calls fibaro, mais le programme LUA fonctionnera normalement et l'interface UI aussi (par contre j'ai l'impression que ça fait disparaitre le QA de l'interface mobile, donc pas forcément une bonne idée...).     Comment fonctionnent les variables persistantes dans un QA ?   Dans HC2, si on veut une variable persistante, on a le choix entre un label de VD ou une variable globale. Les variables globales existent toujours dans la HC3, elles sont gérées par les fonctions fibaro.getGlobalVariable(var) et fibaro.setGlobalVariable(var, value). Par contre les labels de QA ne sont plus persistants (réinitialisés à chaque démarrage du QA), et leur contenu n'est pas facile à lire (pas de fonction fibaro, il faut passer par le JSON du QA). Mais heureusement ils sont remplacés par les "variables QA" (« quickVars ») : des variables persistantes, mais internes au QA. Ces variables sont gérées par les fonctions QuickApp:getVariable(var) et QuickApp:setVariable(var, value).   A noter : Si la "quickVar" n'existe pas, QuickApp:getVariable() renverra une valeur "" et non nil. Il y aura juste un warning dans le log du QA si la variable n'existe pas. Si vous utilisez QuickApp:setVariable() sur une quickVar qui n'existe pas, elle sera créée. Les quickVars peuvent aussi être créées, modifiées ou supprimées dans les paramètres du QA (onglet Variables). MAIS : toute valeur saisie manuellement dans l’interface Web sera convertie en format string (« 99 » au lieu de 99). Pour utiliser un autre format (numérique ou table), il faut utiliser QuickApp:setVariable(). Il est possible de récupérer le contenu des quickVars d'autres QA par des fonctions détournées (mais ce n'était pas l'intention des développeurs). Les variables globales HC3 peuvent être gérées dans l'onglet Variables du menu Réglages/Général (basique, mais j'ai mis du temps à le trouver!).     Comment fonctionnent les fonctions dans un QA ?   Compte tenu de ce qui précède, ça ne devrait pas vous étonner qu’on ait deux types de fonction : les fonctions normales de n’importe quel code LUA (function test(x) return x+x end) et les fonctions QuickApp qui sont ajoutées au code du module virtuel (son « micro-programme » pour reprendre mon image initiale). L’intérêt principal des fonctions QuickApp est qu’elles sont appelables par d’autres QA. L’autre intérêt est que chaque QA vient avec des fonctions déjà existantes qui sont bien utiles (ex : QuickApp:debug(), QuickApp:getVariable(), etc.). La fonction de gestion de l’interface UI notamment est une fonction QuickApp.   Le QA simule une logique de langage orienté objet. Pour faire un parallèle avec Python (le seul langage orienté objet que je pratique un peu), QuickApp est une classe qui contient des fonctions (ou méthodes) mais aussi des variables (QuickApp.id est l'id du QA par exemple). Au sein d'une fonction QuickApp les autres fonctions et variables du QA peuvent être appelées par self:fonction() ou self.variable.   L’appel d'une fonction d’un autre QA se fait via fibaro.call(id, "maFonction", arg1, arg2, etc.). L'inconvénient de cette méthode est qu'il n'y a pas de retour (pas de confirmation de succès, ni possibilité de renvoyer une variable au QA d'origine). Là aussi, il est possible de régler le problème par des contournements, comme expliqué ici.     Comment est structuré le code LUA d’un QA ?   La structure normale du code LUA d’un QuickApp est comme suit : Le code est exécuté une première fois de haut en bas. C'est l'occasion de déclarer les variables et fonctions. Ensuite, le QA lance la fonction QuickApp:onInit() si elle existe. C'est dans cette fonction que votre code doit commencer normalement.   Voici un exemple (fonctionne avec un QA de type "multilevel sensor", qui accepte des valeurs numériques pour sa propriété "value"):   function QuickApp:turnOn() -- appelable par fibaro.call(id, "turnOn") self:updateProperty("value", "99") afficheValeur(self) end function QuickApp:turnOff() -- appelable par fibaro.call(id, "turnOff") self:updateProperty("value", "0") afficheValeur(self) end function afficheValeur(self) self:debug("Valeur du module "..self.id.." : "..self.properties.value) end function QuickApp:onInit() self:debug("onInit - Démarrage du module "..self.id) --afficheValeur(self) setTimeout(function() afficheValeur(self) end, 0) end   Contrairement au code des VD HC2, le code des QA ne s’exécute qu’une seule fois. Si vous souhaitez une boucle, il faut créer une fonction mainLoop() appelée via une fonction setInterval().   Tout est expliqué ici.     Pourquoi on voit souvent l'instruction setTimeout(function() maFonction(self) end, 0) à la fin de la fonction QuickApp:onInit() ?   C’est expliqué ici. En résumé, ça permet d’avoir accès à une variable LUA globale « quickApp » qui contient toutes les propriétés et méthodes de la classe QuickApp (instanciation), mais qui ne s’initialise que si la fonction QuickApp:onInit() est terminée. Même si on n'utilise pas cette variable, c'est une bonne habitude de laisser la fonction QuickApp:onInit() se terminer avant de lancer la fonction suivante.