Aller au contenu

Script Contrôle des noeuds mort et leur réveil


lolomail

Messages recommandés

  • 4 semaines après...
  • 1 mois après...

voilà  la v4.0 (fu module VD) qui arrive.

Normalement elle n'est pas buguée.

 

Nouveauté : compatibilité automatique v4.x et v3.x

 

N.B. pour les firmware v4.x

  • je n'ai pas pu testé le réveil des noeuds morts (je n'ai pas physiquement accès à  ma HC2 de test. Merci au passage à  son propriétaire :13: )
  • il essaye de réveiller les devices sur batterie (bien que inutile), mais je n'ai pas trouvé comment tester (en V4.x) si le device est sur batteries
  • si le device principal est mort, il rapporte également le décès de ses filles (idem, je n'ai pas pu identifier dans le json si un device était maître ou fille)
  • le code pourrait être optimisé entre 3.x et 4.x, mais j'ai voulu garder des codes spécifiques pour le "support"

Voici le VD à  charger :

DeadNodesAnalysis_v4.0.vfib

 

Et pour ceux qui ont déjà  une version précédente, et ne veulent pas multiplier les id (ils se reconnaîtront  ;) )

Code du main loop :

---------------------------------------------------------------------------------------------
-- OBJECTIF
-- Ce VD vérifie les noeuds morts dans le réseau z-wave
-- Fréquence de vérification : toutes les minutes
-- Tentative de réveil des noeuds morts, s'ils ne sont pas sur piles
-- 2 boutons pour choisir si on veut recevoir une notification par mail lorsqu'il découvre
-- un noeud mort
-- un label indique le moment de la dernière vérification
--
-- FIRMWARE
-- v3.x & v 4.x
-- http://www.domotique-fibaro.fr/index.php/topic/101-script-contr%C3%B4le-des-noeuds-mort-et-leur-r%C3%A9veil/
--
-- HISTORIQUE
-- v4.0 (12/05/2015 - Jojo) : compatyibilité v3.x & v4.x
-- v3.6 (24/04/2015 - Jojo) : améliore le code pour l'affichage et les notifs
-- v3.5 (10/03/2015 - Jojo) : affichage icône dead durant la période de tentative de réveil
-- v3.4 (21/02/2015 - Jojo) : label avec affichage moment de la dernière action
-- v3.3 (20/02/2015 - Jojo) : bug test device secondaire sur batteries
-- v3.2 (20/02/2015 - Jojo) : bug test devices sur batteries
-- v3.1 (19/02/2015 - Jojo) : bug affichage
-- v3.0 (19/02/2015 - Jojo) : affichage dans détail du VD la liste des noeuds morts 
--                            2 boutons dans le VD pour indiquer si on veux être notifié
--                            afficha nbr noeuds morts en bas de l'icône
-- v2.1 (02/02/2015 - Jojo) : après réveil d'un noeud mort, ajout d'un délais d'attente de 
--                            30s avant de retester
-- v2.0 (31/01/2015 - Jojo) : transformation en VD; champs d'information complémentaires
-- v1.0 (07/12/2014 - Sebcbien) : scène créée initialement par Sebcbien
----------------------------------------------------------------------------------------------

----------------------------------
-- User Settings
----------------------------------

----------------------------------
-- DO not change bellow this line
----------------------------------

local SendNotification = "" --  Push / no push notification when a dead node is discovered
local Notification = fibaro:get(fibaro:getSelfId(),"TCPPort")
Notification = tonumber(Notification)
if Notification == 0
  then
    SendNotification = "No"
  else
    SendNotification = "Yes"
end
fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Notification.value", SendNotification)

fibaro:call(fibaro:getSelfId(), "pressButton", "1")
fibaro:sleep(1*60*1000)  -- exécuter toutes les min

et le code du bouton "DeadNodesAnalysis" :

--------------------------
-- User Settings
--------------------------
local IconeDead = 1129
local IconeOk = 1081
local IconeRun = 1083
local push_dev = 2 -- id of the user to send push message to (2 is admin user)

----------------------------------
-- DO not change bellow this line
----------------------------------
local selfID = fibaro:getSelfId()

fibaro:call(selfID, "setProperty", "currentIcon", IconeRun)

-- check if notification to be sned
local SendNotification = "" --  Push / no push notification when a dead node is discovered
local Notification = fibaro:get(selfID,"TCPPort")
Notification = tonumber(Notification)
if Notification == 0
  then
    SendNotification = "No"
  else
    SendNotification = "Yes"
end

