Aller au contenu
mprinfo

Sunrisehour, Sunsethour, Os.date Et Variable Jour_Nuit

Recommended Posts

Capito :)

Vu sous cet angle je comprends mieux cette double façon de mettre àjour la variable.

Il est vrai que je code parfois comme un bûcheron vu que la HC2 encaisse pas mal.

Depuis que Krikroff m'a dit qu'il avait des "main loop" en masse qui tournaient sans broncher àcôté de tonnes de scènes... Je me lâche ! ;)

C'est vrai aussi que je devrai prendre l'habitude de vérifier le nombre d'instances d'une Scène avant de la lancer.

Partager ce message


Lien à poster
Partager sur d’autres sites

Ca y est mprinfo hante mes nuits ;) J'ai rêvé des modifications que tu as apportées à  ton code :

local NbreScene = fibaro:countScenes()
if (NbreScene == 1) then

Ton debug ligne 31 n'est pas tout à  fait exact :

fibaro:debug("La variable a été mise a jour Manuellement") 

C'est vrai que la variable a été mise à  jour au démarrage MAIS si le programme arrive à  cette ligne 31 c'est surtout que le nombre de scènes en instance n'est pas égal à  1 !

 

Pour être tranquille il est préférable de mettre ce qui suit juste après l'entête (comme tu l'as dit dans l'excellent tutot             #1             :

if (fibaro:countScenes() > 1) then
  fibaro:abort()
end

Pour visualiser le déroulé de ton code j'ai fait ça (regarde la fenêtre de debug) :

--[[
%% autostart
--]]


local NbreSceneAudemarrage = fibaro:countScenes()
fibaro:debug("On vient de Sauvegarder ou cliquer sur Démarrer : MAJ de la variable. Le nbre de scenes en cours : ".. NbreSceneAudemarrage)
 
local NbreScene = fibaro:countScenes()
if (NbreScene == 1) then
  while true do
    fibaro:debug("Début du while...")
    fibaro:debug("Test de la condition")
    fibaro:sleep(10*1000); 
    fibaro:debug("Fin du while...")
  end
else
  fibaro:debug("Trop de scènes tournent ! Il y en a " .. NbreScene)
end

Maintenant regardes le debug de ça :

--[[
%% autostart
--]]

if (fibaro:countScenes() > 1) then
  fibaro:debug("trop de scènes")
  fibaro:abort()
  else
  fibaro:debug("On a bien 1 scene.")
end

local NbreSceneAudemarrage = fibaro:countScenes()
fibaro:debug("On vient de Sauvegarder ou cliquer sur Démarrer : MAJ de la variable. Le nbre de scenes en cours : ".. NbreSceneAudemarrage)
 

  while true do
    fibaro:debug("Début du while...")
    fibaro:debug("Test de la condition")
    fibaro:sleep(10*1000); 
    fibaro:debug("Fin du while...")
  end

Le code tourne plus rond. Si il y a trop de scènes il avorte la scène.

Partager ce message


Lien à poster
Partager sur d’autres sites

Comme tu me disais que tu aimes optimiser ton code, j'ai une remarque sur ton while.

 

Inutile d'utiliser autant de variables locales alors que tu as un code super optimisé dans les premières lignes :

if (os.date("%H:%M", os.time()) >= fibaro:getValue(1, "sunriseHour"))
and (os.date("%H:%M", os.time()) < fibaro:getValue(1, "sunsetHour")) then
    fibaro:setGlobal("Jour_Nuit", "Jour");
else
    fibaro:setGlobal("Jour_Nuit", "Nuit");
end

Pépite avait donné une piste pour ne pas écrire sans cesse dans la variable (mais ça tournait en rond).

En y ajoutant le teste du nombre d'instance de scène c'est top :

--[[
%% autostart
--]]
 
fibaro:sleep(10*1000) -- Permet de contourner un bug qui empêche le lancement d'une scène au démarrage en V3.6.

