J3R3M Posté(e) le 8 avril 2020 Signaler Posté(e) le 8 avril 2020 (modifié) Bonjour à tous, Dans ce fil, je vais vous expliquer et partager avec vous les principaux et différents éléments qui ont rendu mon appartement intelligent. Je dis bien intelligent, car pour moi, c'est le but premier de la domotique. Allumer la lumière ou fermer les volets quand je suis en déplacement, c'est marrant, mais c'est pas ça qui me change la vie! Mon installation est donc simple et constituée de peu de modules finalement. Dans chaque pièce, il y a au minimum un détecteur de mouvements (Caméra et/ou FGMS001) et un éclairage connecté. J'utilise également Jeedom pour supporter des protocoles autres que Z-Wave, mais cela ne fait pas parti des éléments importants de la domotique. Les explications seront agrémentées au fur-et-à-mesure. Tout cela a été programmé il y a un moment, il faut moi-même que je retrouve mes petits Les scènes importantes sont : Check 1mn qui tourne toutes les minutes 24/24h pour faire des vérifications régulières NetAtmo Welcome que j'ai personnalisé pour mes besoins (Scène originale postée ici) Pièces 2019 qui sera actionnée dès une action dans une pièce. Cette même scène est capable de gérer chacun des pièces intérieures de l'appartement : Volets Roulants, Eclairages, Système d'enceintes... Watchdog qui vérifie simplement que la scène Check 1mn s'exécute correctement et la redémarre le cas échéant. Moins importantes mais néanmoins utiles : Réveil Une adaptation de ma scène Advanced Alarm Clock 3.6 SONOS FO Général : Il s'agit simplement de ma scène Fade Out intelligent pour VD Sonos Les autres scènes SONOS en sont une adaptation individuelle Le VD important est Etat Pièces. C'est surtout sa Main loop qui est importante puisqu'elle gère la variation et extinction des lumières et enceintes en fonction des mouvements des pièces. Je l'utilise en VD puisque je voulais avoir une visualisation sur ce qu'il se passait en le programmant. Cela a toujours bien fonctionné ainsi et je l'ai laissé sous cette forme. Ce VD est également surveillé par l'indispensable scène Watchdog. J'expliquerai son fonctionnement de manière plus précise par la suite. Quelques autres VD (sans Mainloop sauf Surveillance Station) me servent uniquement pour avoir une visualisation de l'état actuel de certaines Variables Globales. Les scènes agissent majoritairement sur les boutons de ces VD pour changer l'état de la variable globale correspondante. D'autres me servent à avoir une interface d'administration sans avoir à programmer quelque chose pour modifier le comportement des scènes. Également, j'expliquerai par la suite la fonction de chaque VD si cela peut intéresser certaines personnes. Avant toutes chose, il faut savoir que toutes les scènes et tous les VDs utilisent des informations encodées en JSON dans une variable globale qui s'appelle T_INFOS_PIECES dont voici l'architecture et un exemple id ID de la pièce correspond à l'id du bouton du VD Pièce Active Code Code de la pièce. Doit être similaire à la clé du tableau principal Nom Nom de la pièce avec majuscule et accents (pour utilisation propre dans SMS par ex) Article Article du nom de la pièce (ex : "l'" pour "entrée") Detect Table des id des détecteurs Fibaro. Si cam, mettre "cam" LumMini À partir de quel seuil de luminosité (lux) la lumière doit-elle s'allumer. nil si uniquement cam LumMax Table des luminosités maximales détectées par chaque détecteur lorsque toutes les lampes gérées sont allumées à 100%. Le but étant de se baser sur ses valeurs pour déterminer si une autre source de lumière est présente. Passage 0/1 - Pièce de passage ou non ? Par exemple, un couloir est un lieu de passage. TpsActive Temps maxi durant lequel la pièce restera considérée comme active sans le moindre mouvement TpsMise Temps maxi durant lequel la mise resetera active sans le moindre mouvement JourNuit 0/1 - Gestion automatique de l'allumage de la pièce (basé sur les heures de levés et couchés du soleil). Utile lorsque seule une cam détecte les mouvements de la pièce HueGroup Table des Ids des VDs Groupe Hue de la pièce HuePreset Bouton du VD à appuyer pour un preset de couleur standard. Ces boutons sont actionnés à la désactivation de HOME_DODO par exemple. HueList Table des Ids des VDs des ampoules Hues utilisées dans la pièce HueType Table des types des lampes Hues précédemment déclarées HuePowerDodo Table des valeurs lorsque la pièce est en mode DODO HuePowerAM Table des valeurs lorsque Moment = Matinée HuePowerMidi Table des valeurs lorsque Moment = Midi HuePowerPM Table des valeurs lorsque Moment = Après-Midi HuePowerSoir Table des valeurs lorsque Moment = Soirée HuePowerNuit Table des valeurs lorsque Moment = Nuit SonosId Table des ID des VD SONOS de la pièce SonosVMax Table contenant les volumes maxi autorisés pour les enceintes de la pièce, en fonction du moment de la journée SonosV Table contenant les volumes auxquels seront montées les SONOS en fonction du moment de la journée SonosFadeOut ID de la scène spécifique qui fait le FADE OUT de la pièce VoletsR IDs des Roller Shutter de la pièce Chambre La pièce est-elle une chambre ? Netatmo Uniquement si Chambre = 1. Tableau contenant les noms (Netatmo) des personnes dormant dans cette chambre. Les personnes seront donc déclarées absentes lorsqu'elles seront couchées, si elles ont été vues dans l'heure précédent le coucher. local pieces = {}; pieces["ENTREE"] = { id = 1, Code = "ENTREE", Nom = "Entrée", Article = "l'", Detect = {"cam"}, LumMini = nil, LumMax = {nil}, Passage = 1, TpsActive = 2, TpsMise = 120, JourNuit = 0, HueGroup = {298}, HuePreset = {Sat=20, Bri=90, Color=10000}, HueList = {89,96,113,112}, -- 112 = Couloir HueType = {"hcol", "hcol", "hcol", "hcol"}, HuePowerDodo = {5,0,0,5}, HuePowerAM = {30,30,30,45}, HuePowerMidi = {40,40,40,50}, HuePowerPM = {40,40,40,50}, HuePowerSoir = {40,40,40,50}, HuePowerNuit = {30,30,30,40}, SonosId = {245}, SonosVMax = {AM=40,Midi=50,PM=50,Soir=50,Nuit=40}, SonosV = {AM=30,Midi=35,PM=35,Soir=35,Nuit=30}, SonosFadeOut = 186, VoletsR = {nil}, Chambre = 0 }; Modifié le 10 avril 2020 par J3R3M 1 1
J3R3M Posté(e) le 8 avril 2020 Auteur Signaler Posté(e) le 8 avril 2020 (modifié) Check 1mn Cette scène est exécutée toutes les minutes 24/24h dans le but de faire des vérifications constantes et mettre à jour les variables qui le nécessitent. Fonction InfosPieces Parcourt le JSON stocké dans T_INFOS_PIECES pour y récupérer les éléments nécessaires Récupération des IDs des détecteusr de mouvements des FGMS001 pour en déduire celui de la température (ID+1) Comparaison des valeurs récupérées avec les valeurs mini et maxi paramétrées dans T_TEMPERATURES. Si hors champ -> Envoi SMS Si une mise est active mais qu'aucun mouvement n'a été détecté dans la pièce en question depuis plus du temps indiqué dans la clé Mise de la pièce (T_INFOS_PIECES) -> Désactivation Une mise est un état lumineux enregistré qui ne sera pas impacté par la domotique pendant un laps de temps prédéfini. Vérification si les lumières de la pièce traitée sont allumées. Si elles le sont sans raison, elles sont éteintes. Pour vérifier si une lumière est allumée à juste titre, je vérifie la valeur de la mise (NomPiece_Mise) et la valeur de l'état (NomPiece_Etat) Etat=0 : Pièce inactive Etat=1 : Pièce considérée comme inactive dans les prochaines 10 secondes (Si lumière allumée, elle sera tamisée) Etat=3 : Pièce considéré comme active (Si lumière nécessaire, elle aura été allumée par la scène Pièces) Gestion du mode nuit : HOME_DODO Les chambres sont comptées Si toutes les chambres sont en mode DODO (VG DODO_NomPiece) : Le minimum entre deux modes DODO consécutifs est fixé sur 4h Si la scène calcule que le mode DODO souhaiterait se ré-enclencher aussitôt après les 4h, plusieurs alertes lumineuses seront faites successivement Ces signaux sont destinés à avertir de ce mode qui va s'enclencher et permet à chacun de désactiver le mode DODO si ça avait été un oubli Pourquoi? Car une seule personne provenant d'une même chambre peut être levée. Dans ce cas, le mode DODO sera désactivé (HOME_DODO = 0) alors que la chambre le sera toujours (DODO_NomPiece = 1). Si la seconde personne se lève sans désactiver ce mode DODO de la chambre, il est possible que ce mode DODO se réactive inopinément dans les heures suivantes si aucune alerte lumineuse n'était effectuée. La fonction retourne une valeur booléenne. True si HOME_DODO=1 & False si HOME_DODO = 0. Fonction Check Modes Absence (VG Absence) : Mode 1 Extinction de toutes les lumières Extinction de toutes les enceintes Désactivation de toutes les mises On indique les absences de tout le monde dans l'API NetAtmo Activation des caméras Notification du mode par SMS Si la prise TV consomme moins de 50W, on l'éteint (sinon, c'est que quelqu'un la regarde) Mode 2 Actions du Mode 1 + Valeur de la VG Absence affectée sur "ok" Extinction de la TV Si aucun mouvement depuis plus de 3h et que le mode DODO est désactivé, on active le mode Absence Niveau 2 Si un enregistrement des caméras est en cours et qu'aucun mouvement n'est détecté depuis plus de 2mn, on désactive l'enregistrement On rentre et on sort dans l'appartement par la pièce ENTREE, qui a été précisée comme un lieu uniquement de passage dans T_INFOS_PIECES. Par conséquent, si PIECE_ACTIVE contient ENTREE après 2mn sans mouvement, c'est que quelqu'un est sorti de l'appartement. Comme pour n'importe quelle pièce, l'éclairage se tamise avant d'être éteint Si au moins une chambre est encore en mode DODO, activation du mode Absence Niveau 1 Si aucune chambre n'est en mode DODO : Extinction de la lumière si la TV est allumée Activation du mode Absence Niveau 2 si la TV n'est pas allumée Fonction Time Execution des fonctions InfosPieces et Check Maintien à jour de Moment de la Journée Maintin à jour de Saison Si la consommation relevée du réfrigérateur est inférieure à celle indiquée dans Seuil_Alerte_Elec -> Notification SMS Si des lumières sont allumées alors que le mode Absence est enclenché -> Démarrage de la scène éteignant tous les devices lumières Si une valeur est définie dans Tests SMS, envoi du SMS à l'heure paramétrée MODIFS À FAIRE : - Mode Absence directement géré par la fonction Action - Changer le nom de cette fonction Action! --[[ %% autostart --]] -- Variables Refresh local delai = 1 local DELAI = delai * 60; -- Variable Netatmo local NETATMO_HomeId = ""; -- Fonction HTTP local http = net.HTTPClient(); -- On récupère les infos de temps local minuteries = json.decode(fibaro:getGlobalValue("HOME_MINUTERIES")); -- Debug local debug = 1; local function Debug(color,message) color = color or "white"; if debug == 1 and message ~= nil then fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span")); end end -- Envoi SMS local function envoi_sms(sms) if os.time() - fibaro:getGlobalModificationTime("DERNIER_SMS") > 20*60 then local char_to_hex = function(c) return string.format("%%%02X", string.byte(c)) end local function urlencode(url) if url == nil then return end url = url:gsub("\n", "\r\n") url = url:gsub("([^%w ])", char_to_hex) url = url:gsub(" ", "+") url = url:gsub(">", "%0A") return url end local url = "http://192.168.2.14:9090/send.html?smsto=+33*********&smstype=sms&smsbody="..urlencode(sms); http:request(url, { options = { method = 'GET', data = json.encode(newVar)}}); fibaro:setGlobal("DERNIER_SMS", os.time()); else Debug("grey", "Un message n'a pas été envoyé en raison du temps défini entre les SMS."); end end -- Fonction explorant les valeurs de T_INFOS_PIECES -- Contrôle température -- Contrôle Mises -- Contrôle si lumières allumées le sont à juste titre -- Gestion Mode DODO -- Return valeur DODO par la fonction local function InfosPieces() local table = json.decode(fibaro:getGlobalValue("T_INFOS_PIECES")); local InfosTemperatures = json.decode(fibaro:getGlobalValue("T_TEMPERATURES")); local NbChambres,NbDodo,Huegroup,boolean = 0,0,{},false; for k,v in pairs(table) do -- Début Contrôle températures local Devices = table[k].Detect; for i=1,#Devices do -- Si le détecteur traité est un FGMS001 if type(Devices[i]) == "number" then local val = tonumber(fibaro:getValue(Devices[i]+1, "value")); -- Si la température est inférieure à ce qui a été paramétré if val < InfosTemperatures.mini then envoi_sms("[Domotique Info] La température de "..v.Article..v.Nom.." est inférieure à "..InfosTemperatures.mini.." °C."); Debug("yellow", "["..k.."] La température de la pièce est inférieure à "..InfosTemperatures.mini.." °C !"); elseif val > InfosTemperatures.maxi then envoi_sms("[Domotique Info] La température de "..v.Article..v.Nom.." est supérieure à "..InfosTemperatures.maxi.." °C."); Debug("yellow", "["..k.."] La température de la pièce est supérieure à "..InfosTemperatures.maxi.." °C !"); end -- Conditions valeur température end -- Device est un nombre end -- Boucle -- Fin Contrôle températures -- Début - Vérification Mises local MisePiece = tonumber(fibaro:getGlobalValue(k.."_Mise")); local DeltaLastMove = math.floor((os.time() - tonumber(fibaro:getGlobalValue(k.."_LastMove")))/60); if MisePiece == 1 and DeltaLastMove > k.TpsMise then fibaro:setGlobal(k.."_Mise", 0); Debug("orange", "["..k.."] Mise automatiquement désactivée car aucun mouvement dans la pièce depuis plus de "..k.TpsMise.." mn."); end -- Fin -- Vérification Mises -- Début - Vérification des lumières local EtatPiece = tonumber(fibaro:getGlobalValue(k.."_Etat")); local HueGroup = table[k].HueGroup; for i=1,#HueGroup do local etat = fibaro:getValue(HueGroup[i], "ui.labelEtat.value"); if ( MisePiece ~= 1 and EtatPiece < 1 and etat == "On" ) then fibaro:call(HueGroup[i], "pressButton", "44"); Debug("blue", "["..k.."] [Groupe Hue "..HueGroup[i].."] Les lampes du groupe ont été éteintes."); end end -- Fin - Vérification des lumières -- Début Gestion DODO if table[k].Chambre == 1 then NbChambres = NbChambres+1; if fibaro:getGlobalValue("DODO_"..table[k].Code) == "1" then NbDodo = NbDodo+1; boolean = true;end end -- Fin Gestion DODO end -- Fin Boucle INFOS_PIECES -- Si toutes les chambres ont dodo=1, on active le mode nuit if NbChambres == NbDodo and fibaro:getGlobalValue("HOME_DODO") == "0" and fibaro:getGlobalValue("Absence") ~= "ok" and (os.time() - tonumber(fibaro:getGlobalModificationTime("HOME_DODO"))) > 4*60*60 then -- Avertissement if (os.time() - tonumber(fibaro:getGlobalModificationTime("HOME_DODO"))) == (4*60*60 + 1) then fibaro:call(302, "pressButton", 21); fibaro:call(302, "setSlider", "10", "30"); Debug("yellow", "[DODO] Avertissement 1 avant activation"); elseif (os.time() - tonumber(fibaro:getGlobalModificationTime("HOME_DODO"))) == (4*60*60 + 2) then fibaro:call(302, "setSlider", "10", "40"); Debug("yellow", "[DODO] Avertissement 2 avant activation"); elseif (os.time() - tonumber(fibaro:getGlobalModificationTime("HOME_DODO"))) == (4*60*60 + 4) then fibaro:call(302, "setSlider", "10", "100"); Debug("yellow", "[DODO] Avertissement 3 avant activation"); elseif (os.time() - tonumber(fibaro:getGlobalModificationTime("HOME_DODO"))) > (4*60*60 + 5) then fibaro:call(162, "pressButton",1); Debug("blue", "[DODO] Activation du mode nuit"); end end return boolean; end -- Vérifications si aucun mouvement local function check(dodo) local function action(lvl) if lvl == 2 then if not dodo then fibaro:setGlobal("Absence", "ok"); end -- Modif Intrusion fibaro:call(217, "turnOff"); -- TV OFF else if tonumber(fibaro:getValue(217,"power")) < 50 then fibaro:call(217, "turnOff"); end -- Prise Multimédia end fibaro:startScene(69); -- Lumière OFF fibaro:startScene(94); -- SONOS OFF fibaro:startScene(66); -- Mises OFF fibaro:startScene(148); -- Tout le monde absent API NetAtmo fibaro:startScene(127); -- Scène NetAtmo fibaro:call(155, "pressButton", 3); -- Activation Cams envoi_sms("[Domotique Info] Mode absence déclenché (Niv. "..lvl..")"); fibaro:call(334, 'sendPush', "Mode absence déclenché (Niv. "..lvl..")") Debug("grey","-- Mode Absence (Niveau "..lvl..") --"); end -- Fin Fonction local ilya = math.floor((os.time() - tonumber(fibaro:getGlobalModificationTime("DernierMouvement")))/60); if ilya >= 180 and not dodo and fibaro:getGlobalValue("Absence") ~= "ok" then action(2); end -- Arrêt enregistrement if ilya >= 2 and fibaro:getGlobalValue("SurvStation_Status") == "Recording" then fibaro:call(155, "pressButton", 2); Debug("red","[INFO] Enregistrement des caméras suspendu."); end -- Mode absence ? if fibaro:getGlobalValue("PIECE_ACTIVE") == "ENTREE" and fibaro:getGlobalValue("Absence") ~= "ok" then local VD = 298; -- ID VD Groupe Entrée if ilya == 2 then -- On tamise local Val = tonumber(fibaro:getValue(VD, "ui.Luminosite.value")); fibaro:call(VD, "setSlider", "10", math.floor(Val/2)); fibaro:setGlobal("ENTREE_HueFade", 1); elseif ilya == 3 and dodo then -- Une chambre au moins est en mode DODO action(1); -- Sans activer Scène Intrusion elseif ilya == 3 and not dodo then -- Tout le monde est levé if tonumber(fibaro:getValue(217,"power")) < 50 then -- Personne ne regarde la TV action(2); -- Scène Intrusion démarée au prochain mouvement else fibaro:call(VD, "pressButton", "44"); -- Simplement Extinction de la lumière end end end -- Etat Piece_active & Absence end -- Fonction -- Gestion Variable Moment de la journée local function moment_journee(Heures,Minutes) -- Mise à jour de la variable Moments de la journée if ( Heures == 7 and Minutes == 0 ) then fibaro:call(174, "pressButton", "1"); --fibaro:debug("Moment de la journée : Matinée"); elseif ( Heures == 12 and Minutes == 0 ) then fibaro:call(174, "pressButton", "2"); --fibaro:debug("Moment de la journée : Midi"); elseif ( Heures == 13 and Minutes == 30 ) then fibaro:call(174, "pressButton", "3"); --fibaro:debug("Moment de la journée : Après-Midi"); elseif ( Heures == 19 and Minutes == 30 ) then fibaro:call(174, "pressButton", "4"); --fibaro:debug("Moment de la journée : Soirée"); elseif ( Heures == 0 and Minutes == 0 ) then fibaro:call(174, "pressButton", "5"); --fibaro:debug("Moment de la journée : Nuit"); end end -- Saison local function saison(jour, mois, heures, minutes) if jour == 21 and heures == 0 and minutes == 0 then if mois == 3 then fibaro:call(176, "pressButton", "1"); elseif mois == 6 then fibaro:call(176, "pressButton", "2"); elseif mois == 9 then fibaro:call(176, "pressButton", "3"); elseif mois == 12 then fibaro:call(176, "pressButton", "4"); end -- Mois end -- Minuit Pile end -- Vérifications électriques local function conso(time) local diff = time - tonumber(fibaro:getGlobalValue("DERNIER_SMS_CONSO")); local delai = 30*60; -- 30mn local ConsoCompteur = tonumber(fibaro:getValue(257,"power")); local ConsoFrigo = tonumber(fibaro:getValue(314,"power")); local ConsoSDB = tonumber(fibaro:getValue(33,"power")); local ConsoChambreTel = tonumber(fibaro:getValue(234,"power")); if ConsoFrigo < tonumber(fibaro:getGlobalValue("Seuil_Alerte_Elec")) and diff > delai then envoi_sms("[Domotique Info] Panne d'électricité\nConso Compteur : "..ConsoCompteur.."W\nConso Frigo/Congel : "..ConsoFrigo.."W\nConso M. à laver : "..ConsoSDB.."W\nConso Chambre : "..ConsoChambreTel.."W"); Debug("purple","Panne de courant détectée. Message envoyé!"); fibaro:setGlobal("DERNIER_SMS_CONSO", os.time()); end end -- Boucle Principale local function time() local Minutes = tonumber(os.date("%M", os.time())); local Heures = tonumber(os.date("%H", os.time())); -- On effectue les vérifications check(InfosPieces()); conso(os.time()); -- Moments de la journée moment_journee(Heures,Minutes); -- Saison JJ MM hh mm saison(tonumber(os.date("%d")), tonumber(os.date("%m")), Heures, Minutes); -- Besoin de charger le téléphone ? if fibaro:getGlobalValue("HOME_MOMENT") ~= "Nuit" and tonumber(fibaro:getGlobalValue("CHAMBRE_Etat")) < 1 then fibaro:call(234, "turnOff"); end -- Si lumière allumée mais personne au domicile if tonumber(fibaro:getGlobalValue("Absence")) == nil and fibaro:getValue(302, "ui.labelEtat.value") == "On" then fibaro:startScene(69); end -- Tests SMS if Heures == tonumber(fibaro:getGlobalValue("HOME_TESTS_SMS")) and Minutes == 0 then envoi_sms("Test SMS Quotidien.\nIl est "..Heures.."h00"); end -- Tempo setTimeout(time, DELAI*1000); end Debug("white", "Démarrage de la scène..."); time(); Modifié le 9 avril 2020 par J3R3M
J3R3M Posté(e) le 8 avril 2020 Auteur Signaler Posté(e) le 8 avril 2020 (modifié) Pièces 2019 Explications en construction... TRIGGERS DE LA SCENE Tous les FGMS-001, référencés dans le champ Detect de chaque pièce de T_INFOS_PIECES Les Variables Globales gérées par les caméras dont les noms sont sous la forme CAM_CodePiece. La valeur de cette VG change à chaque détection de mouvement. Cette scène est donc exécutée à chaque détection de mouvement dans une pièce et son nombre d'instances en conséquence. Première étape : Détection de la pièce dans laquelle le mouvement a été détecté Récupération des valeurs T_INFOS_PIECES concernant la pièce en question Vérification si la pièce est une chambre et que son mode DODO est actif. Si oui -> Traitement de la scène spécifique Fonction Luminosite Fonction HueBtn Fonction LightsOn Fonction SonosAction Fonction VoletsRoulants --[[ %% properties 220 value 226 value 251 value 284 value 345 value 353 value %% globals CAM_ENTREE CAM_SEJOUR --]] local detecteurs = {}; detecteurs[220] = "SDB"; detecteurs[226] = "SEJOUR"; detecteurs[251] = "CUISINE"; detecteurs[284] = "WC"; detecteurs[345] = "SDB"; detecteurs[353] = "CHAMBRE"; -- Debug local debug = 1; local function Debug(color,message) if debug == 1 and color ~= nil and message ~= nil then fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span")); end end -- Dans quelle pièce le mouvement a-t-il été détecté? local trigger, PIECE = fibaro:getSourceTrigger(), ""; if trigger["type"] == "property" then local TriggerID = trigger["deviceID"]; PIECE = detecteurs[TriggerID]; elseif trigger["type"] == "global" then local triggerVAR = trigger["varName"]; PIECE = string.gsub(triggerVAR, "CAM_", "", 1); else Debug("red", "Erreur : La scène doit être démarrée par un module ou une variable!"); fibaro:abort(); end Debug("green", "["..PIECE.."] Un mouvement vient d'être détecté!"); fibaro:setGlobal(PIECE.."_LastMove", os.time()); -- On reforme les tableaux local table_pieces = json.decode(fibaro:getGlobalValue("T_INFOS_PIECES")); local minuteries = json.decode(fibaro:getGlobalValue("HOME_MINUTERIES")); -- Infos de la pièce traitée local INFOS = table_pieces[PIECE]; -- Variables VG local EtatPiece = tonumber(fibaro:getGlobalValue(PIECE.."_Etat")); local MomentJour = fibaro:getGlobalValue("HOME_MOMENT"); local HOME_DODO = tonumber(fibaro:getGlobalValue("HOME_DODO")); local HOME_ALARME = tonumber(fibaro:getGlobalValue("HOME_ALARME")); if HOME_DODO == 0 and INFOS.Chambre == 1 then if fibaro:getGlobalValue("DODO_".. PIECE) == "1" then HOME_DODO = 1; end end -- Fonction besoin de lumière ou non local function luminosite() if type(INFOS.Detect) == "table" then if #INFOS.Detect == 1 and type(INFOS.Detect[1]) == "string" then if INFOS.JourNuit == 0 then Debug("white", "["..PIECE.."] [Luminosité] Détecteur = Caméra - Allumage Constant."); return true; else if fibaro:getGlobalValue("HOME_SOLEIL") == "0" then --and tonumber(fibaro:getGlobalModificationTime("HOME_SOLEIL")) + 60*60 <= os.time() then Debug("white", "["..PIECE.."] [Luminosité] Détecteur = Caméra - Allumage lorsque le soleil est couché"); return true; end -- En fonction du Sunset end -- Fin condition Mode JourNuit else -- DEBUT - Plus d'un seul détecteur for i=1, #INFOS.Detect do if type(INFOS.Detect[i]) == "number" then if tonumber(fibaro:getValue(INFOS.Detect[i] + 2, "value")) <= tonumber(INFOS.LumMini) then Debug("white", "["..PIECE.."] [Luminosité] Détecteur = Motion Sensor - Besoin de lumière ("..fibaro:getValue(INFOS.Detect[i] + 2, "value").."lux)."); return true; end -- Vérif valeur end -- Condition si c'est un FGMS end -- Boucle for - Détecteur par détecteur end -- FIN - Plus d'un seul détecteur end -- if type(INFOS.Detect) == "table" return false; end -- Boutons pour allumer local function HueBtn(HueType) local slider = ""; if HueType == "group" then slider = 10; elseif HueType == "hcol" then slider = 10; elseif HueType == "hwh" then slider = 3; elseif HueType == "iris" then slider = 10; end --Debug("grey","["..PIECE.."] [HueBtn] Bouton du VD associé à l'allumage :"..slider); return slider; end -- Fin Fonction -- Comment allume-t'on ? local function LightsOn(moment) if tonumber(fibaro:getGlobalValue("HOME_DOMO")) == 1 and tonumber(fibaro:getGlobalValue(PIECE.."_Mise")) ~= 1 and EtatPiece < 2 and HOME_ALARME ~= 1 then -- Variables Calcul du temps depuis modificiation de VG HOME_DODO local delta = os.time() - tonumber(fibaro:getGlobalModificationTime("HOME_DODO")); local tempo = tonumber(minuteries.emmerge) * 60; -- Dernière extinction il y a moins du temps indiqué. On charge les dernières valeurs if HOME_DODO == 0 and delta > tempo and os.time() - tonumber(fibaro:getGlobalModificationTime(PIECE.."_Etat")) <= tonumber(fibaro:getGlobalValue("HOME_TPS_HUES"))*60 then local HueList, HueType = INFOS["HueList"], INFOS["HueType"]; --local LastValuesHues = json.decode(fibaro:getGlobalValue("LastValues_Hues")); for i=1,#HueList do local HuePower = tonumber(fibaro:getGlobalValue("VDHue_"..HueList[i])); --local HuePower = tonumber(LastValuesHues[tostring(HueList[i])]); fibaro:call(HueList[i], "setSlider", HueBtn(HueType[i]), HuePower); --if HuePower > 0 then Debug("yellow","["..PIECE.."] [LightsOn] Lampe "..HueList[i].." allumée à "..HuePower.."%."); end Debug("yellow","["..PIECE.."] [LightsOn] Lampe "..HueList[i].." allumée à "..HuePower.."%."); end -- Boucle lampe par lampe -- Pas de mouvement dans la pièce depuis plus du temps indiqué, on cherche les valeurs par défaut else local emmerge = 1; local tPower = ""; if HOME_DODO == 0 then tPower = INFOS["HuePower"..moment]; if delta <= tempo then emmerge = tonumber(fibaro:getGlobalValue("PuissanceEmmerge"))/100 end else tPower = INFOS["HuePowerDodo"]; end if luminosite() then if #tPower == 1 then local HueGroup = INFOS["HueGroup"]; for i=1,#HueGroup do fibaro:call(HueGroup[i], "setSlider", "10", math.floor(tPower[1] * emmerge)); Debug("yellow","["..PIECE.."] [LightsOn] Groupe Hue ("..HueGroup[i]..") de la pièce allumé."); end -- Boucle groupes else local HueList, HueType = INFOS["HueList"], INFOS["HueType"]; for i=1,#HueList do fibaro:call(HueList[i], "setSlider", HueBtn(HueType[i]), math.floor(tPower[i] * emmerge)); Debug("yellow","["..PIECE.."] [LightsOn] Lampe "..HueList[i].." allumée."); end -- Boucle lampe par lampe end -- Condition tPower = 1 else Debug("yellow","["..PIECE.."] [LightsOn] Pas besoin d'éclairage."); end -- Luminosite() end -- Mode lumière : Preset ou dernières valeurs else Debug("red","["..PIECE.."] [LightsOn] Pas besoin d'éclairage."); if tonumber(fibaro:getGlobalValue("HOME_DOMO")) ~= 1 then Debug("white","["..PIECE.."] [LightsOn] HOME_DOMO = 0 (Valeur 1 nécessaire)"); end if tonumber(fibaro:getGlobalValue(PIECE.."_Mise")) == 1 then Debug("white","["..PIECE.."] [LightsOn] "..PIECE.."_Mise = 1 (Valeur 0 nécessaire)"); end if EtatPiece >= 2 then Debug("white","["..PIECE.."] [LightsOn] EtatPiece = "..EtatPiece.." (Valeur <2 nécessaire)"); end if HOME_ALARME == 1 then Debug("white","["..PIECE.."] [LightsOn] HOME_ALARME = 1 (Valeur 0 nécessaire"); end end -- Condition DOMO & Mise end -- Fin Fonction -- Fonction SONOS Follow local function SonosAction(id,piece,sonosV) if fibaro:getGlobalValue('HOME_SONOS_FOLLOW') == "1" and #id > 0 and HOME_DODO == 0 and HOME_ALARME ~= 1 and EtatPiece ~= 2 and fibaro:getGlobalValue(PIECE.."_Mise") ~= "1" then if os.time() - tonumber(fibaro:getGlobalValue(piece.."_LastMove")) <= tonumber(fibaro:getGlobalValue("HOME_TPS_SONOS"))*60 then -- Enregistrement pendant 1h --local LastValuesSonos = json.decode(fibaro:getGlobalValue("LastValues_Sonos")); for i=1,#id do local lastlvl = tonumber(fibaro:getGlobalValue("VDSonos_"..id[i])); --local lastlvl = tonumber(LastValuesSonos[tostring(id[i])]); if tonumber(fibaro:getValue(id[i], "ui.slVolume.value")) < lastlvl then fibaro:call(id[i], "setSlider", "10", lastlvl); Debug("lightgreen","["..piece.."] [Sonos "..id[i].."] Volume de l'enceinte "..i.."/"..#id.." restitué ("..lastlvl.."%)"); end -- Vérification Niveau end -- Boucle FOR pour chaque Sonos else -- Pas de mouvement dans la pièce depuis plus du temps indiqué for i=1,#id do if tonumber(fibaro:getValue(id[i], "ui.slVolume.value")) < sonosV then fibaro:call(id[i], "setSlider", "10", sonosV); end -- Si volume plus bas que prévu, on augmente end -- Boucle FOR pour chaque Sonos Debug("lightgreen","["..piece.."] [SonosAction] Volume des enceintes augmenté"); end -- Mouvement depuis moins de 20mn end -- follow == 1 end -- Fonction -- Fonction Volets Roulants local function VoletsRoulants(var,valeur) if fibaro:getGlobalValue("HOME_SOLEIL") == "1" and fibaro:getGlobalValue("HOME_DODO") == "0" and fibaro:getGlobalModificationTime("HOME_SOLEIL") <= os.time()-minuteries.sunset*60 then if var ~= nil and type(var) == "table" then for i=1,#var do fibaro:call(var[i], "setValue", tonumber(valeur)); Debug("green","[VoletsRoulants] de "..INFOS.Article..INFOS.Nom.." ouverts."); end -- Boucle volet par volet end -- Il y a des volets dans la pièce end -- Nécessité d'ouvrir les volets ? end -- On allume si nécessaire LightsOn(MomentJour); -- SONOS fibaro:killScenes(INFOS.SonosFadeOut); SonosAction(INFOS.SonosId,INFOS.Code,INFOS.SonosV[MomentJour]); -- Volets Roulants VoletsRoulants(INFOS.VoletsR,0); -- Démarrage du REC si nécessaire if tonumber(fibaro:getGlobalValue('REC_OFF')) <= os.time() and tonumber(fibaro:getGlobalValue("NETATMO_Presents")) < 1 and ( HOME_DODO == 0 or ( HOME_DODO == 1 and INFOS.Chambre ~= 1 ) ) then fibaro:call(155, "pressButton", "1"); end -- On met à jour la variable pièce fibaro:call(199, "pressButton", INFOS.id); -- Variable Dernier Mouvement fibaro:setGlobal(PIECE.."_Etat", 2); fibaro:setGlobal("DernierMouvement", os.time()); Modifié le 10 avril 2020 par J3R3M
J3R3M Posté(e) le 8 avril 2020 Auteur Signaler Posté(e) le 8 avril 2020 (modifié) NetAtmo Welcome Explications à venir... --[[ %% globals DernierMouvement --]] -- Informations de compte Netatmo local client_id = ''; local client_secret = ''; local username = ''; local password = ''; -- Informations du VD associé local vd_ID = 304; local vd_refresh = 9; -- Réglages de la scène local refresh = 2; -- Script executé toutes les x secondes. Pas moins de 8s! local debug = 0; -- Faut-il vraiment l'expliquer ? -- Nom de la Variable Globale qui sera créée et utilisée par la scène et le VD local VGNetatmo = "NETATMO_Welcome"; -------------------------------------------------------------- -------- Ne rien modifier à partir de cette ligne ------------ -------------------------------------------------------------- local token = ''; local request_body = ''; Debug = function (color, message) if (debug == 1) then fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span")); elseif (debug == 0) then end end DebugChange = function (color, message) fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span")); end DebugError = function (color, message) fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span")); end -- Envoi SMS local function envoi_sms(sms) if os.time() - fibaro:getGlobalModificationTime("DERNIER_SMS") > 20*60 then local char_to_hex = function(c) return string.format("%%%02X", string.byte(c)) end local function urlencode(url) if url == nil then return end url = url:gsub("\n", "\r\n") url = url:gsub("([^%w ])", char_to_hex) url = url:gsub(" ", "+") url = url:gsub(">", "%0A") return url end local url = "http://192.168.2.14:9090/send.html?smsto=+336********&smstype=sms&smsbody="..urlencode(sms); http:request(url, { options = { method = 'GET', data = json.encode(newVar)}}); fibaro:setGlobal("DERNIER_SMS", os.time()); else Debug("grey", "Un message n'a pas été envoyé en raison du temps défini entre les SMS."); end end -- Fonction Que faire en fonction des personnes reconnues function Action(qui) -- Si scène intrusion active if fibaro:countScenes(141) > 0 then -- Jérémy if qui == "Jérémy" then Debug("grey", "Démmarrage -> Actions prévues pour Jérémy"); StreamSonos(245,"local","//JEREM-NAS/music/HC2/Reconnu.mp3",50); fibaro:call(163, "pressButton", 1); -- VD Présence fibaro:setGlobal("HOME_ALARME", 0); -- Emilie elseif qui == "Emilie" then Debug("grey", "Démmarrage -> Actions prévues pour Emilie"); StreamSonos(245,"local","//JEREM-NAS/music/HC2/Reconnu.mp3",50); envoi_sms("[Domotique Info] Emilie est à la maison!"); fibaro:call(282, "pressButton", 1); -- VD Présence fibaro:setGlobal("HOME_ALARME", 0); -- Maman ou Gilles elseif qui == "Maman" or qui == "Gilles" then Debug("grey", "Démmarrage -> Actions prévues pour Maman"); StreamSonos(245,"local","//JEREM-NAS/music/HC2/Maman.mp3",40); envoi_sms("[Domotique Info] Maman est à la maison!"); fibaro:setGlobal("HOME_ALARME", 0); -- Personnes autorisées sans action spécifique elseif qui == "Déborah" or qui == "Maélys" or qui == "Célia" then Debug("grey", "Démmarage -> Actions prévues pour les personnes autorisées."); StreamSonos(245,"local","//JEREM-NAS/music/HC2/Reconnu.mp3",40); envoi_sms("[Domotique Info] Une personne autorisée a été reconnue."); fibaro:setGlobal("HOME_ALARME", 0); -- Autres non autorisés else if fibaro:getGlobalValue("PRESENCE_JEREMY") == "0" and fibaro:getGlobalValue("PRESENCE_EMILIE") == "0" then DebugChange("orange", "Visage reconnu, mais personne non-autorisée à pénétrer seule dans l'appartement."); envoi_sms("[Domotique Info] Une personne non-autorisée a été reconnue."); fibaro:setGlobal("HOME_ALARME", 1); end -- Condition Propriétaires absents end -- Conditions personnes par personnes fibaro:killScenes(141); -- On tue la scène intrusion end -- Scène intrusion active end -- Fonction -- Fonction Stream Sonos function StreamSonos(VD_ID,Source,Stream,Volume,Duree) local params = { stream = tostring(Stream), source = tostring(Source), duration = tonumber(Duree), volume = tonumber(Volume)}; local _f = fibaro; local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end} _x:set(tostring(VD_ID), { stream = params }); _f:call(tonumber(VD_ID), "pressButton", 20); end -- Ajout pour gestion indépendante des VG function CreerVG(VGNom, VGValeur) local data = {name = VGNom, value=VGValeur}; response, status = api.post("/globalVariables", data); if (status == 201) then DebugError("white", "Variable Globale " .. VGNom .. " créée."); created = true; else DebugError("red", "Impossible de créer la Variable Globale " .. VGNom .. "!"); end end function MajEntree(Nom, ID, Statut, Lastseen) local table = json.decode(fibaro:getGlobalValue(VGNetatmo)); -- Tout est à mettre à jour if Nom ~= nil and ID ~= nil and Statut ~= nil and Lastseen ~= nil then table[Nom] = {id=ID, status=Statut, lastseen=Lastseen}; fibaro:setGlobal(VGNetatmo,json.encode(table)); DebugError("yellow", "L'entrée " .. Nom .. " a été automatiquement créée."); -- Mise à jour du Statut elseif Nom ~= nil and Statut ~= nil and Lastseen == nil then table[Nom].status = Statut; fibaro:setGlobal(VGNetatmo,json.encode(table)); Debug("yellow", "Le statut de " .. Nom .. " a été mis sur la valeur ".. Statut); -- Mise à jour de la dernière vue de la personne elseif Nom ~= nil and Statut == nil and Lastseen ~= nil then table[Nom].lastseen = Lastseen; fibaro:setGlobal(VGNetatmo,json.encode(table)); Debug("yellow", "L'information 'lastseen' de " .. Nom .. " a été mise sur la valeur ".. Lastseen); else DebugError("red", "Erreur lors de l'utilisation de la fonction MajEntree"); if Nom == nil then DebugError("white", "Champ 'Nom' vide !"); end if Statut == nil then DebugError("white", "Champ 'Statut' vide !"); end if Lastseen == nil then DebugError("white", "Champ 'Lastseen' vide !"); end end end if fibaro:getGlobalValue(VGNetatmo) == nil then CreerVG(VGNetatmo,json.encode({})); end -- Fin - Ajout pour gestion indépendante des VG function oAuth(nextFunction) local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=read_camera%20write_camera'; getResponseData('https://api.netatmo.net/oauth2/token', request_body, function(data) if (data.access_token ~= nil) then token = data.access_token fibaro:setGlobal("NETATMO_Token",token); gethomedata() else DebugError( "red", "Impossible de joindre l'API!"); end end ) --setTimeout(oAuth, refresh*1000); end 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, checkCertificate = false }, success = function(response); func(json.decode(response.data)); end }) end function gethomedata() request_body_cam = 'access_token=' ..token.. ''; getResponseData('https://api.netatmo.net/api/gethomedata', request_body_cam, function(getData) if (getData.body ~= nil) then for w, v in pairs(getData.body.homes) do for a, b in pairs(v.persons) do local INFOS = json.decode(fibaro:getGlobalValue(VGNetatmo)); if (b.pseudo ~= nil) then if (b.out_of_sight == false) then if INFOS[b.pseudo] ~= nil then MajEntree(b.pseudo,b.id,nil,b.last_seen); local change_var = tonumber(INFOS[b.pseudo].status); if (change_var == 0) then DebugChange("green", b.pseudo.. ' est présent.'); MajEntree(b.pseudo,b.id,1,nil); Action(b.pseudo); else Debug("white", b.pseudo.. ' est toujours présent.'); end else Debug("red", "L'entrée pour " ..b.pseudo.. " de la table "..VGNetatmo.." n'éxiste pas."); MajEntree(b.pseudo,b.id,0,0); end else if INFOS[b.pseudo] ~= nil then MajEntree(b.pseudo,b.id,nil,b.last_seen); local change_var2 = tonumber(INFOS[b.pseudo].status); if (change_var2 == 1) then DebugChange( "orange", b.pseudo.. ' est absent.'); MajEntree(b.pseudo,b.id,0,nil); else Debug( "white", b.pseudo.. ' est toujours absent.'); end else Debug("red", "L'entrée pour " ..b.pseudo.. " de la table "..VGNetatmo.." n'éxiste pas."); MajEntree(b.pseudo,b.id,0,0); end end end end end else Debug("red", "Impossible de joindre l'API! Vérifier le taux de rafraichissemment!"); end if tonumber(vd_ID) ~= nil then fibaro:call(vd_ID, "pressButton", vd_refresh); end end ) end -- Nb de connexions à l'API ce jour local Compteur = tonumber(fibaro:getGlobalValue("NETATMO_Compteur")); -- Fonction oAuth + refresh local function oAuthRefresh() -- Vérification du nombre de personnes détectées local Welcome_PA = tonumber(fibaro:getGlobalValue("NETATMO_Presents")); local Jeremy = tonumber(fibaro:getGlobalValue("PRESENCE_JEREMY")); local Emilie = tonumber(fibaro:getGlobalValue("PRESENCE_EMILIE")); local NbPresents = Welcome_PA+Jeremy+Emilie; if fibaro:countScenes(141) > 0 and os.time() - tonumber(fibaro:getGlobalValue("DernierMouvement")) < 60 then -- Si la scène intrusion est active if Compteur < 4000 then fibaro:setGlobal("NETATMO_Compteur", Compteur+1); Debug("white", "Scène démarrée et executée toutes les "..refresh.."s."); oAuth(); setTimeout(oAuthRefresh, refresh*1000); else Debug("red", "Nombre maximum de connexions à l'API atteint!"); end -- Mise à jour du nombre de présents elseif Welcome_PA < 3 then if Compteur < 4000 then oAuth(); fibaro:setGlobal("NETATMO_Compteur", Compteur+1); Debug("grey", "Informations NetAtmo mises à jours dans la base de données."); else DebugError("red", "Nombre maximum de connexions à l'API atteint!"); end -- Vérifications régulières elseif NbPresents >= 1 and os.time() - tonumber(fibaro:getGlobalModificationTime(VGNetatmo)) > 10*60 then if Compteur < 4000 then oAuth(); fibaro:setGlobal("NETATMO_Compteur", Compteur+1); Debug("grey", "Informations NetAtmo mises à jours dans la base de données."); else DebugError("red", "Nombre maximum de connexions à l'API atteint!"); end -- Vérification effectuée il y a peu, on ne met pas à jour else Debug("grey", "Inutile d'effectuer une mise à jour des valeurs Welcome."); end end local trigger = fibaro:getSourceTrigger(); if trigger["type"] == "global" then oAuthRefresh(); else oAuth(); fibaro:setGlobal("NETATMO_Compteur", Compteur+1); local Welcome_PA = tonumber(fibaro:getGlobalValue("NETATMO_Presents")); if Welcome_PA == 1 then DebugChange("lightblue", "[".. os.date("%a %d %B") .."] Une personne présente"); elseif Welcome_PA > 1 then DebugChange("lightblue", "[".. os.date("%a %d %B") .."]" .. Welcome_PA.." personnes présentes."); else DebugChange("red", "[".. os.date("%a %d %B") .."] Tout le monde absernt du domicile."); end end Modifié le 8 avril 2020 par J3R3M
J3R3M Posté(e) le 8 avril 2020 Auteur Signaler Posté(e) le 8 avril 2020 VD Etat Pièces Explications à venir... CODE MAINLOOP local RecupValeursHues = "API"; -- VD ou API local HueUser = fibaro:getGlobal('VD_Hue_User'); local table_pieces = json.decode(fibaro:getGlobalValue("T_INFOS_PIECES")); local minuteries = json.decode(fibaro:getGlobalValue("HOME_MINUTERIES")); local Welcome_PA = tonumber(fibaro:getGlobalValue("NETATMO_Presents")); local Manuel_PA = tonumber(fibaro:getGlobalValue("NB_PIECES_ACTIVES")); local TpsMini = minuteries.lightsp; local tTri = {}; local PA = 0; local VirtualPa = 1; local HueCMD = Net.FHttp("192.168.2.21",80); -- Debug local debug = 1; local function Debug(color,message) if debug == 1 and color ~= nil and message ~= nil then fibaro:debug("[DEBUG] " .. string.format('<%s style="color:%s;">%s', "span", color, message, "span")); end end -- Info local function Info(color,message) if color ~= nil and message ~= nil then fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span")); end end -- Récupération et tri des derniers mouvements for k,v in pairs(table_pieces) do table.insert(tTri, {code=v.Code, last=fibaro:getGlobalValue(v.Code.."_LastMove"), passage=v.Passage, tpsActive=v.TpsActive}); end table.sort(tTri, function(a, b) return a.last > b.last end); -- Cb de pièces actives actuellement ? if Manuel_PA ~= nil then PA = Manuel_PA; else PA = Welcome_PA; end -- Boutons luminosité local function HueBtn(HueType) local slider = ""; if HueType == "group" then slider = 10; elseif HueType == "hcol" then slider = 10; elseif HueType == "hwh" then slider = 3; elseif HueType == "iris" then slider = 10; end Debug("white","[HueBtn] ID du Slider (Type = "..HueType..") : "..slider); return slider; end -- Fonction de recherche des valeurs d'un tableau par rapport à celles d'un autre local function TableMatch(ceci,cela) -- Rechercher valeurs de ceci dans cela for i=1,#ceci do for j=1,#cela do if ceci[i] == cela[j] then Debug("yellow","[TableMatch] VD "..ceci[i].." utilisé dans plusieurs pièces."); return true; end end end return false; end -- Fonction Extinction local function Action(Code,Etat) local INFOS = table_pieces[Code]; -- Pièce allumée ? local HueGroup = INFOS["HueGroup"]; local HuesOn = false; for i=1,#HueGroup do local etat = fibaro:getValue(HueGroup[i], "ui.labelEtat.value"); if etat == "On" then HuesOn = true; end end -- Fade if Etat == 1 then --local LastValuesHues = {}; local HueUser = fibaro:getGlobal('VD_Hue_User'); local HueList, HueType = INFOS["HueList"], INFOS["HueType"]; -- Traitement Hues for i=1,#HueList do -- Récupération via VD if RecupValeursHues == "VD" then local val = tonumber(fibaro:getValue(HueList[i], "ui.Luminosite.value")); if val > 0 then fibaro:call(HueList[i], "setSlider", HueBtn(HueType[i]), val/2); Info("lightblue","["..Code.."] [Ampoule "..HueList[i].."] Valeur "..val.." enregistrée et puissance atténuée"); end -- if val > 0 fibaro:setGlobal("VDHue_"..HueList[i], val); -- Récupération via API else local response ,status, errorCode = HueCMD:GET('/api/'..HueUser..'/lights/'..fibaro:get(HueList[i], 'TCPPort')); if (tonumber(status) == 200) then local jsonTable = json.decode(response); -- Vérification si des erreurs existent dans le tableau if (jsonTable[1] ~= nil) then -- Affichage des informations de l'erreur errorType = jsonTable[1].error.type; errorDescription = jsonTable[1].error.description; fibaro:debug("Error type = "..errorType); fibaro:debug("Error description = "..errorDescription); if (errorType == 1) then fibaro:log("Hue: Utilisateur Non Autorisé"); elseif (errorType == 3) then fibaro:log("Hue: n° ID Incorrect"); end -- Récupération des informations via Json else local val = 0; if jsonTable.state.on then val = math.floor(tonumber(jsonTable.state.bri)/2.54); fibaro:call(HueList[i], "setSlider", HueBtn(HueType[i]), val/2); --HueCMD:PUT('/api/'..HueUser..'/lights/'.. fibaro:get(HueList[i], 'TCPPort') ..'/state', '{"on":true, "bri":'.. val/2 ..'}'); Info("lightblue","["..Code.."] [Ampoule "..HueList[i].."] Valeur "..val.." enregistrée et puissance atténuée"); end -- if jsonTable.state.on == "true" fibaro:setGlobal("VDHue_"..HueList[i], val); end -- if (jsonTable[1] ~= nil) end -- if (tonumber(status) == 200) end -- Condition RecupValeursHues end -- Boucle Ampoule par ampoule fibaro:setGlobal(Code.."_Etat", 1); -- Extinction elseif Etat == 0 then -- Traitement Hues if HuesOn then for i=1,#HueGroup do fibaro:call(HueGroup[i], "pressButton", "44"); Info("orange","["..Code.."] [Groupe "..HueGroup[i].."] Ampoules du groupe éteintes."); end end -- Traitement Sonos local Sonos = INFOS["SonosId"]; if fibaro:getGlobalValue('HOME_SONOS_FOLLOW') == "1" and fibaro:getGlobalValue('HOME_DODO') ~= "1" and #Sonos > 0 then -- On liste tous les IDs Sonos sans ceux de la pièce en cours local TableSonos = {}; for k,v in pairs(table_pieces) do if k ~= Code and tonumber(fibaro:getGlobalValue(k.."_Etat")) > 0 then for i=1,#v.SonosId do table.insert(TableSonos, v.SonosId[i]); Debug("white", "["..k.."] ID VD Ajouté à la table TableSonos : ".. v.SonosId[i]); end -- for i=1 end -- if k k ~= Code end -- for k,v -- Si le VD n'est pas utilisé dans une pièce active, on l'atténue à 5% if not TableMatch(Sonos,TableSonos) then fibaro:startScene(INFOS.SonosFadeOut); --local LastValuesSonos = {}; --[[for i=1,#Sonos do fibaro:call(Sonos[i], "setSlider", "10", "5"); Info("lightgreen","["..Code.."] [Sonos "..Sonos[i].."] Enceinte atténuée à 5%."); end]]-- --fibaro:setGlobal("LastValues_Sonos", json.encode(LastValuesSonos)); else Debug("green","["..Code.."] Les enceintes de cette pièce sont aussi affectées à une autre pièce."); end end -- VG Etat Pièce fibaro:setGlobal(Code.."_Etat", 0); end end -- Traitement des Infos local function CountDown(Code,Last,Tps) local Aff = ""; if fibaro:getGlobalValue(Code.."_Mise") ~= "1" then -- Si pas de mise dans la pièce local delta = Tps*60 - (os.time() - Last); if delta >= 0 then -- Temps restant positif, on affiche le décompte Aff = delta.." s"; else -- Temps restant dépassé -- Fade if delta >= -10 or fibaro:getGlobalValue(Code.."_Etat") == "2" then if fibaro:getGlobalValue(Code.."_Etat") ~= "1" then Aff = "Fade"; Action(Code,1); else Aff = "Tamisé"; end -- Extinction elseif delta < -10 and fibaro:getGlobalValue(Code.."_Etat") == "1" then Aff = "Extinction"; Action(Code,0); -- Pièce inactive else Aff = "-"; end end -- Affichages else Aff = "Mise Activée"; end fibaro:call(fibaro:getSelfId(), "setProperty", "ui.".. Code ..".value", Aff); end -- Affichage if PA > 1 then VirtualPa = PA; for i=1,PA do if tTri[i].passage == 1 and i ~= 1 and VirtualPa < #tTri then VirtualPa = VirtualPa+1; end end end for i=1,#tTri do if i <= VirtualPa then if tTri[i].passage == 1 and i > 1 then CountDown(tTri[i].code,tTri[i].last,TpsMini); elseif i == 1 and tTri[i].code ~= "ENTREE" then fibaro:call(fibaro:getSelfId(), "setProperty", "ui.".. tTri[i].code ..".value", "Active"); else CountDown(tTri[i].code,tTri[i].last,tTri[i].tpsActive); end -- Conditions CountDown else CountDown(tTri[i].code,tTri[i].last,TpsMini); end -- Valeur de i end -- Boucle -- Message pour WatchDog Info("black","Check");
J3R3M Posté(e) le 8 avril 2020 Auteur Signaler Posté(e) le 8 avril 2020 (modifié) VDs de paramétrage Explications à venir... VD MINUTERIES Ce VD permet de saisir les informations de temps qui seront exploitées par la HC2. Ces informations sont encapsulées dans un JSON puis enregistrées dans la VG HOME_MINUTERIES. lightsp : Les lumières resteront allumées cette durée au minimum (Lights Présence car, auparavant, j'avais aussi créé une valeur en cas d'absence de ma compagne ou moi-même. Notion que j'ai supprimé depuis.) sms durée minimale entre deux envois de SMS de la part de la HC2 emmerge Durée durant laquelle la HC2 restera en mode Émergement après la sortie du mode DODO. Ce mode émergement adapte notamment la puissance des éclairages. sunset Durée après le coucher du soleil pendant laquelle la HC2 considèrera qu'il fait encore jour VD MOMENT DE LA JOURNÉE Directement géré et exploité par les scènes. Ces informations sont enregistrées dans la VG HOME_MOMENT. VD PIECE ACTIVE Directement géré et exploité par les scènes. Un appui sur un bouton change la valeur de VG PIECE_ACTIVE et effectue éventuellement les actions propres à cette pièce. VD SAISON Directement géré par les scènes. Un appui sur un bouton change la valeur de VG HOME_SAISON et effectue éventuellement les actions propres à cette saison. La saison n'est exploitée nul part... Mais elle est là, au cas-où... VD TEMPÉRATURES Ce VD permet de saisir les informations de températures qui seront surveillées par la HC2. Ces informations sont encapsulées dans un JSON puis enregistrées dans la VG T_TEMPERATURES. mini Température minimale maxi Température maximale VD TESTS SMS Ce VD gère l'heure à laquelle sera envoyé le sms de test journalier provenant de la HC2. Exploite la VG HOME_TESTS_SMS Modifié le 9 avril 2020 par J3R3M 1
J3R3M Posté(e) le 8 avril 2020 Auteur Signaler Posté(e) le 8 avril 2020 (modifié) Variables Globales Repérées en vert dans les précédentes explications Absence Contient la donnée os.tilme() du dernier mouvement détecté, sauf si le mode Absence est enclenché (automatiquement ou manuellement) DernierMouvement Contient la donnée os.time() du dernier mouvement détecté, peu importe la pièce DERNIER_SMS Contient la donnée os.time() du dernier SMS envoyé par la HC2 DERNIER_SMS_CONSO Contient la donnée os.time() du dernier SMS concernant un défaut d'électricité envoyé par la HC2 HOME_DODO Mode Sommeil de l'appartement (0/1) HOME_MINUTERIES Tableau JSON exploité par le VD Minuteries HOME_MOMENT Moment de la journée AM - Midi - PM - Soir - Nuit. Exploité par le VD Moment de la journée HOME_SAISON Saison de l'année. Exploitée par le VD Saison HOME_TESTS_SMS Contient l'heure à laquelle le SMS de test sera envoyé par la HC2. Si la VG contient une valeur string, les tests sont désactivés. Exploité par le VD TEST SMS NETATMO_Compteur VG contenant le nombre d'appels à l'API NetAtmo effectués dans la journée. Nombre d'appels maxi fixés à 4000. PIECE_ACTIVE Contient le code de la dernière pièce ayant détecté un mouvement. Exploité par le VD Pièce Active Seuil_Alerte_Elec Valeur minimum qui doit être consommée par le frigo. En dessous de cette valeur, une notification sera retournée via la scène Check 1mn T_INFOS_PIECES Tableau JSON contenant toutes les informations des pièces : Nom, Devices, Eclairages, Enceintes... T_TEMPERATURES Tableau JSON contenant les valeurs de températures Variables par Pièce de l'appartement : NomPièce_Mise Etat lumineux enregistré pour une pièce. Une mise à 1 désactive l'extinction automatique de la lumière si aucun mouvement NomPièce_Etat Etat de la pièce : 0 Eteinte - 1 dimmée à 50% - 2 allumée Variables par Chambre de l'appartement : Rappel, une chambre est considérée comme telle par les scènes si la valeur de la Chambre dans T_INFOS_PIECES = 1 DODO_NomChambre 0/1 Modifié le 9 avril 2020 par J3R3M
J3R3M Posté(e) le 9 avril 2020 Auteur Signaler Posté(e) le 9 avril 2020 Il y a 15 heures, Nico a dit : Hâte de lire les explications ! J'espère avoir le temps de finir ça avant la fin du confinement... En y allant petit à petit, je me rends compte que c'est un boulot de dingue d'expliquer tout ça, alors qu'il n'y a pas grand chose. Un autre boulot de dingue : me souvenir ce que j'ai fait et pourquoi Tout en me rendant compte de certaines incohérences
Did Posté(e) le 9 avril 2020 Signaler Posté(e) le 9 avril 2020 Il y a 9 heures, J3R3M a dit : J'espère avoir le temps de finir ça avant la fin du confinement... Ne t'en fais pas, on va en reprendre encore une couche.
Messages recommandés