function SendNotif(msg)
  if SendNotification == "Yes" then
    fibaro:call(push_dev, "sendEmail", "Dead nodes discovering", msg) 
  end 
end

function DisplLabel(dead, label)
  if dead <= 9 then
    fibaro:call(selfID, "setProperty", "ui.DeadNode" ..dead.. ".value", label)
  end  
end

local dead = 0     -- counts # dead nodes
local devices = 0  -- counts # devices discovered
local i = 0 
local type = ""
local disabled     -- device caché == 1
local Label = ""

-- clear labels
for i = 1, 9 do
  DisplLabel(i, Label)
end

-- détermination de la version du firmware
local HC2 = Net.FHttp("127.0.0.1",11111)
version = ""
payload = "/api/settings/info"
response, status, errorCode = HC2:GET(payload)
if tonumber(status) == 200 
  then
	jsonTable = json.decode(response)
	if tonumber(jsonTable.softVersion) >= 4 
      then
		version = "4.x"
     else
		version = "3.x"
	end
  else
    fibaro:log("--- ERROR ---")
	fibaro:debug('<span style="color:red;">status='..status..', errorCode='..errorCode..', payload='..payload..', response='..response..'</span>')
end
fibaro:debug('version = ' ..version)

if version == "3.x"
  then -- v3.x
    -- dead nodes analysis
    for i = 2, 1300 do
    -- pas de check sur node 1 = box
      type = fibaro:getType(i)
      disabled = tonumber(fibaro:getValue(i, "disabled"))

      -- si type <> "" et visible
      if (type ~= "" and disabled == 0 ) then 
	    devices = devices + 1
        -- si node i est dead/mort
        if tonumber(fibaro:getValue(i, "dead")) == 1 then 
          -- le node i est dead
          dev = fibaro:getName(i) 
          dead = dead + 1 
          -- affichage du node qui est dead si <=9
          Label = dev.. " (" ..i.. ")"
          DisplLabel(dead, Label)
          -- wakeup dead node only if not on battery et "parentID" = "1"
          if (tonumber(fibaro:getValue(i, "isBatteryOperated")) == 0 
              and tonumber(fibaro:getValue(i, "parentID")) == 1) 
            then
              fibaro:call(selfID, "setProperty", "currentIcon", IconeDead)
              fibaro:call(1, "wakeUpDeadDevice", i)
              fibaro:sleep(30*1000) -- attendre 30s pour tester si le node est réveillé
              if tonumber(fibaro:getValue(i, "dead")) == 1 
                then
                  -- le node i est toujours dead
                  msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..i..") is still dead after unsuccessful wakeup" 
                else
                  -- le node i a été réveillé
                  dead = dead - 1
                  -- effacer le node qui a été réveillée si <=9
                  DisplLabel(dead, " ")
                  msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..i..") was awakened successfully" 
              end
            else
              msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..i..") is on battery and was NOT awakened"
              -- fibaro:debug ("device " ..i.. " " ..dev.. "is on battery, no wakeup")
          end
          -- envoi notification
          SendNotif(msg)     
        end 
      end
    end
  else --v4.x
    -- Récupération de la liste des modules
    reponse = HC2:GET("/api/devices")
    jsonResponse = json.decode(reponse)
    -- dead nodes analysis
    for k, v in ipairs(jsonResponse) do
    fibaro:debug("k="..k)
      if v.visible == true and v.properties.dead ~= nil then 
	    devices = devices + 1
        fibaro:debug("#devices "..devices.. " - devID = "..v.id.. " - devName = " ..v.name.. " - dead = " ..v.properties.dead)
        -- si node est dead/mort
        if v.properties.dead == "true" then 
          -- le node k est dead
          dev = v.name
          devID = tonumber(v.id)
          type = v.type
          dead = dead + 1
          fibaro:debug ("#dead = "..dead)
          -- affichage du node qui est dead si <=9
          Label = dev.. " (" ..devID.. ")"
          DisplLabel(dead, Label)
          -- wakeup dead node only if not on battery
          -- a voir comment faire en v4.x ??
          fibaro:call(selfID, "setProperty", "currentIcon", IconeDead)
          fibaro:call(1, "wakeUpDeadDevice", devID)
          fibaro:sleep(30*1000) -- attendre 30s pour tester si le node est réveillé
          if v.properties.dead == "true" 
            then
              -- le node est toujours dead
              msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..devID..") is still dead after unsuccessful wakeup" 
            else
              -- le node i a été réveillé
              dead = dead - 1
              -- effacer le node qui a été réveillée si <=9
              DisplLabel(dead, " ")
              msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..devID..") was awakened successfully" 
          end  
          -- envoi notification
          SendNotif(msg)     
        end 
      end
    end