-- Test du nombre de scènes en cours
if (fibaro:countScenes() > 1) then
  fibaro:abort()
end
 
--
-- Je ne pense pas que cette partie soit nécessaire :
-- Elle force la mise à  jour au démarrage mais le while fera pareil juste après
-- if (os.date("%H:%M", os.time()) >= fibaro:getValue(1, "sunriseHour"))
-- and (os.date("%H:%M", os.time()) < fibaro:getValue(1, "sunsetHour")) then
--    fibaro:setGlobal("Jour_Nuit", "Jour");
-- else
--    fibaro:setGlobal("Jour_Nuit", "Nuit");
-- end
--
 
while true do
  fibaro:debug("while")
    if (os.date("%H:%M", os.time()) >= fibaro:getValue(1, "sunriseHour"))
    and (os.date("%H:%M", os.time()) < fibaro:getValue(1, "sunsetHour")) then
    
    -- le soleil est levé et la variable est à  "Nuit"
    if (fibaro:getGlobalValue("Jour_Nuit") == "Nuit") then   
        fibaro:setGlobal("Jour_Nuit", "Jour");
        fibaro:debug("MAJ de la variable Periode à  jour !")
     end

    else
    
    -- le soleil est couché et la variable est à  "jour"
    if (fibaro:getGlobalValue("Jour_Nuit") == "Jour") then    
        fibaro:setGlobal("Jour_Nuit", "Nuit");
        fibaro:debug("MAJ de la variable Periode à  nuit !")
     end
    
    end

fibaro:sleep(60*1000)
end

Qu'en penses-tu ?

 

MAJ : Désolé pour les mises à  jour successives j'avais buggué le code ;)

Modifié par JossAlf

Partager ce message


Lien à poster
Partager sur d’autres sites

moi je trouve ca pas trop mal et optimisé ;-)

enfin je crois ;-)))

Partager ce message


Lien à poster
Partager sur d’autres sites

je viens de tester, ca marche parfaitement bien sauf pour la 1ere fois, il a fallu contourner les tests pour donner la 1ere Valeur à  la variable ;-)

 

j'ai triche je l'ai fait vite fait avec GEA et verifie avec VARIABLES globales de steven ;-)

 

Impeccable, j'en ai encoe pas totalement l'utilite mais TOP et SIMPLE

Partager ce message


Lien à poster
Partager sur d’autres sites

jai fait sans predefinie, j'ai,juste eu a mettre la 1ere valeur mais panipwo ;-)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

je viens de me lancer dans GEA.

Pourquoi ne pourrait-on pas faire cela avec GEA ?

S'il n'y a pas de fonction SunSet / SunRise dans GEA, ne pourrait-on pas simplement créer une variable locale avec la valeur du jour, et faire les tests làdessus ?

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Commence par lire le tuto GEA @Steven a écrit pas mal de choses pour apprivoiser GEA (dans la section tuto pas hc2) tu verra que le Sunset sunrise est pris en charge dans GEA

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci,

Oui bien sur, j'ai lu celui-ci

http://www.domotique-fibaro.fr/index.php/topic/1082-gea-gestionnaire-d%C3%A9v%C3%A9nements-automatique/

est-ce bien le bon ?

Car ou j'ai de la m.... dans les yeux, ou ce n'est pas le bon tuto, mais j'ai rien vu

Partager ce message


Lien à poster
Partager sur d’autres sites

@jojo, confirmation c'est bien pris en charge par GEA.

On pourrait effectivement modifier la valeur de la varibale avec GEA, c'est ce que je fais mais j'ai tout de meme tester la scene ;-)

GEA.add(19, 5*60, "Lumière extérieur est éteinte", {{"Inverse"},  {"Time", "Sunset", "Sunrise"}, {"Portable", 71}})
-- Si la lumière extérieur est éteinte (inverse) depuis plus de 5minutes entre le couché du soleil et le levé on envoi un message push au portable ayant l'ID 71 au lieu de celui par defaut.
  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci pour cette réponse. J'avais même pas rêvé de toi cette nuit ... ;)

 

