Aller au contenu

Rechercher dans la communauté

Affichage des résultats pour les étiquettes 'Tuto HC2'.



Plus d’options de recherche

  • Rechercher par étiquettes

    Saisir les étiquettes en les séparant par une virgule.
  • Rechercher par auteur

Type du contenu


Forums

  • Bienvenue
    • Nouveau ? Présentez-vous
    • Le bistrot
    • Mon installation domotique
    • Annonces et suggestions
  • La Home Center et ses périphériques
    • La Home Center pour les nuls
    • HC 2 & Lite
    • HC 3
    • Modules Fibaro
    • Modules Z-wave
    • Périphériques et matériels autres
    • Plugins
    • Quick App
    • Multimédia (audio, vidéo ...)
    • Chauffage et Energie
    • Actionneurs & Ouvrants (Portail, volets, piscines, ...)
    • Eclairage
    • Applications Smartphones et Tablettes
  • Autres solutions domotiques
    • Box / Logiciel
    • Modules Nice (433 & 866 MHz)
    • Modules Zigbee
    • GCE Electronics
    • Modules Bluetooth Low Energy
  • Objets connectés
    • Les Assistants Vocaux
    • Netatmo
    • Philips Hue
    • DIY (Do It Yoursel)
  • Sécurité
    • Alarmes
    • Caméras
    • Portiers
    • Serrures
  • Informatique / Réseau
    • Tutoriels
    • Matériels Réseaux
    • Matériels Informatique
    • NAS
    • Virtualisation
  • Les bonnes affaires
    • Sites internet
    • Petites annonces

Rechercher les résultats dans…

Rechercher les résultats qui…


Date de création

  • Début

    Fin


Dernière mise à jour

  • Début

    Fin


Filtrer par nombre de…

Inscription

  • Début

    Fin


Groupe


Jabber


Skype


Ville :


Intéret :


Version