end

fibaro:call(selfID, "setProperty", "ui.DeadNodes.value", dead)
fibaro:call(selfID, "setProperty", "ui.DateCheck.value", os.date("%d/%m/%y %H:%M"))
fibaro:call(selfID, "setProperty", "ui.Devices.value", devices)

if dead >= 1 
  then
    fibaro:call(selfID, "setProperty", "currentIcon", IconeDead)
    -- affichage du message en bas de l'icône en continu,
    -- durant la minute entre chaque test
    i=0
    while i < 61 do
      fibaro:log(dead.. " DeadNodes - Send Notification = " ..SendNotification )
      fibaro:sleep(9*1000)
      i = i + 9
    end
  
  else
    fibaro:call(selfID, "setProperty", "currentIcon", IconeOk)
    -- affichage du message en bas de l'icône en continu,
    -- durant la minute entre chaque test
    i=0
    while i < 61 do
      fibaro:log("No Dead Nodes - Send Notification = " ..SendNotification )
	  fibaro:sleep(9*1000)
	  i = i + 9
    end
end

Vos propositions d'évolutions sont comme d'habitude les bienvenues

  • Upvote 1
Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

Maintenant que je suis en v4.x j'ai trouvé comment tester si le device était sur batterie.

Donc aussi sur batterie, il n'y a pas de tentative de réveil (inutile).

 

Voici donc la v4.1 du module :

DeadNodesAnalysis_v4.1.vfib

 

Si vous avez déjà  les version précédentes, il suffit de mettre ce code dans le bouton "Dead Nodes Analysis" :

--------------------------
-- User Settings
--------------------------
local IconeDead = 1129
local IconeOk = 1081
local IconeRun = 1083
local push_dev = 2 -- id of the user to send push message to (2 is admin user)

----------------------------------
-- DO not change bellow this line
----------------------------------
local selfID = fibaro:getSelfId()

fibaro:call(selfID, "setProperty", "currentIcon", IconeRun)

-- check if notification to be sned
local SendNotification = "" --  Push / no push notification when a dead node is discovered
local Notification = fibaro:get(selfID,"TCPPort")
Notification = tonumber(Notification)
if Notification == 0
  then
    SendNotification = "No"
  else
    SendNotification = "Yes"
end

function SendNotif(msg)
  if SendNotification == "Yes" then
    fibaro:call(push_dev, "sendEmail", "Dead nodes discovering", msg) 
  end 
end

function DisplLabel(dead, label)
  if dead <= 9 then
    fibaro:call(selfID, "setProperty", "ui.DeadNode" ..dead.. ".value", label)
  end  
end

local dead = 0     -- counts # dead nodes
local devices = 0  -- counts # devices discovered
local i = 0 
local type = ""
local disabled     -- device caché == 1
local Label = ""

-- clear labels
for i = 1, 9 do
  DisplLabel(i, Label)
end

-- détermination de la version du firmware
local HC2 = Net.FHttp("127.0.0.1",11111)
version = ""
payload = "/api/settings/info"
response, status, errorCode = HC2:GET(payload)
if tonumber(status) == 200 
  then
	jsonTable = json.decode(response)
	if tonumber(jsonTable.softVersion) >= 4 
      then
		version = "4.x"
     else
		version = "3.x"
	end
  else
    fibaro:log("--- ERROR ---")
	fibaro:debug('<span style="color:red;">status='..status..', errorCode='..errorCode..', payload='..payload..', response='..response..'</span>')
end
fibaro:debug('version = ' ..version)