Ton code fonctionne et je comprends ton intention avec le test if(NbreScene == 1) mais je trouve le procédé alambiqué. En plus cela t'oblige à  ajouter les fameuses lignes pour mettre à  jour la variable au démarrage ...

En plaçant le test du nombre d'instances au début, et en testant la valeur de la variable "jour-nuit" pour la MAJ que si nécessaire, tu simplifies grandement ton code.

 

C'est vrai que dans la version qui suit la boucle while est toujours exécutée (en partie), mais avec ton code tu arrêtes l'exécution juste avant le while avec un test aussi. Niveau temps processeur je pense que ça ce tient.

Le code qui suit est plus économe en lignes, c'est peut-être son seul avantage ... ;)

--[[
%% autostart
--]]

-- Test du nombre de scènes en cours
if (fibaro:countScenes() > 1) then
  fibaro:abort()
end

-- se lance au démarrage et toutes les 60 secondes.
while true do
    if (os.date("%H:%M", os.time()) >= fibaro:getValue(1, "sunriseHour"))
       and (os.date("%H:%M", os.time()) < fibaro:getValue(1, "sunsetHour")) then
          -- le soleil est levé et la variable est à  "Nuit"
          if (fibaro:getGlobalValue("Jour_Nuit") == "Nuit") then   
            fibaro:setGlobal("Jour_Nuit", "Jour");
          end
    else
           -- le soleil est couché et la variable est à  "jour"
         if (fibaro:getGlobalValue("Jour_Nuit") == "Jour") then    
           fibaro:setGlobal("Jour_Nuit", "Nuit");
         end
    end
fibaro:sleep(60*1000)
end

Déroulé : Au démarrage / Toutes les 60 secondes : Si la scène n'a pas une autre instance en cours ; La boucle while sera exécutée ; MAJ de la variable si cela est nécessaire.

  • Upvote 2

Partager ce message


Lien à poster
Partager sur d’autres sites

Au fait, j'espère que je te prends pas la tête ?  B)

Ton post orignal m'a permis d'assainir plusieurs scènes que j'avais laissées en friche.

 

Je te remercie pour tes retours qui m'ont permis d'avancer dans mes réflexions .  :60:

Partager ce message


Lien à poster
Partager sur d’autres sites

Non pas d'erreur ligne 7.
Si > 1 (donc àpartir de 2). Si tu mets >= làelle ne démarrera jamais ! ;)


Envoyé de mon iPhone àl'aide de Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

c'est pas bete mprinfo ta facon de scripter.

oui pour moi ces echanges sont importants, je suis un noob en lua et grace à  vous, j'apprends beaucoup

 

pas sur de pouvoir le reutiliser de suite pais merci messieurs

 

Encooore ;-)

Partager ce message


Lien à poster
Partager sur d’autres sites

Question,

 

le module téléchargeable, il faut tout de même créer mes scènes en page 1 ?

Partager ce message


Lien à poster
Partager sur d’autres sites

je test merci :)

 

 

Merci mprinfo :)

Modifié par cybersquat

Partager ce message


Lien à poster
Partager sur d’autres sites

Mon avis personnel sur la question.

 

Stopper une scène avec le abort() ou la laisser ce terminer sans rien faire .. revient 100% au même. Ce qu'il faudrait pouvoir empêcher est le déclencheur. Dans votre cas, cette scène ne peux se lancer QUE au démarrage de la box/sauvegarde de la scène ET si vous l'avez lancée volontairement.

 

Donc si on sait ce qu'on fait, on devrait même pas avoir besoin de tester cela ... mais mieux vaut s'assurer et mettre un de vos tests (au choix). Perso j'ai une préférence pour le abort() au début comme cela on a plus besoin d'y prêter attention par la suite.

 

