Aller au contenu
sebcbien

Mise À Jour Rapide Des Virtual Devices Mais Faible Charge Sur La Hc2

Recommended Posts

Cet après midi, j'ai eu le support Fibaro qui s'est connecté sur ma box pour voir pourquoi elle plantait une fois par semaine....

"Coup de bol" elle a planté pendant que ils étaient occupé à  regarder...

 

Diagnostic:

trop de requètes...

Ah bon, cà d ?  :mellow:

Vous avez trois Virtual device qui font du polling.

Ah bon, lesquels ?

les 1322 1458 et 1856 font des requêtes toutes les 3 secondes...

Heuu... et c'est trop ?  :blink:

Essayez de diminuer pour voir...  :22:

 

Bon, on va pas discuter de ça ici mais je me suis donc mis en tête de diminuer les requêtes.

Effectivement on n'en a besoin que lorsque l'on regarde le VD, le reste du temps... ça tourne pour rien.

 

J'ai donc cherché un moyen de pouvoir mélanger en même temps l'update rapide quand on regarde et l'update lent quand il dort.

 

Pour l'update rapide, j'ai bricolé un truc avec un slider, qui me permet de demander un update unique ou de décider facilement d'une durée de mise à  jour.

- si on clique sur le slider entre 0 et 10, ça fait une mise à  jour unique

- si on clique sur le slider entre 10 et 99, ça lance une série de 89 updates à  une fréquence définie dans le script du slider

- Si 89 updates ne suffisent pas, il y a un "multiplicateur" qui permet de multiplier les 89 updates par ce que l'on veut. 10 donne 890 updates...

- Si on change le nombre d'updates automatiques, ou que l'on passe en manuel, l'instance s'arrête et une autre commence avec les nouvelles valeurs.

 

Votre code à  rafraîchir lors de chaque loop est à  mettre dans la fonction refresh_datas à  la ligne 20

 

Pour l'update lent, via mainloop, j'utilise un bout de code de @steven (encore lui) ;-) qui me semble être particulièrement bien foutu et qui ne charge pas la box.

le main loop simule un clic sur le slider en position 1. mais cela ne perturbe pas le décompte automatique s'il y en avait un en cours.

 

Voici à  quoi ça ressemble:

651454131115222753.jpg

 

Je vous ai même concocté tout ça dans un vfib rien que pour ne pas vous fatiguer  ;)

V1.1:

Fast_Updates V1.1.vfib

 

Et voici les scripts:

Script du slider:

local selfId = fibaro:getSelfId()
local ValeurSlider = _sliderValue_  --fibaro:getValue(selfId, "ui.Slider1.value")
local sleepAndcheckslider, ValeurSliderBeforeSleep, ValeurSliderSleep, multiplier_loop, lastCheck, position
local multiplier = 4 -- number of slider value (10 to 99) so 89 values max. To have 356 loops, set multiplier to 4
local sleepBetweenUpdates = 200 -- 1000 = +- 1 second waiting time between each refresh_datas
-- Put your refresh code in the function refresh_datas (line 84)
sleepBetweenUpdates = sleepBetweenUpdates/50

function getSlider()
  ValeurSliderfunct = fibaro:getValue(selfId, "ui.updateauto.value")
  return tonumber(ValeurSliderfunct)
end

function setSlider(position)
  fibaro:call(selfId, "setProperty", "ui.updateauto.value", position) --  fibaro:call(selfId, "setSlider", 25, position) -- set and execute
  return getSlider()
end
function refresh_datas()
------------------------------------ YOUR CODE HERE -----------------------------------------
fibaro:call(selfId, "setProperty", "ui.example.value", os.date("%d/%m/%y %H:%M:%S"))
----------------------------------- END OF YOUR CODE ----------------------------------------
end

if ValeurSlider == 1 then -- Main loop refresh
	refresh_datas()
	fibaro:debug("Main loop refresh at "..os.date("%d/%m/%y %H:%M:%S"))
	lastCheck = "Last Update: " ..os.date("%d/%m/%y %H:%M:%S")
  	fibaro:call(selfId, "setProperty", "ui.updateStatus.value", lastCheck)
end