if version == "3.x"
  then -- v3.x
    -- dead nodes analysis
    for i = 2, 1300 do
    -- pas de check sur node 1 = box
      type = fibaro:getType(i)
      disabled = tonumber(fibaro:getValue(i, "disabled"))

      -- si type <> "" et visible
      if (type ~= "" and disabled == 0 ) then 
	    devices = devices + 1
        -- si node i est dead/mort
        if tonumber(fibaro:getValue(i, "dead")) == 1 then 
          -- le node i est dead
          dev = fibaro:getName(i) 
          dead = dead + 1 
          -- affichage du node qui est dead si <=9
          Label = dev.. " (" ..i.. ")"
          DisplLabel(dead, Label)
          -- wakeup dead node only if not on battery et "parentID" = "1"
          if (tonumber(fibaro:getValue(i, "isBatteryOperated")) == 0 
              and tonumber(fibaro:getValue(i, "parentID")) == 1) 
            then
              fibaro:call(selfID, "setProperty", "currentIcon", IconeDead)
              fibaro:call(1, "wakeUpDeadDevice", i)
              fibaro:sleep(30*1000) -- attendre 30s pour tester si le node est réveillé
              if tonumber(fibaro:getValue(i, "dead")) == 1 
                then
                  -- le node i est toujours dead
                  msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..i..") is still dead after unsuccessful wakeup" 
                else
                  -- le node i a été réveillé
                  dead = dead - 1
                  -- effacer le node qui a été réveillée si <=9
                  DisplLabel(dead, " ")
                  msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..i..") was awakened successfully" 
              end
            else
              msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..i..") is on battery and was NOT awakened"
              -- fibaro:debug ("device " ..i.. " " ..dev.. "is on battery, no wakeup")
          end
          -- envoi notification
          SendNotif(msg)     
        end 
      end
    end
  else --v4.x
    -- Récupération de la liste des modules
    reponse = HC2:GET("/api/devices")
    jsonResponse = json.decode(reponse)
    -- dead nodes analysis
    for k, v in ipairs(jsonResponse) do
    fibaro:debug("k="..k)
      if v.visible == true and v.properties.dead ~= nil then 
	    devices = devices + 1
        fibaro:debug("#devices "..devices.. " - devID = "..v.id.. " - devName = " ..v.name.. " - dead = " ..v.properties.dead)
        -- si node est dead/mort
        if v.properties.dead == "true" then 
          -- le node k est dead
          dev = v.name
          devID = tonumber(v.id)
          type = v.type
          dead = dead + 1
          fibaro:debug ("#dead = "..dead)
          -- affichage du node qui est dead si <=9
          Label = dev.. " (" ..devID.. ")"
          DisplLabel(dead, Label)
          -- wakeup dead node only if not on battery
          -- a voir comment faire en v4.x ??
          if v.properties.batteryLevel == nil
            then -- il n'est pas sur batteie
              fibaro:call(selfID, "setProperty", "currentIcon", IconeDead)
              fibaro:call(1, "wakeUpDeadDevice", devID)
              fibaro:sleep(30*1000) -- attendre 30s pour tester si le node est réveillé
              if v.properties.dead == "true" 
                then
                  -- le node est toujours dead
                  msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..devID..") is still dead after unsuccessful wakeup" 
                else
                  -- le node i a été réveillé
                  dead = dead - 1
                  -- effacer le node qui a été réveillée si <=9
                  DisplLabel(dead, " ")
                  msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..devID..") was awakened successfully" 
              end
            else -- il est sur batterie
              msg = os.date("%d/%m/%y %H:%M").." : "..type.." "..dev.." ID("..devID..") is on battery and was NOT awakened"
          end
          -- envoi notification
          SendNotif(msg)     
        end 
      end
    end
end

fibaro:call(selfID, "setProperty", "ui.DeadNodes.value", dead)
fibaro:call(selfID, "setProperty", "ui.DateCheck.value", os.date("%d/%m/%y %H:%M"))
fibaro:call(selfID, "setProperty", "ui.Devices.value", devices)

if dead >= 1 
  then
    fibaro:call(selfID, "setProperty", "currentIcon", IconeDead)
    -- affichage du message en bas de l'icône en continu,
    -- durant la minute entre chaque test
    i=0
    while i < 61 do
      fibaro:log(dead.. " DeadNodes - Send Notification = " ..SendNotification )
      fibaro:sleep(9*1000)
      i = i + 9
    end
  
  else
    fibaro:call(selfID, "setProperty", "currentIcon", IconeOk)
    -- affichage du message en bas de l'icône en continu,
    -- durant la minute entre chaque test
    i=0
    while i < 61 do
      fibaro:log("No Dead Nodes - Send Notification = " ..SendNotification )
	  fibaro:sleep(9*1000)
	  i = i + 9
    end
end
  • Upvote 1
Lien vers le commentaire
Partager sur d’autres sites

Merci Vincent

 

Petite demande...

 

Tu croix que tu pourrais ajouter une fonction qui permettrait d'exclure volontairement certains id ?

 

Aussi, lors de la détection d'un noeux mort, le push est envoyé régulièrement ( lié à  la fonction "sleep" ), peut on modifier cela afin d'envoyer un unique push ( ou à  régler selon les utilisateurs ) lors de la découverte d'un noeux mort ?