En revanche ... je ne supporte pas de voir 2x "os.date("%H:%M", os.time()) das le même code, faut optimiser les gars :), allez, au boulot.

 

Encore une question est ce que quelq'un a essayé ?

--[[
%% propeties
1 sunsetHour
--]]

Perso, je n'ai jamais fait le test mais la question me semble intéressante :)

 

Allez bravo les gars pour ces échanges qui permettent de faire avancer tous cela.

  • Upvote 2

Partager ce message


Lien à poster
Partager sur d’autres sites

Non non non, il n'y a qu'une ligne àoptimiser.

Stocker las date dans une variable puis l'utiliser au 2e endroit.

:)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Optimisez! Surtout que mprinfo m'a conseillé de m' "inspirer" (copier :D)  de ce post! pour mon cas ...

 

Allez Pascal! Plus que quelques minutes avant le dodo !!! sinon demain 6H LOL

Partager ce message


Lien à poster
Partager sur d’autres sites

Allez, soyons fou :
 
Il y a trois type d'optimisation .. la mémoire, le temps processeur .. le temps du développeur.
 
Une bonne application prend en compte ces 3 critères en essayant de faire un bon compromis entre les 3.
 
Voici donc une petite analyse sur votre code ... attention, je suis volontairement très très critique juste pour essayer d'aider. Perso, la plus part de mon code n'est pas optimiser ainsi, voir pas du tout :)
.
.
Optimisation mémoire
 
Chaque variable déclarée pend une infime place en mémoire (son adresse) donc si on a pas besoin de la réutiliser ou de la maintenir ... on en fait pas :)
Une variable utilisée qu'une seule fois ne sert donc à  rien : exemple 

local message = string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R"))
EnvoiPush(message)

On fait directement : 

EnvoiPush(string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R")))

.
.
Optimisation temps processeur
 
la démarche a déja été faite .. bravo. En effet, certaine opération prenne du temps a être éxécutée, il faut donc éviter de demander 2 fois le même calcul pour rien. Exemple :

if ( os.date("%H:%M", os.time())== lever ) or ( os.date("%H:%M", os.time()) == coucher ) then

On voit bien qu'on demande au processeur de calculer 2 fois l'heure actuelle alors que ce qui a été fait 

local osHeure = os.date("%H:%M", os.time())
if ( osHeure == lever ) or ( osHeure == coucher ) then

est bien moins coà»teux puisque nous divisons simplement pas 2 le temps processeur. Bon ok, on passe de 0.00002 sec à  0.00001 sec :) Mais c'est un exemple.
 
 
Optimisation développeur 
 
Moins il y a de code a maintenir mieux c'est.
 
Donc vu que ceci

if (heure >= lever) and (heure < coucher) then
	valeur = "Jour"
end

revient au même que ceci (dans ce contexte)

if ( OsHeure == Lever ) then
    Valeur = "Jour"
else
    Valeur = "Nuit"
end

On extrait tout cela et on en fait une méthode (function) :

function traitement(lever, coucher, heure)
   local valeur = "Nuit"
   -- test si on est le jour ou la nuit
   if (heure >= lever) and (heure < coucher) then
      valeur = "Jour"
   end
   ...
end

.
.
Optimisation bonus ... optimisation pour l'utilisateur
 
On remonte tout en début du code, les variables, traitements que l'utilisateurs doit modifier afin que ce dernier n'aie pas a chercher dans le code la ligne X ou Y.
Donc on met ce ci tout en haut : 

local NomVG = "Jour_Nuit"
local IdTel = 181

On obtient donc ceci :

--[[
%% autostart
--]]

local NomVG = "Jour_Nuit"
local IdTel = 181

----------------------------------------------------------------------
-- Envoi d'un Push pour avertir que le box à  démarrer ou redémarrer --
----------------------------------------------------------------------
function EnvoiPush(Message)
        fibaro:debug(Message)
        fibaro:call(IdTel, "sendPush", Message)
end
 
