Aller au contenu

Comment simuler les properties d'un QA ?


Messages recommandés

Posté(e)

Bonjour à tous, 

 

Le titre du post n'est peut-être pas le meilleur, mais bon, voilà ce que je cherche à faire...

Je suis en train de faire un QA sur base du VD Dawn and Dusk écrit par @OJC sur HC2.

 

Pour faire simple, j'aimerais que les valeurs de Sunrise, Sunset, Civil Dusk et Civil Dawn puisse être utilisée à la fois dans les scène blocs et dans GEA. Mais si j'ai bien compris, ce qui est utilisable dans ce cas ce sont les 'properties' du QA (exemple value pour un QA Temperature sensor). Comme ici je manipule des heures, le seul type qi me semble utilisable est le QA générique, mais alors il n'y a pas de properties prédéfinies.

 

Y-a-t-il un moyen d'en créer, ou d'en simuler ?

 

Merci d'avance 

Posté(e)

Créer des propriétés personnalisées dans un QA n'est pas supporté (il me semble cependant que c'est possible via un hack)

 

A la limite, je pense que le moins pire dans ton cas, pourrait être de créer 4 QA children, de type multilevel sensor, et de stocker le timestamp de l'heure dans la propriété "value".

ça ne sera pas très beau dans l'interface, mais à la limite tu caches ces QA children, mais leur valeur sera parfaitement récupérable et exploitable dans GEA.

 

Mais je ne sais pas si cela sera pas utilisable dans les scènes blocs

 

Ou bien tout simplement stocker ces valeurs dans des variables globales.... et garder des labels dans le QA si l'utilisateur veut visualiser ces informations facilement.

EDIT : ou des variables locales du QA

Posté(e)

salut @Lazer, merci du retour,

oui, j'ai déjà ca dans des labels, mais le but c'est effectivement de pouvoir utiliser les valeurs dans GEA et de faire simple...  

 

créer des childs me semble un peu compliqué ou usine à gaz rien que pour ca, donc je partirais plus sur des variables.

 

Par contre, de ce côté, tu conseilles quoi ? globales ou locales au QA ? pour être utilisables par GEA ? en fait les scènes blocs je n'utilise pas du tout

Posté(e)

Variable Globale ou Locale au QA e ne change rien pour GEA, il sait traiter les 2.
 

De manière générale, j'ai tendance à dire qu'on doit restreindre la portée des variables au strict nécessaire (même concept que la programmation), donc plutôt variables dans le QA.

 

Mais dans ce cas précis, tu auras une seule instance du QA Dawn and Dusk (en avoir plusieurs n'aurait aucun sens), et ce sont des données météo, donc plutôt globales à toute la domotique... par conséquent ça aurait du sens de stocker ces valeurs dans des VG.

 

Par ailleurs, ça simplifie leur utilisation, que ça soit depuis GEA ou une autre scène, une VG est accessible directement, tandis que pour accéder à une variable de QA il faut déjà connaitre son ID, donc un peu moins pratique. De plus, GEA sait accéder nativement aux variables des QA, mais ce n'est pas le cas du LUA standard qui serait utilisé dans une autre scène/QA (Fibaro ne propose pas (encore ?) de fonction permettant de lire une variable dans un autre QA... mais seulement dans le QA actuel)

 

Du coup, pour ton usage, des variables globales me semblent tout indiquées.

Posté(e) (modifié)

ah oui mais la vous me parlez chinois :-) je n'ai jamais essayé ca, je ne sais même pas de quoi vous parlez :-)

bon, pour l'instant j'ai mis en place sur base de variables globales....

 

si j'essaie de comprendre ce que vous dites, je suppose que le QA devrait lui-même faire le test pour savoir si on est à l'heure du CivilDusk par exemple, et à ce moment là générer un event , c'est ca ?

 