if (ValeurSlider < 10 and ValeurSlider > 1) or (ValeurSlider == 0) then -- Manual refresh
	ValeurSlider = setSlider(0)
	fibaro:call(selfId, "setProperty", "ui.updateStatus.value", "Updating Once")
	fibaro:debug("Manual refresh at "..os.date("%d/%m/%y %H:%M:%S"))
	refresh_datas()
	lastCheck = "Last Update: " ..os.date("%d/%m/%y %H:%M:%S")
  	fibaro:sleep(1000)
	fibaro:call(selfId, "setProperty", "ui.updateStatus.value", lastCheck)
	fibaro:sleep(1000)
end

ValeurSlider = getSlider()
while ValeurSlider > 10 do -- Automatic refresh
	setSlider(ValeurSlider)	
	multiplier_loop = 0
	while multiplier_loop < multiplier do
		refresh_datas()
		multiplier_loop = multiplier_loop + 1
		fibaro:call(selfId, "setProperty", "ui.updateStatus.value", "Updates left: "..((ValeurSlider*multiplier)-(10*multiplier)))
		sleepAndcheckslider = 0
		ValeurSliderBeforeSleep = ValeurSlider
		--fibaro:debug("Silder Value before sleep: " .. ValeurSliderBeforeSleep)
		while sleepAndcheckslider <= 50 do
			fibaro:sleep(sleepBetweenUpdates)
			ValeurSliderSleep = getSlider()
			if ValeurSliderSleep == 1 then -- if it's the VD main loop pushing the slider, ignore and set value before
				ValeurSlider = ValeurSliderBeforeSleep
				setSlider(ValeurSlider)
			end
			if ValeurSliderSleep ~= ValeurSliderBeforeSleep then
				multiplier_loop = multiplier
				ValeurSlider = 1
			end -- chack if slider value not changer between wait (to avoid multiple instances)
			sleepAndcheckslider = sleepAndcheckslider+1
		end
	end
	
	ValeurSlider = ValeurSlider - 1
	if ValeurSlider == 10 -- 3600 = 2h 
	then
		fibaro:debug("End of automatic refresh at "..os.date("%d/%m/%y %H:%M:%S"))
		ValeurSlider = setSlider(0)
		lastCheck = 'Last Update: ' ..os.date("%d/%m/%y %H:%M:%S")
		fibaro:call(selfId, "setProperty", "ui.updateStatus.value", lastCheck)
	end
end

Script main loop:

-- FAST UPDATES by sjauquet
-- V1.1 13/11/2015

--local Verification = fibaro:get(selfId,"TCPPort")
-- 1ère fois que le main loop s'exécute, on crée une variable nommée "instance" car elle n'existe pas. Elle existera au 2ème passage donc ne sera pas recrée.
if (not instance) then
    -- on indique la fréquence d'execution souhaitée (en minutes)
    instance = { lastrun = 0, every = 1 }
    fibaro:debug("first run")
end
 
-- on vérifie la différence entre cette exéction et la dernière (stocké dans instance.lastrun)
diff = os.date("*t", os.difftime(os.time(), instance.lastrun))
 
-- si la différence en minutes et supérieure ou égale à  la fréquence souhaitée (instance.every)
if (diff.min >= instance.every) then
   -- TON CODE ---
        local selfId = fibaro:getSelfId();
		local position = 1;
		fibaro:call(selfId, "setSlider", 2, position); -- set and execute
   -- FIN DE TON CODE ---
   -- on stock l'heure de la nouvelle exécution
   instance.lastrun = os.time()
   fibaro:debug("executed")
end

post-826-0-65138700-1447450646_thumb.jpg

  • Upvote 2

Partager ce message


Lien à poster
Partager sur d’autres sites

merci, tu as rajouté cela aux 3 VD que Fibaro t'avais dit ?

 

P.S. je suppose que tu as voulu dire entre 10 et 99 au lieu de

 

 

- si on clique sur le slider entre 10 et 9, ça lance une série de 89 updates à  une fréquence définie dans le script du slider

Partager ce message


Lien à poster
Partager sur d’autres sites

oui je les ai modifiés (le vd pour analyser les logs entre autres, je crois que tu connais  ;) )

 

J'ai corrigé, merci

Partager ce message


Lien à poster
Partager sur d’autres sites

C est intéressant ça.

Comment on peut savoir quels VD, scènes chargent la box ?

Perso ce que je fais la plus part du temps ç est pas de mainloop et tout dans GEA.

Mais j aimerai bien monitorer la charge de la HC2.

Partager ce message


Lien à poster
Partager sur d’autres sites

Ils ont qu'àmettre un genre de CRON les bougres ! Car effectivement checker toutes les minutes pour savoir si c'est bien 08:52 pour lancer le chauffage de la salle de bain ça n'a pas de sens !

