Aller au contenu

J3R3M

Membres confirmés
  • Compteur de contenus

    593
  • Inscription

  • Dernière visite

  • Jours gagnés

    8

Messages posté(e)s par J3R3M

  1. il y a 6 minutes, hermanos a dit :

    les scénes de filtration je dois aussi les enlever 

     

    copier:coller de nouveau et voila mais il dit chauffage activée mais faux

    image.thumb.png.220585a4e6da3cb157aaad2ffbacd371.png

    Comment ça faux? Cela t'affiche ce message alors que le module apparaît sur OFF dans ton espace HC2?

    Une eau qui était à 32 degrés il y a 20 minutes est déjà descendue à 18 degrés? Tu vis au Pôle Nord? :huh::lol:

  2. Il faut télécharger le fichier sur ton ordinateur et l'ouvrir avec un éditeur de texte.
    Le contenu sera le code ci-dessus.

     

    L'éditeur LUA intégré à la HC2 dispose d'un compteur de lignes sur la partie gauche.

    Tu pourras remarquer que la ligne 8 correspond à un simple retour à la ligne, tu peux simplement essayer de supprimer ce retour à la ligne, au cas où...

  3. Etrange! J'ai testé exactement ce code dans une nouvelle scène de ma HC2 et je n'ai aucune erreur!

    En cas d'erreur de copier/coller, essaie de télécharger le fichier et de copier son contenu dans une nouvelle scène : Chauff Piscine.lua

    En ce qui concerne les IDs de tes modules : 569, 550 et 546, tu es sûr de ceux-ci? Même si une mauvaise indication ne te donnerait pas cette erreur du tout.

  4. 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
  5. VDs de paramétrage

    Explications à venir...

    Administration.png.0713f1e930347461db4d3515ed7cb7c5.png

     

    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

    764745491_VDMinuteries.png.fb4ff3d6d9ecc4d8034129902da47f6f.png

     

    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.

    213024016_VDMomentdelajournee.png.8bcdc2f6ccb2071d7638dbeea4139120.png

    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.

    318656780_VDPieceActive.png.12bc70c859c4c7fa4922ad3b6ebb88e7.png

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

    1223281592_VDSaison.png.b94840acac8c725eb847625a2854b65f.png

    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

    1228680503_VDTemperatures.png.102ba1325eb7e7c731f59bfb99826802.png

     

    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

    532419697_VDTestsSMS.png.dff3fef5904e135c544fe42e2cb0b656.png

     

    • Upvote 1
  6. 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");

     

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

     

  8. 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());

     

  9. 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();

     

  10. 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 :D

     

    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 :

     

    1339498869_ScenesPrincipales.png.f81dda5a420573b5525e9ac8ed9beebf.png

     

    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.

     

    1509500179_Etatpieces.png.5746324b45dc6928e89407c4a971982a.png

     

    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.

     

    VG.png.df0baed75a04b601d428139acfa1b8c9.png

     

    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.

     

    Administration.png.e702af904ddb83516c3edc18c627fee5.png

     

    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
    };

     

    • Like 1
    • Upvote 1
  11. Le fait que la filtration s'allume dans tous les cas est normal, puisque ta première scène demande à ce que la filtration fonctionne pendant 2mn à 8h.

    Et elle est donc censée se stopper automatiquement 120 secondes plus tard.

    De ton côté, tu dis que la filtration est relancée ensuite par tes deux scènes, après ce délai alors que la température ne correspond pas aux conditions des scènes, c'est bien ça?

     

    Si tel est le cas, tu peux essayer simplement de supprimer les lancements de scènes 15-17 et 17-20 dans ta première scène afin de t'assurer que le démarrage de cette filtration ne provienne pas d'autre part?

  12. Hier je n'avais pas de HC2 sous la main, je viens de tester le code et l'ai modifié en ajoutant des messages d'information.

    Cette scène devrait faire ce que tu attends :

     

    --[[
    %% autostart
    %% properties
    %% weather
    %% events
    %% globals
    --]]
    
    -- IDs de tes modules
    local IDSondeTemp = 1
    local IDChauffage = 2
    local IDFiltre = 3
    
    -- Réglages de températures
    local TempMini = 24
    local TempMaxi = 29
    
    -- Horaires de filtration, séparés par une virgule
    local Horaires = {5,12,19};
    
    -- Durée Filtration en minutes
    local DureeFiltration = 5
    
    local function Check()
      local Temp = tonumber(fibaro:getValue(IDSondeTemp, "value"));
      local Nb = #Horaires;
      local Heure = tonumber(os.date("%H"));
      local Return = false;
      for i=1,Nb do
        if Horaires[i] == Heure then
          fibaro:call(IDFiltre, "turnOn");
          fibaro:debug(Heure.." - Cycle de filtration démarré...");
          Return = true;
          setTimeout(function() if Temp >= TempMaxi then fibaro:call(IDFiltre, "turnOff"); fibaro:debug(DureeFiltration.." écoulées - Cycle de filtration terminé"); end end,DureeFiltration*60*1000);
        end
      end
      if Temp <= TempMini then
        fibaro:call(IDChauffage, "turnOn");
        fibaro:call(IDFiltre, "turnOn");
        fibaro:debug("Chauffage et filtre activés car la température de l'eau ("..Temp..") <= à la valeur définie ("..TempMini..")");
      elseif Temp >= TempMaxi then
        fibaro:call(IDChauffage, "turnOff");
        fibaro:debug("Chauffage arrêté car la température de l'eau ("..Temp..") >= à la valeur définie ("..TempMaxi..")");
        if not Return then fibaro:call(IDFiltre, "turnOff");  fibaro:debug("Filtre désactivé également car aucun cycle n'était en cours.");end
      end
      setTimeout(Check,60*60*1000);
    end
    
    
    Check();

     

  13. Bonjour @hermanos,

     

    Je n'ai pas testé, mais cette scène devrait vérifier toutes les heures si la température est correcte.

    Si la température est égale ou inférieure à la valeur indiquée dans TempMini, le filtre et le chauffage sont allumés.

    Si la température est égale ou supérieure à la valeur indiquée dans TempMaxi, le chauffage sera éteint. Le filtre ne le sera pas si une filtration est programmée.

    Par la même occasion, si l'heure actuelle correspond à une des heures paramétrées pour la filtration (variable Horaires), la filtration se mettra en route.

    Lorsqu'une filtration sera lancée suite à un horaire programmé dans la variable Horaires, elle s'éteindra automatiquement 5mn (variable DureeFiltration) après, seulement si la température est égale ou supérieure à TempMaxi.

    Pour tester, il faut modifier la valeur des 3 premières variables :

    • IDSondeTemp
    • IDChauffage
    • IDFiltre

    Et copier le contenu de cette scène dans une nouvelle scène LUA qui pourra être démarrée automatiquement.

    Si cela fonctionne et que cela te convient, cette scène sera apte à remplacer tes cinq scènes en mode blocs.

    EDIT : Nouvelle version ci-dessous

  14. Bonjour @Bobobull,

    Qu'as-tu essayé finalement?

    Car s'il s'agit simplement du gain d'une étape en ne passant plus par le VD, il n'y a aucune raison que cela change autant la situation.

    Si les messages sont parfois faux, il n'y a aucun doute sur l'origine du problème : construction de la phrase.

    Et je suis certain que si tu essayais ce que je te proposais juste avant, soit une phrase simple, en une seule variable et sans construction, les phrases seraient toujours bonnes et prononcées au moment désiré.

     

    Il n'y a pas de variable SONOS à vider. Les variables utilisées servent à l'envoi de ce que tu souhaites avec les paramètres que tu as défini, ni plus, ni moins.

    Si un problème de retranscription de phrase était inhérent au VD, ça se saurait depuis le temps, crois-moi :D

    • Like 1
  15. Ah pardon, j'ai cru que tu avais changé la pile. Si la pile HS est retirée, mais pas remplacée, c'est normal que ça reste affiché ainsi, avec les dernières valeurs remontées.

    Par contre, si après changement par une pile fonctionnelle, tu as encore cela, il faudra s'inquiéter un peu plus :)

  16. Parfait si ça a pu t'être utile!

    Effectivement, j'utilise 1s par défaut entre deux call, mais ça peut normalement marcher avec une plus petite durée.

    À mon avis, le soucis doit venir du fait que les ordres sont envoyées sur le même périphérique physique.

     

    Je ne peux malheureusement pas t'aider pour les solutions Alexa et Google, je n'en ai jamais implanté dans un environnement Fibaro, mais il y a des sujets qui le traitent sur le forum ;)

  17. Il y a 1 heure, pepite a dit :

    Salut @J3R3M

    Bon ben me suis pas embêté, j'ai mis le VD en 2.1, j'etais déjà en V2 ;-)

    2 mots : PARFAIT et MERCI

    Salut @pepite et merci de ton retour et tes compliments! J'espère que cette scène te sera utile :)

    Une nouvelle version va bientôt arriver, puisque j'ai pu constater qu'il y avait une erreur dans l'affichage du pourcentage pour les lignes RGBW...

    La valeur s'affiche en conservant la base 100, au lieu d'être proportionnelle à la puissance saisie dans le VD. Heureusement, ceci ne concerne que l'affichage du debug, pas l'envoi dans le module :rolleyes:

    • Like 1
×
×
  • Créer...