EDIT : OK, j'ai trouvé la fonction fibaro.emitCustomEvent("eventForCivilDawn")....  mais donc ca veut dire que dans le QA je dois boucler en testant l'heure jusqu'au moment ou elle est égale à une des heures gérées par le QA...  ca me parait un peu lourd non ?

Modifié par Cardane
Posté(e)

Les événements sont une des nouveautés de la HC3 (et gérées par GEA depuis la version 7.20) :

 

image.thumb.png.c1f1f03721673ac0b71034b39c9a145f.png

 

(tu noteras ma grande inspiration quand j'avais testé cette fonctionnalité :D )

 

 

 

 

il y a 10 minutes, Cardane a dit :

je suppose que le QA devrait lui-même faire le test pour savoir si on est à l'heure du CivilDusk par exemple, et à ce moment là générer un event , c'est ca ?

C'est ça

 

Les événements, comme leur nom l'indique, permettent d'indiquer... Un événement !

Mais c'est ponctuel, ça arrive une fois, puis c'est fini (jusqu'à ce que ça se répète éventuellement une prochaine fois... dans le cas qui nous concerne, l'aube et le crépuscule, c'est toutes les 24h)

Il n'y a pas d'état associé, aucune donné mémorisée.

 

Donc si tu veux juste réagir au moment précis de l'aube, alors l'événement est adapté : ça déclenche une scène sur trigger, GEA en mode déclenchement instantané (avec durée = -1), etc.

 

A l'inverse, une variable globale mémorise un état (une valeur, n'importe laquelle), jusqu'à ce qu'elle soit modifié et remplacé par une nouvelle valeur. Si on a besoin de lire plusieurs fois la valeur dans la journée, alors la variable est adaptée.

 

 

J'ai constaté (ou plutôt je n'ai pas constaté) que cette notion d'événement introduit dans la HC3 n'a pas vraiment été discuté sur le forum jusqu'à présent, c'est une fonctionnalité méconnue (et que Fibaro a caché dans un onglet... après les variables globales... déjà bien cachées elles-mêmes)

  • Like 1
Posté(e)

mais est-ce qu'il faut passer par cet onglet pour le créer, ou est-ce que l'appel a emitCustomEvent("monEvent") fait aussi la création ?   bon, je suppose en voyant ton écran qu'il faut le créer avant...  je vais essayer ca, ce qui me dérange c'est de devoir tester l'heure dans une boucle dans le QA

Posté(e)

D'après mes tests, pas besoin de les créer dans les onglets, le simple appel à l'API pour émettre un événement suffit.

Du coup je ne sais pas trop à quoi sert cet onglet.... je me dit que c'est bien de les créer pour avoir une liste et s'y retrouver, sinon on a vite fait de les oublier

Posté(e)

Et pas besoin de créer une boucle qui teste l'heure dans le QA.

La bonne méthode, à mon avis :

- à intervalle régulier, la QA calcule (ou récupère en ligne ?) la nouvelle heure d'aube et crépuscule.

- il calcule et définit un setTimeout pour déclencher une fonction

- cette fonction émet le customEvent

Posté(e)

bon, sur base des différents conseils de @lazer et @jang, le QA commence a fonctionner correctement...  il ne me reste plus qu'une chose à faire : le premier déclenchement...

 

ce QA se rafraîchit automatiquement toutes les 24 heures afin d'aller chercher les nouvelles valeurs sur le site externe. Mais je voudrais aussi que, après installation du QA, le premier déclenchement se fasse à 03:00 du matin (heure idéale pour éviter les problèmes de conversion entre temps UTC, heure local, heure d'été, etc...). Une fois ce premier déclenchement effectué, pas de problème, j'utilise un setTimeout de 24 heures et c'est ok...

 

Quelle serait la manière la plus simple pour faire ça à votre avis ?

 

Posté(e) (modifié)

Je propose un truc dans le genre pour calculer le délai d'ici le lendemain à 3h (pas testé, et il y a peut être moyen d'optimiser) :