---------------------------------------------------
-- Mise a jour d'une variable global             --
---------------------------------------------------
function UpdateVG(Valeur)
        if (fibaro:getGlobalValue(NomVG) == nil) then
           fibaro:debug("il faut cree la variable "..NomVG)
           EnvoiPush(string.format("La variable Globale %s n'existe pas ou a ete supprimer", NomVG))
           fibaro:abort() -- fin du programme
        else
           fibaro:debug("VariableGlobale = "..NomVG.." - Valeur = "..Valeur)
           fibaro:setGlobal(NomVG, Valeur);
        end
end

---------------------------------------------------
-- Vérification de l'heure et mise à  jour     --
-- de la variable si necessaire                       -- 
---------------------------------------------------
function traitement(lever, coucher, heure)
	local valeur = "Nuit"
	-- test si on est le jour ou la nuit
	if (heure >= lever) and (heure < coucher) then
		valeur = "Jour"
	end
	UpdateVG(nuit) -- mise a jour de la VG Jour_Nuit
end

-- =======================================
-- Début du code
-- =======================================
----------------------------------------------------------------------
-- Controle si 1 Scéne et déjà  en cours                             --
----------------------------------------------------------------------
local NbreScene = fibaro:countScenes()
fibaro:debug("Nombre de scéne : "..NbreScene)
if (NbreScene ~= 1) then; fibaro:abort(); end
 
----------------------------------------------------------------------
-- Mise a jour de la variable VG Jour_Nuit au Démarrage de la Box   --
-- Ou lors de la sauvegarde de la scéne                             --
----------------------------------------------------------------------
EnvoiPush(string.format("La box a démarré le %s a %s", os.date("%d/%m/%Y"), os.date("%R")))
traitement(fibaro:getValue(1, "sunriseHour"), fibaro:getValue(1, "sunsetHour"), os.date("%H:%M"))
  
----------------------------------------------------------------------
-- Test toute les minutes pour savoir si c'est jour ou nuit         --                      --
----------------------------------------------------------------------
while true do
	local osHeure = os.date("%H:%M", os.time())
	local lever = fibaro:getValue(1, "sunriseHour")
	local coucher = fibaro:getValue(1, "sunsetHour")
 
	if ( osHeure == lever ) or ( osHeure == coucher ) then
		traitement(lever, coucher, osHeure)
	end
	fibaro:debug(string.format("Lever Soleil : %s - Coucher Soleil : %s", lever, coucher))
	fibaro:sleep(60*1000);
end

Maintenant, vous pouvez oublier tout ces bons préceptes car quand on regarde le code des professionnels, on voit bien que la théorie fait bien souvent place à  la fatigue cérébrale et que 90% du code ne respecte pas le moindre petit de ces préceptes.

 

Encore une fois, je ne suis pas là  pour critiquer .. bien au contraire .. je trouve votre idée géniale. De plus, pas vraiment besoin d'optimiser avec cette boxe vu ce qu'elle est capable d'encaisser  :60:

 

Bravo à  vous  :13:

  • Upvote 3

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci Steven de cette piqure de rappel !

 

A mon avis, digne d'un tuto sur les bonnes pratiques en matière de développement.

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Il y a 3 phases difficiles :

 

  1. Comprendre un langage (LUA - fibaro)
  2. Etre capable d'écrire un script en respectant les bonnes pratiques
  3. Etre capable de TOUJOURS appliquer les bonnes pratiques.

Moi, j'ai une excuse, je suis trop vieux et j'oublie donc les bonnes pratiques mais c'est la faute à  ma mémoire :)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Ben toi .. tu sais déjà  plus que tu viens d'écrire :)

 

T'inquête pas, j'ai entendu à  la radio ce matin, qu'on devient "vieux" à  74 ans maintenant ... tu vois, t'es pas encore fichu :)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Euh 74 c'est l'âge ou le département lol

Envoyé avec mon SmartPhone

Partager ce message


Lien à poster
Partager sur d’autres sites

×