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. 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
  2. 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
  3. 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...
  4. 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.
  5. mprinfo

    Module Virtuel - Index Tutos

    TUTOS MODULES VIRTUEL Création D'un Périphérique Virtuel Et Main Loop : ICI Numérotation Des Boutons : ICI Utilisation D'un Label ( Etiquette ) : ICI Le Slider De A À Z (Image + Codes Lua) : ICI Je voudrais savoir si cela vous conviendrez pour rechercher les tutos ? Merci d'avance pour votre réponse
  6. Berale64

    Interrupteur Universel Z-Wave

    Le fameux Fibaro Button n'étant toujours pas d'actualité et, n'ayant pas trouvé d'interrupteur z-wave adéquat j'ai décidé de le faire avec un FGBS-001. Mettre les paramètres 3 et 4 sur monostable et le paramètre 14 sur ON. Brancher un interrupteur monostable (poussoir) double sur les fils jaune et vert du module et vous obtenez un interrupteur qui envoie 12 états différents. De quoi gérer toute la maison ! --[[ %% properties 105 sceneActivation %% globals --]] fibaro:debug("start"); local val = tonumber(fibaro:getValue(105, "sceneActivation")) if (val == 10) then fibaro:debug("Changement de off à on bouton 1"); elseif (val == 11) then fibaro:debug("Changement de on à off bouton 1"); elseif (val == 12) then fibaro:debug("maintenir appui long bouton 1"); elseif (val == 13) then fibaro:debug("relâcher appui long bouton 1"); elseif (val == 14) then fibaro:debug("Double-clic bouton 1"); elseif (val == 15) then fibaro:debug("Triple-clic bouton 1"); elseif (val == 20) then fibaro:debug("Changement de off à on bouton 2"); elseif (val == 21) then fibaro:debug("Changement de on à off bouton 2"); elseif (val == 22) then fibaro:debug("maintenir appui long bouton 2"); elseif (val == 23) then fibaro:debug("relâcher appui long bouton 2"); elseif (val == 24) then fibaro:debug("Double-clic bouton 2"); elseif (val == 25) then fibaro:debug("Triple-clic bouton 2"); end
  7. Bonjour, j'ai testé un truc tout bête ce matin et qui fonctionne. Je pars en vacances et je voulais un accès via l'application Fibaro que j'utilise en intranet seulement. Je sais qu'on peut y accéder par l'extérieur, mais cela me semblait un peu compliqué à gérer de mon smartphone, donc j'ai considéré un truc tout simple : Ayant une fbox V6, on dispose d'un serveur VPN ( OpenVPN ). Dans la Freebox, raccourci Serveur VPN : ajouter un utilisateur avec son mot de passe / Activer PPTP / Activer OpenVPN routé et désactiver la fragmentation Télécharger la configuration ( cliquer sur la disquette ), et se l'envoyer sur le smartphone ( par ex par gmail ) Sur le smartphone ( Android pour ma part mais iphone a sa version aussi ) : télécharger OpenVPN pour Android ( et non OpenVPN connect qui ne fonctionne pas avec la fbox ). Dans l'appli, importer le fichier extension .ovpn, se connecter et voilà ... Pratique aussi si on veut accéder à tout équipement dans son intranet.
  8. C'est un complément à ceci : Précis Sur Les Variables Locales/globales Je remercie STEVEN de me laisser le choix des couleurs pour ses tutos Pour la variable avec une portée globale et les passages de paramètres, voici une explication et un petit script pour bien comprendre son fonctionnement. Notion de base sur le passage de paramètre : Les paramètres d'une fonction peuvent être de 2 manières différentes (par référence ou par valeur) : - référence : la fonction reçoit l'adresse mémoire du paramètre. Un changement de valeur affectera TOUT le script - valeur : on reçoit la valeur du paramètre Ce dernier est copié dans une nouvelle référence propre à la fonction. Un changement de valeur n'affectera que la fonction. en LUA, chaque passage de paramètre ce fait en "valeur" SAUF pour les tables (c'est comme en français, il y a toujours une exception). Donc si je fais : function maFonction(var) print(var) end maFonction("Coucou") J'envoi à ma fonction la valeur, soit une copie de "Coucou". Si a l'intérieur de maFonction je modifie la valeur, cela n'aura un impact QU'AU sein de maFonction. maFonction va donc créer une nouvelle variable "var" dans laquelle il va copier la valeur "Coucou" Si je fais : local coucou = "Coucou" function maFonction() print(coucou) end et que dans maFonction je modifie coucou, alors coucou va être modifié pour tout le script puisque la modification aura eu lieu sur sa référence. En bref, Si on est au sein d'un script ou d'une fonction, nous travaillons sur les références. Si nous passons les informations en tant que paramètre, nous travaillons sur une valeur. local coucou = "Coucou" function maFonction(variable) print(coucou) print(variable) end maFonction("Coucou") Plus compliqué car la référence coucou est envoyée en paramètre et devient donc une copie de valeur. local coucou = "Coucou" function maFonction(variable1, variable2) print(variable1) print(variable2) end maFonction("Coucou", coucou Allez un bon script vaut mieux qu'un long discours : function scope1() -- la variable var n'existe pas print(var) --- nil (variable inexistante) end function scope2(var) -- la variable est passée en paramètres donc visible -- bien que déclarée après -- En sortant de cette méthode, var aura repris ça valeur -- initial car elle a été passée en paramètre soit par -- valeur print(var .. " dans scope2()") -- ______ var = "Scope2" print(var) -- Scope2 end local var = "-=init=-" function scope3() -- la variable est connue car déclarée avant. Elle est assignable -- par contre, si on déclare une variable du même nom au sein -- de cette même function, en sortant la variable aura repris sa valeur "Scope3" print(var .. " dans scope3()") var = "Scope3" print(var) local var = "Byebye" print(var) end function exception(unTableau) -- Les tableaux sont toujours traité comme une référence unTableau[1] = "Et voilà " end print(var .. " avant tout") scope1() print(var .. " après scope1()") scope2(var) print(var .. " après scope2()") scope3() print(var .. " après scope3()") -- Exception avec les table qui sont toujours envoyé en tant que référence. local table = {[1]="Humm"} print(table[1]) exception(table) print(table[1]) Debug : [DEBUG] 11:39:22: -=init=- avant tout [DEBUG] 11:39:22: nil [DEBUG] 11:39:22: --init=- après scope1() [DEBUG] 11:39:22: --init=- dans scope2() [DEBUG] 11:39:22: Scope2 [DEBUG] 11:39:22: -=init=- après scope2() [DEBUG] 11:39:22: -=init=- dans scope3() [DEBUG] 11:39:22: Scope3 [DEBUG] 11:39:22: Byebye [DEBUG] 11:39:22: Scope3 après scope3() [DEBUG] 11:39:22: Humm [DEBUG] 11:39:22: Et voilà
  9. 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
  10. Il y a 3 types d'optimisation. la mémoire, le temps processeur le temps du développeur. Une bonne application prend en compte ces 3 critères en essayant de faire un bon compromis entre les 3. Voici donc une petite analyse sur votre code ... attention, je suis volontairement très très critique juste pour essayer d'aider. Perso, la plus part de mon code n'est pas optimiser ainsi, voir pas du tout . . Optimisation mémoire Chaque variable déclarée pend une infime place en mémoire (son adresse) donc si on a pas besoin de la réutiliser ou de la maintenir ... on en fait pas Une variable utilisée qu'une seule fois ne sert donc à rien : exemple local message = string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R")) EnvoiPush(message) On fait directement : EnvoiPush(string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R"))) . . Optimisation temps processeur La démarche a déjà été faite .. bravo. En effet, certaine opération prenne du temps a être exécutée, il faut donc éviter de demander 2 fois le même calcul pour rien. Exemple : if ( os.date("%H:%M", os.time())== lever ) or ( os.date("%H:%M", os.time()) == coucher ) then On voit bien qu'on demande au processeur de calculer 2 fois l'heure actuelle alors que ce qui a été fait local osHeure = os.date("%H:%M", os.time()) if ( osHeure == lever ) or ( osHeure == coucher ) then est bien moins coà»teux puisque nous divisons simplement pas 2 le temps processeur. Bon ok, on passe de 0.00002 sec à 0.00001 sec Mais c'est un exemple. Optimisation développeur Moins il y a de code a maintenir mieux c'est. Donc vu que ceci : if (heure >= lever) and (heure < coucher) then valeur = "Jour" end revient au même que ceci (dans ce contexte) if ( OsHeure == Lever ) then Valeur = "Jour" else Valeur = "Nuit" end On extrait tout cela et on en fait une méthode (function) : function traitement(lever, coucher, heure) local valeur = "Nuit" -- test si on est le jour ou la nuit if (heure >= lever) and (heure < coucher) then valeur = "Jour" end ... end . . Optimisation bonus ... optimisation pour l'utilisateur On remonte tout en début du code, les variables, traitements que l'utilisateurs doit modifier afin que ce dernier n'aie pas a chercher dans le code la ligne X ou Y. Donc on met ce ci tout en haut : local NomVG = "Jour_Nuit" local IdTel = 181 On obtient donc ceci : --[[ %% autostart --]] local NomVG = "Jour_Nuit" local IdTel = 181 ---------------------------------------------------------------------- -- 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 --------------------------------------------------- -- Mise a jour d'une variable global -- --------------------------------------------------- function UpdateVG(Valeur) 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 else fibaro:debug("VariableGlobale = "..NomVG.." - Valeur = "..Valeur) fibaro:setGlobal(NomVG, Valeur); end end --------------------------------------------------- -- Vérification de l'heure et mise à jour -- -- de la variable si necessaire -- --------------------------------------------------- function traitement(lever, coucher, heure) local valeur = "Nuit" -- test si on est le jour ou la nuit if (heure >= lever) and (heure < coucher) then valeur = "Jour" end UpdateVG(nuit) -- mise a jour de la VG Jour_Nuit end -- ======================================= -- Début du code -- ======================================= ---------------------------------------------------------------------- -- Controle si 1 Scéne et déjà en cours -- ---------------------------------------------------------------------- local NbreScene = fibaro:countScenes() fibaro:debug("Nombre de scéne : "..NbreScene) if (NbreScene ~= 1) then; fibaro:abort(); end ---------------------------------------------------------------------- -- Mise a jour de la variable VG Jour_Nuit au Démarrage de la Box -- -- Ou lors de la sauvegarde de la scéne -- ---------------------------------------------------------------------- EnvoiPush(string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R"))) traitement(fibaro:getValue(1, "sunriseHour"), fibaro:getValue(1, "sunsetHour"), os.date("%H:%M")) ---------------------------------------------------------------------- -- Test toute les minutes pour savoir si c'est jour ou nuit -- ---------------------------------------------------------------------- while true do local osHeure = os.date("%H:%M", os.time()) local lever = fibaro:getValue(1, "sunriseHour") local coucher = fibaro:getValue(1, "sunsetHour") if ( osHeure == lever ) or ( osHeure == coucher ) then traitement(lever, coucher, osHeure) end fibaro:debug(string.format("Lever Soleil : %s - Coucher Soleil : %s", lever, coucher)) fibaro:sleep(60*1000); end Maintenant, vous pouvez oublier tout ces bons préceptes car quand on regarde le code des professionnels, on voit bien que la théorie fait bien souvent place à la fatigue cérébrale et que 90% du code ne respecte pas le moindre petit de ces préceptes. Garbage collector Un gabagge collector n'est-il pas le truc inventé pour palier au mauvais développement ? ... Je plaisante . Il y en a un, mais comme toujours, moins la mémoire est sollicitée, moins le garbage collector fonctionne, meilleures sont les performances. Il ne faut pas oublier que lorsque le garbage collector fait son nettoyage, il prend énormément de ressources. Je travaille sur Java, et c'est horrible de voir que plus on améliore le garbage collector, plus les développeurs ne font pas attention. C'est le serpent qui se mord la queue. "Un garbage collector est coà»teux en performance, bien que dans la plus part des cas, son utilisation permet d'augmenter les performances globales d'une application" ... et si, un jour, on se mettait autour d'une table et qu'on se disait : - Il y a 25 ans, on faisait attention au nombre de ligne de code - Il y a 20 ans, on faisait attention à l'utilisation de la mémoire - Il y a 10 ans, on faisait attention à la place disque - Aujourd'hui, on se fout de tout alors on a inventé la "défragmentation" Pour les curieux : Ramasse-miettes (Garbage Collector) . . . Librairies Oui LUA permet les librairies, mais pas sur la Fibaro ou cette possibilité est désactivée. Le mot clé, de mémoire est : require . Merci Steven pour ces explications. Lien utiles pour la programmation lua : lua.org (Site Officiel Lua Anglais) WX LUA.fr Developer fibaro/ (Anglais) Programmation LUA Structures de Base LUA pour les débutants Introduction à la Programmation LUA Les bases de la programmation avec lua
  11. Bonjour a tous, Ci-dessous un petit tuto afin de detecter si vous êtes chez vous ou non, le principe repose comme d'autres tutos sur la connection du smartphone sur le wifi. Il n'y a nul besoin d'avoir une application installé sur le téléphone. J'ai réalisé des tests avec un smartphone android et iphone4 sous IOS8 Fonctions: 1) Identifier si le ou les smartphones se connectent au réseau wifi. 2) Renseigner une variable de la HC2 sur "Absent" ou "Present". 3) A partir des états des variables pouvoir lancer des scènes. Prérequis: - Linux (genre un raspberry ou ubuntu), fonctionne également sur syno avec la nouvelle fonction docker - Smartphone android ou iphone - une HC2 Remerciements: Merci a sebcbien pour ses icons et ses idées: son post ici Merci a Tony270570 pour son tuto, la plupart de ce tuto a été un "copier/coller" du sien: son post ici Actions a réaliser sur la HC2: 1/ Créer un variable prédéfini avec le nom de votre choix (ex: presence_vince) avec 2 valeurs, Les majuscules sont importantes: - Absent - Present 2/ Ajouter les icones joint a ce post 3/ Créer un virtual device avec le fichier joint a ce post. Modifier dans le main loop les infos suivantes: - Modifier le nom de la variable que vous avez défini ci-dessus. - Modifier le numéro de l'icone pour la fonction "present" et "absent". Actions a réaliser sur le server linux: Télécharger l'application ici wget http://www.overlooksoft.com/getfing4arm Installer fing sudo dpkg -i overlook-fing-2.2.deb Installer les librairies complémentaires sudo apt-get install libpcap* Créer le répertoire hébergent le script sudo mkdir /home/hc2 Création du script de test de connexion wifi et le paramétrer Créer le fichier sudo nano test_presence_vince.sh vous pouvez biensur remplacer le nom du script, il n'a aucune importance mis a part s'y retrouver copier le script ci-dessous dans le fichier #!/bin/bash # Script check IP and update HC2 global variable # Never ending loop # version 1.00 # Author: byackee # Original Author: Tony270570 nomvariable="Presence_vince" login="admin" password="votre mot de passe" hc2ip="192.168.0.3" while : do grep -n "<center>UP</TD><TD>192.168.2.83" /var/www/ping/lan.html if [ $? -eq 0 ] then curl -s -X PUT -d '{"value": "Present"}' http://$login:$password@$hc2ip/api/globalVariables/$nomvariable echo "present" sleep 10 else curl -s -X PUT -d '{"value": "Absent"}' http://$login:$password@$hc2ip/api/globalVariables/$nomvariable echo "absent" sleep 10 fi done Il faut modifier les variables en début de script: nomvariable ==> nom de la variable créé sur la HC2 login ==> login de la HC2 password ==> mot de pass de la HC2 hc2ip ==> adresse ip de la HC2 lancer la commande suivante: sudo chmod 755 « test_presence_vince Les opérations ci-dessus peuvent etre réalisées autant de fois que de personnes/smartphones a tester Créer un script pour le lancement des scripts au boot Créer le fichier sudo nano exec_presence Copier le code suivant dans le fichier #! /bin/sh ### BEGIN INIT INFO # Provides: exec_presence # Required-Start: $all # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: Run /home/HC2/test_presence if it exist ### END INIT INFO # version 1.00 # Author: byackee # Original Author: Tony270570 PATH=/sbin:/usr/sbin:/bin:/usr/bin . /lib/init/vars.sh . /lib/lsb/init-functions scriptpath="/home/hc2/" do_start() { for i in $scriptpath"/"* ; do echo "lancement du script: "$i $i & sleep 2 done } case "$1" in start) do_start ;; restart|reload|force-reload) echo "Error: argument '$1' not supported" >&2 exit 3 ;; stop) ;; *) echo "Usage: $0 start|stop" >&2 exit 3 ;; esac donner les droits et l'autorisation de lancement du script au démarrage sudo chmod 755 exec_presence update-rc.d -f exec_presence defaults 7/ créer un script de demarrage de fing Créer le fichier sudo nano startfing et y copier le code suivant #! /bin/sh ### BEGIN INIT INFO # Provides: startfing # Required-Start: $all # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: Run fing with unlimited loop ### END INIT INFO # version 1.00 # Author: byackee # Original Author: Tony270570 PATH=/sbin:/usr/sbin:/bin:/usr/bin . /lib/init/vars.sh . /lib/lsb/init-functions do_start() { fing -n 192.168.2.0/24 -o table,html,/var/www/ping/lan.html & } case "$1" in start) do_start ;; restart|reload|force-reload) echo "Error: argument '$1' not supported" >&2 exit 3 ;; esac Il faut simplement modifier l'adresse IP de votre reseau. donner les droits et l'autorisation de lancement du script au démarrage sudo chmod 755 startfing update-rc.d -f startfing defaults Voila maintenant votre/vos smartphone sont détectés lors de la connexion au wifi. Le délai peut varié mais il est en générale de 20 a 30s. icons: Presence_So.vfib
  12. 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
  13. 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)
  14. 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
  15. HANSOLO

    Lampe Hue Piloté Par Fgd211

    Une petite scène sans prétention. Mon objectif est de synchroniser une lampe HUE Livingcolors Iris posée dans un coin du salon avec un module FGD211 pilotant deux lampes LED dans le salon. Les lampes HUE sont bien mais pas pratique s'il faut sortir le smartphone pour allumer ou régler la lampe. Du coup avec ma scène l'intensité de la HUE suit celle du FGD211. --[[ %% properties 54 value %% globals --]] local huelightid=3 local hueuser = "newdeveloper"; local hueIP = "192.168.0.12"; local huePort = 80; local hueColor = 36980; local hueSat = 49; local IDlum_Salon = 54; local ValeurDim = tonumber(fibaro:getValue(IDlum_Salon, 'value')); local Bri = math.floor(ValeurDim * 2.55); local Data = '{"on":false}'; if Bri > 0 then Data = '{"on":true, "sat":'..hueSat..', "bri":'..Bri..', "hue":'..hueColor..'}' end fibaro:debug(Data) local httpClient = net.HTTPClient(); httpClient:request('http://'..hueIP..':'..huePort..'/api/'..hueuser..'/lights/'..huelightid..'/state', { success = function(response) if tonumber(response.status) == 200 then print("Updated at " .. os.date()); else print("Error " .. response.status) end end, error = function(err) print('error = ' .. err) end, options = { method = 'PUT', data = Data } }); A adapter selon votre environnement: En entête 54 value : ID de mon FGD211 hueLightid = 3 N° de la lampe HUE à piloter (j'ai deux autres HUE) hueuser = "newdeveloper" à laisser si vous n'avez pas défini de user sur hueIP = "192.168.0.12" IP du pont HUE huePort = 80 à laisser tel quel hueColor = 36980 à adapter selon la couleur désirée hueSat = 49 à adapter selon la saturation désirée de la couleur IDlum_Salon = 54 ID du FGD211
  16. Toutes lumières Ce module virtuel vérifie périodiquement l'état des modules lumière de la maison, et change d'icône en fonction de leur état (au moins une allumée, aucune allumée). Son bouton permet d'éteindre en un clic toutes les lumières de la maison. Contexte Je cherchais à savoir d'un coup d'oeil s'il restait une lumière allumée dans la maison, et à pouvoir y remédier sans chercher le module dans l'interface. Je prévoit également de me servir du bouton d'extinction généralisée de ce module virtuel dans d'autres modules virtuels ou scènes, afin de centraliser les bouts de code intéressants et d'éviter de les dupliquer, cela facilitera la maintenance. J'ai créé les icônes moi-même pour éviter tout problème de droits. Installation - Importez le module virtuel - Ajoutez les icônes fournies - Adaptez les Id d'icônes au début du code de la boucle principale - Si l'intervalle par défaut (10 secondes) ne vous convient pas, vous pouvez le modifier au début du code de la boucle principale Note : incompatible avec les systèmes inférieurs à 4.x Changelog 1.2 : Correction du test d'état prenant en charge les modules variateurs et rétablissement de la condition pour l'extinction 1.1 : Extinction inconditionnelle et prise en charge des modules variateurs Téléchargement Toutes_Lumières-1.2.vfib
  17. neliger

    Etat De Connexion Wimax

    WiMax Ce module virtuel s'authentifie sur un modem Motorola WiMax "MOTOwi4" (fourni notamment par Ozone), récupère le niveau du signal à intervalle régulière, et permet de redémarrer le modem directement depuis la Home Center. Contexte Il s'agit de mon premier module virtuel, que j'ai réalisé pour confirmer d'un coup d'oeil un problème de niveau de signal WiMax, et de redémarrer le modem sans m'y connecter moi-même, ainsi qu'à distance. A de rares occasion, lorsque le pilonne WiMax que l'on reçoit le mieux est coupé durant un moment, le modem se connecte à un autre pilonne bien trop loin, et le ne vérifie pas de lui-même s'il en capte de nouveau un plus fort. Ce modeste module ne s'adresse bien entendu pas à beaucoup de monde, mais sera peut-être une base de travail pour d'autres. J'ai créé les icônes moi-même pour éviter tout problème de droits. Installation - Importez le module virtuel - Renseignez l'IP et le port de votre modem (par défaut 192.168.1.1 et 80) - Ajoutez les icônes fournies - Adaptez les Id d'icônes au début du code du bouton de mise à jour - Si l'intervalle par défaut (30 minutes) ne vous convient pas, vous pouvez le modifier au début du code de la boucle principale Note : le code suppose que vous ayez laissé les données d'identification par défaut du routeur, tel que demandé par l'opérateur Téléchargement WiMax-1.0.vfib
  18. Sunrisehour, Sunsethour, Os.date Et Variable Jour_Nuit V1.00 Une version plus élaborée ce trouve ici : http://www.domotique-fibaro.fr/scene-lua-jour-nuit-avec-decalge-possible-et-optimisation-du-sleep/ Au début j'ai utilisé le mode bloc pour mettre ma variable à jour. Un jour j'ai rencontré un soucis, la variable ne s'était pas mise a jour ? Pourquoi ? Tout simplement ma box était en cours de démarrage lorsque l'heure était égale a l'heure du coucher du soleil. Exemple : J'ai une coupe de courant de 18h00 à 19h00 Le coucher du soleil est a 18h24. Lorsque j'allume ma box a 19h00 la scène s'exécute bien mais comme l'heure de coucher du soleil et 18h24 elle ne met pas a jour la variable globale. J'ai donc décider de faire cela en LUA et dans une seul Scéne. Il me fallait : L'heure de lever du soleil fibaro:getValue(1, "sunriseHour") L'heure de coucher du soleil fibaro:getValue(1, "sunsetHour") L'heure Actuelle Var_Heure = os.date("%H:%M", os.time()) il me reste plus qu'à surveiller l'heure actuelle Et de la comparer avec le avec l'heure du coucher et du lever du soleil while true do local Var_Heure = os.date("%H:%M", os.time()) local Lever = fibaro:getValue(1, "sunriseHour") local Coucher = fibaro:getValue(1, "sunsetHour") if ( Var_Heure == Lever ) then fibaro:setGlobal("Jour_Nuit", "Jour"); elseif ( Var_Heure == Coucher ) then fibaro:setGlobal("Jour_Nuit", "Nuit"); else fibaro:debug("controle en cours") end fibaro:sleep(60*1000); end Avec ce code j'ai toujours le probléme si ma box et éteinte au moment du lever ou du coucher du soleil je vais donc ajouter ce code : if (os.date("%H:%M", os.time()) >= fibaro:getValue(1, "sunriseHour")) and (os.date("%H:%M", os.time()) < fibaro:getValue(1, "sunsetHour")) then fibaro:setGlobal("Jour_Nuit", "Jour"); else fibaro:setGlobal("Jour_Nuit", "Nuit"); end Je teste : Si l'heure et supérieur ou égal est inférieur a l'heure du coucher du soleil Si c'est le cas il fait Jour sinon il fait Nuit. On dispose de tout pour faire notre Scéne : (Version 1.0) --[[ %% autostart --]] -- Test du nombre de scènes en cours if (fibaro:countScenes() > 1) then fibaro:abort() end -- met la variable a jour au démarrage if (os.date("%H:%M", os.time()) >= fibaro:getValue(1, "sunriseHour")) and (os.date("%H:%M", os.time()) < fibaro:getValue(1, "sunsetHour")) then fibaro:setGlobal("Jour_Nuit", "Jour"); else fibaro:setGlobal("Jour_Nuit", "Nuit"); end -- se lance au démarrage et toutes les 60 secondes. while true do local Var_Heure = os.date("%H:%M", os.time()) local Lever = fibaro:getValue(1, "sunriseHour") local Coucher = fibaro:getValue(1, "sunsetHour") if ( Var_Heure == Lever ) then fibaro:setGlobal("Jour_Nuit", "Jour"); elseif ( Var_Heure == Coucher ) then fibaro:setGlobal("Jour_Nuit", "Nuit"); else fibaro:debug("controle en cours") end fibaro:sleep(60*1000); end Date et heure courante (os.date) http://www.luteus.biz os.date([format [, temps ] ]) Retourne dans une table des informations de date et heure formatté par une chaîne de caractère. La chaîne de caractère a le même format que la fonction strftime() de C. Les caractères suivants sont utilisés pour spécifier le format de la date : %a - nom abrégé du jour de la semaine (local) %A - nom complet du jour de la semaine (local) %b - nom abrégé du mois (local) %B - nom complet du mois (local) %c - représentation préférée pour les dates et heures, en local %C - numéro de siècle (l'année, divisée par 100 et arrondie entre 00 et 99) %d - jour du mois en numérique (intervalle 01 à 31) %D - identique à %m/%d/%y %e - numéro du jour du mois. Les chiffres sont précédés d'un espace (de ' 1' à '31') %g - identique à %G, sur 2 chiffres %G - L'année sur 4 chiffres correspondant au numéro de semaine (voir %V). Même format et valeur que %Y, excepté que si le numéro de la semaine appartient à l'année précédente ou suivante, l'année courante sera utilisé à la place %h - identique à %b %H - heure de la journée en numérique, et sur 24-heures (intervalle de 00 à 23) %I - heure de la journée en numérique, et sur 12- heures (intervalle 01 à 12) %j - jour de l'année, en numérique (intervalle 001 à 366) %m - mois en numérique (intervalle 1 à 12) %M - minute en numérique %n - caractère de nouvelle ligne %p - `AM' ou `PM', en majuscule, suivant la valeur donnée, ou la chaîne correspondante pour la locale courante %P - `am' ou `pm', en majuscule, suivant la valeur donnée, ou la chaîne correspondante à la locale courante %r - l'heure au format a.m. et p.m %R - l'heure au format 24h %S - secondes en numérique %t - tabulation %T - l'heure actuelle (égal à %H:%M:%S) %u - le numéro de jour dans la semaine, de 1 à 7. (1 représente Lundi) %U - numéro de semaine dans l'année, en considérant le premier dimanche de l'année comme le premier jour de la première semaine %V - le numéro de semaine comme défini dans l'ISO 8601:1988, sous forme décimale, de 01 à 53. La semaine 1 est la première semaine qui a plus de 4 jours dans l'année courante, et dont Lundi est le premier jour. (Utilisez %G ou %g pour les éléments de l'année qui correspondent au numéro de la semaine pour le timestamp donné.) %W - numéro de semaine dans l'année, en considérant le premier lundi de l'année comme le premier jour de la première semaine %w - jour de la semaine, numérique, avec Dimanche = 0 %x - format préféré de représentation de la date sans l'heure %X - format préféré de représentation de l'heure sans la date %y - l'année, numérique, sur deux chiffres (de 00 à 99) %Y - l'année, numérique, sur quatre chiffres %Z ou %z - fuseau horaire, ou nom ou abréviation (suivant le système d'exploitation) %% - un caractère `%' littéral Exemple : >os.date("%Y/%m/%d %H:%M:%S") '2010/03/04 09:05:16' Module Virtuel Coucher et Lever Soleil :
  19. Variables Globales - VD Module virtuel pour afficher les variables globales Lorsque l'on fait des tests, il est parfois pratique d'avoir la liste des Variables Globales existantes sur votre HC2. Ce module virtuel va vous permettre de les afficher sur votre smartphone. Afin de ne pas afficher toutes les variables, ce modules va afficher les 10 dernières variables à avoir été modifiées et ce, trié par date de modification. Si vous voulez voir plus de variables, 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. Ce dernier affiche donc : Le nom de la variable globale Sa valeur L'heure de la dernière mise à jour Ce module se rafraîchi automatiquement toutes les 3 secondes . . . Installation Il vous suffit juste d'importer le module virtuel ci-joint Cordialement Variables_Globales.vfib
  20. Pour la HCL, j'avais en son temps fait un tuto pour afficher une icône dans un virtual device une icône en fonction de la valeur d'une variable globale, et de pouvoir modifier sa valeur (également depuis son smartphone), quelle se mette à jour lors d'un restart de la box, etc pour une HCL En passant sous HC2, j'avais gardé le même principe, et pour chaque VD (et donc chaque variable), la main loop tournait en continu pour vérifier que l'icône correspond bien à la valeur de la variable. Ce n'est vraiment pas optimal. Je vais vous expliquer ici la solution que j'ai mise en place pour que la charge sur la box soit moins importante. Merci à Steven, i-magin et mprinfo qui m'ont aidé pour débugger Création des variables Je prendrai dans mon exemple 2 variables globales : Auth_PS3 avec 2 valeurs possibles : "Autorisé" et "Interdit" Auth_TV avec 2 valeurs possibles : "Autorisé" et "Interdit" (mais les valeurs pourraient être différentes que pour la 1° variable, ou avoir plus que 2 valeurs) Modules virtuels Chaque variable a son module virtuel. Il a pour objectif d'afficher une icône différente en fonction de la valeur de la variable. Pour facilement les retrouver, j'ai créé une section "Section Virtuelle" et dedans une pièce "Variables". Chaque VD a le nom suivant : "Var_xxxx" où xxxx est le nom de la variable globale. Dans notre exemple : "Var_Auth_PS3" et "Var_Auth_TV". L'icône par défaut du VD est et doit rester l'horrible cube bleu (facile ainsi de repérer si la VD est à jour) J'ai créé les boutons suivants : Bouton 1 : Autorisé / Interdit Il permet simplement de faire le switch de la valeur de la variable. C'est le bouton par défaut du VD. Il n'y a pas d'icône associée. -- nom de la variable à modifier local variable = "Auth_PS3" if fibaro:getGlobal(variable) == "Interdit" then fibaro:call(fibaro:getSelfId(), "pressButton", "3") else fibaro:call(fibaro:getSelfId(), "pressButton", "4") end Label : Statut afficher en texte la valeur de la variable Bouton3 : Autorisé c'est le bouton qui est appelé pour mettre la variable à "Autorisé" Il contient l'icône qu'on veut voir affichée (comme ça on ne doit pas chercher son ID) fibaro:setGlobal('Auth_PS3', 'Autorisé') fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Statut.value", 'Autorisé') Bouton4 : Interdit c'est le bouton qui est appelé pour mettre la variable à "Interdit" Il contient l'icône qu'on veut voir affichée (comme ça on ne doit pas chercher son ID) fibaro:setGlobal('Auth_PS3', 'Interdit') fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Statut.value", 'Interdit') N.B. l'ID de ce bouton ne peut pas être appelée par le bouton Switch, mais seulement son numéro QUI CHANGE si vous changez l'ordre. C'est débile, mais c'est comme ça … Utilisation On clique sur le bouton principal, et il switch la valeur de la variable On peut utiliser Google Calendar pour lui dire d'appuyer directement sur le bouton "Autorisé" ou "Interdit" Vous devez modifier les scènes qui modifiaient directement la variable, en la faisant appuyer sur le bouton de la VD qui modifie la variable et met à jour l'icône de la VD (car il n'y a plus le mainloop qui contrôle en continu la valeur de la variable) Limitations et solution : Lors du redémarage de la box, ou Lors de la sauvegarde du VD (parce que vous avez fait une petite modif, ou …) L'icône qui est affichée pour le VD, est l'icône par défaut du VD. Le cube bleu, pas cool … Donc pour pallier à ce problème, j'ai créé un VD supplémentaire "Var_Update" Dont voici le code : un GRAND merci à mprinfo qui m'a beaucoup aider pour faire qqch de plus sympa et générique ---------------------------------- -- User Settings ---------------------------------- -- la Table doit avoir la structure suivante : -- 1/ nom de la variable globale entre " -- 2/ ID du VD qui affiche la valeur de la VG -- 3/ n° du premier bouton qui doit être appuyé -- (qui correspond à la première valeur de la variable) -- 4/ n° du dernier bouton qui doit être appuyé -- (qui correspond à la dernière valeur de la variable -- on suppose que tous les boutons se suivent de 1 en 1) -- 5/ valeurs possibles de la variable entre " -- (elles doivent être listées dans l'ordre des boutons de la VD) local Table = {"Auth_PS3", 23, 3, 4, "Autorisé", "Interdit", "Auth_TV", 289, 3, 4, "Autorisé", "Interdit", "Auth_VMCEtage", 290, 3, 4, "Autorisé", "Interdit", "Auth_TerrPar", 291, 3, 4, "Autorisé", "Interdit", "Auth_LumHallNuit", 362, 3, 4, "Autorisé", "Interdit", "ECS", 292, 3, 4, "Oui", "Non", "DayPart", 130, 3, 4, "After SunRise", "After SunSet", "Noel", 363, 3, 4, "Oui", "Non", "Saison", 133, 3, 6, "Printemps", "Eté", "Automne", "Hiver", "Chauffage", 351, 3, 5, "0", "1", "2", "Vacances", 293, 3, 4, "Oui", "Non" } ---------------------------------- -- DO not change bellow this line ---------------------------------- local i = 1 while Table[i] ~= nil do local VG_Nom = tostring(Table[i]) fibaro:debug("----------------------------") fibaro:debug("Nom de la variable Globale = " ..VG_Nom) local VD_id = tostring(Table[i+1]) local Btn_Deb = tonumber(Table[i+2]) local Btn_Fin = tonumber(Table[i+3]) local NbrVal = (Btn_Fin - Btn_Deb) + 1 --Nbr de valeur possibles de la variable fibaro:debug('NbrVal = ' ..NbrVal) i = i + 4 local VG_Val = fibaro:getGlobalValue(VG_Nom) fibaro:debug('Valeur de la variable Globale = ' ..VG_Val) for j = 1,NbrVal do if VG_Val == Table[i+j-1] then fibaro:debug(VG_Nom.. ' = ' ..VG_Val) fibaro:debug("Il faut appuyer sur le bouton : " ..Btn_Deb.. " de la VD_id " ..VD_id) fibaro:call(VD_id, "pressButton", Btn_Deb) end Btn_Deb = Btn_Deb + 1 end -- for i = i + NbrVal end -- while Pour retrouver l'ID du VD, vous avez plusieurs solutions : Le toolkit de Krikroff l'API : http://<IP Box>:<Port Box>/api/virtualDevices vous exportez le VD, et dans l'URL vous voyez ?id=xxx vous éditez le VD, et dans l'URL vous voyez ?vid=xxx Il vérifie la valeur de la variable et appuie sur le bouton correspondant à l'icône. D/Variable. Donc maintenant, quand je vois qu'une des icônes associée à mes variables est l'icone standard, je clique sur le bouton, et tout est remis au carré. Cela évite d'avoir un main loop qui tourne pour chaque variable 99% du temps pour rien. On a donc trouvé une parade à la deuxième limitation ;-) Pour la première limitation (mise à jour après un restart de la box) la solution est facile : Créer une scène qui appelle la VD "Var_Update" / bouton 1 au démarrage de la box. --[[ %% autostart --]] fibaro:sleep (10*1000) fibaro:call(361, "pressButton", "1") où 361 est l'ID du Vd "Var_Update" Merci à Steven qui finalement à trouvé la solution du sleep au début de la scène, ainsi qu'à i-magin et mprinfo pour leurs bonnes idées
  21. Bonjour a tous, Suite a la réalisation de Module Virtuel Météo débuté par Bencol et réalisé par un groupe de Membres du FORUM Casimos, Berale24, Pepite, et comme juge Arbitre pour le Main Loop LAZER Voici le lien : http://www.domotique-fibaro.fr/index.php/topic/4087-pr%C3%A9vision-m%C3%A9t%C3%A9o/ Nous Nous sommes posés la question comment faire pour récupérer la latitude et la longitude dans notre box plus de l'écrire dans le module virtuel. J'avais fais un petit tour dans la docs de l'API mais comme je débute c'est un peu du charabia J'ai donc décidé d'y jeté un Å“il de plus prêt. Pour ceux qui ne le savent pas, la docs de notre HC2 ce trouve a l'adresse suivant (V4 Uniquement) http://<ip box>/docs/ exemple : http://192.168.1.54/docs/ j'ai vu qu'il y avait settings Et la miracle je vois location (GET ou PUT) Je choisi GET car je veux récuperer les informations Je vois que finalement on peut récuperé pas mal d'info, En bas de la page je vois que l'on a json je clic sur TRY IT! Au miracle j'ai ma latitude, Longitude et pas mal d'information de mon panneau de configuration. Super tout cela mais comment faire pour récupérer tout cela. je poste donc l'api sur le fofo et miracle une réponse de Bencol que je remercie HC2 = Net.FHttp("127.0.0.1",80); HC2:setBasicAuthentication("admin","xxxx"); local response, status, errorCode = HC2:GET("/api/settings/location"); if (tonumber(errorCode) == 0) then jsonTable = json.decode(response); fibaro:debug(jsonTable.latitude); fibaro:debug(jsonTable.longitude); end Ok c'est cool mais il faut un mot de passe et un utilsateur donc je modifie le début du code comme cela HC2 = Net.FHttp("127.0.0.1",11111); en mettant le port 11111 a la place du 80 On a plus besoin de HC2:set.... Merci qui ? Merci Krikroff Donc maintenant que j'ai mon json cool je n'ai plus l'utiliser comme cela pour avoir la latitude et longitude HC2 = Net.FHttp("127.0.0.1",11111); local response, status, errorCode = HC2:GET("/api/settings/location"); if (tonumber(errorCode) == 0) then jsonTable = json.decode(response); fibaro:debug(jsonTable.latitude); fibaro:debug(jsonTable.longitude); end local latitude = (jsonTable.latitude); local Longitude = (jsonTable.longitude); fibaro:debug("Latitude = " ..latitude) fibaro:debug("Longitude = " ..longitude) On peut biensur retrouver la ville, numero de votre maison, ntpServer, etc.. Bon je début donc je n'irai pas plus loin au niveau de l'api. Commander la HC2 Par requetes HTTP Voici un lien : http://tutoriels.domotique-store.fr/content/49/45/fr/api-commander-le-home-center-par-des-requ%C3%AAtes-http.html
  22. Ce module virtuel permet de modifier les paramètres d'un device. Pour savoir comment l'utiliser, voyez la doc dans le code du VD. Il adapte son code automatiquement pour v3.x et v4.x. Son utilité : vous avez le code pour l'utiliser dans vos VD en fonction de vos besoins (je n'ai pas testé le code pour les scènes) permet d'entrer une valeur précise pour un paramètre sans devoir vous faire .... à bouger le slide bar, qui parfois ne veux jamais mettre la valeur que vous voulez La première fois que vous cliquez sur le bouton, il affiche le device, le paramètre à modifier, sa valeur actuelle et la nouvelle valeur souhaitée Un deuxième clic sur le bouton (dans les 5 secondes - paramétrable) confirme le changement un troisième clic sur le bouton affiche la nouvelle valeur telle que enregistrée dans le device Si vous avez des idées d'amélioration, elles sont les bienvenues. DeviceParameter_v1.0.vfib P.S. J'attends une super icône de notre graphiste national
  23. Petit script permettant de se réveiller en douceur. J'avais fait ce script il y a déjà pas mal de temps, il me permettait de déclencher l'allumage en douceur dans ma chambre et dans celle des enfant dès que le réveil sonnait. Avec le script ALARM de Steven et son GEA, j'en ai profité pour l'améliorer. Maintenant le script se lance soit via mon révei, soit via le Virtual Device ALARM de Steven et GEA Ce script permet de: - choisir la durée de l'allumage des lampes (en minutes) - détecte ces conditions individuellement pour chaque chambre: - Si une lampe est déjà allumée, elle est exclue de l'allumage (évite de passer de 100% à 5% lorsque le script démarre et que l'on est déjà levé) - Si on modifie une lampe elle est exclue (extinction ou allumage à 100% par exemple) - Si toutes les lampes ont été modifiées, fin du script - allumer mon routeur Wifi de l'étage (qui est coupé s'il n'y a pas de mouvement détecté pendant 30 minutes) Depuis ce script, je gagne 15 minutes au lit le matin, plus besoin de réveil qui gueule et les enfants sont réveillés en douceur et de bonne humeur (et moi aussi ) Le voici: Pour ajouter ou supprimer des lampes, je pense que le script parle de lui mème, il suffit de supprimer/modifier/ajouter les lignes Question copyright, je pense l'avoir fait complètement seul (il y a longtemps que je l'ai, et franchement je ne me souvient plus de sa genèse) --[[ %% properties 1277 value %% globals --]] -------------------------------------------------- -- Sweet Wakeup -- Gradually dim up lights, excluding already on lights or modified during the wakeup -- Sebastien Jauquet -- Mars 2015 -------------------------------------------------- local id = { LAMPE_CH_THOMAS = 41, LAMPE_DRESSING = 42, LAMPE_CH_PARENTS = 47, LAMPE_CH_EMILIEN = 58, REVEIL_1_SEB = 1277, PRISE_ROUTEUR_1ER = 22 } local cycle = 30 --duration (in minutes) of the complete cycle of wakeup local dim = 5 -- dimming starting value (5=5%) local startSource = fibaro:getSourceTrigger(); -- launch script if started trough device in the header or "manually"/trough an other script if (( tonumber(fibaro:getValue(id["REVEIL_1_SEB"], "value")) > 0 ) or startSource["type"] == "other") then -- Always execute actions on this/those device(s): fibaro:call(id["PRISE_ROUTEUR_1ER"], "turnOn"); -- If one light is not turned off, disable it from the wakeup loop if(tonumber(fibaro:getValue(id["LAMPE_CH_THOMAS"], "value")) ~= 0 ) then id["LAMPE_CH_THOMAS"] = 0; fibaro:debug("LAMPE_CH_THOMAS Desactivated"); end if(tonumber(fibaro:getValue(id["LAMPE_DRESSING"], "value")) ~= 0 ) then id["LAMPE_DRESSING"] = 0; fibaro:debug("LAMPE_DRESSING Desactivated"); end if(tonumber(fibaro:getValue(id["LAMPE_CH_PARENTS"], "value")) ~= 0 ) then id["LAMPE_CH_PARENTS"] = 0; fibaro:debug("LAMPE_CH_PARENTS Desactivated"); end if(tonumber(fibaro:getValue(id["LAMPE_CH_EMILIEN"], "value")) ~= 0 ) then id["LAMPE_CH_EMILIEN"] = 0; fibaro:debug("LAMPE_CH_EMILIEN Desactivated"); end -- Main wakeup loop while dim < 91 do -- set dim value to all dimmers (excluding disabled: Id["xxx"] not equal to 0) if (id["LAMPE_CH_THOMAS"] ~= 0) then fibaro:call(id["LAMPE_CH_THOMAS"], "setValue", dim) end if (id["LAMPE_DRESSING"] ~= 0) then fibaro:call(id["LAMPE_DRESSING"], "setValue", dim) end if (id["LAMPE_CH_PARENTS"] ~= 0) then fibaro:call(id["LAMPE_CH_PARENTS"], "setValue", dim) end if (id["LAMPE_CH_EMILIEN"] ~= 0) then fibaro:call(id["LAMPE_CH_EMILIEN"], "setValue", dim) end fibaro:debug("Set Dimmers Value at: " .. dim) fibaro:sleep(cycle*3000); -- Check if dimmer value modified, then disable it from the wakeup loop if ((id["LAMPE_CH_THOMAS"]) ~= 0) then if((tonumber(fibaro:getValue(id["LAMPE_CH_THOMAS"], "value")) - dim) ~= 0 ) then id["LAMPE_CH_THOMAS"] = 0; fibaro:debug("LAMPE_CH_THOMAS Desactivated"); end; end; if ((id["LAMPE_DRESSING"]) ~= 0) then if((tonumber(fibaro:getValue(id["LAMPE_DRESSING"], "value")) - dim) ~= 0 ) then id["LAMPE_DRESSING"] = 0; fibaro:debug("LAMPE_DRESSING Desactivated"); end; end; if ((id["LAMPE_CH_PARENTS"]) ~= 0) then if((tonumber(fibaro:getValue(id["LAMPE_CH_PARENTS"], "value")) - dim) ~= 0 ) then id["LAMPE_CH_PARENTS"] = 0; fibaro:debug("LAMPE_CH_PARENTS Desactivated"); end; end; if ((id["LAMPE_CH_EMILIEN"]) ~= 0) then if((tonumber(fibaro:getValue(id["LAMPE_CH_EMILIEN"], "value")) - dim) ~= 0 ) then id["LAMPE_CH_EMILIEN"] = 0; fibaro:debug("LAMPE_CH_EMILIEN Desactivated"); end; end; if id["LAMPE_CH_THOMAS"] == 0 and id["LAMPE_DRESSING"] == 0 and id["LAMPE_CH_PARENTS"] == 0 and id["LAMPE_CH_EMILIEN"] == 0 then fibaro:debug("All Dimmer Values Modified, stopping script"); fibaro:abort(); end dim = dim +5 end -- end of wakeup, set dimmers to max value fibaro:call(id["LAMPE_CH_THOMAS"], "setValue", 99); fibaro:call(id["LAMPE_DRESSING"], "setValue", 99); fibaro:call(id["LAMPE_CH_PARENTS"], "setValue", 99); fibaro:call(id["LAMPE_CH_EMILIEN"], "setValue", 99); end
  24. Boujour a tous Voici une scéme qui va permettre d'envoyer a un ID une Valeur les valeurs autorisé sont : open, close, turnOn, turnOff, 0, 1, 2, 3 etc... jusqu'à 100 je vais utilisé pour cela un tableau exemple : Id = {13, 5, 7, 9, 23} -- Id des volets roulants IdValue = {"turnOff", "open", 99, 0, "close"} -- Valeur : 0=Fermer, 99=Ouvert - open - close - turnOn - turnOff dans un premier temp l' ID 13 recevra la "value" turnOff puis l'id 5 la "value" open etc.... On pourra donc allumer puis eteindre une lampe ou fermer des volets avec des valeurs différentes. J'ai choisi de déclencher la scéne avec une variable globale Jour_Nuit --[[ %% properties %% globals Jour_Nuit --]] il faudra donc crée cette variable Avec les valeurs suivantes : Jour Nuit Puis 2 scénes en mode bloc une pour changer la variable a JOUR et l'autre pour changer la variable a NUIT Jour : Nuit : Ou une Scénes en LUA --[[ %% autostart %% properties %% globals --]] while true do local Var_Jour = os.date("%H:%M", os.time()-15*60) local Var_Nuit = os.date("%H:%M", os.time()+15*60) local currentDate = os.date("*t"); local Jour = fibaro:getValue(1, "sunriseHour") local Nuit = fibaro:getValue(1, "sunsetHour") fibaro:debug("Jour : " ..Jour) fibaro:debug("Nuit : " ..Nuit) if ( Var_Jour == Jour ) then fibaro:setGlobal("Jour_Nuit", "Jour"); elseif ( Var_Nuit == Nuit ) then fibaro:setGlobal("Jour_Nuit", "Nuit"); end fibaro:sleep(59*1000); -- s'execute toutes les minutes end On peut bien entendu modifier ces paramètres ou en ajouter if J_N == "Nuit" then Id = {5, 7, 9, 23, 27, 25, 29, 17, 19} -- Id des volets roulants IdValue = {0, 0, 0, 0, 0, 0, 85, 0, 0} -- Valeur 0=Fermer - 99 = Ouvert fibaro:debug("Nuit") end if J_N == "Jour" then Id = {13, 5, 7, 9, 23, 27, 25, 29} -- Id des volets roulants IdValue = {"turnOff","open", 99, 99, 99, 99, 99, 99, 99, 99} -- Valeur : 0=Fermer, 99=Ouvert - open - close - turnOn - turnOff fibaro:debug("Jour") end Ensuite il y a un autre bloc de programme qui ajoute des ID et des "Value" a la table en fonction du jour de la semaine -- Debut Volets Chambres ouverture du lundi au vendredi local jour = os.date("%w"); --0=Dimanche, 1=Lundi, 2=Mardi,3=Mercredi etc... fibaro:debug("Jours de la Semaine = " ..jour) if ((jour == "1" or jour == "2" or jour == "3" or jour == "4" or jour == "5") and (J_N == "Jour")) then local Id1 = {19, 17} -- 19 ch amis 17 ch enfants local IdValue1 = {99, 99} local t_id = #Id local t_id1 = #Id1 for i = 1,#Id1 do t_id = t_id + 1 table.insert(Id, t_id, Id1[i]) table.insert(IdValue, t_id, IdValue1[i]) end end -- Fin Volets chambres Puis un test pour savoir si il y a bien le même autant d' ID que de "Value" -- Test si le nombres d' Id et Egale au nombre de IdValue if #Id == #IdValue then fibaro:debug("total des id = " ..#Id) else fibaro:debug("Total des id = " ..#Id .." - Total des Values = " ..#IdValue) fibaro:debug("fin de la Scéme...") fibaro:abort(); end pour le push je conseil de créer une variable global avec l'ID du téléphone (vu les soucis avec le push cela évite de modifier toutes ces scénes a chaque fois que l'ID du tél change) Pour récupérer l'id du tel local IdTel = fibaro:getGlobalValue("IdI9305") -- Recuperation de id du tel pour le push Dans cette exemple on récupére l'id du tel qui ce trouve dans la variable globale IdI9305 (je sais c'est un samsung s3 LTE ) j'ai mis une pause de 30s entre chaque commande local VTimer = 30*1000 -- Temp de pause entre chaque commande de modules A la fin de l’exécution de la scéne on envoi un PUSH avec le nombres de modules actionnés -- Envoi du Push fibaro:call(IdTel, "sendPush", "Les " ..#Id .." ont été actionnés") Voici la scéne : --[[ %% properties %% globals Jour_Nuit --]] -- Recupération de la valeur de la variable global Jour_Nuit local num = fibaro:countScenes () -- nombres d'instance en cours d'excution de la sceme fibaro:debug("Nombres de Scéme en cours = " ..num) if (num == 1) then local J_N = fibaro:getGlobalValue( "Jour_Nuit" ); fibaro:debug("Jour_Nuit = " ..J_N) local Id = {} local IdValue = {} if J_N == "Nuit" then Id = {5, 7, 9, 23, 27, 25, 29, 17, 19} -- Id des volets roulants IdValue = {0, 0, 0, 0, 0, 0, 85, 0, 0} -- Valeur 0=Fermer - 99 = Ouvert fibaro:debug("Nuit") end if J_N == "Jour" then Id = {13, 5, 7, 9, 23, 27, 25, 29} -- Id des volets roulants IdValue = {"turnOff","open", 99, "turnOn", 99, 75, 99, 45, 99, 99} -- Valeur : 0=Fermer, 99=Ouvert - open - close - turnOn - turnOff fibaro:debug("Jour") end -- Debut Volets Chambres ouverture du lundi au vendredi local jour = os.date("%w"); fibaro:debug("Jours de la Semaine = " ..jour) if ((jour == "1" or jour == "2" or jour == "3" or jour == "4" or jour == "5") and (J_N == "Jour")) then local Id1 = {19, 17} -- 19 ch amis 17 ch enfants local IdValue1 = {99, 99} local t_id = #Id local t_id1 = #Id1 for i = 1,#Id1 do t_id = t_id + 1 table.insert(Id, t_id, Id1[i]) table.insert(IdValue, t_id, IdValue1[i]) end end -- Fin Volets chambres -- Test si le nombres d' Id et Egale au nombre de IdValue if #Id == #IdValue then fibaro:debug("total des id = " ..#Id) else fibaro:debug("Total des id = " ..#Id .." - Total des Values = " ..#IdValue) fibaro:debug("fin de la Scéme...") fibaro:abort(); end -- Fin du test local IdTel = fibaro:getGlobalValue("IdI9305") -- Recuperation de id du tel pour le push dans la variable globale IdI9305 local VTimer = 30*1000 -- Temp de pause entre chaque commande de modules fibaro:debug("Nombres Modules = " ..#Id) for i = 1,#Id do local TestName = fibaro:getName(Id[i]) local TestValue = fibaro:getValue(Id[i], "value") if IdValue[i] == "open" or IdValue[i] == "close" or IdValue[i] == "turnOn" or IdValue[i] == "turnOff" then fibaro:call(Id[i], IdValue[i]); else fibaro:call(Id[i], "setValue", IdValue[i]); -- Commande Module end fibaro:debug("---------------------") fibaro:debug("Nom = " ..TestName) fibaro:debug("Valeur = " ..TestValue .." - Valeur demander = " ..IdValue[i]) fibaro:sleep(VTimer) end fibaro:sleep(2*1000) -- Envoi du Push fibaro:call(IdTel, "sendPush", "Les " ..#Id .." ont été actionnés") else fibaro:debug("Nombre de Scénes en cours " ..num) end J'utilise cette scéne pour fermer et ouvrir mes volets et j'allume en même temps des lumières que j'éteins ensuite. on peut bien entendu utilisé plusieurs fois le même ID exemple : J'allume ma lampe, je ferme mon volets j' éteins ma lampe. Pour les modules dinnable il faut comme pour les volets mettre une valeur entre 0 et 99 Id = {13, 5, 13} -- Id des volets roulants IdValue = {"turnOn", "close", "turnOff"} -- Valeur : 0=Fermer, 99=Ouvert - open - close - turnOn - turnOff
  25. Bonjour, Le but de ce tuto sera de faire une passerelle pour les données de la netatmo vers emoncms. J'en ai profité pour améliorer le script php classique d'interface entre la netatmo et la HC2 les versions disponibles ot du mal à gérer les installations netatmo avec plusieurs modules. Ici j'ai cherché à améliorer les choses et ça fonctionne même lorsque l'on a plusieurs master device et plusieurs stations additionnelles. En effet, savoir l'ordre des modules renvoyé par netatmo dans ces conditions est un peur hard. J'ai ajouté plusieures pages de résultats au script PHP: une avec un json viewer intégré et un qui retourne le json complet. J'ai aussi optimisé pour minimiser le nombre de requêtes faites à netatmo, histoire de ne pas se faire "jeter" voici déjà la présentation de la plateforme emon CMS très puissante que j'utilise depuis plus d'un an: http://emoncms.org/site/home http://emoncms.org/site/docs/visualisations Personellement je l'utilise pour remonter mes graphiques de valeurs diverses de ma HC2 - températures - consommations eau, gaz, elec - paramètres de ma VMC (T° Vitesse, rendement etc.) J'ai partagé mon script avec un ami et comme il était enchanté, je fais l'effort de le mettre ici aussi ;-) En effet, il suffit de configurer les variables dans le VD, créer un répertoire /netatmo dans www ou web ou html, y mettre le PHP et le répertoire jsoneditor et c'est parti, les données seront remontées automatiquement à emonCMS ! Voici déjà le script côté HC2: Je l'ai mis derrière un bouton, car dans un main loop, une corruption json quelquepart et c'est tout qui plante. Ce bouton dont être cliqué via GEA ou autre scheduler toutes les 10 minutes. Voici le Virtual Device tout fait: Grosse mise à jour à ce post: http://www.domotique-fibaro.fr/index.php/topic/3929-yagda-yet-another-graphic-data-analyser-netatmo-vmc-emoncms-json-viewer/#entry63238 Netatmo_V2.vfib Attention, dans ce post ne figure que les scripts de la première version, voir plus loin dans le fil pour les versions suivantes ! ----------------------------------------------------------------------------------------- -- YAGDA - yet another graphic data analyser V2.01 -- Retreive Netatmo values for more than 2 modules, compute CO2 and push to EmonCMS -- Sebastien Jauquet -- Février 2015 -- Thanks to cedriclocqueneux, krikroff, i-magin and all contibutors to the netatmo code ----------------------------------------------------------------------------------------- -- Instructions: -- Create an free emoncms.org account -- Retrieve your Write API Key from it -- Create a Global variable (undefined) -> CO2_Max_Value to store the max value of CO2 of the house - if you dont need this, set CO2 to false (default: 0) -- Install my netatmo.php in your webserver and write his address in the ip Address of this module -- for each value you want to be pushed to emoncms, modify the section -- Push To EMONCMS -- below -- Create a block scene or use gea to click this button each 10 minutes (to avoid rejection from the api of Netatmo) local EmonCMS_Prefix = "NETATMO_" -- prefix of the id of the inpus to be created in emoncms (convenient for testing to not alter current feeds) local PushToEmonCMS = true -- true = push to emoncms - false = do not push local selfId = fibaro:getSelfId(); local thismodule=fibaro:getSelfId() local domaine = fibaro:get(selfId, 'IPAddress') local PushItem local CO2_Max_Value_Local = 0 -- if you dont need this, set CO2 to false (default: 0) local emoncms = Net.FHttp("emoncms.org",80) local emoncms_api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -- your EMONCMS WRITE api Key EmonCMS = {}; if (temperature_exterieure==nil) then temperature_exterieure = ""; end if (humidite_exterieure==nil) then humidite_exterieure = ""; end if (temperature_interieure==nil) then temperature_interieure = ""; end if (humidite_interieure==nil) then humidite_interieure = ""; end if (co2==nil) then co2 = ""; end if (pression==nil) then pression = ""; end if (bruit==nil) then bruit = ""; end if (temperature_int_mod2==nil) then temperature_int_mod2 = ""; end if (humidite_int_mod2==nil) then humidite_int_mod2 = ""; end if (co2_mod2==nil) then co2_mod2 = ""; end if (temperature_int_mod3==nil) then temperature_int_mod3 = ""; end if (humidite_int_mod3==nil) then humidite_int_mod3 = ""; end if (co2_mod3==nil) then co2_mod3 = ""; end if (temperature_int_mod4==nil) then temperature_int_mod4 = ""; end if (humidite_int_mod4==nil) then humidite_int_mod4 = ""; end if (co2_mod4==nil) then co2_mod4 = ""; end if(refreshUI==nil) then -- Loads in memory only the first occurence function refreshUI(ext, bruit, titre, tempmod, co2mod, humidmod, lastupdate, laststatus) fibaro:call(selfId,"setProperty","ui.ext.value",ext); fibaro:call(selfId,"setProperty","ui.bruit.value",bruit); fibaro:call(selfId,"setProperty","ui.titre.value",titre); fibaro:call(selfId,"setProperty","ui.tempmod.value",tempmod); fibaro:call(selfId,"setProperty","ui.co2mod.value",co2mod); fibaro:call(selfId,"setProperty","ui.humidmod.value",humidmod); fibaro:call(selfId,"setProperty","ui.lastupdate.value",lastupdate); fibaro:call(selfId,"setProperty","ui.laststatus.value",laststatus); end; end if(getExt==nil) then -- Loads in memory only the first occurence function getExt(retry) retry = retry or 0 -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo extérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=ext"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_exterieure = result.body[1].value[1][1] or "n.c"; humidite_exterieure =result.body[1].value[1][2] or "n.c"; -- variable globale pour info sms local msg = "Température extérieure : "..temperature_exterieure.."°C"; fibaro:setGlobal("tempext", msg); return true; else fibaro:debug("Netatmo EXT: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo EXT: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo EXT:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getInt(tonumber(retry+1)); else return false; end end; end if(getInt==nil) then -- Loads in memory only the first occurence function getInt(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=int"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_interieure = result.body[1].value[1][1] or "n.c"; humidite_interieure = result.body[1].value[1][3] or "n.c"; co2 = result.body[1].value[1][2] or "n.c"; pression = result.body[1].value[1][4] or "n.c"; bruit = result.body[1].value[1][5] or "n.c"; -- variable globale pour info sms fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end if(getMod2==nil) then -- Loads in memory only the first occurence function getMod2(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=mod2"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_int_mod2 = result.body[1].value[1][1] or "n.c"; humidite_int_mod2 = result.body[1].value[1][2] or "n.c"; co2_mod2 = result.body[1].value[1][3] or "n.c"; -- variable globale pour info sms -- fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT_mod2: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT_mod2: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT_mod2:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end if(getMod3==nil) then -- Loads in memory only the first occurence function getMod3(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=mod3"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_int_mod3 = result.body[1].value[1][1] or "n.c"; humidite_int_mod3 = result.body[1].value[1][2] or "n.c"; co2_mod3 = result.body[1].value[1][3] or "n.c"; -- variable globale pour info sms -- fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT_mod3: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT_mod3: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT_mod3:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end if(getMod4==nil) then -- Loads in memory only the first occurence function getMod4(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=mod4"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_int_mod4 = result.body[1].value[1][1] or "n.c"; humidite_int_mod4 = result.body[1].value[1][2] or "n.c"; co2_mod4 = result.body[1].value[1][3] or "n.c"; -- variable globale pour info sms -- fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT_mod4: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT_mod4: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT_mod4:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end function EmonCMS:Push(payloademon) payloademon = "/input/post.json?json={" .. EmonCMS_Prefix .. payloademon .. "}&apikey=" .. emoncms_api_key response, status, errorCode = emoncms:GET(payloademon); fibaro:debug("Payload: " .. payloademon) ; fibaro:debug("response: " .. response .. " Status: " .. status .. " errorcode: " .. errorCode) ; fibaro:sleep(500); end local function main() -- retrieve values from netatmo.php local resInt, resExt, resMod2, resMod3, resMod4 = false, false, false, false, false; local status, err = pcall(function () resInt = getInt(); end); fibaro:debug("Récupération des données intérieures: " .. tostring(resInt)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resExt = getExt(); end); fibaro:debug("Récupération des données extérieures : " .. tostring(resExt)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resMod2 = getMod2(); end); fibaro:debug("Récupération des données intérieures Mod2: " .. tostring(resMod2)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resMod3 = getMod3(); end); fibaro:debug("Récupération des données intérieures Mod3: " .. tostring(resMod3)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resMod4 = getMod4(); end); fibaro:debug("Récupération des données intérieures Mod4: " .. tostring(resMod4)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end refreshUI( "Ext: "..temperature_exterieure.." °C - "..humidite_exterieure.." % - "..pression.." mbar", "Bruit Rez: "..bruit.." dB", "Rez - Emilien - Thomas - Parents", temperature_interieure.." - "..temperature_int_mod2.." - "..temperature_int_mod3.." - "..temperature_int_mod4.." °C ", co2.." - "..co2_mod2.." - "..co2_mod3.." - "..co2_mod4.." ppm", humidite_interieure.." - "..humidite_int_mod2.." - "..humidite_int_mod3.." - "..humidite_int_mod4.." % ", os.date("%H:%M"), tostring(resInt).." "..tostring(resExt).." "..tostring(resMod2).." "..tostring(resMod3).." "..tostring(resMod4) ); -- Push To EMONCMS -- if PushToEmonCMS == true then payloademon = "temperature_exterieure:"..temperature_exterieure EmonCMS:Push(payloademon); payloademon = "humidite_exterieure:".. humidite_exterieure EmonCMS:Push(payloademon); payloademon = "pression:".. pression EmonCMS:Push(payloademon); payloademon = "bruit:".. bruit EmonCMS:Push(payloademon); payloademon = "temperature_interieure_Rez:".. temperature_interieure EmonCMS:Push(payloademon); payloademon = "temperature_int_mod2_Emilien:".. temperature_int_mod2 EmonCMS:Push(payloademon); payloademon = "temperature_int_mod3_Thomas:".. temperature_int_mod3 EmonCMS:Push(payloademon); payloademon = "temperature_int_mod4_Parents:".. temperature_int_mod4 EmonCMS:Push(payloademon); payloademon = "humidite_interieure_Rez:".. humidite_interieure EmonCMS:Push(payloademon); payloademon = "humidite_int_mod2_Emilien:".. humidite_int_mod2 EmonCMS:Push(payloademon); payloademon = "humidite_int_mod3_Thomas:".. humidite_int_mod3 EmonCMS:Push(payloademon); payloademon = "humidite_int_mod4_Parents:".. humidite_int_mod4 EmonCMS:Push(payloademon); payloademon = "co2_Rez:".. co2 EmonCMS:Push(payloademon); payloademon = "co2_mod2_Emilien:".. co2_mod2 EmonCMS:Push(payloademon); payloademon = "co2_mod3_Thomas:".. co2_mod3 EmonCMS:Push(payloademon); payloademon = "co2_mod4_Parents:".. co2_mod4 EmonCMS:Push(payloademon); end -- Compute Value MAX CO2 Maison (For VMC Speed VD) if CO2_Max_Value_Local == false then fibaro:debug("not calculating nor storing CO2 Max Value") else CO2_Max_Value_Local = co2 if CO2_Max_Value_Local < co2_mod2 then CO2_Max_Value_Local = co2_mod2 end if CO2_Max_Value_Local < co2_mod3 then CO2_Max_Value_Local = co2_mod3 end if CO2_Max_Value_Local < co2_mod4 then CO2_Max_Value_Local = co2_mod4 end fibaro:setGlobal("CO2_Max_Value", CO2_Max_Value_Local ) fibaro:debug("CO2_Max_Value: ".. CO2_Max_Value_Local ) end end main();
×