local currentTime = os.time()

local futureTime = os.time({
	year  = os.date("%Y", currentTime),
	month = os.date("%m", currentTime),
	day   = os.date("%d", currentTime) + (os.date("%H", currentTIme) >= 3 and 1 or 0),
	hour  = 3,
	min   = 0,
	sec   = 0,
})

local diffTime = os.difftime(futureTime, currentTime)

self:debug("Time is " .. os.date('%H:%M:%S', currentTime) .. ", first loop at " .. os.date("%H:%M:%S", futureTime) .. " in " .. tostring(diffTime) .. " seconds...")

fibaro.setTimeout(diffTime*1000, function() self:loop() end)

C'est perfectible, car si le QA redémarre entre 0 et minuit il va attendre plus de 24h (le lendemain), donc il faut ajouter un test supplémentaire dans la définition du day + 1 => test ajouté

 

A part cela, je me pose une question, je ne sais pas comment la HC3 gère les timeouts de 24h, je me souviens que sur HC2 ça ne fonctionnait pas et qu'il fallait découper en plusieurs intervalles de taille modeste, mais bon, c'était les VD avec tous leurs défauts.

A tester donc.

 

Modifié par Lazer
  • Like 1
Posté(e)

merci @lazer, je vais tester ca, et effectivement pour l'instant je fais un setTimeout d'une heure (mode test), et complètement oublié cette histoire de 24 heures sur HC2...  je vais faire la modification et attendre, je verrai bien si ca passe sur HC3 :-)

 

Posté(e) (modifié)

@Lazer, merci pour le rajout de test, il en me reste plus qu'à aussi tester si on n'est pas en fin de mois et c'est bon

Modifié par Cardane
Posté(e) (modifié)

Example.

local events = {
  {time="02:00",action=function() print("02:00 Ding!") end},
  {time="15:10",action=function() print("15:10 Ding!") end},
  {time="21:03",action=function() print("21:03 Ding!") end},
}

local function setUpDayEvents()
  local now=os.date("*t")
  now=60*60*now.hour+60*now.min+now.sec
  for _,e in ipairs(events) do
    local h,m=e.time:match("(%d+):(%d+)")
    local t = 60*60*tonumber(h)+60*tonumber(m)
    if t >= now then setTimeout(e.action,1000*(t-now)) end
  end
end

function midnightRunner(fun)
  local nxt
  local function loop()
    print("Dong!")
    fun()
    nxt=nxt+24*60*60                    -- Next midnight
    setTimeout(loop,1000*(nxt-os.time()))
  end
  local t = os.date("*t")
  t.hour,t.min,t.sec=0,0,0               -- Last midnight
  nxt=os.time(t)+24*60*60                --  Next midnight
  setTimeout(loop,1000*(nxt-os.time()))
end

function QuickApp:onInit()
  setUpDayEvents()                -- When QA starts up
  midnightRunner(setUpDayEvents)  -- Every midnight
end

Output:

[20.03.2021] [08:09:02] |SYS  |: HC3 SDK v0.199
[20.03.2021] [08:09:02] |SYS  |: Speeding 24 hours
[20.03.2021] [08:09:02] |SYS  |: Created Event server at 192.168.1.184:6872
[20.03.2021] [08:09:02] |SYS  |: Created Terminal server at 192.168.1.184:6972
[20.03.2021] [08:09:03] |SYS  |: Setting speed to true
[20.03.2021] [08:09:03] |LOG  |: Polling HC3 for triggers every 2000ms
[20.03.2021] [08:09:03] |-----|: ----------------------------------- Loading QuickApp 'My QA'...  -----------------------------------
[20.03.2021] [08:09:03] |-----|: ---------------- QuickApp 'My QA', deviceID:999 started at Sat Mar 20 08:09:03 2021 ----------------
[20.03.2021] [08:09:03] |SDBG |: Incoming trigger:{"type":"DeviceCreatedEvent","data":{"id":999}}
[20.03.2021] [15:10:00] [DEBUG] [QUICKAPP999]: 15:10 Ding!
[20.03.2021] [21:03:00] [DEBUG] [QUICKAPP999]: 21:03 Ding!
[21.03.2021] [00:00:00] [DEBUG] [QUICKAPP999]: Dong!
[21.03.2021] [02:00:00] [DEBUG] [QUICKAPP999]: 02:00 Ding!
[21.03.2021] [02:00:00] |SYS  |: Max time - exit
Program completed in 1.15 seconds (pid: 27233).
Debugging session completed (traced 0 instructions).