Allez seb tu leur propses un fibaro:cron("xx:xx")

:D

Partager ce message


Lien à poster
Partager sur d’autres sites

C'est exactement ce que faisait le Scheduler qui fonctionnait en v3.

Je ne sais pas si son auteur a finalement réussi àle porter en v4.

Partager ce message


Lien à poster
Partager sur d’autres sites

Bah ouais mais ça doit être implanté directement par fibaro ça, tellement c'est la base quoi !

Partager ce message


Lien à poster
Partager sur d’autres sites

En fait le problème, ce n'est pas tellement le scheduler, mais la "charge" subie par la HC2 pour effectuer des affichages/contrôles en permanence... alors qu l'on ne l'utilise que durant un temps infime.

Ici par exemple, prenons mon VD qui affiche les derniers events:

- Ce VD allait demander toutes les 3 secondes la liste des 500 derniers events (en json), les parsait pour éliminer températures, mouvements etc et les affichait...

- Travail complètement inutile fait en permanence pour que ce soit bon lorsque je vais y jeter un coup d'oeil 30 secondes une fois par mois... soit 30 secondes sur les 5.184.000 secondes du mois, soit 0.000001% du temps..

 

Donc maintenant je fais un check toutes les heures par exemple, pour qu'il soit un minimum à  jour.

MAIS si on a besoin d'un refresh rapide (pour test ou autre), un click sur le slider (au lieu d'un bouton "rafraîchir" comme avant) et c'est parti pour une mise à  jour rapide pendant XX minutes/heures, au choix

 

Le meilleur des deux mondes, et très pratique (je n'irai pas jusqu'a dire WAF)   ;)

Partager ce message


Lien à poster
Partager sur d’autres sites

voici ce que ça donne:

679463141115115342.jpg

 

Sympa non ?  :)

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui Sebcbien je suis bien d'accord.

 

Pour le VD Evénements, ça fait longtemps que j'ai allongé la durée de rafraichissement, au lieu des 3s.

Par contre le simple bouton update me suffit, en one-shot, je n'ai pas besoin d'un rafraichissement rapide pendant certain temps. Néanmoins ton approche avec le slider est très intéressante.

 

En revanche, je maintiens qu'il n'est pas normal que la box les process développés par Fibaro plantent en cas de charge modérée. N'importe quel PC, serveur, ou autre peut tenir des charges très importantes pendant plusieurs heures, tant que le refroidissement du processeur est assurée. Au pire du pire, c'est du Intel, le processeur se mettra en sécurité en baissant sa fréquence.

Là  on est dans un pur problème de logiciel informatique, avec des développeurs Fibaro qui ne savant pas faire leur travail. J'insiste mais la nuance est importante. Et la réponse du support FIbaro qui rejette la faute sur nos scripts est inacceptable.

Partager ce message


Lien à poster
Partager sur d’autres sites

Moi pour ces VDs (evenemeents et variables globales) c'est GEA qui gère. 1 appuie toutes les 30mn ça me suffit largement.

D'ailleurs j'essai de tout mettre dans GEA et de ne pas avoir de Main Loop ...

GEA est fait par un pro;

Partager ce message


Lien à poster
Partager sur d’autres sites

En revanche, je maintiens qu'il n'est pas normal que la box les process développés par Fibaro plantent en cas de charge modérée. N'importe quel PC, serveur, ou autre peut tenir des charges très importantes pendant plusieurs heures, tant que le refroidissement du processeur est assurée. Au pire du pire, c'est du Intel, le processeur se mettra en sécurité en baissant sa fréquence.

Là  on est dans un pur problème de logiciel informatique, avec des développeurs Fibaro qui ne savant pas faire leur travail. J'insiste mais la nuance est importante. Et la réponse du support FIbaro qui rejette la faute sur nos scripts est inacceptable.

 

Entièrement d'accord avec toi...

Mais pour le moment... as t'on le choix ?

C'est un inconvénient de la box, il faut composer avec :-/

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui Sebcbien, on fait avec, on n'a pas le choix.

 

d'où la discussion sur le watchdog dans le topic "catcher une erreur lua"

 

mais on restera limité par la redoutable erreur 503, qui ne peut être résolu que par un redémarrage de tous des process sous LInux (nécessite un accès root, ou alors reboot de la box via le bouton arrière)

Partager ce message