133 résultats trouvés

  1. pinou

    Zibasegateway Pour Hc2

    Après le calendrier Google, je me suis attaqué maintenant à ma Zibase. En effet, j'ai commencé la domotique il y a quelques temps de ça, avec une Zibase. Depuis elle ne m'a jamais quitté. Même si aujourd'hui j'ai migré (pratiquement) tous mes modules zwave sous la Home center, j'utilise toujours ma Zibase pour les devices Oregon et EnOcean essentiellement. J'ai vu passer différentes solutions permettant de récupérer les infos/valeurs de ces modules au sein de la HC2. Ceci dit, rien de satisfaisant pour moi, car les solutions sur lesquelles je suis tombé font essentiellement du pooling vers la Zibase, or j'ai besoin de temps réel. Pas pour les relevés des sondes Oregon mais pour les détecteur d'ouverture EnOcean. Je me suis donc amusé à trouver une autre solution répondant à mon besoin. Le principe Le principe est assez simple : plutôt que d'aller voir de façon périodique l'état des devices de la Zibase, je me suis dit qu'il suffit en fait "d'écouter" ce que broadcast la Zibase et de chopper dans ce flux ce qui m'interesse. Il suffit alors de passer par l'api de Fibaro pour mettre à jour les variables correspondantes dans ma HC2. Dans le détail... Il s'agit d'un script PHP que j'ai hébergé sur mon syno (mais un RPI ou toute autre machine pouvant faire tourner du PHP 24h/24 suffit). Pas besoin de configurer un serveur web puisque le script PHP tourne en mode CLI (lancé automatiquement au démarrage du syno dans mon cas). Lors du lancement du script, ce dernier va s'abonner aux messages de la Zibase. Il va donc recevoir un flux de ce type a chaque fois qu'un device remonte une info vers la Zibase : Received radio ID (<rf>433Mhz Oregon</rf> Noise=<noise>2420</noise> Level=<lev>3.4</lev>/5 <dev>Temp-Hygro</dev> Ch=<ch>2</ch> T=<tem>+18.4</tem>C (+65.1F) Humidity=<hum>45</hum>% Batt=<bat>Ok</bat>): <id>OS439218434</id> On décode alors ces données pour pouvoir mettre à jour la ou les variables associées au niveau de la HC2. Un des points délicats concerne la configuration du fichier permettant de mettre en place ce décodage. Le fichier de configuration des messages de la Zibase Ce fichier est donc un des éléments essentiels de cette solution. Il s'agit d'un fichier json (pour la facilité de lecture et construction). Il y a 2 parties dans ce fichier : Un premier élément de configuration permettant de définir les différents protocoles radio qui seront reconnus par le script. On vient dire ici, par protocol (Oregon, EnOcean, ...) et par type de device (Détecteurs, sondes température, etc.) quelles sont les données qu'il faut récupérer dans le flux correspondant. Un second élément permet de définir pour chaque device reconnu (par son ID Radio) quelles sont les variables qui seront mise a jour avec quelles données. On indiquera également si cette mise a jour doit se faire à chaque remontée d'info (exemple du détecteur), ou seulement si la donnée à été modifiée depuis la dernière mise à jour (afin de ne pas saturer la HC2 de requêtes inutiles). Autant vous prévenir tout de suite, cette configuration est chiante à souhait à mettre en place, mais bon j'ai pas trouvé plus simple et/ou plus automatisé. Ceci dit, une fois au point, on y touche plus ! Le script PHP Ce dernier vient avec un script contenant les variables de configuration dont les valeurs sont à modifier en fonction de votre installation. C'est assez explicite, je ne vais pas m'attarder dessus. Côté Home center Alors ici, il y a quelques petites choses à faire. Le plus gros problème est que je passe par l'api HTTP pour mettre à jour les variables. Or par ce biais, même si la mise à jour fonctionne, elle ne permet pas de déclencher les scènes et autres scripts qui seraient basés sur ces dernières (limitation de Fibaro ... va comprendre pourquoi ...). Du coup, j'ai implémenté la solution proposée par Jojo dans un autre post qui consiste à passer par l'intermédiaire d'un bouton de module virtuel qui vient mettre à jour la variable avec sa valeur. Bon ne pouvant pas m'amuser à créer un bouton pour chaque valeur discrète possible et imaginable, le script PHP va mettre à jour 2 variables permettant de stocker le nom de la variable finale à mettre à jour et sa valeur(1). On va ensuite déclencher le module virtuel (2) qui va récupérer ces données (3) et mettre à jour à son tour la variable désirée avec la bonne valeur (4). Et voilà , les scènes basées sur cette variable fonctionnent du coup (5) ! Je ne sais pas si vous me suivez toujours dans mon raisonnement (un peu tordu), j'essaye de vous faire un p'tit dessin pour illustrer la chose : script PHP ---------+----(1)--->zibaze_variable = "anemometre" <-. +----(1)--->zibaze_value = "3.2" <-----------+ | (3) `----(2)--->VModuleID = 99, PushButton n°1 --+ | (4) | v anemometre = "3.2" | (5) | v scene "FermetureStore" start Installation Du coup l'installation de tout ce bordel s'effectue en plusieurs étapes : A/ Pour la partie PHP il faut 1) Poser les différents fichiers dans un espace sur votre serveur et connectez vous dessus (ssh, telnet, ...) 2) Modifiez le fichier zibaseGateway_config.php et zibaseGateway.php afin d'initialiser les variables avec les bonnes valeurs (partout ou il y a des XXXX vous devez configurer en fonction de votre installation) 3) Assurez vous que la variable verbose soit positionnée à LogType::CONSOLE dans un premier temps (une fois que tout sera au point vous la changerez comme bon vous semble) 4) Lancez le script à la main php zibaseGateway.php 5) Si tout va bien, les messages reçus de la Zibase devraient s'afficher à l'écran. A vous de jouer maintenant pour mettre à jour le fichier zibaseMessages.json en conséquence. 6) Arrêtez les script (CTRL+c) et relancez le pour vérifier que la configuration est bien prise en compte correctement. B/ On passe maintenant au niveau de la Home Center 7) Déclarez les différentes variables que vous avez déclaré au point 5) 8) Déclarez les 2 variables Zibase_variable et Zibase_value (cf. fichier de configuration zibaseGateway_config.php) 9) Importez le module virtuel C/ Le test final 10) Relancez le script et vérifiez que les variables de votre HC soient bien mises à jour. Si ce n'est pas le cas, reprenez depuis le point 2) : soit vous n'avez pas initialisé vos variables correctement, soit le fichier json ne reflète pas la réalité... D/ Mode automatique Etant nouveau dans le monde des syno, j'avoue avoir un poil galéré pour que mon script php se lance automatiquement au démarrage du NAS. En gros il faut transformer ce script en deamon. 11) Tout d'abord j'ai modifié la config PHP au niveau de l'interface d'admin du NAS : Panneau de configuration > Services web > Paramètres PHP : cliquez sur personnaliser PHP openbase_dir et rajouter les chemins vers vos repertoires d'installation. Sans cette config vous risquez d'avoir des warnings/erreurs PHP lors de l'exécution. 12) J'ai créé un script SH qui permet de "deamonsier" le script PHP. Il suffit de faire un lien de ce script dans le bon répertoire : ln -s S99zibase.sh /usr/syno/etc/rc.d/S99zibase.sh Et voilà , le script sera lancé ou arrêté automatiquement au startup/shutdown de votre NAS. Bien entendu, ces différents points sont à adapter en fonction de votre config... Maintenant que tout fonctionne, il ne vous reste plus qu'a redémarrer votre NAS et vérifier que les variables HC2 soient bien mises à jour. A vous de créer des modules virtuels pour afficher l'état de vos variables dans vos interfaces... Remerciements Un gros merci à Cmoi20, auteur du projet ZiHome dont je me suis très très fortement inspiré pour mettre en place le script PHP jojo pour sa solution de mise à jour d'une variable via un module virtuel Bejamin Garel pour son sdk PHP pour la Zibase Téléchargements package PHP : zibaseGateway.zip Module virtuel : Zibase.vfib Image pour module virtuel :
  2. Sur une idée originale de razowski et dans la continuité du sujet de Steven ici (http://www.domotique-fibaro.fr/index.php/topic/1303-double-clique-pour-confirmer/) voici un module virtuel permettant de déclencher une action sur validation d'un code PIN au préalable renseigné dans le code du Main Loop. Version 1.0.1 L'action peut-être le déclenchement d'une scène, l'allumage ou l’extinction d'un périphérique ou bien encore l’exécution d'un script LUA afin de laisser cours à votre imagination . Le clavier est simple avec juste 12 touches: 10 boutons de 0 à 9, un bouton "clear" et un "Enter". La validation est automatique lorsqu' un code à 4 chiffre est renseigné, sinon il faut utiliser la touche correspondant à "Enter". J' ai fait ça vite fait entre midi et deux et juste pour poser les bases, je ferais évoluer la chose si le code suscite de l’intérêt. Pour la mise en place il faut commencer par créer un variable globale PINCode000, puis d'importer le fichier vfib en téléchargement sur cette page. Ensuite vous devez modifier le code dans le MainLoop pour l'adapter à vos besoins. Explications succinctes: - ["1010"] : correspond au code qui est formaté sur 4 chiffres (de 1 à 4 chiffres). - caption : une légende pour l'action associée au code - task.object : Peut prendre les valeurs suivantes: scene, device, lua, virtual, globalv - task.id : Identifiant de la scène, du device, de la varible ou du vd utilisé [option] - task.value: pour une scène [start, stop], un périphérique [on, off, dim], lua [function], valeur de la variable globale etc. - task targetId: l'id d'un bouton ou d'un slider dans le cas d'un vd. Les options de l'objet task: -- object: device - actions: [on, off, dim] - id: [num] - value: [0-100] (option) -- object: scene - actions: [start, stop] - id: [num] -- object: virtual - actions: [pressButton, setSlider] - id: [num] - value: [0-100] - targetId: [num] -- object: lua - value: [lua function] (ex: function() -- lua code here end) -- object: globalv - id: [name] - value: [xxx] cf. code extrait du Main Loop: local codeTable = { ["1010"] = { caption = "Disarm perimeter with scene", task = { object = "scene", id = 999, action = "start" } }, ["2020"] = { caption = "lua sample", task = { object = "lua", value = (function() fibaro:debug("Custom lua action!"); end) } }, ["3030"] = { caption = "turn on device", task = { object = "device", id = 999, action = "off" } }, ["4040"] = { caption = "dim device", task = { object = "device", id = 999, action = "dim", value = 25 } }, ["5050"] = { caption = "set global variable 'myvar' to 8989", task = { object = "globalv", id = "myvar", value = 8989 } }, ["6060"] = { caption = "set slider id#8 to 75 in virtual device #999", task = { object = "virtual", id = 999, targetId = 8, action = "setSlider", value = 75 } } }; Modifications: Version 1.0.1 - 08/07/2014 1. Renommage du module en "Security Virtual Keybaord" (ça sert à rien mais je préfère) 2. Ajout du support pour: scène, vd, variable globale VirtualDevice-Security-Keyboard-V1.0.1.vfib
  3. ZerobrainStudio pour ecrire et tester vos scripts lua directement sur votre PC Merci a steven et Fred le ouf Dans un premier temps il faut telecharger ZerobrainStudio. Choisir la version qui correspond a votre systéme d'explotation pour moi ce sera Windows 32bit (exe installer) https://studio.zerobrane.com/download?not-this-time Il suffit d'installer le programme comme vous en avez l'habitude et bien regarder ou il sera installer Ensuite il va falloir ajouter le fichier que @Steven a partager sur le forum lualibs1.01.zip By Steven Ajout : le fibaro:sleep(<millisecondes>) fibaro:countScene() retournera toujours 1. Manque encore une astuce pour simuler le fibaro:getSourceTrigger() Il ne vous reste plus qu'a décompresser ce fichier dans le répertoire C:.......\ZeroBraneStudio\lualibs Utilistation : require("FibaroSceneAPI") hc2_user = "admin" hc2_pwd = "admin" hc2_ip = "192.168.x.x" -- Inséré votre code en dessous de cette ligne ----------------- Et pour ceux qui n'aime pas l'anglais : Edit -> Preferences -> Settings: System --[[-- Use this file to specify **System** preferences. Review [examples](+C:\PRGMS\ZeroBraneStudio\cfg\user-sample.lua) or check [online documentation](http://studio.zerobrane.com/documentation.html) for details. --]]-- language = "fr" Et redémarrer l'application Pour ceux qui souhaite les même couleurs que dans leur HC2, il faut aller dans le menu : Edit -> Preferences -> Settings: User et copier le code ci-dessous puis redémarrer. --[[-- Use this file to specify **User** preferences. Review [examples](+C:\PRGMS\ZeroBraneStudio\cfg\user-sample.lua) or check [online documentation](http://studio.zerobrane.com/documentation.html) for details. --]]-- styles = loadfile('cfg/tomorrow.lua')('TomorrowNight') stylesoutshell = styles -- apply the same scheme to Output/Console windows styles.auxwindow = styles.text -- apply text colors to auxiliary windows styles.calltip = styles.text -- apply text colors to tooltips local colors = { orange = {255,158,89}, braun = {217,191,140}, darkgray = {38,38,38}, blue = {89,158,255}, green = {188,210,121}, red = {179,94,77}, white = {255,255,255}, gray = {102,102,102} } styles.comment = {fg = colors.gray} styles.operator = {fg = colors.white} styles.number = {fg = colors.red} styles.stringtxt = {fg = colors.green} styles.keywords0 = {fg = colors.blue} styles.text = {fg = colors.braun, bg = colors.darkgray} styles.keywords3 = {fg = colors.orange} styles.keywords4 = {fg = colors.orange} styles.keywords5 = {fg = colors.orange} styles.keywords6 = {fg = colors.orange} styles.keywords7 = {fg = colors.orange} Encore une amélioration : Copier le fichier ci-joint "fibaro.lua" dans le sous-répertoire /api/lua/ fibaro.lua puis dans le menu : Edit -> Preferences -> Settings: System ajouter cette ligne : api = {luadeb = {'fibaro'}} Vous allez avoir l'auto-complétion des commandes fibaro ainsi que leur description. Astuce. Pour pouvoir tester les triggers, voici le code à utiliser __fibaroSceneSourceTrigger = {type="global", name="Pushbullet"} -- __fibaroSceneSourceTrigger = {type="global", name="Pushbullet"} -- __fibaroSceneSourceTrigger = {type="property", deviceID=6, propertyName="value"} -- __fibaroSceneSourceTrigger = {type="autostart"} -- __fibaroSceneSourceTrigger = {type="other"} print(fibaro.getSourceTrigger().type) -- global print(fibaro.getSourceTrigger().name) -- Pushbullet __fibaroSceneSourceTrigger = {type="autostart"} print(fibaro.getSourceTrigger().type) -- autostart Il suffit donc de modifier la variable __fibaroSceneSourceTrigger en utilisant un des exemple fourni. il est aussi possible de débuguer ligne à ligne, et même de modifier dynamiquement la valeur d'une variable directement en cours d'exécution. Allez, je me lance pour mon 1er tuto Ouvrir Zerobranstudio et afficher les fenêtres suivantes si ce n'est pas encore déjà fait insérer le code suivant dans une nouvelle fenêtre vide de Zerobranstudio (on va réviser les multiplications ) local boucle = true local i = 1 local j = 1 while boucle == true do i = i + 1 j = j + 2 print(i.." x "..j.." = "..i * j) end Pour activer le suivi dynamique des variables, il suffit de sélectionner le nom de la variable que l'on veut suivre, puis de faire clic droit dessus pour faire apparaitre un menu contextuel. Il faut ensuite sélectionner l'option Add watch expression comme dans l'image ci dessous. Dans notre cas, il faut le faire pour les 2 variables i & j. Pour passer en mode debug, appuyer 1 fois sur la touche F5, la fenêtre doit ressembler à ça. Le curseur vert est positionné sur la première instruction, et la fenêtre Watch affiche les valeurs de i et j (à nil pour le moment ce qui est logique) Appuyer maintenant plusieurs fois sur la touche F10 pour exécuter le programme pas à pas, jusqu'à afficher le premier résultat de la multiplication, comme ci dessous. Le résultat de la multiplication est en cohérence avec les valeurs de i et j. Pour tester maintenant la modification à la volée d'une variable, on va continuer l'exécution du programme et réexécuter une seconde fois la boucle en appuyant plusieurs fois sur la touche F10 mais sans exécuter l'instruction print, comme dans l'image ci dessous. La valeur des 2 variables a bien été modifiée par programmation. Pour modifier maintenant dynamiquement la valeur de j, il faut cliquer sur l'onglet Remote console, taper la ligne j = 20 puis appuyer sur la touche Entrée pour valider la commande, comme dans l'image ci dessous. On peut alors voir que la valeur de j a bien été modifiée dans la fenêtre de Watch. Il suffit maintenant de recliquer sur l'onglet Output (suspended), et d'appuyer de nouveau sur la touche F10 pour reprendre l'exécution du programme. On constate alors que la valeur de j mise à 20 à la main a bien été prise en compte dynamiquement par le programme. Je remercie encore une fois steven pour ce super travail
  4. Voici une interprétation / traduction du premier onglet « Résumé des fonctions » (Spis funkcji) de la page officielle de documentation Fibaro http://docs.fibaro.com/?page_id=861. Il s’agit surtout des bases du langage LUA pour les scripts Fibaro. J’ai rajouté quelques interprétations, moyens de compréhension… pour que cette traduction ressemble également à un tutoriel comme j’aurai aimé le trouver quand j’ai commencé il y a quelques mois à écrire quelques bouts de code. Certaines fonctions semblent manquer, avoir changé, avoir disparu, ou même ne fonctionnent pas encore (j’ai cru lire ça quelque part à propos des scripts utilisant les données géographiques), car je ne pense pas que Fibaro mettent à jour très régulièrement cette base de donnée. J’espère que les débutants surtout, apprécieront, et pour les pros, n’hésitez pas à me faire corriger les mauvaises traductions / interprétations. Je ferai surement par la suite, d’autres traductions de leurs pages car cette première m’a vraiment été d’une grande utilité pour démarrer dans le monde de l’automatisme (en LUA ici) sachant que je partais presque de zéro (juste des notions avec excel, si on peut les apparenter de loin…) Comprendre certaines choses avant de démarrer : Un script LUA doit toujours commencer par l’entête suivant. Certes cela fonctionne aussi sans, mais si vous voulez modifier plus tard le script pour : - intégrer des déclenchements automatiques de la scène (trigger) en fonction de certaines actions ou évenements extérieurs - démarrer automatiquement la scène après enregistrement (pratique dans le cas d’une lecture infinie de la boucle de code, puisque cela vous permet de ne pas oublier d’appuyer sur le bouton ‘démarrer’ la scène après enregistrement) - d’autres choses encore, il faudra insérer des éléments dans cet entête. --[[ %% properties %% globals --]] Le mot " local " permet de signaler dans le script qu’on va stocker derrière, une variable en tant que ‘variable locale’. Imaginez que vous ouvrez un tiroir et que vous y mettiez la variable 'a' (ou appelez la comme vous voulez).Vous pouvez lui donner une valeur directement (cas 1) : local a = 50 ou l’associer à une fonction (cas 2) : a = fibaro:getValue(107, 'value') Dans le script vous pourrez rouvrir ce tiroir pour chercher la valeur de 'a' dans le cas 1, ou éviter de retaper plusieurs fois la fonction entière dans le cas 2. - Cas 1 : Imaginons qu’on associe 'a' à l’intensité lumineuse en pourcent d’un spot branché sur un variateur (dimmer fibaro par exemple). Dans le script on pourra faire allumer le spot à une certaine intensité (50%) en demandant à ce que le paramètre de luminosité du variateur associé au spot prenne la valeur de 'a' (ainsi pas besoin de lui donner la valeur 50) ou bien de a + 10 par exemple. local a = 50 -- on définit la variable locale avec nom et valeur fibaro:call(12, 'setValue', a) -- on demande au système d'appeler (call) le module 12 et de lui donner la valeur (setValue) de 'a' (soit 50) -- ou par exemple fibaro:call(12, 'setValue', a + 10) - Cas 2 : Imaginons maintenant que 'a' représente la fonction qui vérifie l'intensité du spot 107. On va créer une scène qui éteint le spot numéro 108, si le spot 107 est allumé et inversement. local a = fibaro:getValue(107, 'value') -- 'a' représente la fonction qui récupère (get) la valeur (Value) de l'intensité (value) du spot 107 if tonumber(a) >= 1 then -- si la valeur récupérée (ramenée en valeur numérique grâce à tonumber) est supérieure à 1 (allumé), alors fibaro:call(108, 'turnOff') -- le spot 108 s’éteint. else fibaro:call(108, 'turnOn') -- sinon le spot 108 s’allume end -- fin de la condition En utilisant 'a' dans ce genre de cas et si on doit répéter plusieurs fois la fonction associée, on évite de surcharger le script ou de faire des erreurs de saisie en retapant plusieurs fois une longue fonction. Le mot " local " n’est pas obligatoire, les variables locales fonctionnent même sans les introduire par ce mot. Cependant il est plus aisé à la relecture d’un script de retrouver les variables qu’on va utiliser en les précédant de ce mot. Ne mettez pas d’accents, d’espace ou de caractères spéciaux dans le nom de vos variables. Il est important de respecter les minuscules et les majuscules des commandes, fonctions, par contre vous pouvez utiliser ‘ ‘ou « » dans vos scripts ça ne changera rien … Dans une parenthèse on peut mettre un espace après l’ouverture de parenthèse et avant la fermeture, ou ne pas en mettre. Cela n’a aucune incidence. Il semble d’ailleurs que les espaces ne soient pas importants dans la construction du script (sauf entre les mots évidemment, mais pas importants entre les mots et les ponctuations). La fonction fibaro:debug() permet « d’imprimer » des messages dans la case sous le script, au fur et à mesure de sa lecture par le système et ainsi permet à l’utilisateur de pouvoir vérifier des résultats de l’automate.Si vous avez besoin de mettre une apostrophe dans une phrase pour la fonction debug, il faut mettre devant le \ pour que la lecture du script ne bug pas sur l’apostrophe. fibaro:debug('Il n\’y a qu\’une action en cours') Une seconde correspond à 1000ms. Lorsqu’on veut donner une durée dans le script il faut convertir le temps voulu en ms. Les tabulations automatiques ou manuelles lors de l’écriture du script ne sont pas importantes, mais un script bien agencé sera plus facile à comprendre, ou permet de repérer des erreurs ou oublis (par exemple en utilisant du conditionnel if then else, il faut finir cette condition par end, mais dans certains cas cette condition se retrouve dans une autre condition ou dans une autre chaîne qui nécessite également un end à la fin).Exemple : la chaine while true do en 1 nécessite end en 14 quand on veut arrêter la lecture en boucle qu’elle commande et reprendre la lecture au début. Dans cette boucle de lecture on a inséré une condition qui commence en 3-4 et se finit en 12, dans laquelle on a glissé une autre condition en 6-7 qui se finit en 10. L’architecture structurée permet de voir plus clair dans le script. while true do local--- if then --------- local--- if then -------- else ------ end else ------ end end On retrouvera des couleurs dans le script. Le gris correspond à des notes personnelles, il faut commencer chaque ligne par -- puis votre texte, ou --[[ texte ]]-- (sur plusieurs lignes). Le système ne tiendra pas compte de nos notes, sauf dans l’entête. Les caractères spéciaux et accents ne posent pas de problème dans ces notes. Le vert correspond aux actions à effectuer sur les modules (‘turnOff’, ‘setValue’…) ; au nom d’une propriété que l’on veut surveiller ou sur laquelle on veut agir (‘value’, ‘dead’, ‘isLight‘…) ; aux messages qu’on associera aux fonctions debug : fibaro:debug('La scène est en cours d\’exécution') ) ; à une valeur à atteindre par une fonction (ouverture de volet ou allumage d’une lampe sur variateur ‘50’, ‘75’). Attention aux valeurs ‘1’ et ‘0’ qui peuvent correspondent à un état d’une propriété d’un module (le module gère l'éclairage ('1') ou le module ne gère pas l'éclairage('0') est le retour d’état de la propiété isLight d'un module dimmer, ON ('1) et OFF ('0') est le retour d'état de la propriété value d'un module relai switch) ; au nom d'une variable globale qu'on utilise dans une fonction; à une position géographique « 52.5648 ;-12.5861 » ; et encore d'autres choses... Le rouge correspond au numéro d’identification d'un module ou d'une scène (DeviceID, SceneID… : 12, 54…) ; à une durée dans la fonction sleep ; à une valeur assignée à une variable locale ou une valeur à comparer. Le bleu correspond à toute l’architecture du système : local qui permet de signaler une variable du nom qu’on choisira et à laquelle on peut associer une fonction ou une valeur ; à des conditions if then else (si alors sinon), while true do (lance une lecture en boucle infinie du script); des valeurs booléennes (false et true dans par exemple la vérification de l'activité ou non d'une scène) …. Le jaune correspond aux variables dont on choisit le nom (en français, en anglais ou autre, sans espace entre les mots ex : MaVariable, qu’on peut retrouver derrière local forcément, mais aussi dans des messages de la fonction fibaro:debug, ou de la fonction fibaro:call, ou bien dans une condition if then pour récupérer ou comparer une valeur associée à cette variable) ; ainsi qu’à toutes les fonctions (fibaro:abort, fibaro:get...). Le orange correspond à des outils système (os.date, string.format, tonumber…) Liste des fonctions (par ordre alphabétique)fibaro:abort() fibaro:calculateDistance(position1, position2) fibaro:call(deviceID, actionName, …) fibaro:countScenes() fibaro:countScenes(sceneID) fibaro:debug(text) fibaro:get(deviceID, propertyName) fibaro:getGlobal(varName) fibaro:getGlobalModificationTime(varName) fibaro:getGlobalValue(varName) fibaro:getModificationTime(deviceID, propertyName) fibaro:getRoomID(deviceID) fibaro:getSectionID(deviceID) fibaro:getSourceTrigger() fibaro:getSourceTriggerType() fibaro:getType(deviceID) fibaro:getValue(deviceID, propertyName) fibaro:isSceneEnabled(sceneID) fibaro:killScenes(sceneID) fibaro:setGlobal(varName, value) fibaro:setSceneEnabled(sceneID, enabled) fibaro:sleep(time) fibaro:startScene(sceneID) Résumé des fonctions (thématique)DISPOSITIFS DE CONTRà”LE fibaro:call(deviceID, actionName, …) fibaro:get(deviceID, propertyName) fibaro:getValue(deviceID, propertyName) fibaro:getModificationTime(deviceID, propertyName) fibaro:getType(deviceID) fibaro:getRoomID(deviceID) fibaro:getSectionID(deviceID) SCENES DE CONTROLE fibaro:abort() fibaro:getSourceTrigger() fibaro:getSourceTriggerType() fibaro:startScene(sceneID) fibaro:killScenes(sceneID) fibaro:setSceneEnabled(sceneID, enabled) fibaro:isSceneEnabled(sceneID) fibaro:countScenes() fibaro:countScenes(sceneID) TRAITEMENT DES GLOBALS fibaro:setGlobal(varName, value) fibaro:getGlobal(varName) fibaro:getGlobalValue(varName) fibaro:getGlobalModificationTime(varName) CARACTÉRISTIQUES SUPPLÉMENTAIRES fibaro:debug(text) fibaro:calculateDistance(position1, position2) Liste des fonctions (par ordre alphabétique) - fibaro:abort() DESCRIPTION On arrête le script en cours d'exécution. CARACTÉRISTIQUES Aucune VALEURS RÉCUPÉRÉES Aucune EXEMPLE local a = 0 -- on définit la variable avec nom et valeur -- On démarre une boucle infinie de lecture, le script sera relu sans arrêt grâce à la commande: while true do -- si a est supérieur à 10 alors la lecture du script s'arrête en 7 if (a > 10) then fibaro:abort() end -- fin de la condition -- si a est inférieur à 10, la lecture du script continue -- on augmente maintenant de 1 la valeur de la variable a a = a + 1 -- on attend 1 seconde fibaro:sleep(1000) end -- fin de la boucle de lecture. La lecture reprend en 3 -- la lecture s'arrête en 13 et redémarre en 3 avec la nouvelle valeur de a jusqu'à ce que a soit supérieur à 10 et que la lecture du script s'arrête - fibaro:calculateDistance(position1, position2) DESCRIPTION On calcule la distance entre deux points géographiques: position1 et position2. CARACTÉRISTIQUES position1: premier point position2: second point Le point est exprimé avec sa latitude et sa longitude. Ces deux valeurs sont exprimées en degrés avec une partie décimale, et sont séparées par un point-virgule. Une valeur négative est donnée pour les valeurs de l'ouest et du sud. Le séparateur décimal est un point. Par exemple, le point 40°44'55"N, 73°59'11"W doit être enregistré comme une chaîne (string) "40.7486;-73.9864". Ce format correspond à la propriété « Location » (emplacement) du device « HC_user » (l’utilisateur) et stocke la dernière position de l'utilisateur du Home Center 2. VALEURS RÉCUPÉRÉES La distance, exprimée en mètres. EXEMPLE -- le système repère l'emplacement (propriété Location) du device 123 (moi par exemple grâce à mon smartphone) et stocke les données de mon emplacement dans la variable : local MonEmplacement = fibaro:getValue(123, 'Location') -- on crée une variable correspondant à la fonction qui récupère (get) la valeur (Value) de la propriété Location (emplacement) du device 123 (moi) -- on va ensuite stocker l'emplacement de notre maison dans une seconde variable: local EmplacementMaison = "52.4325295140701;16.8450629997253" -- on crée une dernière variable qui correspondra au résultat de la fonction qui calcule la distance entre nos 2 points: local Distance = fibaro:calculateDistance(MonEmplacement, EmplacementMaison) -- enfin la fonction debug m'indiquera cette distance grâce au texte que j'y associe et dans lequel j'ai inséré le résultat de ma variable Distance (qui sera retranscrite en valeur numérique) fibaro:debug('La distance est de '..Distance..'m') - fibaro:call(deviceID, actionName, arguments) DESCRIPTION On envoie une demande à un module (device) pour qu’il exécute une action. CARACTÉRISTIQUES deviceID: numéro du module (c’est son identité dans le système) actionName: chaîne (string) qui représente le nom de l’action argument: les arguments peuvent se succéder. De 0 à 7 arguments par action. VALEURS RÉCUPÉRÉES Aucune EXEMPLE -- on demande au module d'ID=12 de s'éteindre fibaro:call(12, 'turnOff') -- on demande au module d'ID=12 de fixer sa valeur à 23 (intensité en % d'une lampe sur variateur, ouverture d'un volet) fibaro:call(12, 'SetValue', '23') DESCRIPTION ÉTENDUE Il convient de noter que tous les arguments des fonctions call sont des chaînes (string). Ici '23' est une chaîne et non une valeur numérique (c'est pour cela qu'il faut mettre des guillemets sinon ça ne fonctionnera pas). Cependant, grâce au mécanisme intégré coercitif [lien Fibaro manquant pour l'explication], il n'est pas nécessaire de convertir les types numériques en chaîne (vous pouvez autant mettre une valeur numérique que le nom d'une variable qui est un format string). Nous verrons plus tard qu'à certains moments il faudra convertir une chaîne en valeur numérique grâce l'outil tonumber). -- le système stocke la valeur 50 pour la variable qu'on appelle 'a' local a = 50 -- on demande au module d'ID=12 de prendre la valeur de 'a' qui est en format string fibaro:call(12, 'SetValue', a) Une description des actions disponibles ainsi que le nombre de paramètres requis est disponible ici. [lien Fibaro manquant]. - fibaro:countScenes() DESCRIPTION On obtient le nombre de lecture en cours de la scène. Par exemple, en cliquant 2x (ou plus) sur 'démarrer' avant la fin de la première lecture, vous démarrez une seconde (ou plus) lecture du script, la première ne s'arrêtera pas ; vous pouvez avoir également plusieurs scènes qui démarrent une scène particulière, il peut donc être utile en début de script de cette scène particulière, d'interdire une nouvelle lecture du script si une lecture est déjà en cours d’exécution. CARACTÉRISTIQUES Aucune VALEURS RÉCUPÉRÉES Un entier positif qui spécifie le nombre d’exécution en cours de la scène. EXEMPLES -- on stocke dans la variable num, le nombre d'instances en cours de la scène local num = fibaro:countScenes() -- si il n'y a qu'une lecture en cours de la scène, alors la fonction debug m'indiquera la phrase que j'y associe ('il n'y a qu'une lecture en cours') if num == 1 then fibaro:debug('Il n\’y a qu\’une lecture en cours') -- sinon la fonction debug intégrera le nombre de lectures de la scène dans une autre phrase que j'y associe ('nombre d'instances en cours: ') else fibaro:debug('Nombre d\’instances en cours: '..num) -- notez que pour insérer une valeur d'une variable dans la fonction debug, il faut 2 points du coté du texte (avant et/ou après) end -- avant qu'une scène ne s'exécute, elle peut vérifier si elle est déja en cours d'exécution pour ne pas être lue plusieurs fois en même temps if fibaro:countScenes() > 1 then -- si la scène est lancée plus d'une fois alors fibaro:abort() -- arrêt de cette lecture du script end -- fin de la condition -- notez qu'on peut écrire aussi de cette façon local num = fibaro:countScenes() if num > 1 then fibaro:abort() end - fibaro:countScenes(sceneID) DESCRIPTION On obtient le nombre d’exécution en cours pour une scène donnée (chaque scène est identifiée par son identité sceneID et peut être utilisée dans d’autres scènes) CARACTÉRISTIQUES sceneID: Numéro de la scène, identité de la scène VALEURS RÉCUPÉRÉES Un entier positif qui spécifie le nombre d'exécution en cours d'une scène donnée. EXEMPLE -- on veut afficher le nombre d'exécution en cours de la scène d'ID=12 local num = fibaro:countScenes(12) fibaro:debug('Nombre d\’instances en cours de la scène 12 '..num) -- on veut vérifier que la scène 12 est en cours d'exécution if fibaro:countScenes(12) >= 1 then fibaro:debug('La scène 12 est en cours d\’exécution') else fibaro:debug('La scène 12 n\’est pas en cours d\’exécution') end - fibaro:debug(text) DESCRIPTION On imprime le message dans la console de débogage associée au script. CARACTÉRISTIQUES text: texte à afficher VALEURS RÉCUPÉRÉES Aucune EXEMPLE fibaro:debug('Exemple de message') Résultat dans la console de débogage du script: - fibaro:get(deviceID, propertyName) DESCRIPTION On récupère les informations (valeur et heure de dernière modification) sur les propriétés d’un module CARACTÉRISTIQUES deviceID: numéro d'identité du module propertyName: intitulé de la propriété VALEURS RÉCUPÉRÉES Une chaîne contenant la valeur actuelle d’une des propriétés d’un module Horodatage (timeStamp) [lien Fibaro manquant pour l'explication] de la dernière modification EXEMPLE -- on veut récupérer (get) l'heure et la valeur de la dernière modification de la propriété 'value' du module d'ID=11. Il existe plusieurs propriétés qu'on peut récupérer ou modifier pour chaque module. La propriété 'value' peut correspondre à une température, une intensité lumineuse en %, une ouverture d'un volet en %... local valeur, HeureModification = fibaro:get(11,'value') -- en LUA, on peut ignorer la seconde valeur de retour (pas très clair) local valeur2 = fibaro:get(11, 'value') -- les valeurs obtenues peuvent ensuite être utilisées dans des scènes -- l'outil tonumber permet de convertir une variable (qui est au format chaîne (string)) en valeur numérique, afin de la comparer à une autre valeur numérique if tonumber(valeur2) >= 50 then -- si la valeur récupérée et transformée en valeur numérique est supérieure à 50 alors fibaro:call(142, 'turnOff') -- le système demande au module d'ID=142 de s'éteindre DESCRIPTION ÉTENDUE Les principales fonctions : fibaro:get(deviceID, propertyName) fibaro:getValue(deviceID, propertyName) fibaro:getModification(deviceID, propertyName) Elles sont utilisées dans les scripts de scènes pour récupérer l'état actuel des modules. La valeur récupérée doit être affectée à des variables locales afin de pouvoir utiliser des instructions conditionnelles (if, then). Voir exemple ligne 7. Ces 3 fonctions ne diffèrent que par la valeur récupérée. Notez que les valeurs récupérées sur les propriétés (propertyName), sont des variables de type ‘chaîne’ (string), ce qui signifie que, si on veut les comparer avec des valeurs numériques, il faut transformer ces variables en valeurs numériques elles aussi, grâce à la commande tonumber. Voir exemple ligne 7. Exemple concret, car l'exemple ci-dessus de la documentation Fibaro n'est pas très intéressant car pour récupérer les valeurs des propriétés des modules classiques, on peut autant utiliser la fonction fibaro:get(deviceID, propertyName) que la fonction fibaro:getValue(deviceID, propertyName). Pour récupérer l'adresse IP d'un module virtuel d'ID=126 deviceIp = fibaro:get(126, "IPAddress") -- merci à i-magin grâce à qui j'ai trouvé l'exemple là sur le forum - fibaro:getGlobal(varName) DESCRIPTION On récupère des informations (valeur et heure de la dernière modification) de la variable globale enregistrée dans le système. CARACTÉRISTIQUES varName: Le nom de la variable globale VALEURS RÉCUPÉRÉES Une chaîne contenant la valeur actuelle de la variable globale Horodatage (timeStamp) [lien Fibaro manquant pour l'explication] de la dernière modification EXEMPLE -- on veut récupérer l'heure et la valeur de la dernière modification de la variable globale appelée 'Nuit' à laquelle on a associé les valeurs '0' (jour) ou '1' (nuit), on aurait pu choisir d'autres noms comme jour et nuit directement ou oui et non... local valeur, HeureModification = fibaro:getGlobal('Nuit') -- en LUA, on peut ignorer la seconde valeur de retour (pas très clair) local valeur2 = fibaro:getGlobal('Nuit') -- les valeurs ainsi obtenues peuvent être utilisées dans des scènes if (value == '1') then fibaro:debug('Il fait nuit') end DESCRIPTION ÉTENDUE Les principales fonctions : fibaro:getGlobal(varName) fibaro:getGlobalValue(varName) fibaro:getGlobalModificationTime(varName) Elles sont utilisées dans les scripts de scènes pour récupérer l'état actuel des variables globales. La valeur récupérée doit être affectée à des variables locales afin de pouvoir utiliser des instructions conditionnelles (if then). Ces 3 fonctions ne diffèrent que par la valeur récupérée. - fibaro:getGlobalModificationTime(varName) DESCRIPTION On récupère des informations (seul l'horodatage de la dernière modification) de la variable globale enregistrée dans le système. CARACTÉRISTIQUES varName: Le nom de la variable globale VALEURS RÉCUPÉRÉES Horodatage de la dernière modification de la variable globale. EXEMPLE -- on veut récupérer la date de la dernière modification de la variable globale nommée 'compteur' local DerniereModif = fibaro:getGlobalModificationTime('compteur') -- si la valeur de cette variable globale a été modifiée il y a plus de 10 secondes if os.time() - DerniereModif >= 10 * 1000 then fibaro:debug('La modification a eu lieu il y a plus de 10s') else fibaro:debug('La modification a eu lieu il y a moins de 10s') VOIR AUSSI fibaro:getGlobal fibaro:getGlobalValue - fibaro:getGlobalValue(varName) DESCRIPTION On récupère des informations (seule la valeur) de la variable globale enregistrée dans le système. CARACTÉRISTIQUES varName: Le nom de la variable globale VALEURS RÉCUPÉRÉES Une chaîne contenant la valeur actuelle de la variable globale. EXEMPLE -- on veut récupérer la valeur de la variable globale nommée 'compteur' local ValeurCompteur = fibaro:getGlobalValue('compteur') VOIR AUSSI fibaro:getGlobal fibaro:getGlobalModificationTime - fibaro:getModificationTime(deviceID, propertyName) DESCRIPTION On récupère des informations (seule l'horodatage de la dernière modification) sur les propriétés d'un module. CARACTÉRISTIQUES deviceID: numéro d'identité du module propertyName: nom de la propriété VALEURS RÉCUPÉRÉES Horodatage des dernières modifications de propriétés du module. EXEMPLE -- on veut récupérer la date de la dernière modification de la propriété 'value' du module d'ID=11, exemple l'heure à laquelle la lampe a changé d'intensité local HeureModif = fibaro:getModificationTime(11, 'value') -- os.time() correspond à l'horodatage au moment de la lecture du script if os.time() - HeureModif >= 10*1000 then -- si la différence de temps entre le moment où le script est lu et le moment de la dernière modification est supérieur à 10s alors fibaro:debug('La dernière modification de la valeur date de plus de 10s') else fibaro:debug('La dernière modification de la valeur date de moins de 10s') - fibaro:getRoomID(deviceID) DESCRIPTION On récupère le numéro de la pièce dans laquelle se trouve le module. CARACTÉRISTIQUES deviceID: numéro d’identité du module VALEURS RÉCUPÉRÉES RoomID: Numéro qui identifie la pièce dans laquelle se trouve le module (Le RoomID de la pièce sans nom ‘non assigné’ est 0) EXEMPLE -- on veut récupérer le numéro d'identité de la pièce dans laquelle se trouve le module d'ID=9 local Piece = fibaro:getRoomID(9) -- on demande au système de récupérer (get) l'identité de la pièce (RoomID) où se trouve le module d'ID=9 et on stocke cette valeur dans la variable qu'on appelera Piece if Piece == 0 then fibaro:debug('Le module se trouve dans la pièce \’non assigné\’') else fibaro:debug('Le module se trouve dans la pièce d\’ID '..Piece) VOIR AUSSI fibaro:getSectionID fibaro:getType - fibaro:getSectionID(deviceID) DESCRIPTION On récupère le numéro d’identité de la section dans laquelle le module est situé. CARACTÉRISTIQUES deviceID: numéro d’identité du module VALEURS RÉCUPÉRÉES SectionID : numéro de la section dans laquelle l'appareil est situé (le SectionID de la section sans nom ‘non assigné’ est 0) EXEMPLE -- on veut récupérer le numéro d'identité de la section dans laquelle se trouve le module d'ID=9 local Section = fibaro:getSectionID(9) -- on demande au système de récupérer (get) l'identité de la section (SectionID) où se trouve le module d'ID=9 et on stocke cette valeur dans la variable qu'on appelera Section if Section == 0 then fibaro:debug('Le module se trouve dans la section \’non assigné\’' else fibaro:debug('Le module se trouve dans la section '..Section) VOIR AUSSI fibaro:getRoomID fibaro:getType - fibaro:getSourceTrigger() DESCRIPTION On récupère les informations sur l’origine du trigger (déclencheur) qui a démarré la scène automatiquement. CARACTÉRISTIQUES Aucune VALEURS RÉCUPÉRÉES Des informations sur le « type » de déclenchement qu’on peut classer dans un tableau. Selon le déclenchement, le « type », peut avoir ces 3 valeurs: ‘property’ - scène déclenchée par la modification d'une propriété d'un module ‘global’ - scène déclenchée par la modification d'une variable globale ‘other’ - dans les autres cas (scène lancée directement grâce à un autre script ou en manuel depuis l'interface par l'utilisateur) Selon la valeur du « type » de déclenchement, la table peut encore avoir des champs supplémentaires, qu'on pourra également récupérer. DESCRIPTION ÉTENDUE Cette fonction peut être utilisée pour déterminer l’origine directe du déclenchement du script. En début de script, dans l’en-tête, on définit les paramètres déclencheurs qui peuvent causer l’exécution du script. Sans cet en-tête rempli correctement, le script ne s’exécutera pas automatiquement. Grâce à la fonction fibaro:getSourceTrigger() on peut récupérer plusieurs éléments en rajoutant derrière : ['type'],['deviceID],[propertyName] ou [varName] : - Le 'type' de l'origine du déclenchement de la scène. On récuperera une des valeurs suivantes: property: si lancement auto de la scène grâce à une modification d'une propriété d'un module global: si lancement auto de la scène grâce à une modification d'une variable globale other: si déclenchement manuel de la scène par l'utilisateur ou depuis une autre scène - 'deviceID' est le numéro d'identité du module surveillé dans l'entête, qui est à l'origine du déclenchement automatique de la scène. - 'propertyName' est le nom de la propriété d'un module surveillé dans l'entête, qui a vu sa valeur changer et qui est à l'origine du déclenchement automatique de la scène. Par exemple une modification de la propriété 'value' quand un éclairage change d'intensité, ou qu'un radiateur se met en route etc, de la propriété 'baterryLevel' quand un module fonctionnant avec pile atteint un certain niveau de batterie, de la propriété 'armed' quand un module comme le capteur d'ouverture de porte est armé au moment de votre départ au travail et que cela démarre la scène qui vous préviendra par notification si la porte s'ouvre et que personne n'a désarmé le module... - 'varName' est le nom de la variable qui a vu sa valeur changer et qui est à l'origine du déclenchement automatique de la scène. Exemple on a crée une variable globale 'SAISON' qui peut prendre la valeur ETE ou HIVER. Quand on modifie cette saison via un module virtuel par exemple, une scène qu'on aura crée auparavant va se lancer automatiquement pour mettre les radiateurs en fonctionnement ou à l'arrêt suivant la saison indiquée. EXEMPLE Démarrage auto de la scène si : Changement de la propriété ‘value’ du module 13 Changement de la propriété ‘value’ du module 15 Changement de la variable globale 'JourNuit’ En outre, le script peut être exécuté directement à partir de l'interface ou en utilisant une autre scène (voir Fibaro: runScene (sceneID)). Lorsque le script est exécuté, il affiche les informations de débogage de la console sur l’origine de son exécution. --[[ %% properties 13 value 15 value %% globals JourNuit --]] local OrigineDeclenchement = fibaro:getSourceTrigger() -- on demande au système de récupérer (get) l'origine (Source) du déclenchement de la scène (Trigger) if OrigineDeclenchement['type'] == 'property' then -- si l'origine du déclenchement de la scène est la modification d'une propriété d'un module surveillée dans l'entête alors fibaro:debug('L\’ origine est la modification d\’une propriété du module '..OrigineDeclenchement['deviceID']) elseif OrigineDeclenchement['type'] == 'global' then -- sinon si l'origine du déclenchement de la scène est la modification d'une variable globale surveillée dans l'entête alors fibaro:debug('L\’ origine est la modification de la variable globale '..OrigineDeclenchement['varName']) elseif OrigineDeclenchement['type'] == 'other' then -- sinon si l'origine du déclenchement de la scène est autre alors fibaro:debug('La scène a été lancée manuellement') end VOIR AUSSI fibaro:getSourceTriggerType() - fibaro:getSourceTriggerType() DESCRIPTION On récupère des informations sur la valeur du « type » du déclencheur qui a causé la scène. CARACTÉRISTIQUES Aucune VALEURS RÉCUPÉRÉES Une chaîne (string) contenant la valeur du « type » du déclencheur (voir fibaro: getSourceTrigger () ) EXEMPLE -- on veut vérifier si la scène a été lancée manuellement if fibaro:getSourceTriggerType() == 'other' then -- si la fonction qui récupère (get) le type (Type) de l'origine (Source) du déclencheur (Trigger) est 'other' alors fibaro:debug('La scène a été lancée manuellement') end -- on a vu au dessus que la même chose peut être obtenue en utilisant le tableau précédent avec l'utilisation de getSourceTrigger() et en se référant au champ 'type' local OrigineDeclenchement = fibaro:getSourceTrigger() if OrigineDeclenchement['type'] == 'other' then fibaro:debug('La scène a été lancée manuellement') VOIR AUSSI fibaro:getSourceTrigger() - fibaro:getType(deviceID) DESCRIPTION On récupère le type de l'appareil. Les différents types d'appareils sont référencés ici PARAMàˆTRES deviceID: numéro d’identification du module VALEURS RÉCUPÉRÉES Une chaîne contenant le type du module EXEMPLE -- on veut récupérer le 'type' du module d'ID=100 local TypeModule = fibaro:getType(100) -- on récupère (get) le type (Type) du module d'ID=100 et on stocke le résultat dans la variable qu'on appelle 'TypeModule' if TypeModule == 'blind' then -- si le module commande un volet roulant alors fibaro:debug('Le module commande un volet roulant') else fibaro:debug('Type du module : '..TypeDispositif) -- sinon la fonction debug indique directement le type du module end VOIR AUSSI fibaro:getRoomID fibaro:getSectionID - fibaro:getValue(deviceID, propertyName) DESCRIPTION On récupère des informations (uniquement la valeur) d'une propriété d'un module. PARAMàˆTRES deviceID: numéro d’identification du module propertyName: nom de la propriété VALEURS RÉCUPÉRÉES une chaîne contenant la valeur actuelle de la propriété voulue EXEMPLE -- on veut récupérer la valeur de la 'valeur de luminosité' du module d'ID=11 local ValeurLum = fibaro:getValue(11, 'brightness') -- C'est ce qu'il y a indiqué sur le document fibaro mais la propriété brightness n'existe plus local ValeurLum = fibaro:getValue(11, 'value') -- C'est maintenant la propriété 'value' d'un dimmer qui permet de récupérer la valeur de la luminosité en pourcentage Exemple concret, une sonde de température dont on veut simplement récupérer la mesure : local TempSalon = fibaro:getValue(115, 'value') -- on demande au système de récupérer (get) la valeur (Value) de la propriété mesure de la température (value) de la sonde de température de salon (module 115) if tonumber(TempSalon) > 20 then -- si la valeur récupérée, une fois transformée en valeur numérique, est supérieure à 20 alors fibaro:call(12, 'turnOff') -- le système demande au relai 12 connecté au radiateur de se couper VOIR AUSSI fibaro:get fibaro:getModificationTime - fibaro: isSceneEnabled (sceneID) DESCRIPTION On vérifie si la scène avec un sceneID donné est active. PARAMàˆTRES sceneID: numéro d’identification de la scène VALEURS RÉCUPÉRÉES valeur booléenne: true si la scène est active, false si non active : d'après la documentation Fibaro, HORS cela ne fonctionne pas. Voir exemple 2 EXEMPLE if fibaro:isSceneEnabled(3) then -- si la scène 3 est activée cela activera la scène 5 fibaro:setSceneEnabled(5, true) end Exemple qui montre qu'on ne récupère pas la valeur true ou false local SceneActive = fibaro:isSceneEnabled(3) if SceneActive == 'true' then fibaro:debug('active') else fibaro:debug('inactive') end Que la scène soit active ou pas, le débogage indiquera inactive. Dans l'exemple précédent on ne pourrait donc pas activer la scène 5 si la scène 3 est inactive... VOIR AUSSI fibaro:setSceneEnabled(sceneID, enabled) - fibaro:killScenes(sceneID) DESCRIPTION On termine toutes les instances en cours d’exécution d'une scène donnée. (On se rappelle que le système peut lire plusieurs fois en même temps un script déjà en cours de lecture) PARAMàˆTRES sceneID: numéro d’identification de la scène VALEURS RÉCUPÉRÉES Aucune EXEMPLE -- si la valeur de 'a' est comprise dans l'intervalle [1;5], toutes les lectures en cours de la scène d'ID=2 s'arrêtent if a >= 1 and a <= 5 then fibaro:killScenes(2) VOIR AUSSI fibaro: startScene (sceneID) fibaro: countScenes () fibaro: countScenes (sceneID) - fibaro:setGlobal(varName, value) DESCRIPTION Modifie la valeur d'une variable globale. PARAMàˆTRES varName: le nom de la variable globale value: la nouvelle valeur de la variable globale VALEURS RÉCUPÉRÉES Aucune EXEMPLE -- on veut attribuer la valeur de 1 à une variable globale nommée 'index' fibaro:setGlobal('index', 1) -- on veut augmenter de 3 la valeur de la variable globale nommée 'test' fibaro:setGlobal('test', fibaro:getGlobalValue('test') + 3) -- on veut assigner à la variable globale nommée 'index', la valeur de la variable locale 'a' local a = 10 * 234 fibaro:setGlobal('index', a) DESCRIPTION ÉTENDUE La fonction fibaro:setGlobal(varName, value) ne peut être utilisée que pour les variables globales qui ne sont pas des variables en lecture seule. Si vous essayez de remplacer la valeur d’une variable en lecture seule, un avertissement sera généré et l'opération ne sera pas effectuée (pas clair). - fibaro:setSceneEnabled(sceneID, enabled) DESCRIPTION Active ou désactive une scène donnée. PARAMàˆTRES sceneID: numéro d’identification de la scène enabled: valeur booléenne (true - active la scène, false - désactive la scène) VALEURS RÉCUPÉRÉES Aucune EXEMPLE if a > 0 then fibaro:setSceneEnabled(3, false) -- si la valeur de la variable 'a' est positive, cela désactive la scène d'ID=3 else fibarosetSceneEnabled(3, true) -- sinon cela active la scène d'ID=3 end VOIR AUSSI fibaro:isSceneEnabled(sceneID) - fibaro:sleep(time) DESCRIPTION On suspend l'exécution du script pendant le temps spécifié en millisecondes. PARAMàˆTRES time: le temps en millisecondes VALEURS RÉCUPÉRÉES Aucune EXEMPLE -- on suspend la lecture du script pendant 10 secondes fibaro:sleep(10000) -- comme les durées doivent être indiquées en millisecondes, pour plus de compréhension on peut écrire fibaro:sleep(10 * 1000) - fibaro:startScene(sceneID) DESCRIPTION On veut démarrer l’exécution d'une scène donnée. PARAMàˆTRES sceneID: numéro d’identité de la scène qui doit être lancée VALEURS RÉCUPÉRÉES Aucune EXEMPLE if a > 20 then fibaro:startScene(10) -- si la valeur de 'a' est supérieure à 20, on démarre l'exécution de la scène d'ID=10 end
  5. Classer les jours du Mois par nom (Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche) Ce script permet de classer les jours du mois par le nom du jour. le but de ce script est de permettre de retrouver le x jour d'un mois ou tous les jours qui ont le même nom Exemple : je veux le 3 mardi du mois je veux tous les jeudi du mois Si vous sauvegardez la table Jours dans une variable globale il faudra exécuter ce script tous les 01 de chaque mois vers 00h01 ---------------------------------------------------------------------- -- Calcul du nombre de jours dans le mois ---------------------------------------------------------------------- -- Si année bissextile local function bissextile(Annee) return Annee % 4 == 0 and (Annee % 100 ~= 0 or Annee % 400 == 0) end -- Nombre de jours dans le mois function JourDansMois(Mois, Annee) return Mois == 2 and bissextile(Annee) and 29 or ("\31\28\31\30\31\30\31\31\30\31\30\31"):byte(Mois) end ---------------------------------------------------------------------- -- Initialisation des variables et creation des tables ---------------------------------------------------------------------- local MoisAnnee = os.date("*t") local mois = MoisAnnee.month -- recuperation du mois en cours local annee = MoisAnnee.year -- recuperation de l'annee en cours local Jmois = JourDansMois(mois, annee) -- calcul le nombre de jour dans le mois en cours local Jours = {["Lundi"]={}, ["Mardi"]={}, ["Mercredi"]={}, ["Jeudi"]={}, ["Vendredi"]={}, ["Samedi"]={}, ["Dimanche"]={}} local JourNom = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"} ---------------------------------------------------------------------------------- for jour = 1,Jmois do local tmpdate = (os.time{year = annee, month = mois, day = jour}) local tmpJourMois = os.date("%d", tmpdate) -- recupere le jour du mois local tmpJourSemaine = tonumber(os.date("%u", tmpdate)) -- Numero du jour de la de semaine local tmpJourNom = JourNom[tmpJourSemaine] -- recupere le nom du jour en francais table.insert(Jours[tmpJourNom], tmpJourMois) --fibaro:debug("Jour = "..tmpJourMois.." "..tmpJourNom) end ----------------------------------------------------------------------- -- Affichage ----------------------------------------------------------------------- print(os.date("Aujourd'hui, nous sommes un %A")) fibaro:debug("Nombre de Jours dans le mois "..Jmois) for i = 1,7 do local jour = JourNom[i] fibaro:debug(jour) for j = 1,#Jours[jour] do fibaro:debug(Jours[jour][j]) end end -- Exemple d'utilisation -- Ici on affiche le 2 lundi du mois local toto = "Lundi" fibaro:debug(Jours[toto][2]) -- ici on affiche le 3 lundi du mois fibaro:debug(Jours.Mardi[3]) On peut sauvegarder la table Jours dans une variable globale afin de l'utiliser dans d'autres scripts (il faudra créer la variable globale) -- Sauvegarde des jours de la semaine dans la variable globale JoursSemaine fibaro:setGlobal('JoursSemaine',json.encode(Jours)) On peut récuperer cette table dans un autre script -- Récupération des jours de la semaine de la variable globale JoursSemaine Jours=json.decode((fibaro:getGlobal('JoursSemaine'))); Utilisation dans un Script ------------------------------------- -- Exemple d'utilisation -- ------------------------------------- -- Ici on affiche le 2 lundi du mois local toto = "Lundi" --Affichage fibaro:debug(Jours[toto][2]) ---------------------------------------------------------------------------------------------- -- ici on affiche le 3 Vendredi du mois local Vendredi3 = Jours.Vendredi[3] --Affichage fibaro:debug(Vendredi3) ---------------------------------------------------------------------------------------------- -- Ici on récupere tous les mardi du mois sous forme de table local Mardi = Jours.Mardi --Affichage for i = 1,#Mardi do fibaro:debug(Mardi[i]) end ---------------------------------------------------------------------------------------------- -- Connaitre le nombre de Samedi dans le mois local NombreSamedi = #Jours.Samedi --Affichage fibaro:debug("Nombre de mardi = "..NombreSamedi) ---------------------------------------------------------------------------------------------- --Recuperer le 3 et 4 jeudi du mois local Jeudi = {Jours.Jeudi[3], Jours.Jeudi[4]} --Affichage for i = 1,#Jeudi do fibaro:debug("Jeudi "..Jeudi[i]) end Voici une version Virtual Device : Fichiers virtual device : Jours_Semaine.vfib
  6. Berale64

    Settimeout

    En convertissant une scène en mode block je suis tombé sur la fonction setTimeout. Cette fonction retarde d'un delay défini l'exécution d'une séquence lua. Si la fonction sleep suspend le déroulement d'une scène, la fonction setTimeout met en arrière plan les instructions de la fonction, mais la scène lua poursuit son cours. --[[ %% properties 52 value 52 armed %% globals --]] fibaro:debug("Start"); fibaro:debug("scene n "..fibaro:countScenes()); local val = fibaro:getValue(52, "value"); local arm = fibaro:getValue(52, "armed"); fibaro:debug("Etat "..val.." "..arm); setTimeout(function() ------ début de la fonction local delayedCheck0 = false; local tempDeviceState0, deviceLastModification0 = fibaro:get(52, "value"); fibaro:debug("Temps écoulé "..os.time() - deviceLastModification0); if (( (tonumber(val) == 0 and tonumber(arm) == 0) ) and (os.time() - deviceLastModification0) >= 120) then delayedCheck0 = true; end if ( delayedCheck0 == true ) then fibaro:call(163, "turnOff"); end end, 120000) ------- fin de lafonction avec delai de 120 secondes fibaro:debug("End"); Le but de ce script est d'éteindre une lampe si plus d'activité (52 = détecteur de mouvement) pendant 2 mn. Analyse du debug. On voit que la scène s'exécute de Start à End en mettant la fonction timeout en attente. A chaque passage, il y a deux scènes qui démarrent. Val = 1 activation du détecteur, val = 0 retour au repos après 20 secondes. Quand le délai arrive à 120 secondes et pas de modification de l'état du détecteur, les instructions sont exécutées. Ici, éteindre la lumière. Il me semble que cette fonction peut ouvrir des horizons pour nos petit bidouillages.
  7. Lazer

    Hc2 Usb Recovery Tweaks

    Les manipulations présentées dans ce sujet de discussion sont destinés à des utilisateurs avancés disposant des compétences nécessaires, et je décline tout responsabilité en cas de fausse manipulation rendant votre clé USB Recovery inopérante, voire même votre Home Center 2. Introduction Voir : Sauvegarde, Restauration, Et Recovery Sur Home Center 2 Clonage de la clé USB de Recovery Présentation de la clé La clé USB fournie avec la box Fibaro Home Center 2 est un élément critique, car sans elle la box ne peut fonctionner. Elle sert pour les sauvegardes de la configuration (en vue de leur restauration éventuelle), notamment avant chaque mise à jour de firmware, mais également pour le Recovery, c'est à dire le retour à une configuration usine en cas de crash de la box. Pour rappel, cette clé est connectée sur un port USB situé derrière la plaque métallique vissée sur le coté gauche de la box. Avant de retirer la clé USB Recovery de la box, s'assurer que celle-ci soit bien éteinte. Dans un premier temps, nous connectons la clé USB sur un PC sous Windows. Dans l'explorateur, nous voyons apparaître une partition d'environ 2 Go : Contenant 3 répertoires et 1 fichier : 24/10/2014 07:44 <REP> backups 02/09/2013 15:40 <REP> system 30/08/2013 12:15 10 network.conf 13/11/2013 22:48 <REP> logs Il est inutile à ce stade là de vouloir copier l'arborescence de cette partition, car le Gestionnaire des disques de Windows nous montre 2 partitions inconnues supplémentaires, ainsi que de l'espace libre : La clé a en réalité une taille de 8 Go, mais seuls 4 Go sont utilisés. Il faut donc monter la clé USB sur un système Linux, qui est capable de lire (presque) tous les formats de partitions existants. J'ai utilisé pour cela une VM sous ESXi sur mon serveur HP Proliant G7 N54L, voici les captures d'écran des fenêtres de modifications des paramètres de la machine virtuelle : On remarque que la clé fournie par Fibaro est de marque Kingston, on n'est donc pas en présence d'une clé chinoise premier prix : Dans ma VM, il s'agit d'un Linux RedHat Enterprise Server, mais n'importe quel Linux peut faire l'affaire, en particulier Debian qui est la distribution utilisée par FIbaro. Il est évidemment possible de monter cette clé sur n'importe quelle machine Linux, dont voici une liste non exhaustive : - Linux natif sur PC - Linux sur Raspberry PI - Linux dans une VM sous VMware Player sous Windows ou MacOS - LiveCD bootable sur CD ou clé USB - etc... Je ne détaille pas ces procédures, de nombreux tutoriels existent sur Internet, et je répète que si vous voulez tenter les manipulations décrites ici cela nécessite d'être suffisamment à l'aise avec Linux (ce qui implique de savoir l'installer). Une fois la clé connectée sur la machine Linux, on la voit apparaître dans les messages du noyau avec la commande dmesg : [root@redhat ~]# dmesg | tail -21 usb 1-2: new high speed USB device number 3 using ehci_hcd usb 1-2: New USB device found, idVendor=13fe, idProduct=4100 usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-2: Product: FIBARO RECOVERY usb 1-2: Manufacturer: FIBARO usb 1-2: SerialNumber: ...................... usb 1-2: configuration #1 chosen from 1 choice scsi4 : SCSI emulation for USB Mass Storage devices usb-storage: device found at 3 usb-storage: waiting for device to settle before scanning usb-storage: device scan complete scsi 4:0:0:0: Direct-Access FIBARO FIBARO RECOVERY PMAP PQ: 0 ANSI: 6 sd 4:0:0:0: Attached scsi generic sg3 type 0 sd 4:0:0:0: [sdc] 15646720 512-byte logical blocks: (8.01 GB/7.46 GiB) sd 4:0:0:0: [sdc] Write Protect is off sd 4:0:0:0: [sdc] Mode Sense: 23 00 00 00 sd 4:0:0:0: [sdc] Assuming drive cache: write through sd 4:0:0:0: [sdc] Assuming drive cache: write through sdc: sdc1 sdc2 sdc3 sd 4:0:0:0: [sdc] Assuming drive cache: write through sd 4:0:0:0: [sdc] Attached SCSI removable disk Dans cet exemple, le device utilisé est /dev/sdc Par curiosité, avec lsusb on peut obtenir des informations sur cette clé Kingston : [root@redhat ~]# lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 002: ID 196d:f100 Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub Bus 001 Device 003: ID 13fe:4100 Kingston Technology Company Inc. [root@redhat ~]# lsusb -s 001:003 -vvv Bus 001 Device 003: ID 13fe:4100 Kingston Technology Company Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x13fe Kingston Technology Company Inc. idProduct 0x4100 bcdDevice 1.00 iManufacturer 1 FIBARO iProduct 2 FIBARO RECOVERY iSerial 3 ...................... bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 200mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk-Only iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0000 (Bus Powered) Avec la commande parted, on découvre plus en détail la structure des partitions de cette clé : [root@redhat ~]# parted /dev/sdc GNU Parted 2.1 Using /dev/sdc Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print Model: FIBARO FIBARO RECOVERY (scsi) Disk /dev/sdc: 8011MB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 1049kB 2000MB 1999MB primary fat32 2 2000MB 2255MB 256MB primary linux-swap(v1) 3 2255MB 3817MB 1561MB primary ext4 boot (parted) quit La taille de 8 Go est confirmée. On trouve les partitions suivantes : FAT32 (la partition visible sous Windows) Linux Swap (l'espace de paging space du système Linux) ext4 (le format de fichier standard d'une partition Linux, et qui se trouve en plus être bootable) Sauvegarde de la clé Sans plus attendre, on procède immédiatement à la sauvegarde cette clé, ce qui est l'étape la plus importante de cette étude. On utilise pour cela la commande dd qui permet de réaliser une copie bit-à -bit de l'intégralité de la clé. [root@redhat ~]# dd if=/dev/sdc of=/tmp/usb.img bs=1M 7640+0 records in 7640+0 records out 8011120640 bytes (8.0 GB) copied, 812.817 s, 9.9 MB/s Débit moyen de lecture de 10 Mo/s, ce n'est pas terrible (le débit max du bus l'USB-2 étant d'environ 25 Mo/s), mais pour l'usage très occasionnel qui est fait de cette clé, ce n'est pas un souci. On obtient un fichier de 8 Go sur le disque dur, qui est l'image exacte de la clé : [root@redhat ~]# ls -l /tmp/usb.img -rw-r--r--. 1 root root 8011120640 Oct 24 10:35 /tmp/usb.img Ce fichier contient donc le MBR (Master Boot Record) de la clé, l'intégralité des 3 partitions, ainsi que l'espace vide, comme le confirme la commande file : [root@redhat ~]# file /tmp/usb.img /tmp/usb.img: x86 boot sector; partition 1: ID=0xb, starthead 32, startsector 2048, 3903488 sectors; partition 2: ID=0x82, starthead 27, startsector 3905536, 499712 sectors; partition 3: ID=0x83, active, starthead 54, startsector 4405248, 3049472 sectors, code offset 0x63 Note : il aurait été possible de réaliser une sauvegarde de façon plus optimisée, en sauvegardant indépendamment le MBR et les 3 partitions, afin de ne conserver que les 4 Go utile. Néanmoins dans ce tutoriel la procédure se voulait simple afin de cloner intégralement la clé USB fournie par FIbaro afin de conserver une copie de secours. Nous verrons peut-être ultérieurement qu'il est possible d'aller beaucoup plus loin dans les manipulations de cette clé. Restauration de la clé On connecte une nouvelle clé USB vierge sur le système Linux. Si cette clé n'est pas vierge, elle sera écrasée. La restauration de la clé de Recovery utilise toujours la même commande dd, mais en sens inverse, c'est à dire qu'on lit le fichier pour écrire sur le périphérique USB. Dans mon exemple il s'agit de /dev/sdd : [root@redhat tmp]# dd if=/tmp/usb.img of=/dev/sdd bs=1M dd: writing `/dev/sdd': No space left on device 7553+0 records in 7552+0 records out 7918845952 bytes (7.9 GB) copied, 703.889 s, 11.3 MB/s On note une erreur car l'espace disponible sur ma nouvelle clé est insuffisant. En effet, j'ai utilisé une clé qui fait un peu moins de 8 Go, donc la commande n'a pas pu écrire la fin des octets. Ce n'est nullement gênant car comme on l'a vu précédemment, seuls 4 Go sont utilisés et la fin de la clé est inutilisé. Dans l'exemple ci-dessus, 7,9 Go ont été écrits, ce qui est plus que suffisant. Test de la clé clonée On insère la clé USB dans la box HC2, on branche l'alimentation, et la box boot comme si de rien n'était. On l'arrête à nouveau, on rebranche la clé d'origine, et on redémarre la box en production. On conserve la nouvelle clé générée bien à l'abri, ou pas, puisque avec l'image binaire présente sur le disque dur il est toujours possible de regénérer autant de clés qu'on le souhaite. Notes complémentaires Cette procédure permet de cloner une clé devant être utilisé sur la même box. L'étude pour cloner une clé sur une box différente sera menée ultérieurement (sans garantie de succès) Le clonage de la clé aurait pu se faire directement avec la commande suivante, sans passer par le disque dur (non testé) : dd if=/dev/sdc of=/dev/sdd bs=1M . Analyse détaillée de la clé A partir de ce chapitre, on commence l'étude approfondie de la clé de Recovery. Par sécurité afin de ne pas tout casser en cas de fausse manipulation, on travaille sur l'image générée précédemment sur disque. Le fichier usb.img est une image en mode "raw" de la clé, et a donc conservé la structure initiale avec les 3 partitions : [root@redhat tmp]# parted usb.img print Model: (file) Disk /tmp/usb.img: 8011MB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 1049kB 2000MB 1999MB primary fat32 2 2000MB 2255MB 256MB primary linux-swap(v1) 3 2255MB 3817MB 1561MB primary ext4 boot On crée les devices dans le noyau permettant de monter les partitions : [root@redhat tmp]# kpartx -v -a usb.img add map loop0p1 (253:2): 0 3903488 linear /dev/loop0 2048 add map loop0p2 (253:3): 0 499712 linear /dev/loop0 3905536 add map loop0p3 (253:4): 0 3049472 linear /dev/loop0 4405248 On crée les points de montages (il est inutile de monter la partition de swap) : [root@redhat ~]# mkdir /mnt/sdc1 [root@redhat ~]# mkdir /mnt/sdc3 On monte les 2 partitions intéressantes : [root@redhat tmp]# mount /dev/mapper/loop0p1 /mnt/sdc1 -o ro [root@redhat tmp]# mount /dev/mapper/loop0p3 /mnt/sdc3 -o ro Dans la partition n°1, on retrouve les fichiers qui étaient visibles sous Windows : [root@redhat tmp]# cd /mnt/sdc1 [root@redhat sdc1]# ls -l total 16 drwxr-xr-x. 7 root root 4096 Oct 24 07:44 backups drwxr-xr-x. 2 root root 4096 Nov 13 2013 logs -rwxr-xr-x. 1 root root 10 Aug 30 2013 network.conf drwxr-xr-x. 2 root root 4096 Sep 2 2013 system Vérification de l'espace occupé/libre : [root@redhat sdc1]# df -m . Filesystem 1M-blocks Used Available Use% Mounted on /dev/mapper/loop0p1 1903 487 1416 26% /mnt/sdc1 Les tailles de Mo de chaque fichier/répertoire : [root@redhat sdc1]# du -sm * 63 backups 1 logs 1 network.conf 424 system On en déduit que sur les 2 Go de cette partition, 424 Mo sont utilisés par l'image système de recovery, et seulement 63 Mo (dans mon cas) pour les sauvegardes de la configuration. Donc les 1416 Mo libres sont plus que suffisants pour réaliser un grand nombre de sauvegardes. Dans mon cas, j'ai seulement 5 sauvegardes, et on remarque que la plus grosse d'entre elle est ma dernière sauvegarde du 24/10/2014 : [root@redhat sdc1]# du -sm backups/* 6 backups/backup16_01_14-2032 6 backups/backup16_01_14-2037 41 backups/backup24_10_14-0944 11 backups/backup28_02_14-1428 2 backups/backup29_11_13-0019 Le fichier network.conf contient seulement l'info permettant au réseau de fonctionner en DHCP lorsqu'on boot en recovery : [root@redhat sdc1]# cat network.conf type=dhcp Etudions maintenant le contenu de ma dernière sauvegarde : [root@redhat sdc1]# cd backups/backup24_10_14-0944/ [root@redhat backup24_10_14-0944]# ls -l total 40812 -rwxr-xr-x. 1 root root 117 Oct 24 07:44 checksum -rwxr-xr-x. 1 root root 131 Oct 24 07:44 info drwxr-xr-x. 2 root root 4096 Oct 24 07:44 scenes -rwxr-xr-x. 1 root root 41757696 Oct 24 07:44 sql -rwxr-xr-x. 1 root root 16528 Oct 24 07:44 zwave Il y a quelques fichiers textes, une base de données SQLite, et un fichier binaire : [root@redhat backup24_10_14-0944]# file * checksum: ASCII text info: ASCII text scenes: directory sql: SQLite 3.x database zwave: data Le fichier checksum contient des sommes de contrôles permettant de s'assurer de la cohérence des fichiers stockés sur la clé avant la restauration éventuelle : [root@redhat backup24_10_14-0944]# cat checksum 82a0e8acacb02838248ff032dfb16a7e sql 96d7a2aac279dc2be1abd77bb1f37196 zwave c9bf3777d6c6990e37a59aa3cfac49af info Vérification, tout est OK : [root@redhat backup24_10_14-0944]# md5sum sql 82a0e8acacb02838248ff032dfb16a7e sql [root@redhat backup24_10_14-0944]# md5sum zwave 96d7a2aac279dc2be1abd77bb1f37196 zwave [root@redhat backup24_10_14-0944]# md5sum info c9bf3777d6c6990e37a59aa3cfac49af info Le fichier info contient quelques informations génériques qui sont affichées par l'interface Web lorsqu'on boote la box en recovery : [root@redhat backup24_10_14-0944]# cat info devices=90 rooms=12 scenes=22 hour=09 minute=44 day=24 month=10 year=2014 timestamp=1414136694 description=24/10/2014 v3.590 stable Le fichier sql contient toute la configuration, dont voici un extrait : [root@redhat backup24_10_14-0944]# sqlite3 sql ".tables" Alarm_Fibaro_Scene Alarm_Zone Alarm_Zone_PIN Backups Borrowed_Devices Cooling_Zone Cooling_Zone_Room Dashboard Device_Association_Group [...] Par exemple : [root@redhat backup24_10_14-0944]# sqlite3 sql 'select * from Room;' 1|1|Salon|room_kominek|999|96|97|0|0 2|1|Entrée|room_kapelusz|999|0|0|0|0 3|1|Salle à manger|room_jadalnia|999|0|0|0|0 [...] Dans le sous-répertoire scenes, on y trouve des pages html et des scritps LUA : [root@redhat backup24_10_14-0944]# cd scenes/ [root@redhat scenes]# ls -l total 484 -rwxr-xr-x. 1 root root 17288 Oct 24 07:44 10.html -rwxr-xr-x. 1 root root 828 Oct 24 07:44 10.lua -rwxr-xr-x. 1 root root 17346 Oct 24 07:44 11.html -rwxr-xr-x. 1 root root 947 Oct 24 07:44 11.lua -rwxr-xr-x. 1 root root 19930 Oct 24 07:44 12.html -rwxr-xr-x. 1 root root 1047 Oct 24 07:44 12.lua -rwxr-xr-x. 1 root root 17756 Oct 24 07:44 13.html -rwxr-xr-x. 1 root root 923 Oct 24 07:44 13.lua -rwxr-xr-x. 1 root root 26374 Oct 24 07:44 14.html -rwxr-xr-x. 1 root root 1112 Oct 24 07:44 14.lua [...] Au hasard, prenons la plus grosse scène, et ô surprise (oui je sais j'utilise encore une veille version de GEA) : [root@redhat scenes]# head -22 22.lua --[[ %% autostart %% properties 46 value %% globals --]] -- ------------------------------------------------------------ -- GEA : Gestionnaire d'Evénements Automatique -- Scénario permettant de contrôler si une périphérique est -- activé depuis trop longtemps ou lancer -- un push d'avertissement -- L'état du périphérique est contrôlé toutes les X secondes -- si passer le délai souhaité le périphérique est toujours -- activé, le système envoi une notification -- -- Auteur : Steven P. with modification of Hansolo -- Version : 3.50 -- Special Thanks to : -- Fredric, Diuck, Domodial, moicphil, lolomail, byackee, -- JossAlf, Did and all other guy from Domotique-fibaro.fr -- ------------------------------------------------------------ . On retourne maintenant à la racine de la partition n°1, afin d'étudier rapidement le répertoire system : [root@redhat scenes]# cd /mnt/sdc1 [root@redhat sdc1]# cd system [root@redhat system]# ls -l total 433920 -rwxr-xr-x. 1 root root 33 Sep 2 2013 checksum -rwxr-xr-x. 1 root root 444328464 Sep 2 2013 image.gz -rwxr-xr-x. 1 root root 0 Jul 17 2012 version3 -rwxr-xr-x. 1 root root 0 Aug 23 2013 version4 Comme pour les sauvegardes, une somme de contrôle permet de s'assurer de l'intégrité de l'image à restaurer : [root@redhat system]# cat checksum c496e1fe5e3095b73e2f376b35ae5307 [root@redhat system]# md5sum image.gz c496e1fe5e3095b73e2f376b35ae5307 image.gz Ce fichier image.gz est une archive compressée d'une image raw d'un disque : [root@redhat system]# file image.gz image.gz: gzip compressed data, was "image", from Unix, last modified: Mon Sep 2 15:27:19 2013 [root@redhat system]# gzip -dc image.gz | file - /dev/stdin: x86 boot sector; partition 1: ID=0x83, active, starthead 32, startsector 2048, 1951744 sectors; partition 2: ID=0x82, starthead 157, startsector 1953792, 499712 sectors; partition 3: ID=0x83, starthead 184, startsector 2453504, 1368064 sectors, code offset 0x63 On décompresse cette archive dans un répertoire temporaire : [root@redhat system]# cd /tmp [root@redhat tmp]# gzip -cd /mnt/sdc1/system/image.gz > image [root@redhat tmp]# ls -l image -rw-r--r--. 1 root root 2002780160 Oct 25 18:26 image Il s'agit de l'image du disque système interne de la HC2 (clé USB SLC de 2 Go) : [root@redhat tmp]# parted image print Model: (file) Disk /tmp/image: 2003MB Sector size (logical/physical): 512B/512B Partition Table: msdosNumber Start End Size Type File system Flags 1 1049kB 1000MB 999MB primary ext4 boot 2 1000MB 1256MB 256MB primary linux-swap(v1) 3 1256MB 1957MB 700MB primary ext4 En cas de recovery de la box, c'est donc cette image qui est restaurée sur la mémoire interne de la box, puis la dernière sauvegarde peut être restaurée. Je ne détaille pas plus le contenu de ces partitions systèmes, mais il est tout à fait possible de les monter et d'accéder à leur contenu. Je précise néanmoins que la première partition est la racine du système (/), tandis que la troisième partition est montée dans /var (contient les journaux, les pages Web, etc...). La première partition (FAT32) de la clé de Recovery est montée dans /home/fghc2-recovery/recovery On étudie maintenant la partition n°3 de la clé de Recovery : [root@redhat mnt]# cd /mnt/sdc3 [root@redhat sdc3]# ls -l total 96 drwxr-xr-x. 2 root root 4096 Dec 8 2011 bin drwxr-xr-x. 3 root root 4096 Dec 8 2011 boot drwxr-xr-x. 5 root root 4096 Dec 8 2011 dev drwxrwxr-x. 74 root root 4096 Aug 30 2013 etc drwxr-xr-x. 3 root root 4096 Oct 3 2011 home lrwxrwxrwx. 1 root root 28 Dec 8 2011 initrd.img -> boot/initrd.img-2.6.32-5-686 drwxr-xr-x. 12 root root 12288 Dec 22 2011 lib drwx------. 2 root root 16384 Dec 8 2011 lost+found drwxr-xr-x. 6 root root 4096 Dec 8 2011 media drwxr-xr-x. 2 root root 4096 Oct 3 2011 mnt drwxr-xr-x. 3 root root 4096 Dec 11 2011 opt drwxr-xr-x. 2 root root 4096 Oct 3 2011 proc drwx------. 4 root root 4096 Sep 12 2012 root drwxr-xr-x. 2 root root 4096 Dec 12 2011 sbin drwxr-xr-x. 2 root root 4096 Jul 21 2010 selinux drwxr-xr-x. 2 root root 4096 Dec 8 2011 srv drwxr-xr-x. 2 root root 4096 Jan 1 2011 sys drwxrwxrwt. 2 root root 4096 Aug 30 2013 tmp drwxrwxr-x. 10 root root 4096 Dec 8 2011 usr drwxrwxr-x. 14 root root 4096 Sep 11 2012 var lrwxrwxrwx. 1 root root 25 Dec 8 2011 vmlinuz -> boot/vmlinuz-2.6.32-5-686 Il s'agit du système Linux sur lequel la box boot en mode Recovery. [root@redhat sdc3]# df -m . Filesystem 1M-blocks Used Available Use% Mounted on /dev/mapper/loop0p3 1467 769 624 56% /mnt/sdc3 . Conclusion Après un certains nombres d'expériences non décrites ci-dessus : La restauration du dump sur la même clé fonctionne, j'ai pu rebooter et faire un recovery. En revanche, la restauration du dump sur une autre clé ne fonctionne pas complètement (certaines fonctionnalités ne fonctionneront pas, comme les sauvegardes, la réinitialisation de la puce Z-Wave, l'exclusion de modules, ... particulièrement en v4 où la sécurité a été renforcée) En effet, Fibaro utilise cette clé comme un dongle de protection. Les informations utilisées sont situées dans le firmware de la clé, et non sur les cellules flash. Par conséquent, elle ne sont pas prises en compte par la commande "dd". Donc si la clé est défectueuse (read only, secteurs défectueux, etc...), la méthode officielle est de se rapprocher du revendeur ou de Fibaro pour procéder à un échange. A noter que dans la mesure où la génération d'une nouvelle clé expose une partie des protections mises en place par Fibaro, ils refusent l'intervention à distance et imposent jusqu'à présent un retour complet de la box. Cependant, dans le cas où les données de la clé USB sont corrompues, mais que la clé n'est pas physiquement endommagée, il est tout à fait envisageable de reconstruire une clé de recovery from scratch pour les utilisateurs qui n'auraient pas fait de clone préalable. Il faut simplement les éléments suivants : - MBR (512 octets) - archive du répertoire system de la première partition - image de la seconde partition Cette expérience a été validée avec succès dans ce topic.
  8. labomatik

    Pilotez Votre Qnap Avec La Hc2

    Bonjour à tous, Voici un petit tutoriel sur comment piloter son nas QNAP avec la HC2. Je ne suis pas dévelopeur LUA sous HC2 donc il y a surement moyen d'optimiser tout ça (notamment les variables login/pass). Les 3 exemples sont basés sur mes besoins actuels, j'arrête mon nas le soir avec l'armement de mon alarme et rallume avec le désarmement de mon alarme grace au WOL (plugin fibaro). Avec les nouvelles génération de nas X51, il est possible de lancer la commande sleep et non shutdown, ce qui permet au NAS d'être réveillé en 5 secondes (RAM sauvegardée) Configuration QNAP Vous devez autoriser la connexion sans SSL (la HC2 ne supporte pas le ssl) HC2 voici un exemple de quelques fonctions que j'ai utilisé pour commander mon NAS - arrêter le nas proprement - démarrer l'enregistrement des caméras de la station de surveillance - arrêter l'enregistrement des caméras de la station de surveillance si vous voulez obtenir l'API complet des fonctions des NAS qnap, envoyez un petit mail à developer@qnap.com (anglais) --> Je ne suis pas dévelopeur et/ou je ne veux pas comprendre Voici alors le virtuel device déjà prêt avec les 3 fonctions vous devez configurer l'IP et le port dans la configuration du virtuel device et adapter le login/pass dans le code des 3 boutons (remplacez LOGIN_NAS et PASSWORD_NAS) QNAP.vfib.zip --> Je suis dévelopeur et/ou je veux comprendre démarrer l'enregistrement: local ip_module = fibaro:get(fibaro:getSelfId(), "IPAddress") local port = fibaro:get(fibaro:getSelfId(), "TCPPort") surveillance_Station = Net.FHttp(ip_module, port) surveillance_Station:setBasicAuthentication("LOGIN_NAS", "PASSWORD_NAS") response = surveillance_Station:GET("/cgi-bin/mrec.cgi?ch=1&act=1") if (string.find(response, "OK")) then fibaro:log("Starting Recording") else fibaro:log("ERROR") end arrêter l'enregistrement local ip_module = fibaro:get(fibaro:getSelfId(), "IPAddress") local port = fibaro:get(fibaro:getSelfId(), "TCPPort") surveillance_Station = Net.FHttp(ip_module, port) surveillance_Station:setBasicAuthentication("LOGIN_NAS", "PASSWORD_NAS") response = surveillance_Station:GET("/cgi-bin/mrec.cgi?ch=1&act=0") if (string.find(response, "OK")) then fibaro:log("Stop Recording") else fibaro:log("ERROR") end la partie plus complexe qui nécessite un parseur XML, l'arret du NAS if (not QNAP) then QNAP = {} QNAP.qnap_ip = fibaro:get(fibaro:getSelfId(), "IPAddress"); QNAP.port = fibaro:get(fibaro:getSelfId(), "TCPPort"); QNAP.globalvariable = "" -- -------------------------------------------------------------------------------------------------------------- -- Obtient le XML et le retourne sous forme de table LUA -- -------------------------------------------------------------------------------------------------------------- QNAP.getTokenFromXml = function() local QNAP2URL = Net.FHttp(QNAP.qnap_ip,QNAP.port); response = QNAP2URL:GET("/cgi-bin/authLogin.cgi?user=LOGIN_NAS&plain_pwd=PASSWORD_NAS&remme=1"); xmlTable = QNAP.iif(response ~= nil, QNAP.newParser().ParseXmlText(response), ""); if (xmlTable.QDocRoot ~= nil) then qsidstr = xmlTable.QDocRoot.authSid:value(); if (string.len(qsidstr)>0) then fibaro:debug("Qtoken founded"); qsidstr = qsidstr:gsub("[".."<![CDATA[".."]", ''); qsidstr = qsidstr:gsub("[".."]".."]", ''); qsidstr = qsidstr:gsub("["..">".."]", ''); fibaro:debug(qsidstr); response = QNAP2URL:GET("/cgi-bin/sys/sysRequest.cgi?subfunc=power_mgmt&count=0.1234&sid="..qsidstr.."&apply=shutdown"); if (string.find(response, "OK")) then fibaro:log("Power Off Server") else fibaro:log("ERROR") end end end end -- ------------------------------------------------------------------------------------------------------------- -- Teste la condition et retourne la valeur true ou false -- ------------------------------------------------------------------------------------------------------------- QNAP.iif = function(condition, iftrue, iffalse) if (condition) then return iftrue end return iffalse end -- ------------------------------------------------------------------------------------------------------------- -- Ceci est une version modifiée par Steven de Corona-XML-Module par Jonathan Beebe qui a son tour -- est basée sur Alexander Makeev's Lua-only XML parser . -- see https://github.com/Cluain/Lua-Simple-XML-Parser -- ------------------------------------------------------------------------------------------------------------- QNAP.newParser = function() parseXml = {} parseXml.FromXmlString = function(value) value = string.gsub(value, "([%x]+)%;", function(h) return string.char(tonumber(h, 16)) end); value = string.gsub(value, "([0-9]+)%;", function(h) return string.char(tonumber(h, 10)) end); value = string.gsub(value, "'", "'"); value = string.gsub(value, ">", ">"); value = string.gsub(value, "<", "<"); value = string.gsub(value, "&", "&"); return value; end parseXml.ParseArgs = function(node, s) string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a) node:addProperty(w, parseXml.FromXmlString(a)) end) end parseXml.ParseXmlText = function(xmlText) local stack = {} local top = parseXml.newNode() table.insert(stack, top) local ni, c, label, xarg, empty local i, j = 1, 1 while true do ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i) if not ni then break end local text = string.sub(xmlText, i, ni - 1); if not string.find(text, "^%s*$") then local lVal = (top:value() or "") .. parseXml.FromXmlString(text) stack[#stack]:setValue(lVal) end if empty == "/" then -- empty element tag local lNode = parseXml.newNode(label) parseXml.ParseArgs(lNode, xarg) top:addChild(lNode) elseif c == "" then -- start tag local lNode = parseXml.newNode(label) parseXml.ParseArgs(lNode, xarg) table.insert(stack, lNode) top = lNode else -- end tag local toclose = table.remove(stack) -- remove top top = stack[#stack] if #stack < 1 then error("XmlParser: nothing to close with " .. label) end if toclose:name() ~= label then error("XmlParser: trying to close " .. toclose.name .. " with " .. label) end top:addChild(toclose) end i = j + 1 end local text = string.sub(xmlText, i); if #stack > 1 then error("XmlParser: unclosed " .. stack[#stack]:name()) end return top end parseXml.newNode = function(name) local node = {} node.___value = nil node.___name = name node.___children = {} node.___props = {} function node:value() return self.___value end function node:setValue(val) self.___value = val end function node:name() return self.___name end function node:setName(name) self.___name = name end function node:children() return self.___children end function node:numChildren() return #self.___children end function node:addChild(child) if self[child:name()] ~= nil then if type(self[child:name()].name) == "function" then local tempTable = {} table.insert(tempTable, self[child:name()]) self[child:name()] = tempTable end table.insert(self[child:name()], child) else self[child:name()] = child end table.insert(self.___children, child) end function node:properties() return self.___props end function node:numProperties() return #self.___props end function node:addProperty(name, value) local lName = "@" .. name if self[lName] ~= nil then if type(self[lName]) == "string" then local tempTable = {} table.insert(tempTable, self[lName]) self[lName] = tempTable end table.insert(self[lName], value) else self[lName] = value end table.insert(self.___props, { name = name, value = self[name] }) end return node end return parseXml; end end QNAP.getTokenFromXml();
  9. Clé Usb Recovery Explication en image de la FAT32 Je vais vous expliquer ce que contient la partition FAT32 de la clé USB Recovery Je précise que ni moi ni le forum de peux être tenu responsable en car d'une mauvaise utilisation de ce TUTO Je ne ferai aucun support sur ce tuto 1 - Il faut eteindre ca box FIBARO via le bouton. 2 - Retirer la clé USB Recovery de la box (je passe le démontage des plaques pour y avoir accés ) 3 - Brancher la clé USB Recovery sur un PC Windows (Pour mac je sais pas si il lit les fat32) 4 - Accéder à la clé USB Recovery via l'explorateur de fichier Windows 5 - Voici ce que vous allez voir : 3 Répertoires et 1 Fichier le fichier network.conf contient la configuration réseau de votre HC2 Passons au répertoire Backups On retrouve ici toutes nos sauvegardes Regardons d'un peu plus prêt une sauvegarde On y trouve 4 fichiers et un dossier scenes checksum = Il contient le numero MD5 pour la vérification de la sauvegarde Info = fichier contenant les infos de la sauvegarde (date, heures, nombres de pièce etc...) sql = base de données sql Regardons de plus prêt le dossier scenes dans le dossier on retrouve tout les scripts de nos scènes ainsi qu'un fichier html par scéne Passons au répertoire log Ce répertoire est vide Le répertoire system checksum : stock le MD5 de l'image (image.gz) image.gz : c'est l'image qui sera restauré lors d'un recovey les fichiers version3 et version4 sont vide Mettre a jour l'image qui sert au recovery Pour cela il suffit de télécharger l'une des images partager par @jojo est de copier les fichiers dans le dossier system https://drive.google.com/drive/folders/0B1AXBMQhZAKAWlpsWk1FTEhlMHM Donc on s' aperçoit qu'il n'est pas très compliquer de faire une copie de ces sauvegardes sur notre PC Pour ceux qui aurait l'idée de modifier la base sql, il faudra recalculer le MD5, mais je dé-conseil de faire cela car en cas d'erreur c'est recovery obligatoirement
  10. VERIFICATEUR D'ID Très souvent, trop souvent, notre HC2 plante car nous utilisons des IDs (identifiants) qui n'existent pas/plus. Ces identifiants ont tendance à changer lors : d'une mise à jour de la box de la reconfiguration d'un device Parfois, même un simple changement de pile Bref, il est difficile de contrôler périodiquement tous nos scènarios, VD, ... Voici donc un scénario qui va "tenter" de faire cette vérification pour vous. Ce scénario N'EST PAS intelligent, il analyse votre code sans le comprendre et vous affiche des éléments qui méritent d'être vérifiés. Ce scénario peut vous envoyer un push en cas d'avertissement rencontré, peux tourner à intervalle régulier et vous envoyer un rapport par email. Lorsque ce scénario rencontre quelque chose d'étrange, il vous affiche la ligne suivante : [DEBUG] 09:57:24: checking scene : [425] Graphs pull [DEBUG] 09:57:24: code --> contient une référence erronée dans fibaro:call(81, "pressButton", "1") [ignored = {id=425, field="81"}] Vous allez donc vérifier le code de votre scène (Graphs pull) dans cet exemple. Si effectivement l'ID n'existe plus, il vous suffit de corriger votre code. Inversement, si cet avertissement n'a pas de sens, il vous suffit de copier le code commencant par ignored [ignored = {id=425, field="81"}] situé en fin de ligne et de le copier entre les deux lignes suivantes local ignored = { -- {id=425, field="81"}, -- Graph pull - Ligne en commentaire } Ainsi cette scène ignorera cet avertissement pour les prochaines fois. Cette scène nécessite un petit effort de mise en place mais permet de corriger et prévenir des erreurs d'ID qui peuvent être désagréable. Courage et n'hésitez pas si vous avez des questions. Ci-joint la scène en question et l'icone créé par @sebcbien. Historique : 1.0 -> Initialisaton 2.0 -> vérifie ou non les scènes et VDs désactivés (voir local checkDisabled = false) 2.0 -> corrige l'analyse de l'entête des scènes (du mois, je crois) 2.0 -> permet d'ignorer certaines erreurs (voir local ignored = {}) 2.1 -> optimisation du code 2.2 -> lors de la recherche de la valeur d'une variable, prend en compte la position dans le code 2.3 -> Vérifie les variables courantes : "id", "deviceid", ... (voir local mostUseVariables = {}) 3.0 -> Auto-détection de GEA 3.1 -> Ignore les warnings liés à cette propre scène 3.2 -> Autostart et envoi de push + notification en cas de problème 3.3 -> Envoi de mail + relancement automatique toutes les X heures 3.4 -> Mise à disposition des utilisateurs 3.5 -> Affichage du nom du bouton en cas d'avertissement 3.6 -> Ne confond plus les variables contenant caractères et chiffres (Windows5, Radiateur_4) avec des IDs de module 3.6 -> Ne confond plus le numéro du CentralSceneEvent avec un ID de module CheckAll_v3.6.lua
  11. Krikroff

    Notification Center

    Notification Center Le centre de notifications à pour objectif de centraliser au mieux les besoins en communication en mettant à disposition une interface (lua) permettant d’accéder à divers services (HC2 Push & Mail, Pushover, passerelle personnalisée etc.) afin de pousser des messages dynamiques et informations diverses vers l’ extérieur. Version: 1.0.1 Phase du projet : Bêta Actuellement « Notification Center » est capable de gérer de manière automatique des demandes de notifications (concurrentes ou non) en utilisant les services suivants : HC2 Push (Mobile ID) HC2 Email (User ID) Pushover: Simple Notifications for Android, iOS, and Desktop (https://pushover.net/) Pushingbox (http://www.pushingbox.com) Prowl (http://www.prowlapp.com/) En cours d' intégration: Passerelle personnalisée (Ex : script php free sms, etc.) LiveNotifier (http://www.livenotifier.net) Roadmap: SMS Gateway & PAW Notification XBMC (Popup) TTS (support tiers) Messages prédéfinis (avec "template" ou non) Périphérique virtuel avec retour visuel : Nombre d’envois (Jours/mois), état du moteur de notification etc. Table de correspondance Mobile ID / User ID <-> Périphérique / Utilisateur par réflexion de l’API Panic Mode: routage automatique de tous les messages (prioritaires) vers une passerelle GSM (PAW, SMS Gateway) en cas de défaillance de fourniture Internet (ADSL/Fibre/Etc) En cours d'enrichissement...
  12. Hello Faisant suite au VD de Krikroff avec Waze, je me suis dit que cela sera sympa d'avoir un VD 'info trafic transport' J'ai donc regarder les api de dispo J'ai trouvé un API d'un mec bien sympa qui récupère les infos RATP (Metro et RER partie RATP) Avec mes très faibles connaissances, j'ai donc bricolé un petit VD pour récupérer l’état du trafic et aussi l'horaire d'un prochain train ... (merci à Lazer également) à‡a doit être très perfectible, donc si vous avez des idées d’optimisation, en ce jours de HC2 surchargé c'est toujours bien de partager :-) C'est pas un VD "universel", dans le sens ou vous allez avoir besoin de modifier 2/3 choses dans le code pour l'adapter à vos stations/lignes habituelles. si vraiment il y a un besoin, on pourrait faire quelque chose de plus propre. Avec l’état du trafic je push des nofifs avec GEA, on pourrait aussi le mettre ce push dans le main loop avec un sleep. Dans mon cas perso, je remonte l’état du RER A et du metro1 et je push toutes les 15Mn l’état trafic du RER si trafic perturbé Je remonte aussi l'horaire temps réel du prochain RER, qui part de la Défense à destination de la maison :-) Avant d'importer le VD, vous allez devoir créer un variable : EtatTrafic , sans valeur particulière. Dans le code il faut modifier : 1/les IDs de vos icônes (merci à Did) local TraficOk = 1121 local TraficNok = 1122 2/pour la partie RER, si vous voulez le A mettre un 1 si vous voulez le B un 2 local LineRer = jsonTable.response.rers[1].line local EtatRer = jsonTable.response.rers[1].title local EtatLongRer = jsonTable.response.rers[1].message 3/pour le metro, idem suivant votre ligne 1,2 etc... local LineMetro = jsonTable.response.metros[1].line local EtatMetro = jsonTable.response.metros[1].title si vous voulez faire un push plutôt sur le métro que sur le RER, suffit de remplacer la ligne local EtatLongRer = jsonTable.response.rers[1].message par local EtatLongRer = jsonTable.response.metros[1].message avec bien sur le paramètre [1] qui vous correspond et aussi d'ajuster les labels ... (je pourrais aider si besoin c'est pas compliqué) 3/Pour la partie horaire un poil plus compliqué (faudrait créer des variables locales pour faire plus simple ...) mais grosso modo allez ici http://api-ratp.pierre-grimaud.fr/v2/rers/a ou ici http://api-ratp.pierre-grimaud.fr/v2/metros/1 en modifiant bien sur le N° de la ligne qui vous intéresse. et récupérer le 'slug' de votre ligne et la destination et modifier l'appel API en conséquence local response ,status, err = TRAFIC:GET("/v2/rers/a/stations/grande+arche+la+defense?destination=st+germain+en+laye+poissy+cergy") ensuite la boucle for i=1, Max do if jsonTable.response.schedules[i].destination == "Poissy" then ProchainRer = jsonTable.response.schedules[i].message break elseif jsonTable.response.schedules[i].destination == "Cergy-Le Haut" then ProchainRer = jsonTable.response.schedules[i].message break else ProchainRer = 0 end end est pour mon cas particulier car j'ai 2 possibilités de desitnations pour rentrer. A adapter suivant vos cas. Ensuite je rafraichi le VD et push l'état du trafic avec GEA -- Push Trafic GEA.add(true, 2*60, "", {{"VirtualDevice", id["ETAT_TRAFIC"], 1},{"Repeat"}}) -- Refresh toutes les 2mn l'etat du trafi GEA.add ({"Global!", "EtatTrafic", "OK"}, 15*60, "#value#",{{"Repeat"}}) -- Push Etat toutes les 15mn si NOK Voilà en gros, je suis désolé c'est pas plug en play, mais c'est pas très compliqué à modifier, car moi même j'ai réussi lol Si il y a un intérêt plus important, je pourrai regarder pour faire quelque chose de plus facile à intégrer chez vous. J'essai de regarder maintenant la partie TRANSCILIEN, ça fonctionne de la même façon avec l'API Transicilien, sauf que je récupérer un XML et pas un JSON, donc je sais pas trop comment le lire ... idem si intérêt, on peut regarder ensemble. Etat_Trafic.vfib
  13. Faire un RECOVERY en moins de 30 mn By MPRInfo Tout en Image Comment on passe la box en mode recovery ? (éteindre la box, puis appuyer sur les deux boutons simultanément) Petite précision avant de commencer : J'ai modifié l'image recovery sur ma clef usb, j'ai aussi modifié la taille de la partition fat32 de ma clef recovery de 8go Donc lors de ce recovery je ne vais donc pas passer par la 3.60 mais directement en 4.031 Cela ne change rien au principe pour les box anciennes comme la mienne il faudra passer par la V3 je suis donc en 4.031 pour ceux qui on une image recovery ancienne on doit arrivé en 3.60 si mais souvenir sont bon il faut donc faire la mise a jours pour passer en V4 On passe ensuite en 4.054 Stable On accepte de prendre pleins des risque sans rien dire ou râler Après acceptation il faut parfois re saisir l'adresse de la box pour avoir l'image suivante On ferme le navigateur est on vide le cache comme a chaque mise à jours Ensuite si on veut on peut installer la 4.055B la procédure est la même On oublie pas de nouveau a vider le cache du navigateur une fois la mise a jour faite On ferme le navigateur est on vide le cache comme a chaque mise à jours Pour la clef ou j'ai augmenté la taille voici un aperçu : Liens utiles : Images Clé Usb : https://www.domotique-fibaro.fr/topic/6824-images-clã©-usb/ Clé Usb Recovery Explication En Image De La Fat32 : https://www.domotique-fibaro.fr/topic/5534-clé-usb-recovery-explication-en-image-de-la-fat32/ The END
  14. Faire une copie de la clef usb RECOVERY sous windows Ceci est un complément a ce tuto : http://www.domotique-fibaro.fr/index.php/topic/2364-hc2-usb-recovery-tweaks/ !!! Attention !!! ce tuto n'est pas sans risque si vous ne le suivez pas a la lettre vous risquez de corrompre votre clef USB RECOVERY Il faut télécharger : Win32 Disk Imager : http://sourceforge.net/projects/win32diskimager/ HashMyFiles v2.11 : http://www.nirsoft.net/utils/hash_my_files.html Il faut éteindre la box Retirer la clef USB Recovery pour cela il faut dévissé les 4 vis pour et retirer le cache afin d'avoir accès a la clef Brancher la clef USB RECOVERY sur votre PC Installer Win32 Disk Imager sur votre PC Voici un aperçu des partitions de la clef Lancer Win32 Disk Imager ATTENTION bien cliquer sur READ sinon on risque de détruire la clef usb Notre clef USB et Cloner dans un fichier IMG. Nous allons récupérer le MD5 On copie cette clef MD5 dans un fichier TXT cela nous servira a vérifié si notre fichier IMG n'est pas corrompu lorsque l'on voudra la restaurer. La clef MD5 controler l'intégrité de notre sauvegarde. Cette clef ne changera pas temps que l'on ne modifie pas notre sauvegarde voici un lien qui explique ce qu'est le MD5 : http://fr.wikipedia.org/wiki/MD5 Verification du fichier IMG avec le MD5 On vérifie que la clef MD5 et bien identique a la clef que l'on a copié dans le fichier TXT On copie les fichiers qui ce trouvent sur la partition Fat32 de notre clef USB recovery dans un répertoire de notre PC Répertoires : Backups (contient toutes nos sauvegardes) logs (ce répertoire est vide chez moi system (Contient l'image qui sera restauré lors d'un recovery) network.conf (le fichier contient seulement l'info permettant au réseau de fonctionner en DHCP lorsqu'on boot en recovery) Ce qui nous donne ceci : Avant de faire quoi que ce soit sur votre HC2 Solutions en cas de probléme : Contacter le support FIBARO (surtout si ils peuvent avoir accès à la box) Brancher un écran sur votre HC2 pour voir ce qui ce passent Je précise que le clonage de la clef ne peut normalement être utilisé sur une autre clef USB il faut absolument la clef USB RECOVERY fourni par fibaro
  15. Pour la HCL, j'avais en son temps fait un tuto pour afficher une icône dans un virtual device une icône en fonction de la valeur d'une variable globale, et de pouvoir modifier sa valeur (également depuis son smartphone), quelle se mette à jour lors d'un restart de la box, etc pour une HCL En passant sous HC2, j'avais gardé le même principe, et pour chaque VD (et donc chaque variable), la main loop tournait en continu pour vérifier que l'icône correspond bien à la valeur de la variable. Ce n'est vraiment pas optimal. Je vais vous expliquer ici la solution que j'ai mise en place pour que la charge sur la box soit moins importante. Merci à Steven, i-magin et mprinfo qui m'ont aidé pour débugger Création des variables Je prendrai dans mon exemple 2 variables globales : Auth_PS3 avec 2 valeurs possibles : "Autorisé" et "Interdit" Auth_TV avec 2 valeurs possibles : "Autorisé" et "Interdit" (mais les valeurs pourraient être différentes que pour la 1° variable, ou avoir plus que 2 valeurs) Modules virtuels Chaque variable a son module virtuel. Il a pour objectif d'afficher une icône différente en fonction de la valeur de la variable. Pour facilement les retrouver, j'ai créé une section "Section Virtuelle" et dedans une pièce "Variables". Chaque VD a le nom suivant : "Var_xxxx" où xxxx est le nom de la variable globale. Dans notre exemple : "Var_Auth_PS3" et "Var_Auth_TV". L'icône par défaut du VD est et doit rester l'horrible cube bleu (facile ainsi de repérer si la VD est à jour) J'ai créé les boutons suivants : Bouton 1 : Autorisé / Interdit Il permet simplement de faire le switch de la valeur de la variable. C'est le bouton par défaut du VD. Il n'y a pas d'icône associée. -- nom de la variable à modifier local variable = "Auth_PS3" if fibaro:getGlobal(variable) == "Interdit" then fibaro:call(fibaro:getSelfId(), "pressButton", "3") else fibaro:call(fibaro:getSelfId(), "pressButton", "4") end Label : Statut afficher en texte la valeur de la variable Bouton3 : Autorisé c'est le bouton qui est appelé pour mettre la variable à "Autorisé" Il contient l'icône qu'on veut voir affichée (comme ça on ne doit pas chercher son ID) fibaro:setGlobal('Auth_PS3', 'Autorisé') fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Statut.value", 'Autorisé') Bouton4 : Interdit c'est le bouton qui est appelé pour mettre la variable à "Interdit" Il contient l'icône qu'on veut voir affichée (comme ça on ne doit pas chercher son ID) fibaro:setGlobal('Auth_PS3', 'Interdit') fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Statut.value", 'Interdit') N.B. l'ID de ce bouton ne peut pas être appelée par le bouton Switch, mais seulement son numéro QUI CHANGE si vous changez l'ordre. C'est débile, mais c'est comme ça … Utilisation On clique sur le bouton principal, et il switch la valeur de la variable On peut utiliser Google Calendar pour lui dire d'appuyer directement sur le bouton "Autorisé" ou "Interdit" Vous devez modifier les scènes qui modifiaient directement la variable, en la faisant appuyer sur le bouton de la VD qui modifie la variable et met à jour l'icône de la VD (car il n'y a plus le mainloop qui contrôle en continu la valeur de la variable) Limitations et solution : Lors du redémarage de la box, ou Lors de la sauvegarde du VD (parce que vous avez fait une petite modif, ou …) L'icône qui est affichée pour le VD, est l'icône par défaut du VD. Le cube bleu, pas cool … Donc pour pallier à ce problème, j'ai créé un VD supplémentaire "Var_Update" Dont voici le code : un GRAND merci à mprinfo qui m'a beaucoup aider pour faire qqch de plus sympa et générique ---------------------------------- -- User Settings ---------------------------------- -- la Table doit avoir la structure suivante : -- 1/ nom de la variable globale entre " -- 2/ ID du VD qui affiche la valeur de la VG -- 3/ n° du premier bouton qui doit être appuyé -- (qui correspond à la première valeur de la variable) -- 4/ n° du dernier bouton qui doit être appuyé -- (qui correspond à la dernière valeur de la variable -- on suppose que tous les boutons se suivent de 1 en 1) -- 5/ valeurs possibles de la variable entre " -- (elles doivent être listées dans l'ordre des boutons de la VD) local Table = {"Auth_PS3", 23, 3, 4, "Autorisé", "Interdit", "Auth_TV", 289, 3, 4, "Autorisé", "Interdit", "Auth_VMCEtage", 290, 3, 4, "Autorisé", "Interdit", "Auth_TerrPar", 291, 3, 4, "Autorisé", "Interdit", "Auth_LumHallNuit", 362, 3, 4, "Autorisé", "Interdit", "ECS", 292, 3, 4, "Oui", "Non", "DayPart", 130, 3, 4, "After SunRise", "After SunSet", "Noel", 363, 3, 4, "Oui", "Non", "Saison", 133, 3, 6, "Printemps", "Eté", "Automne", "Hiver", "Chauffage", 351, 3, 5, "0", "1", "2", "Vacances", 293, 3, 4, "Oui", "Non" } ---------------------------------- -- DO not change bellow this line ---------------------------------- local i = 1 while Table[i] ~= nil do local VG_Nom = tostring(Table[i]) fibaro:debug("----------------------------") fibaro:debug("Nom de la variable Globale = " ..VG_Nom) local VD_id = tostring(Table[i+1]) local Btn_Deb = tonumber(Table[i+2]) local Btn_Fin = tonumber(Table[i+3]) local NbrVal = (Btn_Fin - Btn_Deb) + 1 --Nbr de valeur possibles de la variable fibaro:debug('NbrVal = ' ..NbrVal) i = i + 4 local VG_Val = fibaro:getGlobalValue(VG_Nom) fibaro:debug('Valeur de la variable Globale = ' ..VG_Val) for j = 1,NbrVal do if VG_Val == Table[i+j-1] then fibaro:debug(VG_Nom.. ' = ' ..VG_Val) fibaro:debug("Il faut appuyer sur le bouton : " ..Btn_Deb.. " de la VD_id " ..VD_id) fibaro:call(VD_id, "pressButton", Btn_Deb) end Btn_Deb = Btn_Deb + 1 end -- for i = i + NbrVal end -- while Pour retrouver l'ID du VD, vous avez plusieurs solutions : Le toolkit de Krikroff l'API : http://<IP Box>:<Port Box>/api/virtualDevices vous exportez le VD, et dans l'URL vous voyez ?id=xxx vous éditez le VD, et dans l'URL vous voyez ?vid=xxx Il vérifie la valeur de la variable et appuie sur le bouton correspondant à l'icône. D/Variable. Donc maintenant, quand je vois qu'une des icônes associée à mes variables est l'icone standard, je clique sur le bouton, et tout est remis au carré. Cela évite d'avoir un main loop qui tourne pour chaque variable 99% du temps pour rien. On a donc trouvé une parade à la deuxième limitation ;-) Pour la première limitation (mise à jour après un restart de la box) la solution est facile : Créer une scène qui appelle la VD "Var_Update" / bouton 1 au démarrage de la box. --[[ %% autostart --]] fibaro:sleep (10*1000) fibaro:call(361, "pressButton", "1") où 361 est l'ID du Vd "Var_Update" Merci à Steven qui finalement à trouvé la solution du sleep au début de la scène, ainsi qu'à i-magin et mprinfo pour leurs bonnes idées
  16. gargamel01000

    Gateway Sms Autonome

    Salut à tous, pour mon premier petit tuto, je vais vous détailler la mise en place d'une passerelle SMS perso et autonome que je viens de mettre en place. Cette passerelle SMS va vous permettre d'envoyer depuis le HC2 vos propres SMS gratuitement sur n'importe quel numéro de portable. Pour ce faire vous avez besoin : -d'un abonnement GSM, j'utilise le forfait à 2 euro de free, gratuit pour les freenaute. -d'un vieux portable sous android, version 1.6 minimum -et d'un HC2, ou de n'importe qu'elle box domotique qui sait envoyer des requêtes HTTP. 1- Préparation du matériel : Il suffit de connecter en WIFI votre téléphone sur votre réseau, de préference avec une ip fixe ou une réservation dans le DHCP. Installer l'application SMS Gateway de l'éditeur APK Soft à télécharger sur le google play 2-Configuration du logiciel : Très simple d’utilisation il suffit de paramétrer SMS Gateway pour qu’elle crée un serveur HTTP au sein de votre téléphone en lui spécifiant un port (ou laisser celui par défaut). Votre serveur domotique communiquera avec la passerelle SMS en HTTP via ce serveur web embarqué. Un mot de passe peut être demandé afin de limiter les accès au serveur web. Ce mot de passe devra être spécifié dans la requête http voici le lien pour configurer l'application : http://www.abavala.com/2012/07/09/sms-gateway-une-passerelle-sms-a-la-maison/ Du coté du HC2, il faut créer un périphérique virtuel, en indiquant l'adresse IP du téléphone et son port TCP (9090 par defaut). Ensuite j'ai créer un bouton qui correspond à un message prédefini --Récupération de l'adresse IP et du Port inscrit sur le module virtuel. --fibaro:getSelfId() retourne l'ID du module virtuel en cours. local ip_module = fibaro:get(fibaro:getSelfId(),"IPAddress") local port = fibaro:get(fibaro:getSelfId(), "TCPPort") local id_module = fibaro:getSelfId() local status = "" local TelFred = "+3367*******" HC2 = Net.FHttp(ip_module,port) response ,status, errorCode = HC2:GET("/sendsms?phone=067*******&text=ceci%20est%20un%20test&password=*********") fibaro:debug("response = " .. response) fibaro:debug("status = " .. status) if response ~= nill and tonumber(status)==200 then fibaro:debug("Succes: SMS envoyé") else fibaro:debug("Error: Failed to SEND SMS") end Le SMS de votre serveur domotique sera envoyé directement par la passerelle dès qu’il s’adressera à elle via une URL de la forme: http://***.***.***.***:9090/sendsms?phone=xxxxxxxxxx&text=ceci%20est%20un%20test&password=yyyyy Vous pouvez créer autant de bouton que nécessaire En espérant avoir pu vous être utile.
  17. lionel

    Créer et utiliser une Variable

    bonjour a tous Je cherche a créer une scène entre le coucher et le lever du soleil, j ai essayé avec les scènes blocs ,mais ça ne fonctionne pas une idée, de script? Merci Lionel
  18. Berale64

    De L'utilisation Des Triggers

    Je continue mon apprentissage de la HC2 et j'investigue les triggers (en français gâchette ou détente). Dans notre domaine c'est donc un évènement qui, lorsqu'il intervient, va déclencher une action. J'avais fait un petit script qui affiche les températures min et max à l'intérieur de la maison et à l'extérieur. http://www.domotique-fibaro.fr/index.php/topic/3438-temp%C3%A9rature-min-max/ Il est en fait très peu efficace du point de vue ressources machines puisqu'il est basé sur une boucle infinie qui, à interval régulier, va chercher les températures, même si elles n'ont pas changé. Je l'ai donc modifié en utilisant les triggers, et c'est maintenant un changement de température qui actionne la scène pour afficher les nouvelles valeurs. Dans l'entête sous "%% properties" il faut indiquer les IDs des devices concernés et exit le "while true do". --[[ %% autostart %% properties 35 value 42 value %% globals --]] Comme la scène ne tourne pas en continue, il faut enregistrer les valeurs min/max dans des variables globales. Vous devez créer GVTempE et GVTempI. également json.encode ne fonctionne pas dans les scènes (suis en 3.600) je le fais moi même. Voilà le code complet: --[[ %% autostart %% properties 35 value 42 value %% globals --]] local temp; local TempExtMin; local TempExtMax; local TempSalonMin; local TempSalonMax; local str; local id = {}; id.tempext = 35; id.tempint = 42; id.display = 83; -- GVTemp format 099.99/-99.99 GVTempE = fibaro:getGlobal("GVTempE"); GVTempI = fibaro:getGlobal("GVTempI"); -- fibaro:debug(GVTempE); -- fibaro:debug(GVTempI); TempExtMin = tonumber(string.sub(GVTempE,1,6)); TempExtMax = tonumber(string.sub(GVTempE,8,13)); TempSalonMin = tonumber(string.sub(GVTempI,1,6)); TempSalonMax = tonumber(string.sub(GVTempI,8,13)); -- Température extérieur temp = fibaro:getValue(id.tempext,"value"); -- fibaro:debug(temp); if (tonumber(temp) < TempExtMin) then TempExtMin = tonumber(temp); end if (tonumber(temp) > TempExtMax) then TempExtMax = tonumber(temp); end str = string.format("%3.1f",TempExtMin).." / "..string.format("%3.1f",TempExtMax); fibaro:call(id.display, "setProperty", "ui.Label1.value", str.." °C"); fibaro:call(id.display, "setProperty", "ui.Label7.value", temp.." °C"); str = string.format("%06.2f",TempExtMin).."/"..string.format("%06.2f",TempExtMax); -- fibaro:debug(str); fibaro:setGlobal("GVTempE",str); -- temérature intérieur temp = fibaro:getValue(id.tempint,"value"); -- fibaro:debug(temp); if (tonumber(temp) < TempSalonMin) then TempSalonMin = tonumber(temp); end if (tonumber(temp) > TempSalonMax) then TempSalonMax = tonumber(temp); end str = string.format("%3.1f",TempSalonMin).." / "..string.format("%3.1f",TempSalonMax); fibaro:call(id.display, "setProperty", "ui.Label11.value", str.." °C"); fibaro:call(id.display, "setProperty", "ui.Label13.value", temp.." °C"); str = string.format("%06.2f",TempSalonMin).."/"..string.format("%06.2f",TempSalonMax); -- fibaro:debug(str); fibaro:setGlobal("GVTempI",str); le code du bouton reset du VD est aussi changé. Il remet les variables globales à 099.99/-99.99 Changer le numéro de la scène (23) et du VD (83) ou mettre un getSelfId. fibaro:killScenes(23); fibaro:setGlobal("GVTempE","099.99/-99.99"); fibaro:setGlobal("GVTempI","099.99/-99.99"); fibaro:sleep(1000); fibaro:startScene(23); local Date = os.date("%d/%m/%y %H:%M"); fibaro:call(83, "setProperty", "ui.Label5.value",Date); Depuis que j'ai une HC2, je regarde avec plus d'attention les script LUA et je vois énormément de boucles infinies quand des triggers seraient beaucoup plus efficaces. Un petit clien d'oeil à Jojo qui semble aimer les VD. Il faut lire la petite phrase concernant la "Boucle principale". Dans ta version des températures, tu actives ce script toutes les secondes, alors que les températures changent en gros toutes les 20 à 30 minutes. (mes fgk sont réglés tous les 0.5°) Je pense également au tuto de sebcbien sur les dead nodes. Je n'ai pas fait le test, mais il semble qu'il est possible de faire un script avec sous %% properties des choses comme. 35 dead 42 dead 69 dead etc .... Et de faire une scène qui ne s'actionnera que s'il y a un dead node. Ces considérations me sont venues en lisant vos posts sur la température de vos HC2. Je me demande s'il n'y a pas trop de boucles qui tournent pour rien, ou pas grand chose, et surchauffent le CPU. PS: En me relisant, j'ai peur de passer pour un donneur de leçons, ce n'est certainement pas le cas, mais juste des pistes de réflexions.
  19. Après discussion avec Andrew, il m'a donnée une fonction très intéressante pour empêcher une fonction de faire planter un script. Celui-ci m'a été surtout donnée pour le main loop d'un virtual device, pour éviter que le main loop ne plante et ne redémarre pas. local ok = pcall(function() -- -- place here the code that can raise an error -- -- wrong json string test = json.decode('{"a:2}') fibaro:debug(test.a) end) if (not ok) then fibaro:debug('decode raised an error') end Remplacer la partie après function() avec la partie de votre code complète qui exécutera une commande ou il peut y avoir une erreur comme Net.FHttp. Par exemple pour récupérer un json, le parser et faire ce que vous voulez avec le informations récupérés. Pour info après quelque recherche, la fonction pcall retourne une valeur TRUE ou FALSE pour ceux que sa intérresse.
  20. Steven

    Pushbullet

    --------------------------------- PUSHBULLET API --------------------------------- Bonjour, Si comme moi, vous appréciez le service de notification "Pushbullet" et que vous souhaitez l'utiliser depuis votre HC2, voici un script qui vous permettre 2 ou 3 petites choses : Consulter la liste de vos appareils connectés au service Pushbullet Envoyer un message sur tous vos appareils connectés Envoyer un message sur un appareil précis. Avantage de ce script : Pas besoin de service intermédiaire comme pushingbox Plus besoin d'utiliser les notifications aléatoires et capricieuses de Fibaro Pré-requis : Un compte chez Pushbullet L'application Pushbullet installée sur vos appareils (https://www.pushbullet.com/apps) Obtenir un "Token" ... Connectez-vous sur le site Pushbullet -> My Account (en cliquant sur votre avatar) -> Create Access Token Voici le script local pushbullet = { token = "o.Ax6xXFI5Qa8YZX1BFoWzozmVL5plEwGd", titreDesMessage = "Fibaro", debug = false, -- ============================================== -- Affichage dans la console -- Paramètres : -- message : le message a afficher -- force : affiche le message même si debug est à false -- ============================================== log = function(self, message, force) force = force or false if (self.debug or force) then print(__convertToString(message)) end end, -- ============================================== -- Affichage les devices reconnus et actifs -- Paramètres : -- data : tableau des devices -- ============================================== displayDevices = function(self, data) self:log("----------========== D e v i c e s =========----------", true) for k,v in ipairs(data.devices) do if (v.model) then self:log(v.model .. " --- " .. v.iden, true) end end end, -- ============================================== -- Interrogation des devices -- Paramètres : -- func : une fonction a rappeler après traitement ou nil -- ============================================== getDevices = function(self, func) local http = net.HTTPClient() http:request("https://api.pushbullet.com/v2/devices", { options = { method = 'GET', headers = { ["Access-Token"] = self.token, ["Content-Type"] = "application/json" }, data = "" }, success = function(response) if (func) then func(json.decode(response.data)) else self:displayDevices(json.decode(response.data)) end end, error = function(response) self:log(" ERROR !!! " .. url, true) end, }) end, -- ============================================== -- Envoi un message -- Paramètres : -- message : le message à envoyer -- id : l'identifiant du device OU nil -- ============================================== sendPush = function(self, message, id) local http = net.HTTPClient() http:request("https://api.pushbullet.com/v2/pushes", { options = { method = 'POST', headers = { ["Access-Token"] = self.token, ["Content-Type"] = "application/json" }, data = json.encode({ ["body"]=message, ["title"]= self.titreDesMessage, ["type"]="note" }), device_iden = id, }, success = function(response) local data = json.decode(response.data) self:log("----------========== P u s h e s =========----------") self:log("Identifiant du message : " .. data.iden) end, error = function(response) self:log(" ERROR !!! " .. url, true) end, }) end, -- ============================================== -- Envoi d'un message push -- Paramètres : -- message : le message à envoyer -- device : le nom du device concerné ou nil -- ============================================== send = function(self, message, device) if (device) then self:getDevices(function(data) local found for k,v in ipairs(data.devices) do if (v.model == device or v.iden == device) then found = true self:sendPush(message, v.iden) end end if (not found) then self:log(device .. " non trouvé", true) end end) else self:sendPush(message, nil) end end } Quand je lance directement la scène, elle va m'afficher la liste des appareils connectés. Par contre quand je met à jour la variable globale "Pushbullet", elle va m'envoyé un push contenant le message de la variable globale directement sur mon téléphone "HTC One_M8 dual sim". Voici donc une manière simple de recevoir des pushs fonctionnel depuis sa HC2. Pushbullet permet aussi l'envoi de lien http, d'image, ... ce script est donc modifiable à votre convenance.
  21. Berale64

    Température Min / Max

    Bon, ça casse pas une patte à un canard, mais pour apprendre LUA mieux vaut commencer simple. L'objet de cette petite chose est d'avoir un visu des températures min/max. Quand vous achetez un thermomètre à deux balles il a des options de mini/maxi, mais pas chez Fibaro. Il y a donc une scène qui tourne en continue et retient les min et max. L'affichage ce fait dans un device virtuel. Le bouton reset tue la scène et la redémarre. Il vous faudra changer les "id" de vos thermomètres et du virtual device. Rien ne vous empêche de rajouter les thermomètres de la chambre du petit dernier, du cellier de vos bonnes bouteilles (moi, c'est Saint Emilion - Merci ). Au printemps je mettrais la piscine. --[[ %% autostart %% properties %% globals --]] local temp; local TempExtMin = 100; local TempExtMax = -100; local TempSalonMin = 100; local TempSalonMax = -100; local temin = ""; local temax = ""; local tsmin = ""; local tsmax = ""; local id = {}; id.tempext = 35; id.tempint = 42; id.display = 74; while true do -- Température extérieur temp = fibaro:getValue(id.tempext,"value"); if (tonumber(temp) < TempExtMin) then TempExtMin = tonumber(temp); temin = string.format("%2.1f",TempExtMin); end if (tonumber(temp) > TempExtMax) then TempExtMax = tonumber(temp); temax = string.format("%2.1f",TempExtMax); end fibaro:call(id.display, "setProperty", "ui.Label1.value", temin.." / "..temax.." °C"); fibaro:call(id.display, "setProperty", "ui.Label7.value", temp.." °C"); -- temérature intérieur temp = fibaro:getValue(id.tempint,"value"); if (tonumber(temp) < TempSalonMin) then TempSalonMin = tonumber(temp); tsmin = string.format("%2.1f",TempSalonMin); end if (tonumber(temp) > TempSalonMax) then TempSalonMax = tonumber(temp); tsmax = string.format("%2.1f",TempSalonMax); end fibaro:call(id.display, "setProperty", "ui.Label11.value", tsmin.." / "..tsmax.." °C"); fibaro:call(id.display, "setProperty", "ui.Label13.value", temp.."°C"); fibaro:sleep(3*60*1000); end Temp_minmax.vfib PS: Cet outil est vraiment très pratique sur smartphone.
  22. Edit : ce VD fait double emploi avec celui de Krikroff : Waze Calculator Je n'ai malheureusement pas le temps de faire un joli tuto, mais voici le gros du sujet : Connaitre le temps estimé de trajet entre votre domicile et votre travail. L'idée étant d'être averti en cas perturbation. Ce code s'appuie sur les services Google Maps. Voici donc le VD et l'icone en pièces jointes Ensuite il vous faut obtenir une clé API chez google ... voici le lien : https://developers.google.com/maps/documentation/geocoding/get-api-key Une fois la clé obtenue, il ne vous reste plus qu'à créer un scène LUA et y coller et adapter le code suivant. -- Votre clé API Google local key = "AIxxYYYzz-8sdI9BY2hEbrEO34IiNaQfELETtls" -- Votre adresse à la maison local origins = "18+rue+des+bois+Annecy+France" -- Votre adresse professionnel local destinations = "7+rue+de+la+fontaine+Geneva+Switzerland" -- Numéro du module virtuel précédemment crée/importé. local hc2_module_virtuel = 475 -- ------------------------------------------------------------------------ -- NE PAS TOUCHER -- ------------------------------------------------------------------------ local duree = "" local version = "V1.00" -- ------------------------------------------------------------------------ -- Affichage dans la console -- ------------------------------------------------------------------------ function log(message, force) force = force or false if (debug or force) then print("["..version.."] ".. __convertToString(message)) end end -- ------------------------------------------------------------------------ -- Interrogation de l'API -- ------------------------------------------------------------------------ function getResponseData(url, body, func) local httpClient = net.HTTPClient(); httpClient:request(url.."?"..body, { success = function(resp) func(json.decode(resp.data)) end, error = function(err) print('error = ' .. err) end, options = { method = 'GET' } }); end -- ------------------------------------------------------------------------ -- Mesures de l'unité interne -- ------------------------------------------------------------------------ -- ------------------------------------------------------------------------ -- Mesures de l'unité interne -- ------------------------------------------------------------------------ function getDuree(origine, destination, message, label) getResponseData("https://maps.googleapis.com/maps/api/distancematrix/json", "origins="..origine.."&destinations="..destination.."&language=fr-FR&key="..key, function(data) log("----------========== Module intérieur ==========----------") duree = data.rows[1].elements[1].duration.value log(message .. duree, true) fibaro:call(hc2_module_virtuel, "setProperty", label, math.floor(duree/60)) end ) end getDuree(origins, destinations, "Durée travail = ", "ui.Label1.value") getDuree(destinations, origins, "Durée maison = ", "ui.Label2.value") log("Last request : " .. os.date("%x - %X"), true) . Perso, j'utilise GEA pour executé cette scène toutes les 5 mn. . A vous de jouer et d'adapter tout cela à votre convenance. Durée_Trajets_(mn).vfib
  23. VD - Visualisation IOSDevice Smartphone, IPhone etc... Voici un VD qui va permettre a ceux qui cherche toujours comment trouver l'ID de leurs Téléphone ou Tablette de résoudre le probléme. Nouvelle version : Ajout d'un bouton Push pour test . Icones de megabubu Fichier à Telecharger : IOS_Info_v1.00.vfib
  24. Comment piloter IMPERIHOME depuis sa HC2 et pourquoi ? Imperihome fournit, depuis le 26 janvier 2014, une api qui permet : De faire du TTS (faire parler votre tablette/smartphone) De faire de la reconnaissance vocale (utile que sur certain périphérique) De changer les pages Pourquoi faire : Personnellement, le matin il m’intéresse de connaitre la température extérieur, m'assurez que les enfants ont bien éteint leur lampe, ouvrir le porte du garage, voir s'il pleut, .. Alors que le soir, cela ne m’intéresse plus du tout. Ce que je veux, le soir, c'est allumer la TV, tamiser les lumières, ... J'ai donc créer mes "pages" Imperihome selon mes besoin dans la journée (une page : Matin, une page : Soir, ...) et par rapport à l'heure, ma HC2 change de page automatiquement Sur détection de mouvement dans le jardin, Imperihome affiche automatiquement la page avec la vue de la caméra du jardin. ... A vous de faire fonctionner votre imagination que je sais très fertile. Comment : Simplement en important ce module virtuel et en remplaçant l'adresse IP et le port par celui de votre tablette/smartphone hébergeant Imperihome (je vous conseil d'indiquer une IP fixe). Si vous nécessitez de plus de page, il vous suffit de copier un bouton et de simplement indiquer l'indice de la page souhaitée (la numérotation commence à 0. Le pageIdx 4 affiche donc la page 5, pageIdx 0 affiche la page 1, .... status, response = HC2:GET("/api/rest/dashboard/gotopage?pageIdx=4") IMPORTANT : Par défaut, les API d'Imperihome sont désactivé. Vous devez allez les activer dans les "Préférences générales" d'Imperihome et "Activé le serveur HTTP API" (tout à la fin). Notez par la même occasion le port "8080" par défaut. Have fun Spéciale dédicace à @Moicphil et @Yohan : "aucun support pour vous 2 ... vous êtes trop méchant" Cliquer sur l'icone avant de la sauver sur votre poste sinon, elle n'aura pas la bonne taille et ne fonctionnera pas. Imperihome.vfib
  25. Bonjour, Vous êtes nombreux a me demander la suite des Leçons LUA pour HC2, ben….. voilà la suite Aujourd’hui je vais vous parler de l’API Net.Fhttp Cette API nous permet d’envoyer des commandes via HTTP vers notre HC2 ou d’autre appareils. Je vais vous expliquer comment cloner la télécommande de la Freebox V6 et commander la télé via HC2.Free a mis a notre disposition des divers API, on va s’intéresser particulièrement a une pour l’intégrer dans notre HC2Essayer de taper dans votre navigateur web la ligne suivante: http://hd1.freebox.f...e_control?code= &key=power Le [code TELECOMMANDE] se trouve dans le menu Réglages/Télécommande de votre FreeBoxComme vous pouvez voir cette commande éteint/ allume votre FreeBox.Donc maintenant il nous reste juste de créer une télécommande virtuel dans notre HC2.Pour cela nous allons utiliser un Module Virtuel et une variable global.Etape 1Créer une nouvelle variable et attribuez lui la valeur de votre [code TELECOMMANDE]Nommez la « CodeTeleFree »Etape 2Créer un nouveau module virtuel et nommez le « Télécommande« .Ajouter exactement le même nombre de boutons que sur votre Télécommande original. Etape 3Passons a un peu de code maintenant:Dans chaque bouton il faut saisir le code correspondant aux API Free.Pour cela il faut traduire notre ligne « http://hd1.freebox.f...e_control?code=[code TELECOMMANDE]&key=power » en code LUA -- on déclare une variable local CodeTeleFree et on lui attribue -- le code de notre télécommande stocké précédemment dans la variable HC2 local CodeTeleFree = fibaro:getGlobal("CodeTeleFree"); -- on crée une instance HC2 et on lui attribue l adresse de notre FreeBox HC2 = Net.FHttp("hd1.freebox.fr"); -- on attribue la suite de notre adresse avec le code télécommande response = HC2:GET("/pub/remote_control?code=" ..CodeTeleFree.. "&key=power") Copiez ce code dans chaque touche en remplacent « power » par le code touche correspondant. Voilà le code de chaque touche de la V6:power : la touche rouge on/off0 à 9 : les touches 0 à 9vol_inc : augmente le volumevol_dec : diminue le volumeprgm_inc : incrémente de 1 le programmeprgm_dec : décrémente de 1 le programmeok : touche OKup, right, down, left : les touches directionnelles (haut, droite, bas, gauche)mute : la touche de mise en sourdinehome : la touche freerec : la touche d’enregistrementbwd : la touche de retour en arrière (<<)prev : la touche « précédent » (|<<)play : la touche lecture/pause fwd : la touche d’avance rapide (>>) next : la touche « suivant » (>>|) red : le bouton rouge green : le bouton vert yellow : le bouton jaune blue : le bouton bleu Pour ceux qui ne veulent pas tous faire soit même voilà le lien pour télécharger le module virtuel: http://domotique-hom...lécommande.vfib
×