setTimeout can handle 24.8 days ;)

Modifié par jang
  • Like 4
Posté(e)
Il y a 3 heures, jang a dit :

setTimeout can handle 24.8 days ;)

yes, i saw that in documentation...  i did start a test yesterday, will see later on today if everything is running correctly, then i'll try to optimise my code based on your example ;-)

 

Il y a 3 heures, jang a dit :

ome exercise: How to survive daylight time savings?...

 

i guess we can manage that using the isdst flag ?

Posté(e) (modifié)
Le 17/03/2021 à 11:43, Lazer a dit :

D'après mes tests, pas besoin de les créer dans les onglets, le simple appel à l'API pour émettre un événement suffit.

Du coup je ne sais pas trop à quoi sert cet onglet.... je me dit que c'est bien de les créer pour avoir une liste et s'y retrouver, sinon on a vite fait de les oublier

pour info, si j'ai bien vu, les définir dans l'onglet permet simplement que les events soient utilisables dans les scènes blocs....

Modifié par Cardane
  • Like 1
Posté(e)

This is how I would tackle DST

local events = {
  {time="02:00",action=function() print("02:00 Ding!") end},
  {time="15:10",action=function() print("15:10 Ding!") end},
  {time="21:03",action=function() print("21:03 Ding!") end},
}

local function setUpDayEvents(self)
  local now=os.date("*t")
  now=60*60*now.hour+60*now.min+now.sec
  for _,e in ipairs(events) do
    local h,m=e.time:match("(%d+):(%d+)")
    local t = 60*60*tonumber(h)+60*tonumber(m)
    if t >= now then
      quickApp:debug("Schedule:"..e.time)
      setTimeout(e.action,1000*(t-now),e.time) 
    end
  end
end