Lien à poster
Partager sur d’autres sites
Invité chris6783

J'arrive après le débat mais c quand même sacrément honteux pour les dev fibaro de si mal maîtriser leur sujet. La HC3 sera un super - calculateur histoire de tenir entre 2 reboot de mise àjour.

Ah non ça va pas suffire ça .... il faudra un cluster de calculateurs vu les délais entre 2 mise àjour... Je retourne àma tele car côté domotique fibaro rien de passionnant àl'horizon... Heureusement qu'il y a le forum pour garder un intérêt àçette marque.

Partager ce message


Lien à poster
Partager sur d’autres sites

Soyons positifs, après de longs mois (années ?) d'instabilités, on a maintenant un moteur Z-Wave au top, certainement l'un des plus stables et rapide du marché.

Gageons qu'ils arriveront àreproduire ce miracle sur le reste de la box.... RDV en 2016 :D

Partager ce message


Lien à poster
Partager sur d’autres sites

yes, du beau boulot  !!

 

je suis un peu comme Lazer, je trouve dommage que cela soit à  nous de nous en soucier....

mais du gros boulot..

A ârtir de ce jour, je fais atte,tion au polloing inutile..

J'essaie de le faire avec GEA..

Partager ce message


Lien à poster
Partager sur d’autres sites

J'ai remarqué un effet pervers de gea...

Tout les événement schédulés sont lancés pile au même moment... a ce moment, la box est chargée àfond de requêtes de db, réseau, id's etc... puis plus rien.

J'ai la nette impression que depuis que j'ai réparti les requêtes sur la minute, la mémoire est beaucoup plus libre.

Pour la charge cpu par contre làc'est certain ,et la db ne va certainement pas s'en plaindre non plus...

Partager ce message


Lien à poster
Partager sur d’autres sites

Voici ce que ça donne maintenant, en répartissant les charges plutôt qu'en les lançant toutes en même temps via GEA:

Avant j'avais un gros pic à  100% pendant plusieurs secondes toutes les 30 secondes.

La mémoire ram s'en ressent également beaucoup mieux, beaucoup moins de % d'utilisation.

post-826-0-75103700-1447780238_thumb.jpg

 

17-11-2015 17-33-36.jpg

Partager ce message


Lien à poster
Partager sur d’autres sites
Invité chris6783

Il doit y avoir un copier coller car je ne vois pas de différence ☺

Envoyé de mon SM-G850F en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

C'est la même photo mais en grand ;-)

Je n'ai pas de screenshot de "avant" ... mais c'était horrible àvoir ;-)

Sent from my Note4

Partager ce message


Lien à poster
Partager sur d’autres sites

Tu as décalé des qq secondes alors ?

30,35,40 etc ... ?

Partager ce message


Lien à poster
Partager sur d’autres sites

:D Je n'ai pas de screenshot de "avant" ... mais c'était horrible à  voir ;-)

Merci de nous avoir épargné cette horreur

Partager ce message


Lien à poster
Partager sur d’autres sites

Tu as décalé des qq secondes alors ?

30,35,40 etc ... ?

 

Oui, comme je pars du principe que au démarrage de la box tout les scripts démarrent en même temps, j'ai ajouté des sleep, soit dans le main loop, soit dans le bouton, en fonction des boutons, du temps de réponse demandé etc.

par exemple:

dans beaucoup de mainloop, j'utilise le sheduler de steven

               . Si je ne peux pas ajouter 15 secondes au bouton (pour qu'il réagisse instantanément quand je clique)

                 alors je met un sleep de 800ms par exemple, ou 650 etc, ainsi les scripts s'éloignent peu à  peu au fur et a mesure que le temps depuis le boot s'allonge.

certains scripts de main loop ont des longs temps d'execution et donc il n'y a rien besoin de faire.

 

je sais pas si je me suis bien fait comprendre ;-)

Partager ce message


Lien à poster
Partager sur d’autres sites

Aujourd'hui sans rien touché pour le moment, j'ai une charge de ce type sur 1h de temps.

je précise qu'il n'y a personne à  la maison, donc la box est plutot dans un mode std-by au niveau des actions à  faire.

grave docteur ?

 

193405Sanstitre.png

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui ça me semble des gros pics.

Par contre ce qui m'intrigue c'est la différence de résolution entre ton graphique et le mien...

Tu est en quelle version ?

Sent from my Note4

Partager ce message


Lien à poster
Partager sur d’autres sites

×