Lien vers le commentaire
Partager sur d’autres sites

Merci pour ces bonnes idées.

J'ai remarqué depuis que je suis passé en v4.x que le bouton send notif Yes/No ne fonctionnait qu'en v3.x => j'ai corrigé, mais je devrais publier. 

Question : y en a-t-il qui sont intéressé que je garde une compatibilité v3.x / v4.x. Si non, je simplifie le code.

 

Je vais rajouter la possibilité d'exclure des devices.

 

Pour la possibilité d'envoyer qu'une seule fois la notif (et tant qu'à  faire avec un rappel toutes les x heure ?) je crains qu'il faille passer par stocker l'info dans une variable, et j'aimerais éviter la multiplication des variables. Qu'en pensez-vous ? Si on sait qu'un device est mort pendant un certain temps, on le rajouterait à  la liste des devices à  exclure du test. Ne serait-ce pas suffisant ?

 

je rajoute également un paramètre pour la fréquence de vérification

Lien vers le commentaire
Partager sur d’autres sites

On va avoir des améliorations de partout grâce a jojo v4 lol je pense que tu devrai faire un module v4 car si les gens veulent rester en 3.60 ils faut qu'ils assument leurs choix de non évolution

Envoyé de mon SM-G900F

Lien vers le commentaire
Partager sur d’autres sites

Ce que je ferais ( ce n'est que mon avis ) , j'utiliserais le " port " pour renseigner en secondes le temps de relance des push.

Cela évitera la création d'une variable.

 

Les push ( e-mail ou push hc2 ) je les mettrais en "dur" en supprimant "yes" et "no".

Juste 2 lignes dans le debut du code ou chacun activerait e-mail et/ou push.

Lien vers le commentaire
Partager sur d’autres sites

j'utilisais déjà  port pour notification oui/non

Je peux utiliser IP adresse pour la fréquence.

 

Mais je pensais que tu voulais que si une alerte avait déjà  été envoyée pour un device, elle ne soit pas répétée à  la fréquence de vérification globale des noeuds morts. Et pour celà  il faudrait une variable.

 

QUESTION pour ceux qui sont toujours en 3.6 : utilisez-vous ce script ? Si oui, ce sera avec plaisir que je continuerai à  maintenir la compatibilité, sinon, je fais que pour v4.x. Mais faites vous connaître

Lien vers le commentaire
Partager sur d’autres sites

En fait, concrètement ce que je verrais :

 

- contrôle des noeux morts > toutes les 1 min ( paramétrable )

- push unique dés qu'un noeux mort est trouvé ( mais relance du push paramétrable x min )

 

Du coup tu as raison, je sais pas si c'est possible sans passer par une variable...

Lien vers le commentaire
Partager sur d’autres sites

local TousLesModules = api.get("/devices?") -- Création de la table qui va permettre de retrouver l'id
local NombresModules = #TousLesModules
fibaro:debug("Nombres de modules : " ..#TousLesModules)

avec cela tu n'auras plus a mettre le nombres de modules

Lien vers le commentaire
Partager sur d’autres sites

voici une version 4.2

DeadNodesAnalysis_v4.2.vfib

  • paramétrisation de la fréquence d'analyse (en secondes) dans le champ TCP Port
  • Possibilité d'exclure un liste de devices (table exclude)
  • amélioration diverses de l'affichage

Encore à  venir :

  • possibilité de ne pas répéter les notifications pour les noeuds morts à  une fréquence
  • possibilité de réveiller ou pas les noeuds morts

P.S. : cela commence à  devenir lourd de maintenir le code en double. Y a-t-il toujours des gens intéressés par les évolutions en v3.600 ?

 

  • Upvote 2
Lien vers le commentaire
Partager sur d’autres sites

@Jojo je pense que ton VD est au top pour V3 et V4, donc la prochaine version tu devrais la faire que pour la V4, ça fait un moment que je ne m'occupe plus si mon code est compatible avec la v3. Peux ceux qui sont a en v3 il faut qu'ils assument leurs choix

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

 

Encore à  venir :

  • possibilité de ne pas répéter les notifications pour les noeuds morts à  une fréquence
  • possibilité de réveiller ou pas les noeuds morts

P.S. : cela commence à  devenir lourd de maintenir le code en double. Y a-t-il toujours des gens intéressés par les évolutions en v3.600 ?

 

Vincent, as-'tu du coup amélioré ton script, notamment pour le réveil auto des nÅ“uds morts ?

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...