function intervalRunner(seconds,fun)
  local nxt
  local function loop()
    if fun()=='RESTARTED' then return end -- We still resturn after plugin.restart...
    nxt=nxt+seconds     
    local a = setTimeout(loop,1000*(nxt-os.time()))
  end
  local t = (os.time() // seconds) * seconds
  nxt=t+seconds
  setTimeout(loop,1000*(nxt-os.time()-(seconds > 3600 and 3600 or 0)))
end

function QuickApp:onInit()
  quickApp = self
  setUpDayEvents()
  intervalRunner(24*60*60,setUpDayEvents)
  self:setVariable("DST",os.date("*t").isdst)
  intervalRunner(60*60,function()
      if os.date("*t").isdst ~= self:getVariable("DST") then 
        self:debug("DST changed")
        plugin.restart() 
        return "RESTARTED"
      end
    end)
end

-- rebooting the QA at DST... In this case it could be solved in other ways (with more code) - in more complicated QAs with many timers it may be the only approach...

(DST in Sweden is on Sun Mar 28 03:00:00)

Program starting as '"/Applications/ZeroBraneStudio.app/Contents/ZeroBraneStudio/bin/lua.app/Contents/MacOS/lua53" -e "io.stdout:setvbuf('no')" "/var/folders/ft/sp22kj0d52l0f96grjcqwfyw0000gn/T/.kUBXRl"'.
Program 'lua53' started in '/Users/erajgab/Dropbox/LUA/EventRunner/EventRunner' (pid: 65727).
Debugging session started in '/Users/erajgab/Dropbox/LUA/EventRunner/EventRunner/'.
[21.03.2021] [13:56:50] |SYS  |: HC3 SDK v0.199
[21.03.2021] [13:56:50] |SYS  |: Speeding 48 hours
[21.03.2021] [13:56:50] |SYS  |: Created Event server at 192.168.1.184:6872
[21.03.2021] [13:56:50] |SYS  |: Created Terminal server at 192.168.1.184:6972
[27.03.2021] [10:00:00] |SYS  |: Setting emulator time to Sat Mar 27 10:00:00 2021
[27.03.2021] [10:00:00] |LOG  |: DST at Sun Mar 28 03:00:00 2021
[27.03.2021] [10:00:00] |SYS  |: Setting speed to true
[27.03.2021] [10:00:00] |-----|: ----------------------------------- Loading QuickApp 'My QA'...  -----------------------------------
[27.03.2021] [10:00:00] |-----|: ---------------- QuickApp 'My QA', deviceID:999 started at Sat Mar 27 10:00:00 2021 ----------------
[27.03.2021] [10:00:00] [DEBUG] [QUICKAPP999]: Schedule:15:10
[27.03.2021] [10:00:00] [DEBUG] [QUICKAPP999]: Schedule:21:03
[27.03.2021] [10:00:00] |SDBG |: Incoming trigger:{"type":"DeviceCreatedEvent","data":{"id":999}}
[27.03.2021] [15:10:00] [DEBUG] [QUICKAPP999]: 15:10 Ding!
[27.03.2021] [21:03:00] [DEBUG] [QUICKAPP999]: 21:03 Ding!
[28.03.2021] [00:00:00] [DEBUG] [QUICKAPP999]: Schedule:02:00
[28.03.2021] [00:00:00] [DEBUG] [QUICKAPP999]: Schedule:15:10
[28.03.2021] [00:00:00] [DEBUG] [QUICKAPP999]: Schedule:21:03
[28.03.2021] [03:00:00] [DEBUG] [QUICKAPP999]: 02:00 Ding!
[28.03.2021] [03:00:00] [DEBUG] [QUICKAPP999]: DST changed
[28.03.2021] [03:00:00] |SYS  |: Restarting QA 999, timers=3, memory used 1298.5kB
[28.03.2021] [03:00:00] |-----|: ---------------- QuickApp 'My QA', deviceID:999 started at Sun Mar 28 03:00:00 2021 ----------------
[28.03.2021] [03:00:00] [DEBUG] [QUICKAPP999]: Schedule:15:10
[28.03.2021] [03:00:00] [DEBUG] [QUICKAPP999]: Schedule:21:03
[28.03.2021] [14:00:00] |SDBG |: Incoming trigger:{"type":"DeviceModifiedEvent","data":{"id":999}}
[28.03.2021] [15:10:00] [DEBUG] [QUICKAPP999]: 15:10 Ding!
[28.03.2021] [21:03:00] [DEBUG] [QUICKAPP999]: 21:03 Ding!
[29.03.2021] [01:00:00] [DEBUG] [QUICKAPP999]: Schedule:02:00
[29.03.2021] [01:00:00] [DEBUG] [QUICKAPP999]: Schedule:15:10
[29.03.2021] [01:00:00] [DEBUG] [QUICKAPP999]: Schedule:21:03
[29.03.2021] [02:00:00] [DEBUG] [QUICKAPP999]: 02:00 Ding!
[29.03.2021] [10:00:00] |SYS  |: Max time - exit
Program completed in 0.84 seconds (pid: 65727).
Debugging session completed (traced 0 instructions).

Btw, even on the HC3 the code continues after the call to plugin.restart() until current function terminates - took me 3 hours to find the bug...:-) 

 

  • Like 2
×
×
  • Créer...