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. Zorgonaute84

    Particle Photon Et Hc2

    Pour ceux qui ne connaissent pas le Particle Photon, il s'agit d'une petite carte électronique programmable avec une puce Wifi embarquée. La programmation de la puce se fait avec un IDE en ligne disponible sur le site de Particle et le language est très sensiblement le même que pour les cartes Arduino. L'avantage de cette puce, c'est d'une sa taille (De mémoire ils parlent de 6x plus petites qu'un Arduino), le wifi intégré, et le prix : 19USD hors frais de port et enfin (et surtout), le Particle Cloud ! Le Particle Cloud permet a votre puce d'être connecté, consultable et pilotable en tout instant via vos propres requêtes REST. En gros, avec cette puce vous êtes capable de fabriquer n'importe quoi pour votre système domotique et de l'intégrer totalement avec votre HC2. Le tuto qui va suivre portera de manière générique sur la communication bi directionnel entre le Photon et votre HC2. Je publierai plus tard et dans un autre sujet, le code source d'un module permettant d'activer et désactiver l'alarme d'une HC2 avec confirmation d'activation et retour d’échec (avec informations des portes restées ouvertes qui ont causées l’échec). Ce Alarme Button comme je l'ai appelé est basé sur le hardware de l'Internet Button vendu sur le site de Particle (il s'agit d'une puce Photon pluggé sur une carte avec 4 boutons, un accéléromètre et 11 LED RGB disposées en cercle. (Voir Internet Button). Communication du HC2 --> Particle Photon : a/ Exécuter quelque chose sur le Particle Photon : Tout d'abord, il faut déclarer dans le code de votre Photon votre fonction publique (a l'intérieur de votre boucle void setup ) : void setup() { Spark.function("NomDeLaFonctionCLOUD", NomDeLaFonctionLOCAL); } NomDeLaFonctionCLOUD sera le nom appelé depuis la HC2 (ATTENTION contrairement a mon exemple le nom ici ne doit pas dépasser les 12 caractères) NomDeLaFonctionLOCAL sera le nom de votre fonction exécutée dans le code de votre Photon : int NomDeLaFonctionLOCAL() { // Les trucs a exécuter } Et voila, c'est fini du côté de votre Photon. Maintenant, sur votre HC2. A noter que la connexion avec le Photon se fait en https et non http. Ce qui veut dire que la fonction netFhttp n'est pas possible ! Il faut donc utiliser la commande Net.HttpClient qui fonctionne uniquement dans une scène ! Donc exit le code dans un virtual device. A vous de voir comment vous voulez vous y prendre, mais pour ma part, j'ai créer une scène dédiée a la communication avec le Photon. Mes virtuals device ne font que passer 2 arguments dans une variable global, arguments repris par la scène de communication avec le Photon. Donc pour comprendre le schéma, l'appui sur un bouton de mon virtual device, modifie une variable pour contenir le nom de la fonction a exécuter, puis une seconde variable avec un éventuel paramètre. Puis ma scène se déclenche automatiquement, récupère ces deux valeurs pour communiquer avec le photon et réinitialise les variables pour la prochaine utilisation. D'un point de vue authentification sur le Cloud, il vous faut récupérer le N° unique de votre device Photon et le Token d'authentification. Voici donc le code de ma scène pour gérer l’exécution d'une scene. (Les deux variables globales que j'ai créé auparavant sont donc : IntBut_Function et IntBut_Argument) : local Device ='xxxxxxxxxxx' local Token ='xxxxxxxxx' local FunctionRequested = fibaro:getGlobalValue("IntBut_Function") local ArgumentSent = fibaro:getGlobalValue("IntBut_Argument") ------------------ FONCTION SPARK ------------------ function SparkFunction(Name,Argument) local Path = 'https://api.particle.io/v1/devices/'..Device..'/'..Name..'?access_token='..Token local Spark = net.HTTPClient(); Spark:request(Path, { options = { method = 'POST', headers = {["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"} , data = 'arg='..Argument } , success = function(response) if tonumber(response.status) == 200 then print('Function "'..Name..'" ('..Argument..') sent with success'); SparkTable = json.decode(response.data) else print('Function "'..Name..'" ('..Argument..') Error Status : '..response.status); end end , error = function(err) print('Connection error = ' .. err) end }); end ------------------ FIN DE FONCTION SPARK ------------------ Cette fonction est donc générique pour tous les appels de fonctions. J'ajoute alors a cette scène a la suite, un bout de code comme celui-ci pour chaque fonction : if FunctionRequested == "NomDeLaFonctionCLOUD" -- Ici il s'agit du nom de la fonction Cloud déclaré précedement dans le code de notre Photon then SparkFunction(FunctionRequested, ArgumentSent) end PS : J'aurais pu exécuter le code de la fonction en direct sans passer par ce bout de code, mais j'ai fais ce choix afin de pouvoir également exécuter d'autres actions que celle de communiquer avec le Photon. Et enfin pour lancer tout le processus depuis un virtual device ou depuis une scène, il suffit d'intégrer ces deux lignes de codes dans un bouton ou ailleurs : fibaro:setGlobal("IntBut_Argument",ArgumentATransmetre) fibaro:setGlobal("IntBut_Function",NomDeLaFonctionCLOUD) b/ Récupérer la valeur d'une variable contenue dans le Photon : Cette fois nous souhaitons récupérer la valeur d'une variable. On déclare une variable public dans le code source du Photon : //Particle.variable("LaVariableCLOUD", &LaVariableLOCAL, STRING); Puis dans la HC2, l'approche est exactement la même, mais il faudra tout d'abord créer une autre variable global pour stocker temporairement le nom de la variable demandé et une autre pour stocker le résultat (ex : IntBut_Variable et MaVariableDeResultat). Et voici la fonction a intégrer dans la scène gérant la communication avec le Photon : local VariableRequested = fibaro:getGlobalValue("IntBut_Variable") --------------------- VARIABLE SPARK ---------------------- function SparkVariable(Name) local Path = 'https://api.particle.io/v1/devices/'..Device..'/'..Name..'?access_token='..Token local Spark = net.HTTPClient(); local Result Spark:request(Path, { options = { method = 'GET', headers = {["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"} , } , success = function(response) if tonumber(response.status) == 200 then print('Variable "'..Name..'" requested with success'); SparkTable = json.decode(response.data) Result = SparkTable.result fibaro:setGlobal("MaVariableDeResultat",Result) else print('Function "'..Name..' Error Status : '..response.status); end end , error = function(err) print('Connection error = ' .. err) end }); end ------------------ FIN DE VARIABLE SPARK ------------------ Puis le bloc d'appel a ajouter a la suite : if VariableRequested == "LaVariableCLOUD" -- Ici il s'agit du nom de la variable Cloud déclaré précedement dans le code de notre Photon then SparkFunction(VariableRequested) end et enfin le code a intégrer a un boutton pour autre pour appeler tout le bazard : fibaro:setGlobal("IntBut_Variable","LaVariableCLOUD") Communication du Particle Photon --> HC2 : Cette fois ce sera beaucoup plus simple. A noter qu'il est possible de modifier la valeur d'une variable via un requete REST mais que cette modification ne déclenche pas une éventuelle scène associée. Je vais alors vous montrer ce qui me semble être la requête la plus utile, a savoir une requête demandant l'appuie sur le bouton d'un Virtual Device : Ici tout ce passe dans le code source du Photon : Comme vous pouvez le voir, il faut renseigner l'adresse IP de la box, votre admin:password en base 64, l'ID du device a actionner et le N° du boutton. Dans mon exemple ci-dessous le Photon demande l'appui sur le bouton 1 du device 50 dès sont initialisation : String server = "AdresseIPdelaHC2"; // Adresse IP de la box Fibaro String FibaroLogin = "xxxxxxxxxxx"; // admin:password en base 64 int FibaroDeviceID = 50; // N°ID du device Fibaro a piloter int NduBoutton = 1; // N° du bouton a actionner void setup() { FibaroCommunication("{\"args\":[" + String(NduBoutton) + "]}"); } void loop() { } /////////// FONCTION PRIVE DE COMMUNICATION AVEC LA FIBARO /////////// bool FibaroCommunication(String PostData) { if (Fibaro.connect(server,80)) { Serial.println("Connection Success"); Fibaro.print("POST /api/devices/"); Fibaro.print(NduBoutton); Fibaro.print("/action/pressButton"); Fibaro.println(" HTTP/1.1"); Fibaro.print("Host: "); Fibaro.println(server); Fibaro.print("Authorization: Basic "); Fibaro.println(FibaroLogin); Fibaro.print("Content-Length: "); Fibaro.println(PostData.length()); Fibaro.println(); Fibaro.println(PostData); return true; } else { Serial.println("Connection Failed."); return false; } } Bon voila, c'est terminé ! En espérant avoir été assez clair ! Vous verrez on peut faire de vrai merveilles avec ce Photon couplé a notre HC2.
  2. OJC

    Heating Manager

    HEATING MANAGER v. 3.1.2 - 16/12//2017 Heating Manager est un programme permettant d'utiliser le Home Center 2 pour gérer avec une grande souplesse le chauffage d'une habitation, en permettant de franchir une étape supplémentaires dans la gestion de celui-ci. En effet, s'il est parfaitement capable de fonctionner en suivant une planification, Heating Manager permet de passer à l'étape suivante et d'exploiter pleinement les potentialités de la domotique en se passant totalement de planification et en gérant le chauffage sur une base événementielle exclusivement dynamique. Heating Manager, qui propose de réguler le chauffage sur un mode proportionnel avec prise en compte des déperditions (Ubat) ou sur un mode classique avec hystérésis, est compatible avec n'importe quel système de commande de chauffage, y compris des modules virtuels. Il peut fonctionner en tout ou partie en mode planification via l'utilisation des panneaux de chauffage natifs du Home Center 2, de modules dédiés ou de variables globales. En mode événementiel, il peut s'appuyer sur n'importe quelle propriété de n'importe quel module, virtuel ou non, ainsi que sur des variables globales. L'utilisation de boucles conditionnelles dans la configuration permet en outre de faire varier cette configuration en fonction de n'importe quelle condition. Ces développements doivent beaucoup aux échanges stimulants intervenus sur ce fil de discussion, qui m'ont amené à aller bien plus loin que ce qui était prévu au départ, à savoir simplement pouvoir utiliser les panneaux de chauffage avec les modules fils pilote proposés par Qubino... Que tous soient remerciés , ainsi que ceux qui relèvent des bugs et permettent d'améliorer le script. _ _ _ PRE-REQUIS Ce programme a été conçu et testé sur le Home Center 2 tournant avec le firmware v. 4.140. Il ne requiert aucun matériel particulier et peut s'adapter facilement à toutes les configurations. _ _ _ INSTALLATION 1. Pour une utilisation en tout ou partie en mode planification, il faut commencer par définir les plannings de chauffe souhaités. La première étape dans cette optique de fonctionnement est de définir un planning de chauffe dans lequel Heating Manager ira chercher la température de consigne à atteindre. Ce planning de chauffe peut être mis en place en utilisant les panneaux de chauffage fournis nativement par le Home Center 2. Attention cependant, un bug a été constaté, évoqué dans ce fil, entraînant l'absence de prise en compte du changement de température de consigne après minuit. Il peut également être mis en place en utilisant n'importe quel module virtuel ou bien celui, basique, fourni avec Heating Manager >>>> Heating_Provider.vfib Pour utiliser ce module virtuel, il faut adapter la configuration donnée en exemple à votre cas en modifiant, et en ajoutant le cas échéant, les étiquettes, chaque étiquette correspondant à une zone de chauffage. La définition du planning de chauffe pour chacun de ces zones intervient dans le main loop du module virtuel, dans la partie Configuration : HeatingManager:add(zone, day, time, temperature) zone correspond au nom d''une étiquette du module virtuel day est soit un ou plusieurs jours de la semaine (en anglais e.g. {"monday","friday"}), soit "weekday" (du lundi au vendredi), soit "weekend", soit "week" time est l''heure à laquelle la température de consigne devra être appliquée "hh:mm" temperature est la température de consigne devant être appliquée à compter de l''horaire défini juste avant Il est important que la construction du planning de chauffe soit faite de manière chronologique, le module virtuel ne faisant pas de tri chronologique, ce qui peut entraîner un comportement s'écartant de celui attendu. 2. Pour une utilisation en tout ou partie en mode événementiel, il faut importer un thermostat par pièce concernée >>>> Thermostat.vfib Ce module virtuel permet de définir la température de consigne (mode Confort et mode Economique) pour la pièce, de forcer l'un de ces deux modes ou de passer en mode manuel avec un minuteur permettant de retourner au mode automatique. Les ordres donnés par l'intermédiaire de ce module viruel l'emportent sur toute autre évènement défini dans la configuration de Heating Manager. Il faut juste mettre un module virtuel dans chaque pièce. Sa détection par Heating Manager se fait automatiquement. 3. [OPTIONNEL] Pour afficher de manière centralisée les températures de consigne en cours, il faut installer le module virtuel Heating Viewer >>>> Heating_Viewer.vfib Pour le bon fonctionnement de ce module, chaque pièce dont le chauffage est géré par Heating Manager doit avoir une étiquette, dont l'ID doit être le nom de cette pièce débarrassé de tous les accents, espaces et autres caractères exotiques. Ainsi, pour la pièce "Séjour Principal #1", l'ID de l'étiquette doit être "SejourPrincipal1". Les étiquettes inutilisées peuvent être supprimées, tout comme il peut être ajouté autant d'étiquettes que nécessaire. 4. Création d'une scène en mode Lua avec copier-coller du code >>>> Heating Manager - Scène.lua La configuration de Heating Manager est réalisée par l'exécution de neuf fonctions différentes à paramétrer dans la partie USER CONFIGURATION ZONE qui se trouve à partir de la ligne 100 du code. self:setConfiguration(checkConfig, oldLastTempUpdate, logInfo, pushWarnErrLog, pushTo, popupWarnErrLog, logMemory) checkConfig est un booléen dont la valeur par défaut est true, qui permet de définir si Heating Manager doit contrôler de manière approfondie la configuration (existence des pièces, des modules, des propriétés de modules, des variables globales, etc.) Une fois que votre configuration est rodée et fonctionne sans problème, vous pouvez passer ce paramètre à false. oldLastTempUpdate est un nombre dont la valeur par défaut est 180 et qui est le nombre de minutes depuis la dernière remontée de température d'une sonde intérieure au-delà duquel Heating Manager adressera un message d'alerte et arrêtera la chauffe. logInfo est un booléen dont la valeur par défaut est true et qui permet de définir si l'intégralité des messages doit s'afficher dans la fenêtre de debug, ou uniquement les plus importants (action, survenance d'un événement, changement de la température de consigne). pushWarnErrLog est un booléen dont la valeur par défaut est false et qui permet de définir si les messages d'alerte et d'erreur doivent faire l'objet d'une notification Push. pushTo est une table contenant l'ID des téléphones mobiles auxquels envoyer les notification Push si le paramètre précédent est à true. popupWarnErrLog est un booléen dont la valeur par défaut est false et qui permet de définir si les messages d'alerte et d'erreur doivent faire l'objet d'une notification dans le centre de notification du Home Center 2. logMemory est un booléen dont la valeur par défaut est true et qui permet d'afficher dans la fenêtre de debug, toutes les cinq minutes, la mémoire utilisée par Heating Manager. self:setProportionalMode(default_kP, auto_kP, default_kT, cycle, minCycle, defaultSetpoint) Cette fonction ne doit être utilisée que si vous souhaitez utiliser le mode de régulation proportionnel. default_kP est un nombre dont la valeur par défaut est 60 et qui est le coefficient proportionnel utilisé par Heating Manager dans le cadre de la régulation proportionnelle si aucun coefficient particulier n'est défini pour un radiateur donné. auto_kP est un booléen dont la valeur par défaut est true et qui permet de définir si Heating Manager doit adapter le coefficient proportionnel en fonction de l'expérience acquise lors des cycles de chauffe. default_kT est un nombre dont la valeur par défaut est 1 et qui est le coefficient de déperditions thermiques (Ubat) utilisé par Heating Manager dans le cadre de la régulation proportionnelle si aucun coefficient particulier n'est défini pour un radiateur donné. La valeur 1 correspond à une maison bien isolée. Pour un bâtiment mal isolé, ce coefficient peut être fixé à 3. cycle est un nombre dont la valeur par défaut est 15 et qui est la durée d'un cycle de chauffage en minutes, au sein duquel s'insère la période de chauffe calculée par Heating Manager. minCycle est un nombre dont la valeur par défaut est 1 et qui est la durée minimale en minutes d'une période de chauffe. defaultSetpoint est soit comfort, soit eco (sans guillemets) et permet de déterminer, uniquement pour un fonctionnement en mode événementiel, si la consigne à appliquer en dehors de tout événement est la température de confort définie dans le thermostat virtuel ou la température économique. La valeur par défaut est comfort. self:setHysteresisMode(hysteresis, cycle, defaultSetpoint) Cette fonction ne doit être utilisée que si vous souhaitez utiliser le mode de régulation par hystérésis. hysteresis est un nombre dont la valeur par défaut est 0 et qui est l'écart en degré entre la température courante et la température de consigne au-delà ou en-deça duquel le chauffage sera démarré. cycle est un nombre dont la valeur par défaut est 15 et qui est l'intervalle en minutes entre deux comparaisons de la température courante et de la température de consigne. defaultSetpoint est soit comfort, soit eco (sans guillemets) et permet de déterminer, uniquement pour un fonctionnement en mode événementiel, si la consigne à appliquer en dehors de tout événement est la température de confort définie dans le thermostat virtuel ou la température économique. La valeur par défaut est comfort. self:setEventDefaults(eCumulative, eSetpoint, eDuration, eStep, ePersistence) eCumulative est un booléen dont la valeur par défaut est true et qui permet de définir si les conditions d'un événement doivent toutes être réalisés pour que l'événement soit considéré comme survenu, ou si la réalisation d'une seule condition est suffisante. Il s'agit ici de définir la valeur par défaut qui sera utilisée à défaut de paramétrage contraire lors du paramétrage de chaque événement. eSetpoint est un nombre dont la valeur par défaut est 18 et qui permet de définir la température de consigne qui sera appliquée par défaut en cas de survenance d'un événement lorsqu'aucune température de consigne propre n'est définie lors du paramétrage de l'événement. eDuration est un nombre dont la valeur par défaut est 0 et qui permet de définir la durée en minutes devant s'écouler entre la survenance de l'événement et l'application de la température de consigne correspondante, permettant ainsi de prévoir une diminution ou une augmentation graduelle de la température de consigne. eStep est un nombre dont la valeur par défaut est 0.5 et qui permet de définir les étapes de diminution ou d'augmentation graduelle de la température de consigne. ePersistence est un nombre dont la valeur par défaut est 0 et qui permet de définir la durée par défaut pendant laquelle Heating Manager continuera à considérer qu'un événement est réalisé à partir de l'instant où les conditions de sa réalisation ne sont plus remplies. Si les conditions sont à nouveau remplies pendant le délai de persistence, Heating Manager agira comme si elles n'avaient jamais cessé d'être remplies. self:addHeater(idRoom, idHeater, idSonde, localkP, localkT) Cette fonction permet de déclarer les radiateurs qui seront gérés par Heating Manager. La fonction doit être paramétrée pour chaque radiateur. idRoom est l'ID de la pièce définie dans le Home Center 2 dans laquelle se trouve le module de commande du radiateur. idHeater désigne un module de commande d'un radiateur sous forme de table {ID du module, instruction pour mise en route, instruction pour arrêt, valeur à l'arrêt} : ID du module est l'ID d'un module, virtuel ou non, permettant de commander la mise en route ou l'arrêt du chauffage. instruction pour mise en route est soit la commande à transmettre s'il s'agit d'un module 'réel' ("turnOn" par exemple), soit le numéro d'ordre du bouton d'un module virtuel. instruction pour arrêt est soit la commande à transmettre s'il s'agit d'un module 'réel' ("turnOff" par exemple), soit le numéro d'ordre du bouton d'un module virtuel. valeur à l'arrêt est la valeur de la propriété value lorsque le radiateur est arrêté, et est utilisé pour éviter d'envoyer les commandes de mise en route et d'arrêt inutilement. idSonde désigne une sonde de température qui peut être définie spécifiquement pour un radiateur s'il n'est pas asservi à la sonde de température principale de la pièce définie dans le Home Center 2. Il peut s'agir d'une sonde de température proprement dite ou d'un module virtuel et sera dans tous les cas sous la forme {ID du module, nom de la propriété contenant la température}. Il peut également s'agir du nom d'une variable globale dans laquelle est stockée la température. localkP permet de définir un coefficient proportionnel fixe qui sera utilisé pour calculer la commande de chauffe de ce radiateur. localkT permet de définir un coefficient de déperditions thermiques qui sera utilisé pour calculer la commande de chauffe de ce radiateur. self:addEvent(idRoom, idEvent, conditions, cumulative, setpoint, duration, persistence) Cette fonction permet de définir les événements qui entraîneront une modification de la température de consigne (ouverture d'une fenêtre, absence temporaire ou prolongée, lumière allumée ou éteinte...). idRoom est l'ID de la pièce concernée par l'événement, ou une table contenant les IDs de plusieurs pièces concernées par l'événement. idEvent est le nom de l'événement, qui sera affiché dans la fenêtre de debug lors de sa survenance. conditions est une table contenant les différentes conditions devant être réalisées, ensemble ou séparément, pour que l'événement soit considéré comme survenu et la température de consigne modifiée en conséquence. Cette table contient elle-même une table par condition (il y a donc forcément une double accolade au début et à la fin), sous la forme {nom de variable globale, opérateur ("==", "~=", ">=", "<=", ">", "<"), valeur à vérifier, durée en minutes devant s'être écoulée depuis que le résultat de la comparaison est vrai} ou {ID d'un module, nom de la propriété d'un module, opérateur ("==", "~=", ">=", "<=", ">", "<"), valeur à vérifier, durée en minutes devant s'être écoulée depuis que le résultat de la comparaison est vrai}. cumulative est un booléen permet de définir, pour cet événement particulier, si sa survenance implique la réalisation de toutes les conditions ou si une seule est suffisante. setpoint permet de définir la température de consigne devant être appliquée lorsque l'événement survient. Dans le cadre du mode de fonctionnement événementiel, vous pouvez utiliser les variables comfort et eco qui font références aux températures définies pour la pièce avec le module virtuel Thermostat. duration est la durée en minutes devant s'écouler entre la survenance de l'événement et l'application de la température de consigne correspondante, permettant ainsi de prévoir une diminution ou une augmentation graduelle de la température de consigne. persistence est un nombre qui permet de définir la durée pendant laquelle Heating Manager continuera à considérer que l'événement est réalisé à partir de l'instant où les conditions de sa réalisation ne sont plus remplies. Si les conditions sont à nouveau remplies pendant le délai de persistence, Heating Manager agira comme si elles n'avaient jamais cessé d'être remplies. Dans le cadre de la configuration, cette fonction peut s'insérer dans une boucle conditionnelle permettant de ne laisser l'événement se réaliser que sous des conditions précises, par exemple d'horaires. self:addGlobalEvent(idEvent, conditions, cumulative, setpoint, duration, persistence) Cette fonction permet de définir un événement s'appliquant à toutes les pièces dont le chauffage est géré par Heating Manager, et se configure exactement de la même manière que la précédente, le paramètre idRoom en moins. Attention : le fait que l'événement soit global ne signifie pas qu'il l'emporte sur les événements spécifiques d'une pièce. Heating Manager contrôle les événements les uns à la suite des autres pour chaque pièce, dans l'ordre de leur configuration. Dès que les conditions d'un événement sont remplies, le programme cesse la boucle et n'analyse pas les autres événements déclarés. self:setIndoorSonde(idRoom, idSonde) Cette fonction permet de définir la sonde de température d'une pièce si vous ne souhaitez pas utiliser la sonde de température principale définie dans le Home Center 2. idRoom est l'ID de la pièce concernée. idSonde désigne une sonde de température proprement dite ou un module virtuel et sera dans tous les cas sous la forme {ID du module, nom de la propriété contenant la température}. Il peut également s'agir du nom d'une variable globale dans laquelle est stockée la température. self:setSetpoint(idRoom, idSetpoint) Cette fonction permet de définir, pour une pièce donnée, la source de la température de consigne qui devra être appliquée. L'utilisation de cette fonction n'est requise que dans le cas de l'utilisation du mode planification, et est inutile lorsque le chauffage de la pièce est effectué selon le mode événementiel. idRoom est l'ID de la pièce concernée. idSetpoint désigne la source de la température de consigne et peut être : l'ID d'un panneau de chauffage natif du Home Center 2. une table sous la forme {ID du module, propriété du module contenant la température de consigne} s'il s'agit d'un module, virtuel ou non. le nom d'une variable globale qui contiendra la température de consigne. self:setOutdoorSonde(idSonde) Cette fonction permet définir une sonde de température extérieure. Elle n'est utilise que dans le cas de la régulation proportionnelle qui tient compte de la température extérieure, et est inutile pour une régulation à base d'hystérésis. idSonde désigne une sonde de température proprement dite ou un module virtuel et sera dans tous les cas sous la forme {ID du module, nom de la propriété contenant la température}. Lorsqu'aucune sonde de température extérieure n'est définie et que le mode de régulation proportionnel est utilisé, Heating Manager utilise la température fournie par le plugin Météo. 5. Mise à jour depuis une version précédente Cette nouvelle version apporte des modifications en profondeur du programme et de la manière de le configurer. Il n'est donc pas possible de faire simplement un copier-coller de la configuration d'une version précédente à la 3.0, qui était éclatée entre la scène et un module virtuel, mais il est nécessaire de reprendre la configuration depuis le départ. Depuis la version 3.0, il est impératif de modifier les fonctions self:addEvent pour ajouter dans les conditions le paramètre operator : "==", "~=", ">=", "<=", ">" ou "<". Si le contrôle de configuration est activé, un message d'erreur s'affichera dans la fenêtre de debug sans faire planter le programme. L'ajout du paramètre ePersistence dans la fonction self:setConfiguration et persistent dans les fonctions self:addEvent n'est pas indispensable puisqu'il s'agit du dernier paramètre de ces fonctions. A défaut de les ajouter, c'est la valeur par défaut (0) qui s'appliquera. _ _ _ ROADMAP [VIDE] _ _ _ ICONES
  3. Voici une solution pour créer une variable globale en LUA il existe 8 types de base: nil, boolean, number, string, userdata, function, thread, et table Je remercie Gazous pour son aide Ce code va crée une variable globale Pascal -- Creation de Variable Pascal Merci Gazous json = '{"name":"Pascal", "isEnum":0}' HC2 = Net.FHttp("127.0.0.1", 11111) HC2:POST("/api/globalVariables", json) Voici une solution pour créer une variable globale prédéfinie ce code appartient entièrement a Gazous il va crée une variable prédéfinie Gazous qui aura comme valeur Gazous1 ou Gazous2 -- Creation de Variable Gazous json = '{"name":"Gazous", "isEnum":1}' HC2 = Net.FHttp("127.0.0.1", 11111) HC2:POST("/api/globalVariables", json) -- Ajout de 2 valeurs à la Variable Gazous et modification avec une des 2 valeurs json = '{"value":"Gazous1","isEnum":true,"enumValues":["Gazous1", "Gazous2"]}' HC2:PUT("/api/globalVariables/Gazous", json) ou comme cela avec des variables : local VG_Nom = "MPRInfo" local VG_Value = "MPRInfo1" local VG_enumValues = '["'..VG_Value..'", "MPRInfo2"]' --Creation de Variable Gazous json = '{"name":"'..VG_Nom..'", "isEnum":1}' fibaro:debug(json) HC2 = Net.FHttp("127.0.0.1", 11111) HC2:POST("/api/globalVariables", json) --Ajout de 2 valeurs à la Variable Gazous et modification avec une des 2 valeurs json = '{"value":"'..VG_Value..'","isEnum":true,"enumValues":'..VG_enumValues..'}' fibaro:debug(json) HC2:PUT("/api/globalVariables/"..VG_Nom, json) Il ne vous reste plus qu'a vérifier dans le panneau des variables globales. Je pense que je vais crée un Module Virtuel avec toutes mes variables comme cela lors d'un recovery je clic sur le bouton de VD et mes variables sont crées. Code réalisé par Gazous Je complète avec une petite fonction pratique pour créer une variable si elle n'existe pas La version pour un Virtual Device (avec Net.FHttp) function createGlobalIfNotExists(varName, defaultValue) if (fibaro:getGlobal(varName) == "") then fibaro:debug("Création de la variable "..varName.." avec comme valeur par défaut "..defaultValue) newVar = {} newVar.name = varName newVar.value = defaultValue HC2 = Net.FHttp("127.0.0.1", 11111) HC2:POST("/api/globalVariables", json.encode(newVar)) end end createGlobalIfNotExists("Gazous", "Oui c'est moi") La version pour une Scène (avec net.HTTPClient) function createGlobalIfNotExists(varName, defaultValue) if (fibaro:getGlobal(varName) == nil) then fibaro:debug("Création de la variable "..varName.." avec comme valeur par défaut "..defaultValue) newVar = {} newVar.name = varName newVar.value = defaultValue local http = net.HTTPClient() http:request("http://127.0.0.1:11111/api/globalVariables", { options = { method = 'POST', data = json.encode(newVar)}}) end end createGlobalIfNotExists("Gazous", "Oui c'est moi") La doc ce trouve ICI : http://xxx.xxx.xxx.xxx/docs/#!/globalVariables/getGVariables Il faut remplacer les xxx.xxx.xxx.xxx par l'adresse IP du Home Center 2 Un Petit Merci ou un Petit J'aime fais toujours plaisir..... Comme d’habitude voici un petit Bonus Cette Scéne permet d'envoyer une notification lorsqu'il y a un démarrage de la box Le message contient la date et l'heure de démarrage Il faut juste mettre l'ID du portable (Téléphone ou GSM pour nos amis Belge ) --[[ %% autostart --]] local IdTel = 181 local heure = os.date("%R"); local date = os.date("%d/%m/%Y"); local Message = "Votre Home center 2 à démarrée le " ..date .." à " ..heure fibaro:debug(Message) fibaro:call(IdTel, "sendPush", Message)
  4. Objectif : Crée des déclencheurs (trigger) toutes les 30mn sans avoir besoin de faire une boucle "while true do" afin de mettre a jours 2 variables globale qui nous servirons a déclencher des scènes. Méthode : Utiliser la variable Globale que l'on mets a jour pour lancer la scèneVariable Globale a créée : Heure DemiHeure Ce script va mettre a jour : La variable DemiHeure sera mis a jour à chaque fois que les minutes seront égales a 0 ou 30 La variable Heure sera mis a jour si les minutes sont égale à 0 Nous aurons donc 1 déclenchement par heure pour la VG: Heure et 2 déclenchements par heure pour la VG DemiHeure Voici le script (a copier dans une scène) : --[[ %% autostart %% globals DemiHeure --]] local Minutes = tonumber(os.date("%M", os.time())) local trigger = fibaro:getSourceTrigger() if (trigger['type'] == 'autostart') then fibaro:setGlobal("DemiHeure", "0"..Minutes) fibaro:debug("Demarrage via autostart") fibaro:abort() end fibaro:debug("Demarrage en cours...") local NbreScene = fibaro:countScenes() fibaro:debug("Nombres de Scéne en cours : "..NbreScene) fibaro:sleep(60*1000) local Pause = 0 if Minutes > 30 then Pause = 60 - Minutes else Pause = 30 - Minutes end fibaro:debug("Mise a jour Variable : "..Pause.."mn") fibaro:sleep(Pause*60*1000) Minutes = tonumber(os.date("%M", os.time())) fibaro:debug("mise a jour VG DemiHeure"..Minutes) fibaro:setGlobal("DemiHeure", Minutes) if Minutes == 0 then local Heure = tonumber(os.date("%H", os.time())) fibaro:setGlobal("Heure", Heure) fibaro:debug("mise a jour VG Heure"..Minutes) end Exemple d'utilisation : Je veux que ma scène se lance à 17h --[[ %% globals Heure --]] local heure = fibaro:getGlobalValue("Heure") if heure ~= 17 then; fibaro:abort(); end fibaro:debug("le script peut être exécuté ") Un peut plus compliquer --[[ %% globals DemiHeure --]] local trigger = fibaro:getSourceTrigger() if (trigger['type'] == 'global') then nomTrigger = trigger['name'] valeurTrigger = tonumber(fibaro:getGlobalValue(nomTrigger)) print("Nom du déclencheur = ", nomTrigger, " - Minutes : ", valeurTrigger) if valeurTrigger ~= 17 then; fibaro:abort(); end else fibaro:debug("La scéne ne peut être lancer que par une Variable Globale") fibaro:abort(); end if nomTrigger="Heure" and valeurTrigger ~= 17 then fibaro:abort() end
  5. Voici un Scène qui va vous permettre de savoir si on est le jour ou la nuit et d'avoir un décalage en minute par rapport ou jour ou a la nuit IL va nous falloir pour cette scène 2 variables globales et 1 variable globale prédéfinie Jour_Nuit (Variable prédéfinie avec comme valeur Jour ou Nuit. elle aura 2 déclenchements) SoleilLever (cette variable recevra les valeurs de la table TLever elle aura donc autant de déclenchement que de valeur dans la table TLever) SoleilCoucher (Cette variable recevra les valeurs de la table TCoucher, elle aura donc autant de déclenchement que de valeur dans la table TCoucher) Ces variables seront créées automatiquement si vous êtes en V4. Vous pouvez donnez un autre nom a chaque variable globales que les valeurs par défaut. -- Nom des Variables Globales local VGJourNuit = "Jour_Nuit" local VGLeverSoleil = "SoleilLever" local VGCoucherSoleil = "SoleilCoucher" -- Minutes de décalages par rapport au lever du soleil local TLever = {-60, -15, 30, 60, 50, 124} -- Minutes de décalages par rapport au Coucher du soleil local TCoucher = {-5, 30, 0, -30} -- Id du téléphone local IdTel = 181 Pour notre ami JoJo ainsi qu'a tout ceux qui sont en V3.60 il faudra crées les variables manuellement et désactivé ces trois lignes VerifVG(VGJourNuit, "Jour", {"Jour", "Nuit"}) VerifVG(VGLeverSoleil, 0) VerifVG(VGCoucherSoleil, 0) ----------------------------- Il faut renseigner IdTel avec l'id de votre téléphone cela va servir a vous envoyez une notification lorsque la box démarre ou lorsqu il y a modification de la scène. Une notification est aussi possible si il y a un probléme de variable globale. Le programme est optimisez pour que le sleep passe automatiquement de 1 mn à 30 mn en fonction des valeurs des tables coucher et lever Exemple d'utilisation : Scène bloc : Scène LUA je veux un déclenchement de scène (Il n'y a aucun ordre a respecter) 45 minutes avant le lever = -45 15 minutes avant le lever = -15 23 minutes apres le lever = 20 1h20 minutes apres le lever = 80 0 minutes = Jour dans la tables TLever il est donc inutile de mettre 0, il sera ajouter automatiquement a la table Je renseigne donc ma table TLever comme ceci local TLever = {-45, 20, 80, -15} Je fais de même avec la table TCoucher local TCoucher = {-5, 30, -30} Récupération des triggers dans une scène Utilisation de la variables globales Jour_Nuit comme trigger --[[ %% globals Jour_Nuit --]] local JourNuit = fibaro:getGlobalValue("Jour_Nuit") if JourNuit == "Jour" then fibaro:debug("Il fait "..JourNuit) end if JourNuit == "Nuit" then fibaro:debug("Il fait "..JourNuit) end Utilisation de ou des variables globales SoleilLever et SoleilCoucher comme trigger --[[ %% globals SoleilLever SoleilCoucher --]] local trigger = fibaro:getSourceTrigger() if (trigger['type'] == 'global') then LeverCoucher = trigger['name'] valeur = tonumber(fibaro:getGlobalValue(LeverCoucher)) print(nom, valeur) end -- le code dans ce test sera déclencher 15 mn aprés le coucher if LeverCoucher == "SoleilCoucher" and valeur == 15 then fibaro:call(7, "close") --Fermeture volet 15 mn après le coucher end -- le code dans ce test sera déclancher 30 mn avant le coucher if nom == "SoleilLever" and valeur == -30 then fibaro:call(7, "close") --Fermeture volet 30 mn avant le lever du soleil end Merci a STEVEN pour m'avoir aider a optimisez ce code Voici le code a copier dans une scène Version 3.00b --[[ %% autostart --]] -- Nom des Variables Globales local VGJourNuit = "Jour_Nuit" local VGLeverSoleil = "SoleilLever" local VGCoucherSoleil = "SoleilCoucher" -- Minutes de décalages par rapport au lever du soleil local TLever = {-60, -15, 30, 60, 50, 124} -- Minutes de décalages par rapport au Coucher du soleil local TCoucher = {-5, 30, 0, -30} -- Id du téléphone local IdTel = 181 --************ Ne rien modifier en dessous de cette ligne ************ ---------------------------------------------------------------------- -- Envoi d'un Push pour avertir que le box à démarrer ou redémarrer -- ---------------------------------------------------------------------- function EnvoiPush(Message) fibaro:debug(Message) fibaro:call(IdTel, "sendPush", Message) end -- ----------------------------------------------------------------- -- Vérification Variable Globale et création si besoin -- -- ----------------------------------------------------------------- function VerifVG(nom, valeur, choix) if (fibaro:getGlobalValue(nom) == nil) then local enum = 0 if (type(choix) ~= "nil") then enum = 1 end api.post("/globalVariables", {name=nom, isEnum=enum}) if enum == 1 then local variable = {} variable.value = tostring(valeur) variable.isEnum = false if (type(choix) ~= "nil") then variable.isEnum = true variable.enumValues = choix end api.put("/globalVariables/" .. nom, variable) end end end ---------------------------------------------------------------------- -- Mise a jour d'une variable global -- ---------------------------------------------------------------------- function UpdateVG(NomVG, Valeurs) if (fibaro:getGlobalValue(NomVG) == nil) then fibaro:debug("il faut cree la variable "..NomVG) EnvoiPush(string.format("La variable Globale %s n'existe pas ou a ete supprimer", NomVG)) fibaro:abort() -- fin du programme end fibaro:debug("Mise a jour de la Variable Globale : "..NomVG.." = "..Valeurs) fibaro:setGlobal(NomVG, Valeurs); end ---------------------------------------------------------------------- -- Vérification de l'heure et mise à jour -- -- de la variable si nécessaire -- ---------------------------------------------------------------------- function UpdateJourNuit(NomVG, heure) local valeurs = "Nuit" -- test si on est le jour ou la nuit if (heure >= leverSoleil) and (heure < coucherSoleil) then valeurs = "Jour" end fibaro:debug(string.format("Lever Soleil : %s - Coucher Soleil : %s", leverSoleil, coucherSoleil)) UpdateVG(NomVG, valeurs) -- mise a jour de la VG Jour_Nuit end ---------------------------------------------------------------------- -- Compare les tables Lever et coucher du soleil -- -- avec sunrisehour et sunsethour -- ---------------------------------------------------------------------- function LeverCoucher(NomVG, TableNom, SunRiseSet, JourNuit) for index, v in ipairs(TableNom) do if (os.date("%H:%M", os.time()+v*-60)) == SunRiseSet then UpdateVG(NomVG, v) if v == 0 then fibaro:debug("il fait : "..JourNuit) UpdateVG(VGJourNuit, JourNuit) end end end end ---------------------------------------------------------------------- -- Conversion Date format texte en format Date -- ---------------------------------------------------------------------- function ConvertionDate(NomDate) -- on extrait l'heure et minute (%d+) est un digit local heure, minute = string.match(NomDate, "(%d+):(%d+)") -- On récupère l'heure et date actuelle sous forme de tableau local TableDate = os.date("*t") -- On modifie l'heure et les minutes TableDate.hour = heure TableDate.min = minute -- Nous pouvons maintenant exploiter "MonHeure" comme une vrai date local MonHeure = os.time(TableDate) return (MonHeure) end ---------------------------------------------------------------------------- -- Calcul la valeur du Sleep en fonction des Max et Mini -- -- des Tables Lever et Coucher -- ---------------------------------------------------------------------------- function calculPause(j, heure, minilever, maxilever, minicoucher, maxicoucher) fibaro:debug("Heure Actuelle : "..heure) -- mini et max lever local heurelever = ConvertionDate(leverSoleil) local heureleverMini = (os.date("%X", heurelever+(minilever*60))) local heureleverMaxi = (os.date("%X", heurelever+(maxilever*60))) fibaro:debug("heure Lever Soleil Mini : "..heureleverMini.." - Maxi : "..heureleverMaxi) -- mini et max coucher local heurecoucher = ConvertionDate(coucherSoleil) local heurecoucherMini = (os.date("%X", heurecoucher+(minicoucher*60))) local heurecoucherMaxi = (os.date("%X", heurecoucher+(maxicoucher*60))) fibaro:debug("heure Coucher Soleil Mini : "..heurecoucherMini.." - Maxi : "..heurecoucherMaxi) if heure >= heureleverMini and heure < heureleverMaxi or heure >= heurecoucherMini and heure < heurecoucherMaxi then j=1 end return (j) end -- =================================================================== -- == Nous avons fini la préparation de notre code == -- == Nous pouvons Exécuter le programme == -- == Script réaliser par MPRINFO Version 3.00B == -- == Grand Merci à STEVEN pour son aide == -- =================================================================== ---------------------------------------------------------------------- -- Envoi d'un Push pour donner la date et l'heure de démarrage -- ---------------------------------------------------------------------- EnvoiPush(string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R"))) ---------------------------------------------------------------------- -- Contrôle si 1 Scène et déjà en cours -- ---------------------------------------------------------------------- local NbreScene = fibaro:countScenes() if NbreScene ~= 1 then; fibaro:debug("Il y a déjà une instance en cours... ") fibaro:abort(); end ---------------------------------------------------------------------- -- Vérification si les variables globales existe -- -- et Création ou Modification si Besoin -- ---------------------------------------------------------------------- VerifVG(VGJourNuit, "Jour", {"Jour", "Nuit"}) VerifVG(VGLeverSoleil, 0) VerifVG(VGCoucherSoleil, 0) ---------------------------------------------------------------------- -- Mise a jour de la variable VG Jour_Nuit au Démarrage de la Box -- -- Ou lors de la sauvegarde de la scène -- ---------------------------------------------------------------------- leverSoleil = fibaro:getValue(1, "sunriseHour") coucherSoleil = fibaro:getValue(1, "sunsetHour") UpdateJourNuit(VGJourNuit, os.date("%H:%M", os.time())) --------------------------------------------------------------------- -- Trie des Tables et récupération des valeurs min et maximum -- --------------------------------------------------------------------- -- Traitement de la Table TLever table.insert(TLever, 1, 0) -- ajout de 0 mn dans la table table.sort(TLever) local MiniLever = ((TLever[1]-30)) local MaxiLever = ((TLever[#TLever]+1)) -- Traitement de la Table TChoucher table.insert(TCoucher, 1, 0) -- ajout de 0 mn dans la table table.sort(TCoucher) local MiniCoucher = ((TCoucher[1]-30)) local MaxiCoucher = ((TCoucher[#TCoucher]+1)) --------------------------------------------------------------------- -- Test toute les minutes pour savoir si c'est jour ou nuit -- --------------------------------------------------------------------- while true do local j = 30 local osHeure = os.date("%H:%M", os.time()) leverSoleil = fibaro:getValue(1, "sunriseHour") coucherSoleil = fibaro:getValue(1, "sunsetHour") LeverCoucher(VGLeverSoleil, TLever, leverSoleil, "Jour") LeverCoucher(VGCoucherSoleil, TCoucher, coucherSoleil, "Nuit") j = calculPause(j, osHeure, MiniLever, MaxiLever, MiniCoucher, MaxiCoucher) fibaro:debug(string.format("Valeur du Sleep %s mn",j)) fibaro:sleep(j*60*1000); -- Pause en fonction de la valeur de J end A ceux qui vont utiliser cette scène, Merci de me faire un retour sur ce code...
  6. Bonsoir, Je vous propose un petit module virtuel que j'ai développé hier soir pour bien gérer le décodeur Orange LiveBox Play. J'ai en ce qui me concerne développé ce module pour pas mal de raisons dont voici les principales : 1) Pouvoir piloter la LiveBox bien sà»r 2) Gérer son état (ON, OFF, SLEEPING, STARTING) en temps réel 3) Trouver une solution de contournement à son absence de HDMI CEC, très ennuyeux 4) Pouvoir la couper durant l'absence prolongée, la nuit et surtout la redémarrer proprement chaque jour au bon moment et ainsi éviter de devoir la rebooter manuellement lorsqu'on en a vraiment besoin 5) Faire des économies car même en veille elle consomme quand même 17W à moins d'activer la veille profonde qui désactive les enregistrements programmés. Voici donc le code du module virtuel. Et 4 icônes que je propose pour les 4 états : Une fois le module importé, il faudra renseigner l'adresse IP de votre décodeur LiveBox (réservation DHCP recommandée) ainsi que le port qui est 8080. A noter : une des partie chiante de ce développement est liée à un bug de la version actuelle de l'API JSON de la LiveBox qui retourne une erreur lorsque l'ont souhaite récupérer son état courant. Or j'en ai besoin pour initialiser mon Virtual Device... La solution de contournement que j'ai trouvé repose sur l'utilisation de la Long Polling API qui permet d'être notifié d'un changement de contexte sur la LiveBox. Ainsi au démarrage de la MainLoop, afin de connaître l'état courant de la bête : 1) Je simule un appui sur un bouton (le dernier du Virtual Device) qui va simplement me permettre de faire un appel asynchrone temporisé simulant un appui sur Menu puis CH+ 2) Je lance immédiatement un appel de cette fameuse Long Polling API (notifyEvent) qui est bloquante 55s si rien ne se passe ou répond instantanément si un événement survient 3) Je peux ainsi initialiser mon état et être notifié des futurs changements en appellant en permanence la méthode notifyEvent qui au pire partira en timeOut au bout de 55s Pour ne rater aucun événement, je suis obligé de faire un while true dans la MainLoop sinon je prend le risque de perdre un événement qui pourrait survenir durant les 3s de sleep de celle-ci... Je teste ce module depuis hier et tout fonctionne très bien, c'est hyper réactif, vous pouvez faire des essais avec la télécommande physique de la LiveBox ou tout autre moyen de pilotage. Je suis même étonné de ne pas rencontrer de souci. Si vous n'avez pas de module relais en amont de l'alimentation de votre LiveBox, mettez simplement nil comme valeur pour la variable powerSwitchId (MainLoop, button ⎋ ON/VEILLE et button ⎋ POWER OFF. Vous n'aurez pas de gestion de l'état OFF mais ne supprimez pas le bouton ⎋ POWER OFF car cela décalera les ID des boutons. Si vous souhaitez le faire il faudra aller modifier en conséquence du dernier bouton de la MainLoop ligne 54 (32->31) -- Si je ne connais pas l'état, je déclenche un appui temporisé sur le bouton menu if (lbCurrentStatus == "NA") then fibaro:call(deviceId, "pressButton", 32) end Pensez également à mettre à jour les ID de vos icônes dans la fonction updateLiveBoxIcon() ​Il est fort probable qu'il y ait quelques bugs que je n'ai pas encore vus donc n'hésitez pas à me les signaler. Aussi, je viendrais mettre à jour le Device si j'apporte des améliorations. Voici enfin le code complet de la MainLoop ------------------------------------------------------ -- TV Commande v0.2 -- ------------------------------------------------------ -- Auteur : Brice Cassagnabère -- ------------------------------------------------------ -- Changelog : -- -- v0.2 : Ajout d'un test port et IP au démarrage -- -- Amélioration du code -- -- v0.1 : Version initiale -- ------------------------------------------------------ -- Plus d'infos : http://is.gd/RcK1xZ -- ------------------------------------------------------ -- Variables globales de la MainLoop lbCurrentStatus = "NA" lbNewStatus = "NA" -- ID du module relais de l'alimentation (FGS, WallPLug, Greenwave...) nil si pas présent powerSwitchId = 235 deviceId = fibaro:getSelfId() -- Functions utiles function debug(text, color) color = color or "white" fibaro:debug("<font color='"..color.."'>"..text.."</font>") end function updateLiveBoxUIStatus() if (lbCurrentStatus == lbNewStatus) then return end lbCurrentStatus = lbNewStatus fibaro:log("Status : "..lbCurrentStatus) debug("LiveBox status : "..lbCurrentStatus, "green") fibaro:call(deviceId, "setProperty", "ui.labelStatus.value", lbCurrentStatus) end function updateLiveBoxIcon() if lbCurrentStatus == "ON" then iconId = 1035 elseif lbCurrentStatus == "SLEEPING" then iconId = 1033 elseif lbCurrentStatus == "OFF" then iconId = 1034 elseif lbCurrentStatus == "STARTING" then iconId = 1032 end fibaro:call(deviceId, "setProperty", "currentIcon", iconId) end function liveBoxEventPolling() if (tonumber(powerSwitchId ~= nil and fibaro:getValue(powerSwitchId, 'value')) == 0) then lbNewStatus = "OFF" debug("LiveBox à l'arrêt complet", "red") else -- Detection de l'état de la livebox debug("En attente d'événement de la LiveBox...") LBox = Net.FHttp(tostring(fibaro:get(deviceId, 'IPAddress')), tostring(fibaro:get(deviceId, 'TCPPort'))) -- Si je ne connais pas l'état, je déclenche un appui temporisé sur le bouton menu if (lbCurrentStatus == "NA") then fibaro:call(deviceId, "pressButton", 32) end -- Je lance une commande long polling response = LBox:GET("/remoteControl/notifyEvent") -- Un événement est survenu, je traite l'événement if (response ~= nil and response ~= "") then debug(response, "yellow") jsonResponse = json.decode(response) if jsonResponse.result.message == "request timeout" then if lbCurrentStatus == "NA" then lbNewStatus = "SLEEPING" else debug("Pas d'événement durant 55s, LiveBox toujours en état : "..lbCurrentStatus, "orange") end elseif jsonResponse.result.message == "event notification" then if jsonResponse.result.data.eventType == "OSD_CONTEXT_CHANGED" then debug(jsonResponse.result.data.service, "orange") -- Dans ce cas, la LiveBox est allumée donc je peux mettre à jour son statut if (jsonResponse.result.data.service == "HOMEPAGE") then lbNewStatus = "ON" elseif (jsonResponse.result.data.service == "MAIN_PROCESS") then lbNewStatus = "SLEEPING" end elseif jsonResponse.result.data.eventType == "MEDIA_STATE_CHANGED" then lbNewStatus = "ON" debug("ZAPPING", "orange") fibaro:log("ZAPPING") end end elseif lbCurrentStatus == "OFF" or lbCurrentStatus == "NA" then lbNewStatus = "STARTING" end end end local error = false if (fibaro:get(deviceId, 'IPAddress') == "") then debug("Vous devez renseigner l'Adresse IP du décodeur dans le champs dédié du Virtual Device", "red") debug("Vous pouvez retrouver cette adresse dans l'interface d'administration de la LiveBox") debug("Il est recommandé de faire une réservation DHCP pour être sà»r que l'IP ne change jamais") error = true end if (fibaro:get(deviceId, 'TCPPort') == "0") then debug("Vous devez renseigner le Port dans le champs dédié du Virtual Device", "red") debug("Le port par défaut est 8080 sur le décodeur LiveBox Play (noir)") error = true end if (error) then return end while true do pcall(liveBoxEventPolling) pcall(updateLiveBoxUIStatus) pcall(updateLiveBoxIcon) if (lbCurrentStatus == "OFF" or lbCurrentStatus == "STARTING") then fibaro:sleep(5000) end end J'espère que cela vous sera utile ! TV_Commande v0.2.vfib
  7. EDIT : VD disponibles dans les pages suivantes Ce tuto est un projet qui démarre, il n'y a encore rien à partager... Mais vu la saison, j'ai la pression. Le but du virtal device est de simplifier la gestion de la piscine, en commençant par la filtration. Pour le moment je débute en LUA et VD et je m'attaque à la logique avant de l'enrober dans un VD ou plugin. La partie logique ne devrait pas trop poser de problème mais l'absence de fonctions partagées sur la HC2 rends les codes peu digeste à priori un peu de théorie: Vous trouverez plein de sites qui traitent de la filtration piscine allant du simple 'température / 2' à des notions plus complexes. Je me base sur la notion de 'durée de cycle' pour régler le temps de marche de la pompe. En effet dans l'absolu le temps n'est pas un bon critère car tout dépend du dimensionnement de la filtration versus le volume de la piscine. Une règle de base répandue sur le net donne Eau > 25 °C : on conseille 3 cycles complets de filtration, au minimum 12 h. 20 °C < eau < 24 °C : compter environ 1 à 2 cycles de filtration soit de 10 à 11 h. 15 °C < eau < 20 °C : 1 cycle complet suffit. 10 °C < eau < 14 °C : ½ voire même ¼ de cycle dans ce cas, ce qui dure approximativement entre 1 et 2 h. Eau < 10 °C : dans ce cas la filtration quotidienne est facultative. Avec un peu de lissage on obtient une courbe température / cycles (donc durée) de la forme Cette courbe n'est pas linéaire mais sans entrer dans les détails elle reste un cas général à adapter à chaque bassin (type désinfection, fréquentation moyenne, environnement....) Je propose de ne pas trop discuter la forme/hauteur de la courbe sur ce forum... De toute façon le VD permettra de fixer votre courbe de référence allant de la simple droite à une forme ultra 'optimisée'. des choix à faire: Vous trouverez de tout comme stratégie pour économiser/optimiser perso je suis plutôt contre la filtration de nuit en HC... - bon et au final + cher filtrer X minutes par heure pour atteindre la durée totale me parait moyen aussi pour mon algo (à créer) je pars sur - 1 à 3 périodes de filtration par jour - filtrer plus en fin de journée pour compenser la fréquentation et assurer un bon nettoyage avant le repos nocturne - j'ai des HC entre 12h et 13h30 autant filtrer (il n'y a pas de petites économies). De plus avoir une filtration fixe vers midi permettra de prendre une température de référence cohérente de jour en jour en plus de la gestion automatique le VD doit permettre de superposer des périodes de 'filtration choc' ; départ immédiat et non-stop pour 12, 24, 48h d'appliquer une correction à la courbe 0 à 400% par exemple pour s'adapter aux périodes de sur-fréquentation ou vent ou.... de proposer un bouton 'baignade' qui permettrait de mettre en marche une heure histoire d’être certain d'avoir la circulation d'eau pour masser le dos :-). de reprendre la planification après un reboot HC2 quelques pistes pour l'affichage dans le VD affichage température de référence utilisée pour le calcul + durée totale de filtration du mode auto affichage température courante affichage état pompe bouton baignade bouton "CHOC +12" + affichage progression choc totale/restante bouton "annuler choc" ajustement 0 à 400% Je vais arrêter la, car c fait déjà pas mal de cas à gérer sans tomber dans une usine à gaz. voila une maquette de VD
  8. Steven

    Double-Clique Pour Confirmer

    CODER UN BOUTON FONCTIONNANT UNIQUEMENT SUR DOUBLE-CLIQUE Les boutons des modules virtuels ne permettent malheureusement pas grand chose d'autre que de cliquer dessus. Il arrive même parfois que nous cliquions sur un bouton par inadvertance. Dans la plus part des cas cela n'est pas grave mais pour certaines opérations sensibles, il serait judicieux de pouvoir valider notre clique. L'idée (soumise par @Moicphil) est de déclencher l'action uniquement lors d'un double-clique sur le bouton. Pour réaliser cela, il nous faut : Un bouton Un label Le label va nous servir à avertir l'utilisateur qu'un double-clique est nécessaire, mais il va surtout nous servir à savoir si un clique précédent a été effectuer. Au premier clique, le système affiche le message pendant un temps limité. Si pendant ce temps, l'utilisateur ré appuie sur le bouton, l'action est confirmée, sinon on retire le message et la confirmation est annulée. Voici donc le code a implémenter derrière votre bouton : -- ---------------------------- -- Ne pas toucher -- -- ---------------------------- function confirm(msg, labelId, secondes) local current = fibaro:getValue(fibaro:getSelfId(), "ui."..labelId..".value") if (current == msg) then fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value", " ") return true else fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value", msg) fibaro:sleep(secondes*1000) fibaro:call(fibaro:getSelfId(), "setProperty", "ui."..labelId..".value","") return fibaro:getValue(fibaro:getSelfId(), "ui."..labelId..".value") == " " end end -- ---------------------------- -- A vous de jouer --- -- ---------------------------- local message = "Ré-appuyer pour confirmer" -- le message de confirmation local label_id = "lblMessage" -- l'ID du label qui recevra le message local duree = 1 -- la durée max entre 2 clique (en seconde) if ( confirm(message, label_id, duree) ) then fibaro:log("Confirmé") -- votre code ici en cas de confirmation else fibaro:log("Annulé") -- votre code ici en cas d'annulation end Le code n'est pas si compliqué et la partie qui vous intéresse début à la ligne 21. Voilà , j'espère que cela puisse vous éviter quelque catastrophe P.S. Il y a aussi moyen d'utiliser une variable global à la place du label mais l'insertion d'une valeur dans une variable globale est trop lente pour être viable.
  9. Pluviométrie Avec WeatherUnderground Bonjour, Sur une idée originale de Steven, qui remonte les données d'un pluviomètre Netatmo et récupère les previsions depuis le site de WU, j'ai crée ce VD qui permet de s'affranchir de l'achat d'un pluviomètre et de faire appel uniquement à WU pour récupérer les précipitations (de la dernière heure, du jour, d'hier, des 5 derniers jours et des 10 derniers jours) d'une station WU proche de chez vous; Suite à ca on fait un rapide calcul (à affiner selon vos besoins) pour mettre à jour une variable globale. (credit Steven aussi - je n'ai pas encore affiner ce calcul avec les datas que je remonte - ca sera une V2) Cette variable sert ensuite chez moi à déclencher l'arrosage automatique. HC2 en V4 (et 3.6 après le test de Jojo) 1ère étape - Creation des clefs WU à l'adresse ici Pour crée un compte : http://www.wundergro...pi/d/login.html Pour trouver sa "station ID" : http://www.wundergro...dCountry=France La création du compte va vous permettre d'obtenir une "cle api" Et la recherche de la station la plus proche de chez vous, une station ID (attention à bien choisir une station qui mesure à les precipitations .. ;-) Important Les clés gratuites permettent 500 appels par jour et 10appels par minutes. Dans le VD vous avez 4 boutons - Today qui fait 1 appel - Last Days, qui fait 10 appels - Next 2 days, qui fait 1 appel il faut donc faire attention à vos clicks :-) si vous dépasser la limite, c'est le carton jaune, au bout de 3 carton jaune, c'est le rouge et la clé est HS. (Perso ce que j'ai fait c'est créer une clé pour les 10jours. et une autre pour les 2 autres boutons, et j'utilise GEA pour cliquer à intervalle régulier sur les boutons, sans dépasser les 500 appels jours / clef.) -- Arrosage GEA.add(true, 10*60, "", {{"VirtualDevice", id["CALCUL_ARROSAGE"], 2},{"Repeat"}}) -- Historique Pluie du Jour et derniere heure GEA.add(true, 30, "", {{"Time", "02:06", "02:07"},{"VirtualDevice", id["CALCUL_ARROSAGE"], 5}}) -- Historique Pluie jusqu'à 10jours GEA.add(true, 10*60, "", {{"VirtualDevice", id["CALCUL_ARROSAGE"], 9},{"Repeat"}}) -- Prévisions à 2 jours ce qui donne 300 appels par jour et max 10appels /mn - donc ok pour 1clef, sauf si l'appel 10jours passe la meme minutes qu'un autre appel ... Pour ceux qui n'ont pas GEA, voici ce que vous pouvez mettre dans le main loop (j'ai pas testé donc merci pour vos retours si ça fonctionne pas) while true do local Var_Heure = os.date("%H:%M") local Var_Min = os.date("%M") --fibaro:debug("heure OS : " ..Var_Heure) if Var_Heure == "02:06" then fibaro:call(fibaro:getSelfId(), "pressButton", "5") fibaro:debug("heure OS : " ..Var_Heure .."Historique des derniers jours récupéré") end if Var_Min =="00" or Var_Min == "15" or Var_Min == "30" or Var_Min == "45" then fibaro:call(fibaro:getSelfId(), "pressButton", "2") fibaro:debug("heure OS : " ..Var_Heure .."Historique du jour récupéré") fibaro:call(fibaro:getSelfId(), "pressButton", "9") fibaro:debug("heure OS : " ..Var_Heure .."Prévisions récupérées") end fibaro:sleep(60*1000) -- sleep 1 min end 2eme étape - Importer le VD - Modifier la clé (ou les clefs) API et la Station ID dans tous les boutons (sauf calcul) - Modifier l'id de votre smartphone dans le bouton calcul arrosage - Modifier les ID de vos icones dans la bouton calcul arrosage 3eme étape - Créer une variable "Arrosage" avec 3 valeurs Non, Leger, Important J'utilise les icônes de Couillerot merci à lui. Merci. Mon 1er VD partagé sur le forum. En remerciement pour tout ce que je prends/deja pris et ce que j'apprends ! V.1.0 V.1.1: optimisation sur conseil de jojo V.1.2: integration des icônes en fonction de l'arrosage nécessaire (toujours sur idée de jojo) V.1.3: meilleure gestion des appels et 1clé WU peut suffire V.1.4: fine tuning V.1.5: optimisation des appels historiques sur 1 bouton (merci jojo) -- 15 Mai 2015 -- V2.1 : ici Calcul_Arrosage V1.5.vfib
  10. Barelle

    VD UPS

    Hello, Comme vous le savez, nos matériels électroniques n’apprécient pas du tout les coupures électriques. Pour cela, il est plus que recommandé d’utiliser un onduleur (ou UPS, "Uninterruptible Power Supply")… Le VD que je vous propose ici permet l’interrogation du serveur UPS résidant sur un NAS Synology (auquel l’onduleur est connecté par un port USB). Il met à jour une variable globale (appelée UpsStatus par défaut) avec les valeurs "power-line" ou "battery" selon que l’onduleur est sur secteur ou sur batterie. Cette variable globale permet le lancement de la scène ci-après qui : - lors d’un passage sur batterie, après le délai "delayBeforePowerOff" réalisera l’arrêt de la HC2 ; - lors du retour de l’alimentation, appuiera sur le bouton "WOL" du VD. Là aussi, le réveil se fera après un délai "delayBeforeWakeUp". Ces délais ont pour objet de s’affranchir de retours temporaires de tension. --[[ %% properties %% events %% globals UpsStatus --]] local globalVarName = "UpsStatus"; -- values "power-line" or "battery" local wolVdId = "337"; local wolVdBtnId = "11"; local delayBeforePowerOff = 5; -- minutes local delayBeforeWakeUp = 5; -- minutes local debug = true; function trace(text, color) color = color or "white"; if debug then fibaro:debug("<font color='"..color.."'>"..text.."</font>"); end end -- trace function tracerr(text, color) color = color or "red"; fibaro:debug("<font color='red'>ERROR! </font>".."<font color='"..color.."'>"..text.."</font>"); end -- tracerr function wakeOnLan() fibaro:call(wolVdId, "pressButton", wolVdBtnId); end -- wakeOnLan local sourceTrigger = fibaro:getSourceTrigger(); trace("sourceTrigger[type] = " .. sourceTrigger["type"], "deepskyblue"); if (sourceTrigger["type"] == "global") then if (sourceTrigger["name"] ~= globalVarName) then tracerr("unknown global "..sourceTrigger["name"].." exiting"); fibaro:abort(); end elseif (sourceTrigger["type"] == 'other') then trace("Scene triggered manually", "lightgreen"); -- inform user local upsStatus = fibaro:getGlobalValue(globalVarName); if (upsStatus ~= nil) then trace(globalVarName.." = "..upsStatus, "lightgreen"); fibaro:abort(); end else tracerr("unexpected trigger type ".. sourceTrigger["type"], "orange"); fibaro:abort(); end if (fibaro:countScenes() > 1) then trace("Script already running, exiting.", "green"); return; end local upsStatus = fibaro:getGlobalValue(globalVarName); if (upsStatus == nil) then tracerr("global "..globalVarName.." = nil"); fibaro:abort(); end if (upsStatus == "power-line") then local i = 0; for i = 1, (delayBeforeWakeUp * 6) do -- check every 10 seconds during delayBeforeWakeUp minutes fibaro:sleep(10 * 1000); -- ten seconds upsStatus = fibaro:getGlobalValue(globalVarName); if (upsStatus ~= "power-line") then trace("Still on battery, aborting", "orange"); fibaro:abort(); -- not stable end end -- Time to wake up devices trace("Waking up devices", "lightgreen"); wakeOnLan(); elseif (upsStatus == "battery") then local i = 0; for i = 1, (delayBeforePowerOff * 6) do -- check every 10 seconds during delayBeforePowerOff minutes fibaro:sleep(10*1000); -- ten seconds upsStatus = fibaro:getGlobalValue(globalVarName); if (upsStatus ~= "battery") then trace("Power is back, shut down aborted", "orange"); fibaro:abort(); end end -- shutdown HC2 gracefully trace("shutting down", "lightgreen"); fibaro:sleep(10*1000); HomeCenter.SystemService.shutdown(); else tracerr("global "..globalVarName.." unknown value: "..upsStatus); end Installation du VD : - Importer le VD, - Renseigner l’adresse IP du NAS connecté à l’onduleur, le port TCP 3493 est optionnel. - Les username et password présents dans le code du bouton Update fonctionnent pour un Synology. - Dans le code du bouton WOL, vous devrez préciser les adresses MAC des matériels que vous souhaitez réveiller. Il va de soi qu’ils devront être paramétrés pour accepter les "magic packets" afin d’être réveillés (pour les PC vérifier les paramètres de la carte réseau). - Pour les Nas Synology, il faut activer le WOL : "Panneau de configuration", "Matériel et alimentation", onglet "Général", cocher "Activer WOL sur le réseau local x". - Et ne pas oublier d’activer le serveur réseau UPS : "Panneau de configuration", "Matériel et alimentation", onglet "UPS", cocher "Activer la prise en "charge UPS" et "Activer le serveur réseau UPS"). - Enfin bien sûr, trouver une jolie icône pour les boutons du VD. Installation de la scène : - Préciser l’id du VD réalisant le WOL dans "wolVdId". - et le numéro du bouton à appuyer "wolVdBtnId". Pour ceux qui veulent personnaliser le VD, le code du bouton "Update" contient, à la fin, une description des principaux champs retournés par les serveurs UPS, Tous ne sont pas implémentés par Synology ou mon onduleur. Configuration utilisée pour les tests : - HC2 : 4.153 Beta - Onduleur : Eaton Ellipse PRO 1200 - NAS : Synology DS1010+ with DSM 5.2-5967 Update 6 Joyeux réveillon et bonne année à tous… UPS.vfib
  11. Steven

    Pluviométrie Avec Netatmo

    PLUVIOMETRIE (ET ARROSAGE) AVEC NETATMO firmware 4.x seulement Partie 1 : récupérer l'historique Netatmo est une station météo sur laquelle vous pouvez brancher un "pluviomètre" de la même marque. Afin d'exploiter les données de ce pluviomètre et vous pouvez utiliser l'application Netatmo ou son site web. Vous pouvez aussi installer le plugin Netatmo fourni par Fibaro. Ce dernier vous affichera uniquement les données à l'instant précis ou vous être entrain de le regarder. Nous, nous voulons allez plus loin, nous voulons connaitre les quantités de pluie ayant eu lieu depuis : 1 jour, 1 semaine, 1 mois, cela dans l'optique de pouvoir gérer correctement notre arrosage. Pour ce faire, il existe un grand nombre de script PHP, Google Script qui permet de gérer cela .. mais ... depuis la v4.x, Fibaro nous fait bénéficier de la librairie net.httpClient dans une scène et cette librairie nous permet de récupérer des données via HTTPS, ce qui auparavant n'était pas possible depuis notre HC2. Alors vu que nous avons, aujourd'hui, tout le nécessaire pour attaquer notre Netatmo directement depuis notre HC2, pourquoi s'en priver Les données recueillies par votre Netatmo sont mis à diposition via des API que vous pouvez interroger quand bon vous semble à la seul condition d'avoir un compte Développeur Netatmo (ne vous inquiéter pas, vous n'aurez pas beson de développer, ni de répondre à des questions étranges). Pour vous inscrire, c'est donc ici : https://auth.netatmo.com/fr-FR/access/signup Suite à votre enregistrement, vous allez obtenir : un id (exemple : 45b1931d19665803515b571c) un code secret (exemple : lyRkJXZLIM8xShACtmQjsCQV4U3djL08Zq1hUStbUJ4) Ces informations + votre login et mot de passe vont permettre d'accéder à vos informations. Voici donc le script nécessaire, à vous de l'importer dans une nouvelle scène et de modifier les 4 premières lignes. local n_client_id = "45b1931d19665803515b571c" local n_client_secret = "lyRkJXZLIM8xShACtmQjsCQV4U3djL08Zq1hUStbUJ4" local n_username = "______________@_____.com" local n_password = "password" local hc2_module_virtuel = 139 -- le module virtuel "Pluie" local debug = true -- affiche ou non les message dans la console local long_lat_adjust = 0.1 -- ajustement de la distance pour trouvé un pluviomètre local version = 2.0 -- ------------------------------------------------------------------------ -- NE PAS TOUCHER -- ------------------------------------------------------------------------ local force_use_rain_public = false local loc = api.get("/settings/location") local lat_ne = loc.latitude + long_lat_adjust local lon_ne = loc.longitude + long_lat_adjust local lat_sw = loc.latitude - long_lat_adjust local lon_sw = loc.longitude - long_lat_adjust local token = "" local int_id = "" local ext_id = "" local ext_bat = 0 local rain_id = "" local rain_bat = 0 local temperature_interieure = -1000 local temperature_exterieure = -1000 local co2 = -1000 local humidite_interne = -1000 local humidite_externe = -1000 local pression = -1000 local bruit = -1000 local rains = {hour = -1000, day = -1000, week = -1000, month = -1000} -- ------------------------------------------------------------------------ -- Exécuté après chaque requète HTTP -- ------------------------------------------------------------------------ function afterHttpRequest() if (temperature_interieure > -1000) then end if (temperature_exterieure > -1000) then end if (co2 > -1000) then end if (humidite_interne > -1000) then end if (humidite_externe > -1000) then end if (pression > -1000) then end if (bruit > -1000) then end if (rains["hour"] > -1000) then if (rains["hour"] == -1) then fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblHeure.value", "n/a") else fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblHeure.value", " "..rains["hour"]) end end if (rains["day"] > -1000) then if (rains["day"] == -1) then fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblJour.value", "n/a") else fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblJour.value", " "..rains["day"]) end end if (rains["week"] > -1000) then if (rains["week"] == -1) then fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblSemaine.value", "n/a") else fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblSemaine.value", " "..rains["week"]) end end if (rains["month"] > -1000) then if (rains["month"] == -1) then fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblMois.value", "n/a") else fibaro:call(hc2_module_virtuel, "setProperty", "ui.lblMois.value", " "..rains["month"]) end end end -- ------------------------------------------------------------------------ -- Affichage dans la console -- ------------------------------------------------------------------------ function log(message, force) force = force or false if (debug or force) then print(__convertToString(message)) end end -- ------------------------------------------------------------------------ -- Retourne le niveau de batterie en pourcent -- ------------------------------------------------------------------------ function calcBat(bat, ext) local max = 6000 local min = 4200 if (ext) then max = 6000 min = 3600 end if (bat > max) then bat = max end return math.floor(bat * 100 / max) end -- ------------------------------------------------------------------------ -- Arrondi -- ------------------------------------------------------------------------ local function roundToNthDecimal(num, n) local mult = 10^(n or 0) return math.floor(num * mult + 0.5) / mult end -- ------------------------------------------------------------------------ -- Interrogation de l'API -- ------------------------------------------------------------------------ function getResponseData(url, body, func) local http = net.HTTPClient() http:request(url, { options = { method = 'POST', headers = { ["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8" }, data = body }, success = function(response) func(json.decode(response.data)) afterHttpRequest() end, error = function(response) log(" ERROR !!! " .. url, true) end, }) end -- ------------------------------------------------------------------------ -- Mesures de l'unité interne -- ------------------------------------------------------------------------ function getMesuresInt() getResponseData("https://api.netatmo.net/api/getmeasure","access_token="..token.."&device_id="..int_id.."&scale=max&type=Temperature,CO2,Humidity,Pressure,Noise&date_end=last", function(data) log("----------========== Module intérieur ==========----------") temperature_interieure = data.body[1].value[1][1] co2 = data.body[1].value[1][2] humidite_interne = data.body[1].value[1][3] pression = data.body[1].value[1][4] bruit = data.body[1].value[1][5] log("temperature_interieure = " .. temperature_interieure) log("co2 = " .. co2) log("humidite_interne = " .. humidite_interne) log("pression = " .. pression) log("bruit = " .. bruit) end ) end -- ------------------------------------------------------------------------ -- Mesure de l'unité externe -- ------------------------------------------------------------------------ function getMesuresExt() getResponseData("https://api.netatmo.net/api/getmeasure","access_token="..token.."&device_id="..int_id.."&module_id="..ext_id.."&scale=max&type=Temperature,Humidity&date_end=last", function(data) log("----------========== Module extérieur ==========----------") temperature_exterieure = data.body[1].value[1][1] humidite_externe = data.body[1].value[1][2] log("temperature_exterieure = " .. temperature_exterieure) log("humidite_externe = " .. humidite_externe) end ) end -- ------------------------------------------------------------------------ -- Obtention des informations sur un pluviomètre proche -- ------------------------------------------------------------------------ function getRainNear() getResponseData("https://api.netatmo.net/api/getpublicdata","access_token="..token .. "&lat_ne="..lat_ne.."&lon_ne="..lon_ne.."&lat_sw="..lat_sw.."&lon_sw="..lon_sw, function(data) --log(data) rains["week"] = -1 rains["month"] = -1 rains["hour"] = -1 rains["day"] = -1 log("----------========== D e v i c e s =========----------") for _, v in pairs(data.body) do for l, w in pairs(v.measures) do if (type(w.rain_24h) ~= "nil") then rains["day"] = w.rain_24h rains["hour"] = w.rain_60min end end end if (rains["day"] == -1000) then log("Impossible de trouver un pluviomètre à proximité, augmentez [long_lat_adjust]", true) else log("Pluie jour : " .. rains["day"]) log("Pluie heure : " .. rains["hour"]) end end ) end -- ------------------------------------------------------------------------ -- Mesure du détecteur de pluie historique -- ------------------------------------------------------------------------ function getMesuresRain(duree, variable) local now = os.time(); getResponseData("https://api.netatmo.net/api/getmeasure","access_token="..token.."&device_id="..int_id.."&module_id="..rain_id.."&scale=1hour&type=sum_rain&real_time=true&date_begin="..os.date("!%c", (now - duree)), function(data) log("----------========== Pluie histo ==========----------") local cumul = 0 for k, v in pairs(data.body) do for l, w in pairs(v.value) do cumul = cumul + w[1] end end cumul = roundToNthDecimal(cumul, 2) rains[variable] = cumul log("rain["..variable.."] = " .. rains[variable]) end ) end -- ------------------------------------------------------------------------ -- Obtention des informations sur les devices -- ------------------------------------------------------------------------ function getDevices() getResponseData("https://api.netatmo.net/api/devicelist","access_token="..token, function(data) log("----------========== D e v i c e s =========----------") for _, v in pairs(data.body.modules) do if (v.data_type[1] == "Rain") then rain_id = v._id rain_bat = calcBat(v.battery_vp, true) else ext_id = v._id ext_bat = calcBat(v.battery_vp, true) end end int_id = data.body.devices[1]._id getMesuresInt() getMesuresExt() if (rain_id ~= "" and not force_use_rain_public) then getMesuresRain(60 * 60, "hour") getMesuresRain(60 * 60 * 24, "day") getMesuresRain(60 * 60 * 24 * 7, "week") getMesuresRain(60 * 60 * 24 * 30, "month") else getRainNear() end end ) end -- ------------------------------------------------------------------------ -- Authentification -- ------------------------------------------------------------------------ function auth(nextFunction) local request_body = "grant_type=password&client_id=" .. n_client_id .. "&client_secret=" .. n_client_secret .. "&username=" .. n_username .. "&password=" .. n_password .. "&scope=read_station" getResponseData("https://api.netatmo.net/oauth2/token", request_body, function(data) token = data.access_token log(token) nextFunction() end ) end auth(getDevices) log("Last request : " .. os.date("%x - %X"), true) si vous avez l'âme d'un développeur ou d'un aventurier, la méthode à modifier est afterHttpRequest() sinon, rendez-vous au post suivant. P.S. Merci à @PITP2 pour son support. Edit : nouvelle version du script. Si ce dernier détecte que vous n'avez pas de pluviomètre, il va rechercher un pluviomètre à proximité de chez vous (uniquement les relevés de la dernière heure et jour). La distance de recherche peux être adaptée en ajustant la variable long_lat_adjust (0.1 par défaut). Il s'agit du cercle de recherche en latitude/longitude autour de chez vous.
  12. HANSOLO

    Jour Chômé

    V2 du 27/06/2014 grandement amélioré par STEVEN Nouveautés de la V2: - Calcul si le jour en cours et jour +1 est chômé ou pas - Choix des jours fériés France ou Suisse - Ce qui change par rapport à la V1: ajout d'un label dans le module virtuel et ajout d'une variable globale JourChomeJ1, pour lancer le calcul depuis GEA ou SCHEDULER bouton 3 au lieu de 2 pour la version précédente. Objectif: calculer si le jour en cours est chômé (WE ou férié) ou pas et stocker le résultat dans une variable globale, le tout sans dépendre d'un agenda externe à la HC2 et de script intermédiaire. Il s'agit d'une légère adaptation du code pour la VERA LITE de josDBlog http://gurau-audibert.hd.free.fr/josdblog/2014/01/lua-vacances-jours-chomes-et-jours-feries/ 1er étape, dans le panneau des variables, créer deux variables globale prédéfinie JourChome JourChomeJ1 avec les valeurs prédéfinies OUI NON. 2 iém étape, créer un module virtuel avec deux labels et un bouton: Le détail: Et ci-dessous la code à coller dans le bouton du module virtuel: -- Retourne OUI si le jour courant et J+1 est un jour chômé (WE ou férié) -- Adapté de http://gurau-audibert.hd.free.fr/josdblog/2014/01/lua-vacances-jours-chomes-et-jours-feries/ -- Pour la HC2 par Hansolo -- V1 26/06/2014 Initié par HANSOLO -- V2 27/06/2014 Amélioré par STEVEN, gestion des JS SUISSE et calcul J et J+1 local france = true local suisse = false local geneve = false -- Retourne le jour de la semaine en clair function josdGetJourSemaine(jour) --fibaro:debug ("jour: ") josdGetJourSemaineTab={[0]="dimanche",[1]="lundi",[2]="mardi",[3]="mercredi",[4]="jeudi",[5]="vendredi",[6]="samedi"} return josdGetJourSemaineTab[tonumber(jour)] end -- Retourne le jour de Pâques au format epoch -- annee : année (Integer) dont on désire connaître le jour de Pâques (ex : 2014) function josdGetJourPaques(annee) local a=math.floor(annee/100); local b=math.fmod(annee,100); local c=math.floor((3*(a+25))/4); local d=math.fmod((3*(a+25)),4); local e=math.floor((8*(a+11))/25); local f=math.fmod((5*a+,19); local g=math.fmod((19*f+c-e),30); local h=math.floor((f+11*g)/319); local j=math.floor((60*(5-d)+b)/4); local k=math.fmod((60*(5-d)+,4); local m=math.fmod((2*j-k-g+h),7); local n=math.floor((g-h+m+114)/31); local p=math.fmod((g-h+m+114),31); local jour=p+1; local mois=n; josdGetJourPaquesAnnee=annee; josdGetJourPaquesEpochPaque=os.time{year=annee,month=mois,day=jour,hour=12,min=0}; return josdGetJourPaquesEpochPaque; end -- Retourne true si le jour courant est un jour férié function josdJourFerie(time) local today=os.date("%m-%d", time); local annee=tonumber(os.date("%Y", time)); -- Dates fixes josdJourFerieTab = {} local epochPaques=josdGetJourPaques(annee); if (france) then josdJourFerieTab["01-01"] = true; -- 1er janvier josdJourFerieTab["05-01"] = true; -- Fête du travail josdJourFerieTab["05-08"] = true; -- Victoire des alliés josdJourFerieTab["07-14"] = true; -- Fête nationale josdJourFerieTab["08-15"] = true; -- Assomption josdJourFerieTab["11-01"] = true; -- Toussaint josdJourFerieTab["11-11"] = true; -- Armistice josdJourFerieTab["12-25"] = true; -- Noà«l -- Dates variables josdJourFerieTab[os.date("%m-%d",epochPaques)] = true; -- Pâques josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60)] = true; -- Lundi de Pâques = Pâques + 1 jour josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60*39)] = true; -- Ascension = Pâques + 39 jours josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60*50)] = true; -- Pentecôte = Ascension + 50 jours end if (suisse) then josdJourFerieTab["01-01"] = true; -- 1er janvier josdJourFerieTab["08-01"] = true; -- Fête national josdJourFerieTab["12-25"] = true; -- Noà«l -- Dates variables if (geneve) then josdJourFerieTab[jeuneGenevois(time)] = true; -- jeunes genevois else josdJourFerieTab[jeuneFederal(time)] = true; -- jeunes genevois end josdJourFerieTab[os.date("%m-%d", epochPaques)] = true; -- Pâques josdJourFerieTab[os.date("%m-%d", epochPaques+24*60*60)] = true; -- Lundi de Pâques = Pâques + 1 jour josdJourFerieTab[os.date("%m-%d", epochPaques+24*60*60*39)] = true; -- Ascension = Pâques + 39 jours josdJourFerieTab[os.date("%m-%d", epochPaques+24*60*60*50)] = true; -- Pentecôte = Ascension + 50 jours josdJourFerieTab[os.date("%m-%d", epochPaques-48*60*60)] = true; -- Vendredi-saint = Pâques - 2 jour end return josdJourFerieTab[today]; -- (nldr : Both nil and false make a condition false) end -- Calcul le jeudi qui suit le 1er dimanche de septembre function jeuneGenevois(time) local jour = 1 local annee = tonumber(os.date("%Y", time)) while (os.date("%A", os.time{year=annee, month=9, day=jour}) ~= "Sunday") do jour = jour + 1 end return os.date("%m-%d", os.time{year=annee, month=9, day=(jour+4)}) end -- Calcul le lundi qui suit le 3ème dimanche de septembre function jeuneFederal(time) local jour = 1 local annee = tonumber(os.date("%Y", time)) while (os.date("%A", os.time{year=annee, month=9, day=jour}) ~= "Sunday") do jour = jour + 1 end return os.date("%m-%d", os.time{year=annee, month=9, day=(jour+15)}) end -- Affiche le résultat function display(jour, result, label, variable, time) selfId = fibaro:getSelfId() fibaro:debug ("Jour chomé: " .. result) -- Mise à jour de la variable globale if (variable) then fibaro:setGlobal(variable, result) end -- Mise à jour du label du module virtuel fibaro:call(selfId,"setProperty","ui."..label..".value", jour .. " " .. os.date("%d.%m.%Y ",time).." Jour chomé: ".. result) end -- Lancement du calcul function doCalculate(time, label, variable) local jour = josdGetJourSemaine(os.date("%w", time)) josdJourChomeReturn = (jour=="samedi" or jour=="dimanche" or josdJourFerie(time)) if josdJourChomeReturn then display(jour, "OUI", label, variable, time) else display(jour, "NON", label, variable, time) end end doCalculate(os.time(), "Label1", "JourChome") doCalculate(os.time()+24*60*60, "Label2", "JourChomeJ1") J’exécute le code tous les jours à 00H15 depuis le Scheduler (90 étant l'ID de mon module virtuel et 3 la position du bouton) ce qui évite d'utiliser le main loop du module virtuelle et d'éventuels problèmes. luaDaySchedule:add("00:15","90", 3 , "pressButton",{"All"},true) La même chose depuis GEA. GEA.add({"Global", "", ""}, 30, "", {{"VirtualDevice", 90, 3},{"Time", "00:00", "00:01"}}) Pour choisir les jours fériés France ou Suisse (au début du code) local france = oui local suisse = non local geneve = non Merci à STEVEN pour les améliorations. Voilà un truc tout simple que j'utilise pour gérer mes volets Correction du 13/07/2014, utiliser true ou false pour la sélection des calendriers des jours fériés local france = true local suisse = false local geneve = false Correction du 14/04/2015, calcul du jeudi de l’ascension erroné Correction du 03/05/2015, calcul du jeudi de l'ascension dans la partie Suisse Correction du 25/05/2015, calcul du lundi de pentcôte
  13. Tout est dans le titre. Il s'agit d'un simple device virtuel permettant de rebooter ou arreter un serveur synology. L'idée est inspirée de la solution de Labomatik pour QNAP La solution est tres tres largement inspirée du module virtuel de lazer permettant de piloter la surveillance station ... effectivement, je n'ai pas inventé grand chose. Toute la mécanique d'authentification est issue du dev de Lazer (que je remercie au passage). Les fonctions que l'on exploite ici ne sont pas officiellement mise à dispo par l'API Synology, mais un peu de reverse engeneering permet de retrouver ce qui est fait par l'interface web du synology. La configuration est tres simple : - Paramétrer l'adresse IP et le port du device virtuel avec l'adresse ip et le port du synology ==> Il doit s'agir d'un port HTTP. La solution ne supporte pas l'HTTPS. Dans chaque bouton, remplacer les variables par un login / password existant sur votre synology. Attention : Il doit s'agir d'un utilisateur ayant des droits admin Ajouté au virtuel device de Lazer, nous voilà aussi bien équipé que les utilisateurs QNAP. Plus de jaloux! Une remarque pour ceux qui souhaitent égallement redémarrer leur synology via la HC2 : Tous les synology ne supportent pas le Wake On Lan. Plus d'info : https://www.synology.com/fr-fr/knowledgebase/faq/437 Synology.vfib Icone pour le device virtuel :
  14. sebcbien

    Modes Éclairage Auto/manuel Waf

    Bonjour, Petit partage, un VD et quelques lignes GEA pour activer/désactiver l'éclairage automatique chez moi. J'avais déjà implémenté la possibilité d'activer un mode "manuel" via un VD et 3 boutons (Automatique / Manuel / Manuel pendant 3H) Ce mode manuel était utilisé dans GEA de la manière suivante: local estHouse_Manuel = {"Global", "House_Mode", "Manual"} local estNotHouse_Manuel = {"Global", "House_Mode", "Auto|Scheduler"} GEA.add({{"Value", id2["SAM_MVT"],1},estNotHouse_Manuel}, -1, "",{{"turnOn", id2["SALLE_A_MANGER"]}}) Problème, pour activer ce mode il fallait sortir le téléphone de sa poche, pas WAF du tout et pas pratique (mon mantra en domotique: si t'a besoin de ton téléphone pour gérer ta domotique -> FAIL) Voici la solution mà»rement réfléchie: - Un interrupteur mural (ils ont l'avantage de ne pas se perdre et d'être proches ) - Un Virtual Device qui sert aussi de Variable Globale - GEA - TTS pour le feedback J'ai donc activé le paramètre 41 (Scène activation sur un FGD) et j'utilise un long press sur S2 pour basculer du mode AUTO en Manuel et vice-versa Dans GEA, je détecte cet appui long et je clique sur le bouton correspondant du VD GEA: 1894 sceneActivation 2139 ui.ModeRez.value local estLumRez_Auto = {"Label", id2["MODES_AUTO_MANUEL"], "ModeRez", "Automatique"} local estLum1er_Auto = {"Label", id2["MODES_AUTO_MANUEL"], "Mode1er", "Automatique"} local estLumGarage_Auto = {"Label", id2["MODES_AUTO_MANUEL"], "ModeGarage", "Automatique"} ----------- GESTION MODES AUTO/MANU ----------- -- Bascule mode éclairage actuel GEA.add({{"SceneActivation", id2["POUSSOIRS_HAUT"], 12}}, -1, "Switch changing Rez Auto/Manuel Mode at #time#",{{"VirtualDevice", id2["MODES_AUTO_MANUEL"], 5}}) --Annonce TTS du Mode sauf si en passage en mode Away ou Night_All_Off GEA.add({{"Label", id2["MODES_AUTO_MANUEL"], "ModeRez", ""},estNotAwayOrNigh_All_Off}, -1, "Eclairage Rez Set to Mode: #value# at #time#", {{"Inverse"},{"Label", id2["SONOS_SAY_IT"], "Message", "éclairage ré en mode #value#."},TTS_Default}) Exemple d'utilisation: - Si un soir on veut faire un jeu de nuit avec les enfants, un simple appuy sur l'interrupteur va annoncer dans les SONOS que le mode automatique à été désactivé et plus aucune lampe ne s'allumera automatiquement. - Si mon frère passe faire un baby sitting et veut regarder son film dans le noir, il peut activer le mode lui même. - Si un matin on veut profiter de la lumière du lever de soleil sans lampes Exemple de ligne GEA qui n'allume les lampes que si le mode est en auto: GEA.add({{"Value", id2["SAM_MVT"],1},estLumRez_Auto }, -1, "",{{"turnOn", id2["SALLE_A_MANGER"]}}) A chaque fois que l'alarme est mise ou que le mode nuit est activé, GEA me remet tout en automatique: ------------ WHEN AT HOME DO------------------- GEA.add(estAt_Home, -1, "", { estLumRez_Auto, estLum1er_Auto, estLumGarage_Auto }) A partir d'un autre VD, j'ai 3 boutons - Forcer tout en automatique - Manuel - Manuel pour une durée de 3H puis retour en mode automatique Bouton tout Manuel: local selfId = fibaro:getSelfId() local NewState = "Manuel" local id2 = { --Maison (Global) MODES_AUTO_MANUEL = 2139, } fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeRez.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.Mode1er.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeGarage.value", NewState); fibaro:call(selfId, "setProperty", "ui.HouseMode.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.LastChange.value", "Tout "..NewState.." à "..os.date("%H:%M")); fibaro:debug(os.date("%a %d/%m", os.time()).." Set all modes to "..NewState); Bouton tout Auto: local selfId = fibaro:getSelfId() local NewState = "Automatique" local id2 = { --Maison (Global) MODES_AUTO_MANUEL = 2139, } fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeRez.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.Mode1er.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeGarage.value", NewState); fibaro:call(selfId, "setProperty", "ui.HouseMode.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.LastChange.value", "Tout "..NewState.." à "..os.date("%H:%M")); fibaro:debug(os.date("%a %d/%m", os.time()).." Set all modes to "..NewState); Bouton manuel pour une durée de 3H (puis retour en mode automatique si tout est toujours en manuel, donc si personne n'a appuyé sur le bouton): local selfId = fibaro:getSelfId() local NewState = "Manuel" local id2 = { --Maison (Global) MODES_AUTO_MANUEL = 2139, } fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeRez.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.Mode1er.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeGarage.value", NewState); fibaro:call(selfId, "setProperty", "ui.HouseMode.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.LastChange.value", "Tout "..NewState.." pour 3H à "..os.date("%H:%M")); fibaro:debug(os.date("%a %d/%m", os.time()).." Set all modes to "..NewState.." and wait 3H"); -- sleep 3H: --fibaro:sleep(10*1000) fibaro:sleep(60*60*1000) fibaro:debug(os.date("%a %d/%m", os.time()).." 1H Done") fibaro:sleep(60*60*1000) fibaro:debug(os.date("%a %d/%m", os.time()).." 2H Done") fibaro:sleep(60*60*1000) fibaro:debug(os.date("%a %d/%m", os.time()).." 3H Done") if fibaro:getValue(id2["MODES_AUTO_MANUEL"], "ui.ModeRez.value") == "Manuel" and fibaro:getValue(id2["MODES_AUTO_MANUEL"], "ui.Mode1er.value") == "Manuel" and fibaro:getValue(id2["MODES_AUTO_MANUEL"], "ui.ModeGarage.value") == "Manuel" then NewState = "Automatique" fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeRez.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.Mode1er.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.ModeGarage.value", NewState); fibaro:call(selfId, "setProperty", "ui.HouseMode.value", NewState); fibaro:call(id2["MODES_AUTO_MANUEL"], "setProperty", "ui.LastChange.value", "Tout "..NewState.." à "..os.date("%H:%M")); fibaro:debug(os.date("%a %d/%m", os.time()).." Set all modes to "..NewState); end fibaro:debug(os.date("%a %d/%m", os.time()).." Time's up set mode Auto") --fibaro:setGlobal("House_Mode", "Scheduler") Voilà un petit apperçu et un bon cas d'utilisation de LABELS au lieu de VG Voici le VD: Et voici les icônes Modes_Auto-Manuel.vfib
  15. Ce module virtuel va crée automatiquement les variables si elles n'existent pas. Comment utiliser la table : "Nom de la variable", "1" (si prédéfinie) ou "0" (Variable Globale), "Valeur par défault", '"Valeur Prédéfinie"' -- Table variable Globale local VG_Table = { "Mode", "1", "Absent", '"Maison", "Vacances"', -- Variable Prédéfinie Mode "MPRInfo", "0", "100", -- Variable MPRInfo "Jour", "1", "Oui", '"Non"' -- Variable Prédéfinie Jour } Création des Variables Globales et Prédéfinies --************************ --Creation de Variable --- --************************ function VG_Creation(VG_Nom, VG_isEnum, VG_Value, VG_enumValues) if (fibaro:getGlobal(VG_Nom) == "") then fibaro:debug(VG_Nom.." "..VG_isEnum.." "..VG_Value) newVar = {} newVar.name = VG_Nom newVar.isEnum = tonumber(VG_isEnum) if tonumber(VG_isEnum) == 0 then newVar.value = VG_Value end HC2 = Net.FHttp("127.0.0.1", 11111) HC2:POST("/api/globalVariables", json.encode(newVar)) --------------------------------------------- -- création des valeurs prédéfinies si Besoin --------------------------------------------- if tonumber(VG_isEnum) == 1 then VG_Predefinie = '{"value":"'..VG_Value ..'","isEnum":true,"enumValues":'..'["'..VG_Value..'", '..VG_enumValues..']' ..'}' HC2:PUT("/api/globalVariables/"..VG_Nom, VG_Predefinie) end end end Lecture du tableaux et création si besoin des variables ---------------------------------------------------- -- Execution du programme ---------------------------------------------------- local j = 1 local NbreVG = 0 while VG_Table[j] ~= nil do if tonumber(VG_Table[j+1]) == 0 then fibaro:debug((NbreVG+1).." - Variable Globale") VG_Creation(VG_Table[j], VG_Table[j+1], VG_Table[j+2]) j=j+3 elseif tonumber(VG_Table[j+1]) == 1 then fibaro:debug((NbreVG+1).." - Variable prédéfinie") VG_Creation(VG_Table[j], VG_Table[j+1], VG_Table[j+2], VG_Table[j+3]) j=j+4 else fibaro:debug("Erreur dans la table VG") end NbreVG = NbreVG + 1 end fibaro:debug("Nombres de variable dans le tableau : " ..NbreVG) J'ai simplement ajouter un bouton aux VD Variables Globales de STEVEN comme cela on voit de suite si la variable n'est pas crée Petit Exercice : Optimiser ce code qui et fonctionnel mais pas très académique, il permet de crée les valeurs de la variable prédéfinie : if tonumber(VG_isEnum) == 1 then VG_Predefinie = '{"value":"'..VG_Value ..'","isEnum":true,"enumValues":'..'["'..VG_Value..'", '..VG_enumValues..']' ..'}' fibaro:debug(VG_Predefinie) HC2:PUT("/api/globalVariables/"..VG_Nom, VG_Predefinie) end Variables_Globales.vfib
  16. Gestion simple des Variables Globale en LUA Le script que je partage avec vous va vous permettre de gérer simplement les Variables globales et Variables globales prédéfinie en LUA. C'est une adaptation du code de STEVEN Avantage : Il permet de faire une sauvegarde des Variables globales ce qui est bien pratique lorsque l'on fait un recovery Il permet de créé des variables globales prédéfinie ou pas très simplement à partir d'une scène ou d'un VD sans avoir à sortir artillerie lourde. Voici le code a mettre dans une Scéne : --[[ %% properties %% globals GestionVG --]] local trigger = fibaro:getSourceTrigger() local variables = {} local variablesASupprimer ={} -- creation de ou des VG avec la variable GestionVG if (trigger['type'] == 'global') then fibaro:debug('Global variable source = ' .. trigger['name']) variables = json.decode((fibaro:getGlobal('GestionVG'))); if variables == nil then fibaro:abort() end -- creation de ou des VG manuellement ou par une autre scène ou un appel API elseif (trigger['type'] == 'other') then fibaro:debug('Global variable source = ' .. 'Other source.') variables = { {nom = "GestionVG", valeur = ""}, -- Gestion de VG -- Ex : Variable Globale predefini avec valeur1 pour valeur par default {nom = "Test1", valeur = "Valeur1", choix = {"Valeur2", "Valeur3"}}, -- Ex : Variable Globale qui à pour valeur 0 {nom = "Test2", valeur = "0"}, } variablesASupprimer = { {nom = "Test1"}, {nom = "Test2"} } end ------------------------------------------------- ---- Merci a STEVEN pour ce code -- ----------------------------------------------- -- Supprime une variable -- ----------------------------------------------- function supprimer(nom) local http = net.HTTPClient() http:request("http://127.0.0.1:11111/api/globalVariables/"..nom, { options = { method = 'DELETE' } , success = function(response) fibaro:debug(nom .. " supprimée avec succès") end, error = function(response) fibaro:debug(nom .. " ERROR !!!") end, }) end -- ----------------------------------------------- -- Modifie une variable -- ----------------------------------------------- function modifier(nom, valeur, choix) local variable = {} variable.value = valeur variable.isEnum = false if (type(choix) ~= "nil") then variable.isEnum = true table.insert(choix, 1, valeur) variable.enumValues = choix end local http = net.HTTPClient() http:request("http://127.0.0.1:11111/api/globalVariables/"..nom, { options = { method = 'PUT', data = json.encode(variable) }, success = function(response) fibaro:debug(nom .. " modifiée avec succès") end, error = function(response) fibaro:debug(nom .. " ERROR !!!") end, }) end -- ----------------------------------------------- -- Ajoute une variable -- ----------------------------------------------- function ajouter(nom, valeur, choix) local enum = 0 if (type(choix) ~= "nil") then enum = 1 end local http = net.HTTPClient() http:request("http://127.0.0.1:11111/api/globalVariables", { options = { method = "POST", data = json.encode({name=nom, isEnum=enum}) }, success = function(response) fibaro:debug(nom .. " créé avec succès") modifier(nom, valeur, choix) end, error = function(response) fibaro:debug(nom .. " ERROR !!!") end, }) end -- ----------------------------------------------- -- Voir si une variable existe ou non -- et la modifier ou créer -- ----------------------------------------------- function traiter(nom, valeur, choix) if (fibaro:getGlobalValue(nom) == nil) then ajouter(nom, valeur, choix) else -- modifier(nom, valeur, choix) end end ---------------------------------------------------- -- Execution du programme ---------------------------------------------------- for _,v in ipairs(variables) do traiter(v.nom, v.valeur, v.choix) end for _,v in ipairs(variablesASupprimer) do supprimer(v.nom) end Dans un premier temps il va falloir exécuter le script manuellement afin qu'il crée la VG GestionVG cette VG va être utiliser pour crée les variables globale à partir de n'importe quel script Lua Exemple d'utilisation : Création d'une variables globales "Test2" avec la valeur 0 local variables = { {nom = "Test2", valeur = "0"}, } fibaro:setGlobal('GestionVG',json.encode(variables)) Création d'une variables globales prédéfinie "Test1" avec Valeur1 , Valeur2 et Valeur3, vValeur1 sera la valeur par défaut dans cette exemple local variables = { {nom = "Test1", valeur = "Valeur1", choix = {"Valeur2", "Valeur3"}}, } fibaro:setGlobal('GestionVG',json.encode(variables)) Création de plusieurs variable globales prédéfinie ou pas en une seul fois local variables = { {nom = "Test1", valeur = "Valeur1", choix = {"Valeur2", "Valeur3"}}, {nom = "Test2", valeur = "0"}, } fibaro:setGlobal('GestionVG',json.encode(variables)) Création et suppression de variables via la scéne il faut modifier le code suivant, la méthode est la même que les exemples si dessus. Lors de l'exécution de la scene en mode manuel les variables seront créés si elle n'existe pas. elseif (trigger['type'] == 'other') then fibaro:debug('Global variable source = ' .. 'Other source.') variables = { {nom = "GestionVG", valeur = ""}, -- Gestion de VG -- Ex : Variable Globale predefini avec valeur1 pour valeur par default {nom = "Test1", valeur = "Valeur1", choix = {"Valeur2", "Valeur3"}}, -- Ex : Variable Globale qui à pour valeur 0 {nom = "Test2", valeur = "0"}, } variablesASupprimer = { {nom = "Test1"}, {nom = "Test2"}, } Ce code est fonctionnel chez moi, par manque de temps je ne pourrais vous aidez si vous avez des soucis de compréhension sur la création des VG ou leurs suppression
  17. cboubou

    Module Virtuel "smartvmc"

    Bonjour la communauté, Je vous propose aujourd'hui mon module virtuel "SmartVMC". Ce dernier me permet de piloter de manière automatique ma VMC en fonction de la qualité de l'air de ma maison : On allume la VMC si le taux moyen d'humidité relative est supérieur à 60% OU si la concentration moyenne de CO2 est supérieure à 1000 ppm. Le traitement s'arrêtera si le taux moyen d'humidité relative est inférieur ou égal à 55% ET si la concentration moyenne de CO2 est inférieure ou égale à 900 ppm. Le but étant de ne pas allumer/éteindre la VMC dès que l'on atteint la limite de 60% ou de 1000 ppm. Les données sur la qualité de l'air (humidité relative et concentration de CO2) sont extraites de ma Netatmo par le biais du plugin idoine disponible dans la V4. Ma configuration matérielle est la suivante : VMC simple flux, hygroréglable, Aldès, MicroWatt. Home Center 2 en version v4.033. WallPlug Fibaro pour piloter la VMC. Station Netatmo avec modules additionnels. Le module virtuel se présente de la sorte : Un visuel des moyennes d'humidité relative et de concentration de CO2. Un bouton permettant d'analyser à l'instant "t" l'air de la maison. Un visuel de l'état actuel de la VMC. Un bouton de marche forcée de la VMC. Un bouton d'arrêt complet de la VMC. Un bouton pour basculer la VMC en mode automatique. La date de la dernière analyse de l'air. Les 4 états différents de la VMC sont les suivants : Marche Forcée Arrêt Complet Auto (En cours...) Auto (Pause) Il est nécessaire de créer 2 variables globales : Une première variable globale "VMC" est utilisée afin de savoir si la VMC est : en marche automatique, en pause, en marche forcée ou arrêtée (Auto, Pause, Forcée, Arrêtée). Une seconde variable globale "RecyclAir" est utilisée afin de savoir si la VMC est déjà en train d'assainir l'air, par le biais de ce traitement (Oui, Non). J'ai commenté le code afin d'en faciliter la compréhension. NB : Il peut être envisageable pour les personnes possédant une VMC à 2 vitesses que le mode "Auto (En cours...)" corresponde à la grande vitesse et que le mode "Auto (Pause)" corresponde à la petite vitesse. Voici les icônes (2 variantes) : Orange => Marche Forcée Rouge => Arrêt Complet Vert => Auto (En cours...) Bleu => Auto (Pause) Les originaux qui m'ont servi de base sont ici : http://www.domotique...zibase/?p=25155 Vous trouverez également de magnifiques icônes pour la Netatmo ici (merci Stef). ChangeLog => v1.0 : Création du module. v1.1 : Ajout du push lors du passage "En cours" <=> "Pause". Modification des conditions du passage au mode "Auto". Ajout d'un contrôle sur l'état du plugin Netatmo pour mode "Auto". SmartVMC.vfib
  18. jojo

    Backup Variables

    Le soucis de bon nombre d'entre nous est le fait qu'on soit lié à un backup sur une clé USB propriété de Fibaro. L'excellent tuto de Lazer explique comment faire un backup de la clé, mais il faut avoir des connaissances Linux, que perso je n'ai pas. Merci à mprinfo pour son tuto sur la création des variables en LUA qui m'a donné l'idée et les premières infos pour le restore. Merci également à Steven pour son script de génération des ID dont je me suis inspiré pour faire le backup. Alors, ici, je vous présente mon premier couple scène / VD de backup / restore, d'une série que j'espère longue … Avec la scène en mode débug, on crée le backup des variables. On colle le résultat du debug de la scène dans le bouton restore du VD (que vous exportez sur votre disque dur), et en cliquant sur le bouton Restore, il recrée les variables si elles n'existaient pas. Si vous lancez le restoreen Debug, vous avez un débug détaillé de ce qu'il a fait. C'est très utile pour faire un restore sur une nouvelle box (ou après un recovery) Les instructions se trouvent dans le code de la main loop. Version 2.0 : Backup_Variables_v2.0.vfib Backup_Variables_v2.0.lua Version 1.0 : Backup_Variables_v1.0.vfib Backup_Variables_v1.0.lua
  19. Watchdog Version 1.3 Voici une scène permettant de surveiller le fonctionnement des Scènes et Main Loop de Modules Virtuels sur Home Center 2 en version 4.x. Pour ce faire, les messages de la fenêtre de Debug sont analysés. De plus, pour les scènes uniquement, le nombre d'instances est compté. En cas de problème détecté, la scène ou le virtual device considéré est automatiquement redémarré, et une notification peut être envoyée. Copier/coller le script LUA suivant dans une nouvelle scène : --[[ %% autostart %% properties %% globals --]] -------------------------------------------------- -- Scene : Watchdog -- Author : Lazer -- Version : 1.3 -- Date : June 2017 -------------------------------------------------- -- User variables local intervalle = 60 local delay = 15*60 local watchdog = { } local userID = {} -- Email local smartphoneID = {} -- Push local sms = { ["VD_ID"] = 0, -- Virtual Device ID ["VD_Button"] = "1", -- Virtual Device Button ["VG_Name"] = "SMS" -- Global Variable Name } local debug = false -- -- Message function -- function Message(color, message) if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..(message or '<nil>')..'</span>') else fibaro:debug(message or '<nil>') end end -- -- Notification function -- function Notification(message, param) local message = message or "<vide>" Message("yellow", "Notification : "..message) if param then for _, notif in ipairs(param) do if debug then Message("grey", notif) end -- Envoi Push if notif == "push" and smartphoneID then for _, id in ipairs(smartphoneID) do if debug then Message("grey", "Send Push smartphone ID : "..id) end fibaro:call(id, "sendPush", message) end -- Envoi Email elseif notif == "email" and userID then for _, id in ipairs(userID) do if debug then Message("grey", "Send Email user ID : "..id) end fibaro:call(id, "sendEmail", "HC2 Watchdog", message) end -- Envoi SMS elseif notif == "sms" and sms then if debug then Message("grey", "Send SMS : VD_ID="..(sms["VD_ID"] or 0).." VD_Button="..(sms["VD_Button"] or "0").." VG_Name="..(sms["VG_Name"] or "")) end fibaro:setGlobal(sms["VG_Name"], message) if sms["VD_ID"] and tonumber(sms["VD_ID"])>0 and sms["VD_Button"] and tonumber(sms["VD_Button"])>0 then fibaro:call(sms["VD_ID"], "pressButton", sms["VD_Button"]) end end end else Message("orange", "Warning : no notification options given") end end -- -- Restart function -- function Restart(type, id, restart, notification, reason) Message("blue", 'Restart '..type..'('..id..')') -- Prepare API URL local getURL = "" local putURL = "" if type:lower() == "scene" then getURL = 'http://127.0.0.1:11111/api/scenes/'..id putURL = 'http://127.0.0.1:11111/api/scenes/'..id elseif type:lower() == "vd" then getURL = 'http://127.0.0.1:11111/api/virtualDevices/'..id putURL = 'http://127.0.0.1:11111/api/virtualDevices/'..id end -- Load VD/Scene local httpClient = net.HTTPClient() httpClient:request(getURL, { success = function(response) if response.status == 200 then local jsonTable = json.decode(response.data) local name = jsonTable.name or "" if restart and restart == true then -- Add new line at end of scene lua code if type:lower() == "scene" and jsonTable.lua then jsonTable.lua = jsonTable.lua .. "\n" response.data = json.encode(jsonTable) end -- Save VD/Scene httpClient:request(putURL, { success = function(response) if response.status == 200 then Message("green", type.."("..id..") successfully restarted") Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") a été redémarré : "..(reason or "???"), notification) else Message("red", type.."("..id..") Error : status="..tostring(response.status)) Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end end, error = function(err) Message("red", type.."("..id..") Error : "..err) Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end, options = { method = 'PUT', -- headers = { -- ["content-type"] = 'application/x-www-form-urlencoded;' -- }, data = response.data } }) else Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") doit être redémarré manuellement : "..(reason or "???"), notification) end else Message("red", type.."("..id..") Error : status="..tostring(response.status)) Notification('Watchdog : '..type..' ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end end, error = function(err) Message("red", type.."("..id..") Error : "..err) Notification('Watchdog : '..type..' ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end, options = { method = 'GET' } }) end -- function -- -- Check function -- function Check(interval) Message(nil, "Check") -- Browse VD/Scene list local httpClient = net.HTTPClient() local elements = #watchdog for i = 1, elements do -- Initialization local countscene_found = false if debug then Message(nil, "Check : type="..watchdog[i].type.." id="..watchdog[i].id) end -- Check number of running scene instances if watchdog[i].type:lower() == "scene" and watchdog[i].count and watchdog[i].count > 0 then local countScenes = fibaro:countScenes(watchdog[i].id) if countScenes < watchdog[i].count then Message("orange", watchdog[i].type..'('..watchdog[i].id..') '..countScenes..' running instance') countscene_found = true Restart(watchdog[i].type, watchdog[i].id, watchdog[i].restart, watchdog[i].notification, countScenes..' instance') elseif debug then Message("green", watchdog[i].type..'('..watchdog[i].id..') '..countScenes.." running instance") end end if countscene_found == false then -- Do not enter this loop if scene has already been restarted -- Prepare API URL local getURL = "" if watchdog[i].type:lower() == "scene" then getURL = "http://127.0.0.1:11111/api/scenes/"..watchdog[i].id.."/debugMessages" elseif watchdog[i].type:lower() == "vd" then getURL = "http://127.0.0.1:11111/api/virtualDevices/"..watchdog[i].id.."/debugMessages/0" else Message("red", "Error : unknown type value") end if getURL ~= "" then if debug then Message("grey", getURL) end -- Load VD/Scene debug messages httpClient:request(getURL, { success = function(response) if response.status == 200 then if response.data and response.data ~= "" then local jsonTable = json.decode(response.data) local current_timestamp = os.time() local oldest_timestamp = current_timestamp local match_found = false local no_match_found = false local reason = "" -- Reverse browsing of debug messages for j = #jsonTable, 1, -1 do oldest_timestamp = jsonTable[j].timestamp -- Check if debug message match lookup string within allowed interval if watchdog[i].match.text and watchdog[i].match.text ~= "" and watchdog[i].match.interval > 0 and jsonTable[j].txt:match(watchdog[i].match.text) then if jsonTable[j].timestamp > current_timestamp - watchdog[i].match.interval then if debug then Message("green", watchdog[i].type..'('..watchdog[i].id..') Found string "'..watchdog[i].match.text..'"') end match_found = true end end -- Check if debug message match forbidden string if watchdog[i].no_match.text and watchdog[i].no_match.text ~= "" and jsonTable[j].txt:match(watchdog[i].no_match.text) then Message("orange", watchdog[i].type..'('..watchdog[i].id..') Found string "'..watchdog[i].no_match.text..'"') no_match_found = true reason = os.date('%H:%M:%S', (jsonTable[j].timestamp or 0)) .. " " .. jsonTable[j].type .. " : " .. jsonTable[j].txt break end if watchdog[i].no_match.type and watchdog[i].no_match.type ~= "" and jsonTable[j].type == watchdog[i].no_match.type then Message("orange", watchdog[i].type..'('..watchdog[i].id..') Found type "'..watchdog[i].no_match.type..'"') no_match_found = true reason = os.date('%H:%M:%S', (jsonTable[j].timestamp or 0)) .. " " .. jsonTable[j].type .. " : " .. jsonTable[j].txt break end end -- for if debug and oldest_timestamp > current_timestamp - watchdog[i].match.interval then Message("grey", watchdog[i].type..'('..watchdog[i].id..') oldest debug timestamp more recent than interval') end -- Restart VD/Scene if watchdog[i].match.text and watchdog[i].match.text ~= "" and watchdog[i].match.interval > 0 and match_found == false and oldest_timestamp < current_timestamp - watchdog[i].match.interval then Message("orange", watchdog[i].type..'('..watchdog[i].id..') String "'..watchdog[i].match.text..'" not found') reason = 'Chaine « ' .. watchdog[i].match.text .. ' » non trouvée' if #jsonTable > 0 then reason = reason .. ', dernier message : ' .. os.date('%H:%M:%S', (jsonTable[#jsonTable].timestamp or 0)) .. ' « ' .. (jsonTable[#jsonTable].txt or "<nil>") .. ' »' end Restart(watchdog[i].type, watchdog[i].id, watchdog[i].restart, watchdog[i].notification, reason) --if watchdog[i].no_match.text and watchdog[i].no_match.text ~= "" and no_match_found == true then elseif no_match_found == true then Restart(watchdog[i].type, watchdog[i].id, watchdog[i].restart, watchdog[i].notification, reason) end else Message("red", "Error : empty response") end else Message("red", "Error : status=" .. tostring(response.status)) end end, error = function(err) Message("red", 'Error : ' .. err) end, options = { method = 'GET' } }) end end end -- for -- Wait if interval and interval > 0 then setTimeout(function() Check(interval) end, interval*1000) end end -- function -- -- Main loop -- local trigger = fibaro:getSourceTrigger() if trigger["type"] == "autostart" then Message(nil, "Watchdog instance autostart") -- Check function call delayed to prevent killing all other scenes not already started right after HC2 boot setTimeout(function() Check(intervalle) end, delay*1000) else Message(nil, "Watchdog instance manual launch") -- Call Check function Check(nil) end . Le paramétrage du script s'effectue dans les quelques lignes situées sous le commentaire "User variables" : intervalle : durée entre 2 vérifications delay : délai avant la première vérification. En effet, cette scène ayant la propriété autostart afin de démarrer automatiquement au boot de la box, le risque est de démarrer avant les autres Scène/VD, et de forcer un redémarrage de ceux-ci alors qu'ils n'ont pas encore effectivement démarré. Ce délai laisse donc aux autres Scène/VD le temps de démarrer et de s'initialiser proprement. watchdog : tableau dont chaque ligne représente une Scène ou un Virtual Device à monitorer : type : "Scene" ou "VD" id : valeur numérique représentant l'ID de la Scène ou VD à monitorer match : texte qui doit être trouvé pendant un certain laps de temps afin de confirmer le bon fonctionnement du VD/Scène. Cela correspond typiquement à un message affiché cycliquement à intervalle régulier. Les 2 champs suivants doivent être renseignés pour que la condition soit prise en compte (condition ET) : text : chaine de caractères à trouver interval : durée en secondes no_match : texte qui ne doit pas être trouvé, sous peine de considérer le VD/Scène comme planté. Cela correspond typiquement à un message d'erreur LUA qui entraine le plantage du script. A noter que la condition no_match à priorité sur la condition match, c'est à dire que si le texte recherché par no_match est détecté, le VD/Scène sera redémarrer même si le texte recherché par match a été détecté. L'un ou l'autre des 2 champs suivants peuvent être renseignés pour que la condition soit prise en compte (condition OU) : text : chaine de caractères à trouver type : "ERROR" correspond aux messages affichés en rouge dans la fenêtre de Debug de l'interface HC2. A noter que jusqu'en v4.056, dans une scène une erreur LUA affichait le message en rouge avec le type "ERROR", tandis que depuis les Beta v4.057 et v4.058, cette même erreur s'affiche en blanc sans le type ERROR, par conséquent ce test ne fonctionne plus. En revanche, aucun changement de mode de fonctionnement concernant les Virtual Devices. count : valeur valable pour les scènes uniquement, et indiquant le nombre minimal d'instances qui doivent fonctionner pour confirmer le bon fonctionnement de la scène. Cela correspond typiquement à l'instance de type boucle infinie lancée en autostart. restart : true ou false afin de redémarrer le VD/Scène concerné, ou seulement envoyer une notification signalant qu'il faut le redémarrer manuellement. notification : liste séparée par des virgules des moyens de notifications à employer. userID : liste séparée par des virgules des ID des utilisateurs qui doivent recevoir des notifications par email (le mail est celui configuré pour chaque utilisateur dans le panneau de contrôle d'accès) smartphoneID : liste séparée par des virgules des ID des smartphones qui doivent recevoir des notifications push (à récupérer dans le toolkit de Krikroff ou via l'API : /api/iosDevices) sms : si vous avez une passerelle SMS sous Android avec SMS Gateway (ou équivalent) pilotée par un module virtuel, il faut renseigner ici les informations nécessaires : VD_ID : ID du module virtuel VD_Button : ID du bouton du module virtuel VG_Name : nom de la variable globale debug : true ou false afin d'activer l'affichage étendu dans la fenêtre de débugage de la scène. Exemple de paramètres : -- User variables local intervalle = 60 local delay = 15*60 local watchdog = { {type = "Scene", id = 1, match = {text="", interval=0}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email", "sms"}}, -- Présence Lazer {type = "Scene", id = 2, match = {text="Last run", interval=2*60}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email", "sms"}}, -- DomoCharts {type = "Scene", id = 3, match = {text="Durée des traitements", interval=11*60}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email", "sms"}}, -- GEA {type = "VD", id = 1, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Surveillance Station {type = "VD", id = 2, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Clock Sync {type = "VD", id = 3, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- My Batteries {type = "VD", id = 4, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Evénements {type = "VD", id = 5, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Network Monitor {type = "VD", id = 6, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- GEA Alarm {type = "VD", id = 7, match = {text=" ", interval=30}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Sonos Player (Tk.isTraceEnabled = true) {type = "VD", id = 8, match = {text="Start main process", interval=31*60}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}} -- Freebox Serveur } local userID = {1} -- Email local smartphoneID = {1, 2} -- Push local sms = { ["VD_ID"] = 99, -- Virtual Device ID ["VD_Button"] = "1", -- Virtual Device Button ["VG_Name"] = "SMS" -- Global Variable Name } local debug = false
  20. Utilisation de fibaro:call en fonction du module commandé Voici un lien qui vous donnera les actions que l'on peut utiliser pour chaque type de modules fibaro http://www.fibarouk.co.uk/support/lua/actions-use-fibarocall-api/ armed close firmwareUpdate open pollingDeadDevice pollingTimeSec pressButton requestNodeNeighborUpdate resetMeter sendDefinedEmailNotification sendDefinedPushNotification sendDefinedSMSNotification sendEmail sendGlobalEmailNotifications sendGlobalPushNotifications sendGlobalSMSNotifications sendPhotoToEmail sendPhotoToUser sendPush sendSipUserID setArmed setB setColor setG setProperty setProtectionLocalAndRF setR setSipDisplayName setSipUserID setSipUserPassword setSlider setTargetLevel setTime setValue setValue2 setW startProgram stop turnOff turnOn close Application pour : blind Description: Closes a blind. Usage: This action takes no arguments. Exemple: -- Close the blind with the device ID of 94 fibaro:call(94, "close") open Application pour : blind Description: Opens a blind. Usage: This action takes no arguments. Exemple: -- Open the blind with the device ID of 94 fibaro:call(94, "open") pressButton Application pour : virtual_device Description: Triggers a virtual device button press. Usage: This action takes one argument. The number of the button to be pressed. Each element of a virtual device has a unique number starting from 1. If your virtual device has two labels followed by two buttons, the buttons will be numbered 3 and 4. Exemple: -- Trigger a button press of button 3 of -- the virtual device with an ID of 358 fibaro:call(358, "pressButton", "3") sendDefinedEmailNotification Application pour : HC_user Description: Sends a notification to the email address associated with a user. Usage: This action takes one argument. The id of the notification to be sent. Exemple: 1-- Send notification 2 via email to the -- address associated with user 107. fibaro:call(107, "sendDefinedEmailNotification", "2") sendDefinedPushNotification Application pour : iOS_device Description: Sends a push notification to a device. Usage: This action takes one argument. The id of the notification to be sent. Exemple: -- Send notification 2 via push to modile device number 10. fibaro:call(10, "sendDefinedPushNotification", "2") sendDefinedSMSNotification Application pour : HC_user Description: Sends an SMS notification to a phone number. Usage: This action takes two arguments. The phone number to send the message to.This should be in the form xxyyyyyyyyy where xx = country code and yyyyyyyyy = phone number. The id of the notification to be sent. Exemple: -- Send notification 3 via SMS to device number +441234567890. fibaro:call(2, "sendDefinedSMSNotification", "441234567890", "3") sendEmail Application pour : HC_user Description: Sends an email to the email address associated with a user. Usage: This action takes two arguments. The subject of the email. The message body of the email. Exemple: -- Send an email to the email address associated with user 2. local subject = "This is the subject of the email." local message = "This is the body of the email.\nWith a line break." fibaro:call(2, "sendEmail", subject, message) sendPhotoToEmail Application pour : IP_camera Description: Sends a still image from a camera to a specified email address. Usage: This action takes one argument. The email address to send the image to. Exemple: -- Send an image from camera 120 to someone@this.address. fibaro:call(120, "sendPhotoToEmail", "someone@this.address") sendPhotoToUser Application pour : IP_camera Description: Sends a still image from a camera to the email address associated with a user. Usage: This action takes one argument. The id number of the user to send the image to. Exemple: -- Send an image from camera 120 to -- the email address associated with user 2. fibaro:call(120, "sendPhotoToUser", "2") sendPush Application pour : iOS_device Description: Sends a push notification to an iOS device. The device must have connected with the Home Centre recently, however once this connection has been made the app can be closed. Usage: This action takes one argument. The message to be pushed to the device. Exemple: -- Send a push notification to the iOS device with the ID of 10 fibaro:call(10, 'sendPush', 'This is the message to be pushed.') setArmed Application pour : motion_sensor, door_sensor, window_sensor, smoke_sensor Description: Arms or disarms a device. Usage: This action takes one argument. The armed state of the device. 0 = disarmed, 1 = armed. Exemple: -- Arm the door sensor with device ID of 174 fibaro:call(174, "setArmed", "1") -- Disarm the door sensor with device ID of 174 fibaro:call(174, "setArmed", "0") setB Application pour : rgb_driver Description: Sets the brightness of the blue channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the blue channel of device 81 to 56% fibaro:call(81, "setB", "56") setColor Application pour : rgb_driver Description: Sets the colour of an rgb_driver. This is done by setting the brightness of the red, green, blue and white channels. Usage: This action takes four arguments. The brightness (0-99) of the red channel. The brightness (0-99) of the green channel. The brightness (0-99) of the blue channel. The brightness (0-99) of the white channel. Even if the device is in RGB mode, the white channel needs to be specified – in this case, just use 0. Exemple: -- Set the colour of device 81 to a blue-indigo colour -- (60% red, 23% green, 99% blue, 0% white) fibaro:call(81, "setColor", "60", "23", "99", "0") setG Application pour : rgb_driver Description: Sets the brightness of the green channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the green channel of device 81 to 56% fibaro:call(81, "setG", "56") setProperty Application pour : virtual_device Description: Sets value of the elements of a virtual device (labels and sliders). Usage: This action takes two arguments. The name of the element. The value to set the element to. Exemple: -- Set the content of Label1 in virtual device 1170 to 'program 1' fibaro:call(1170, "setProperty", "ui.Label1.value", "program 1") -- Set the value of Slider1 in virtual device 1170 to 45 fibaro:call(1170, "setProperty", "ui.Slider1.value", "45") setR Application pour : rgb_driver Description: Sets the brightness of the red channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the red channel of device 81 to 56% fibaro:call(81, "setR", "56") setSlider Application pour : virtual_device Description: Triggers a change in the value of a virtual device slider. Usage: This action takes two arguments. The number of the slider to be changed. Each element of a virtual device has a unique number starting from 1. If your virtual device has two labels followed by two buttons and then a slider, the slider will be numbered 5. The value (0-99) to set the slider to. Exemple: -- Set the slider with an ID of 2 of the -- virtual device with an ID of 334 to 50% fibaro:call(334, "setSlider", "2", "50") setTargetLevel Application pour : thermostat_setpoint Description: Sets the target temperature of a thermostat_setpoint. Usage: This action takes one argument. A temperature in degrees. Exemple: -- Set the target temperature of device 117 to 18 degrees. fibaro:call(117, "setTargetLevel", "18") setTime Application pour : thermostat_setpoint Description: Sets the value of the timeStamp property of the thermostat_setpoint. Usage: This action takes one argument. A timestamp. Exemple: -- Set the timeStamp of the thermostat_setpoint -- with device ID of 117 to 2 hours from now. fibaro:call(117, "setTime", tonumber(os.time()) + 120*60) setValue Application pour : dimmable_light, blind, rgb_driver Description: Sets the brightness of a dimmable_light or rgb_driver or sets the position of a blind. When changing the brightness of rgb_drivers, all channels are set to the same level (white light). Usage: This action takes one argument. A value (0-99) representing the brightness of the light or position of the blind. For a blind, 0 = fully closed, 99 = fully open. Exemple: -- Set the brightness of the light with device ID of 68 to 25%. fibaro:call(68, "setvalue", "25") -- Set the position of the blind with the device ID of 94 to 75% open. fibaro:call(94, "setvalue", "75") setW Application pour : rgb_driver Description: Sets the brightness of the white channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the white channel of device 81 to 56% fibaro:call(81, "setW", "56") startProgram Application pour : rgb_driver Description: Instruct the rgb_driver to play one of the preconfigured colour programmes. Usage: This action takes one argument. The light programme number to run. Exemple: -- Start programme number 2 ("storm") on device number 81 fibaro:call(81, "startProgram", "2") stop Application pour : blind Description: Stops the movement of a blind. Usage: This action takes no arguments. Exemple: -- Stop the blind with the device ID of 94 fibaro:call(94, "stop") turnOff Application pour : binary_light, dimmable_light, rgb_driver Description: Turns off a device. Usage: This action takes no arguments. Exemple: -- Turn off device number 58. fibaro:call(58, "turnOff") turnOn Application pour : binary_light, dimmable_light, rgb_driver Description: Turns on a device. Usage: This action takes no arguments. Exemple: -- Turn on device number 58. fibaro:call(58, "turnOn")
  21. Lazer

    Network Monitor

    Network Monitor Version 1.20 Voici un module virtuel permettant de surveiller plusieurs équipements sur le réseau local (et aussi sur Internet), et d'envoyer des notifications en cas de problème détecté. Icônes : Je propose ces 2 icônes, mais d'autres icônes sont disponibles dans les pages du topic : Configuration : Après import du module virtuel, modifier la section "User Variables" du 1er bouton du module virtuel : -- User variables local userID = {5} -- Mail local smartphoneID = {73, 127} -- Push local sms = { ["VD_ID"] = 98, -- Virtual Device ID ["VD_Button"] = "1", -- Virtual Device Button ["VG_Name"] = "SMS" -- Global Variable Name } local icons = { ["OK"] = 1028, -- Normal Icon ID ["Error"] = 1045 -- Error Icon ID } local DEVICES = { -- ["Service Name"] = { IP Address , Port, Protocol, Data to send, Expected return code, Expected data, Retry, {Notification methods}, VG, VG }, ["Eco-Devices"] = {"192.168.1.1", 80, "http", "/index1.htm", 200, "Eco Devices" , 1, {"push", "email", "sms"}, nil, nil}, ["HP ProLiant Remote Access Card"] = {"192.168.1.2", 80, "http", "/login.html", 200, "Remote Access Card" , 1, { "email" }, nil, {"Vacances", "1"}}, ["HP ProLiant Gen8 ILO"] = {"192.168.1.3", 443, "tcp", "", nil, "" , 1, { "email" }, nil, nil}, ["ESXi"] = {"192.168.1.4", 80, "http", "/", 301, "" , 1, {"push", "email", "sms"}, nil, nil}, ["Synology DiskStation"] = {"192.168.1.5", 5000, "http", "/webman/index.cgi", 200, "DiskStation" , 1, {"push", "email", "sms"}, nil, nil}, ["Raspberry PI"] = {"192.168.1.6", 80, "http", "/", 200, "Welcome to nginx" , 1, {"push", "email", "sms"}, nil, nil}, ["Sonos"] = {"192.168.1.7", 1400, "http", "/status", 200, "Options" , 1, {"push", "email" }, nil, {"Vacances", "1"}}, ["SMS Gateway"] = {"192.168.1.8", 9090, "http", "/", 200, "Welcome to SMS Gateway" , 5, {"push", "email" }, nil, nil}, ["VRT-IP"] = {"192.168.1.9", 80, "http", "/", 200, "Volets Roulant de Toit" , 1, {"push", "email" }, nil, nil}, ["IPX800"] = {"192.168.1.10", 80, "http", "/user/index2.htm", 200, "IPX800" , 1, {"push", "email" }, nil, nil}, ["Foscam"] = {"192.168.1.11", 88, "http", "/", 200, "IPCam Client" , 1, {"push", "email", "sms"}, nil, {"Vacances", "0"}}, ["Hikvision"] = {"192.168.1.12", 80, "http", "/doc/page/login.asp", 200, "login" , 1, {"push", "email", "sms"}, nil, nil}, ["HAproxy"] = {"192.168.1.13", 80, "http", "/", 503, "" , 1, {"push", "email", "sms"}, nil, nil}, ["FHEM"] = {"192.168.1.14", 8083, "http", "/fhem", 200, "EnOcean" , 1, {"push", "email", "sms"}, nil, nil}, ["Freebox"] = {"192.168.1.15", 80, "http", "/login.php", 200, "Freebox OS" , 1, { "sms"}, nil, nil}, ["OpenVPN"] = {"192.168.1.16", 443, "tcp", "", nil, "" , 1, { "email", "sms"}, nil, nil}, ["Redhat"] = {"192.168.1.17", 22, "tcp", nil, nil, "OpenSSH" , 1, { "email" }, nil, nil}, ["Google"] = {"www.google.fr", 80, "http", "/", 200, "Recherche Google" , 1, { "sms"}, nil, nil}} } local debug = false userID : liste séparée par des virgules des ID des utilisateurs qui doivent recevoir des notification par email (le mail est celui configuré pour chaque utilisateur dans le panneau de contrôle d'accès) smartphoneID : liste séparée par des virgules des ID des smartphones qui doivent recevoir des notifications push (à récupérer dans le toolkit de Krikroff ou via l'API : /api/iosDevices) sms : si vous avez une passerelle SMS sous Android avec SMS Gateway (ou équivalent) pilotée par un module virtuel, il faut renseigner ici les informations nécessaires. icons : si vous avez 2 icônes personnalisées, remplacer les valeurs nil par les ID numériques de vos icones (à trouver dans /api/icons) DEVICES : c'est la partie la plus longue à paramétrer, pour cela je vous ai laissé un exemple de tout ce que je monitore chez moi (j'ai juste changé les IP). C'est assez parlant, vous pouvez copier/coller en respectant bien la syntaxe. A noter que si l'avant-dernière colonne qui contient le nom facultatif d'une variable globale à incrémenter, celle-ci est automatiquement créée par le module. La dernière colonne permet d'annuler le monitoring d'un équipement particulier en fonction de la valeur d'une variable globale. debug : true ou false afin d'activer l'affichage étendu dans la fenêtre de débugage du bouton du module virtuel. Dans la Main Loop, le code est de Steven. Il y a une variable nbHeure permettant de paramétrer l'intervalle de vérification, par défaut à 1 heure. Si vous voulez un rafraichissement inférieur à 40 minutes, il suffit de tout remplacer par un simple fibaro:sleep(), car cette fonction ne plante pas pour les durées inférieures. Network_Monitor_v1.01.vfib Network_Monitor_v1.10.vfib Network_Monitor_v1.20.vfib
  22. Steven

    Evénements

    Evénements Module virtuel pour afficher les derniers événements Lorsque l'on fait des tests, il est parfois pratique d'avoir la liste des derniers événements ayant eu lieu sur notre HC2. Voici donc mon dernier module virtuel avant les vacances :-) Comme vous pouvez le voir, ce module affiche les 10 événements en oubliant volontairement les modules de températures. Si vous voulez voir plus d'événements, il vous faudra rajouter vous-même des labels en faisant juste attention que leur ID suivent la numérotation Label11, Label12, Label13, ... et modifier la position du bouton rafraîchir dans le Main Loop. J'ai volontairement ajouté la pièce pour certaine personne qui se reconnaîtrons Ce dernier affiche donc : Le nom du module concerné La pièce dans laquelle il se trouve Son ancienne valeur Sa nouvelle valeur L'heure de l'événement Ce module se rafraîchi automatiquement toutes les 3 secondes . . . Installation Il vous suffit juste d'importer le module virtuel ci-joint puis de modifier votre pseudonyme et mot de passe qui se trouve dans le bouton Rafraichir local user = "admin" local pwd = "password" HC2 = Net.FHttp("127.0.0.1",80) HC2:setBasicAuthentication(user, pwd) ... Cordialement Evenements.vfib
  23. Voici un périphérique virtuel qui a pour utilité de détecter et de notifier un utilisateur lorsqu’une nouvelle mise à jour est disponible en téléchargement pour le HC2 de Fibaro. (Publié sur le blog de Pascal le 21-03-2014) Version 1.0.8 - Mise à jour : 13/01/2015 Vous pouvez télécharger la dernière version ici et sur le blog consulter la notice d'installation et d'utilisation bien que tout soit simplifié au maximum Version 1.0.8 - Mise à jour : 13/01/2015 (Pour HC2 >= V4.031) Aucunes configuration nécessaire dorénavant, il faut importer le vd et c'est tout. Compatible API REST de la V4 L'unique paramétrage restant à faire par l'utilisateur est de préciser dans le code (dans le mainloop) l' ID du smartphone et de l' utilisateur pour les notifications. local userID = 2; local smartphoneID = 844; Version 1.0.6 - Mise à jour : 08/09/2014 (Pour HC2 <= V3.600) L'image principale du Virtual Device réapparaît maintenant automatiquement après l'appui sur un bouton Notification de mise à jour disponible sur la home du périphérique virtual. Remise en forme et révision du code Version 1.0.5 - Mise à jour : 04/09/2014 Amélioration: Récupération automatique de la variable en cas de données corrompues (suggéré par Lazer) Mise à jour des traductions Version 1.0.4 - Mise à jour : 03/09/2014 Nouveau: Affichage du numéro de version dans l'interface utilisateur et ajouté à la notification (mail & push) Nouveau: Icône d'un membre du forum domotique-fibaro.fr, merci Lazer Amélioration: Envoyer une notification si une nouvelle mise à jour est détectée et ne pas répéter les envois. Corrections mineures. Version 1.0.2 - Mise à jour : 21/02/2014 Corrections mineures. Version 1.0.1 - Mise à jour : 14/02/2014 Installation automatisée pour faciliter la mise en place des variables globales et du paramétrage de l’application. Possibilité de choisir le type de notification avec un bouton à trois états depuis l’interface graphique: Email, Push ou les deux. Possibilité de choisir le type de mise à jour devant être notifié avec un bouton à trois états depuis l’interface graphique : Bêta, stable ou les deux. Multilingue : Français, Anglais. Téléchargements: UpdateNotifier_1.0.8.zip pour HC2 en V4.xxx
  24. sebcbien

    Detection De Présence

    Bonjour, Suite à une conversation en MP avec un de nos admin chéri ;-), voici ma solution pour détecter la présence via smartphone. L'idée est de savoir quand ma femme ou moi même sommes à la maison afin de pouvoir lancer des scénarios ou en bloquer l’exécution. J'ai fait ça il y a longtemps, et bien sur je n'ai pas tout fait tout seul. Je me souviens avoir fait quelques modifications pour que ça tourne comme je le voulais, mais je ne sais plus lesquelles. Bref, voici le package complet, pour certains scripts, comme pour le ping par exemple la base est de Krikroff et j'ai laissé le copyright. J'ai mis le Virtual Device en attach et le code du bouton ci-dessous . IP Smartphone Presence Check V1.0.vfib !!! voir post plus loin dans le fil pour les V1.1 V1.2 V1.3 V2.0 et suivantes !!! V2.1 ici: https://www.domotique-fibaro.fr/topic/2613-detection-de-prã©sence/?do=findComment&comment=121355 V1.3 ici: http://www.domotique-fibaro.fr/index.php/topic/2613-detection-de-pr%C3%A9sence/page-3#entry35219 - il faut créer une variable globale (non prédéfinie) par device à surveiller (moi j'utilise "Phone_GG_Present" pour le tel de ma femme) et la déclarer en début de script du bouton. - il faut encoder l'adresse IP du téléphone dans les paramètres du Virtual device (pensez à déterminer une ip Wifi fixe pour votre smartphone) - il faut encoder le port ouvert sur votre téléphone dans les paramètres du Virtual device (3500 ou 3401) - Sur Androà¯d, il n'y a pas de port ouvert par défaut pour accepter le ping, le moyen le plus simple est d'installer l'application Sonos et a lancer, c'est tout (pas besoin d'avoir du matos sonos pour que ça fonctionne) - Sur iPhone idem, mais je n'ai pas testé personellement - si vous ne voulez pas utiliser le mainloop comme "scheduler" , créez simplement une scène qui va cliquer sur le bouton de demande de présence toutes les minutes... ou avec l'excellent GEA, avec la ligne ci-dessous (à adapter): -- Mise à jour des Présences par détection d'adresses IP toutes les minutes GEA.add(true , 1*60, "",{{"VirtualDevice", id["VD_PRESENCE_SEB"], "1"},{"VirtualDevice", id["VD_PRESENCE_GG"], "1"},{"Repeat"}}) Notification de présence en utilisant GEA, entre 8h et 21h: N'oubliez pas de mettre les VG dans l'entête. Ces exemple sont repris dans le post GEA de ma signature --------------DETECTION PRESENCE-------------- -- Signale GG at Home GEA peux se déclencher sur un changement de valeur d'une variable global GEA.add({"Global", "Phone_GG_Present", "1"}, -1, "Presence GG est maintenant à #value#", {{"Portable", 53}, {"Time", "08:00", "21:00"}}) GEA.add({"Global", "Phone_GG_Present", "0"}, -1, "Presence GG est maintenant à #value#", {{"Portable", 53}, {"Time", "08:00", "21:00"}}) Code bouton VD détect presence V1.0 (ancien code): -- IP Smartphone Presence Check V1.0 -- Copyright © 2014 Sébastien Jauquet. -- http://www.domotique-fibaro.fr/index.php/topic/2613-detection-de-pr%C3%A9sence/ --Using code from: -- Ping v 1.0.1 [05-2013] -- Copyright © 2013 Jean-christophe Vermandé -- http://www.domotique-fibaro.fr/index.php/topic/109-ping-dun-%C3%A9quipement-r%C3%A9seau/page-2 fibaro:log("Starting process"); local _deviceIp = "192.168.10.112"; local variable_globale_phone = "Phone_GG_Present"; local _devicePort = 3500; local _maxRetryProcess = 20; local time = tonumber(os.time()); local maxtime = 56; -- fibaro:setGlobal("Lock_Away","Unlocked") function SecondsToClock(sSeconds) local nSeconds = tonumber(sSeconds) if nSeconds == 0 then return "00:00:00"; else nHours = string.format("%02.f", math.floor(nSeconds/3600)); nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60))); nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60)); return nHours..":"..nMins..":"..nSecs end end -- recursive function to ping device local function _ping(retry) retry = retry or 0; -- notify state local elapsed = os.difftime(os.time(), tonumber(time)); local msg = "Loop #".. retry .." since "..SecondsToClock(elapsed); fibaro:log(msg); -- check for no more than 30 seconds if elapsed > maxtime then return false; end --open the socket local tcpSocket = Net.FTcpSocket(_deviceIp, _devicePort); --set the read timeout tcpSocket:setReadTimeout(250); --send packet local bytes, errorCode = tcpSocket:write("test"); --check for error if errorCode == 0 then return true; else if retry < _maxRetryProcess then --fibaro:log("Retry process, please wait..."); fibaro:sleep(1*750); return _ping(retry + 1); end return false; end end --ping device, secure with pcall to catch errors. local f, result = pcall(_ping); local Lock_Away = fibaro:getGlobal("Lock_Away") if (f) then if (result == true) and (Lock_Away == "Unlocked") then fibaro:log("Device has been found."); fibaro:setGlobal(variable_globale_phone,"1") -- fibaro:setGlobal("Present_Phones",os.time()) else fibaro:log("Device was not found!"); fibaro:setGlobal(variable_globale_phone,"0") end else fibaro:log("Error: " .. f); end Code main loop du VD local thismodule = fibaro:getSelfId(); local status = fibaro:getGlobal("Phone_GG_Present") -- fibaro:debug(thismodule); if status == "0" then fibaro:call(thismodule, "setProperty", "currentIcon", 1037) end if status == "1" then fibaro:call(thismodule, "setProperty", "currentIcon", 1036) end fibaro:sleep(1000); Ce n'est certainement pas le code le plus "léché" mais je pense que ça en aidera quand même certains... et puis c'est "tout fait" ;-) Le script va détecter quasi instantanément lorsque le smartphone apparaît sur le réseau, mais pourra mettra jusqu'à une minute pour valider son absence Enjoy !
  25. Krikroff

    Hc2 Waze Calculator

    Après longue absence voici un petit script permettant d’utiliser sur notre HC2 le service de trafic et de navigation communautaire WAZE (https://www.waze.com/fr/) Le principe du script est très simple : 1 scène pour interroger l’ API Waze pour tous les trajets parametrés et autant de vd qui seront mis à jour par la dite scène.] 1 - Installation Importer le vd HC2_Waze_Calculator.vfib sur le HC2, 1x pour un trajet, 2x pour deux etc... Créer la scène HC2 Waze Calculator cf. fichier HC2 Waze Calculator Scene.txt puis passer au paramètrage 2 - Paramétrage Configurer l'object params: nom, id du vd cible, polling, latitude, longiture etc... pour tous les trajets. Pour trouver les coordonnées GPS, latitude et longitude il existe les services : www.coordonnees-gps.fr, www.torop.net/coordonnees-gps.php, www.gpsfrance.net etc. local params = { { name = "Trajet 1", virtualDeviceId = 1449, from = { name = "Palais de l'Élysée", x = 2.3167538999999806, -- longitude y = 48.8704156 -- latitude }, to = { name = "Théâtre Guignol", x = 2.311747670173645, -- longitude y = 48.86977710077997 -- latitude }, pollingMs = 60*1000 }, { name = "Trajet 2", virtualDeviceId = 1452, from = { name = "Palais de l'Élysée", x = 2.3167538999999806, -- longitude y = 48.8704156 -- latitude }, to = { name = "Théâtre Guignol", x = 2.311747670173645, -- longitude y = 48.86977710077997 -- latitude }, pollingMs = 5*60*1000 } } 4 - Icône Merci à Moicphil de m’avoir suggéré la chose et aussi pour son icône tip-top Fichier du vd: HC2_Waze_Calculator.vfib Fichier de la scène: HC2 Waze Calculator Scene.txt
×