Encore un script d'alarme

Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
freulon9292
Messages : 45
Inscription : 03 nov. 2018, 22:53

Encore un script d'alarme

Message par freulon9292 »

Bonjour,

pour faire mon original, je vous soumet un script d'alarme.
Et je demande un peu d'aide : la partie "effraction" de mon script ne se déclenche pas (et je ne vois pas pourquoi !)

Code : Tout sélectionner

commandArray = {}

local counter = 'Niveau_Alerte_counter'
local detection = (tonumber(uservariables[counter] +3))  -- +3 = coeff de modification
local seuil = 8 -- <=8 un seuil de declenchement, soit 3 detections
local dureesirene = 3 -- duree de la gueulante
local effraction = (tonumber(uservariables[counter] +8))  -- +8 = coeff de modification
local log = 'oo Alarme oo ->   '
local cmd ="tail -n 1000 /tmp/domoticz.txt |grep \'oo Alarme oo\'|sed 's/$/<BR>/'"
tc=next(devicechanged)
v=tostring(tc)

--- Each Time a device with a name who start by : " motion "
if (v:sub(1,6)== 'motion') and (tostring(globalvariables['Security']):sub(1,5) == 'Armed') then  
        print (log..'Détecteur '..v..' activé')
        -- increment compteur/sensibilité
        commandArray['Variable:Niveau_Alerte_counter']= tostring(detection)
                if (detection <= seuil) then   
                else print (log.."Seuil déclenchement Alarme atteint suite détection")
                        -- seuil sensibilité/compteur atteint -- déclenchement sirene alarme
                        if otherdevices['Dummy_Sirene'] =='On' then -- print (log.."La sirene sonne deja")
                        else print (log.."Declenchement de la sirene")
                        commandArray['Dummy_Sirene'] = 'On FOR ' ..dureesirene
                                -- Envoi log par mail
                                local f = assert(io.popen(cmd,'r'))
                                local retourf = assert(f:read('*a'))
                                commandArray ['SendEmail'] = log..'#Declenchement de l\'alarme dans la maison : <BR> ' ..tc..'<BR>Les logs : <BR>'..retourf..'#xxx@xxx'
                        end
                end
else


--- la même avec effraction

if  (v:sub(1,10) == 'effraction') and (tostring(globalvariables['Security']):sub(1,5) == 'Armed') then 
        print (log..'effraction détecteur '..v)
        -- increment compteur/sensibilité
        commandArray['Variable:Niveau_Alerte_counter']= tostring(effraction)
                if (effraction <= seuil) then -- print ("****** effraction detecteur " ..v)
                else print (log.."Seuil déclenchement Alarme atteint suite effraction")
                        -- seuil sensibilité/compteur atteint -- déclenchement sirene
                        if otherdevices['Dummy_Sirene'] =='On' then -- print (log.."La sirene sonne deja")
                        else print (log.."Déclenchement de la sirene")
                        commandArray['Dummy_Sirene'] = 'On FOR ' ..dureesirene
                                local f = assert(io.popen(cmd,'r'))
                                local retourf = assert(f:read('*a'))
                                commandArray ['SendEmail'] = log..'#Declenchement de l\'alarme dans la maison : '..tc..'<BR>Les logs : <BR>'..retourf..'#xxx@xxx'
                        end
                end
end
end


return commandArray
quand ça fonctionnera correctement, je rajouterai un troisième morceau avec la détection incendie ...


je prends touts les critiques et les coup de main.
vil1driver
Messages : 5661
Inscription : 30 janv. 2015, 11:07
Localisation : Rennes (35)

Re: Encore un script d'alarme

Message par vil1driver »

Salut,

Un

Code : Tout sélectionner

print(tc)
print(v:sub(1,10)) 
En début de script aiderait probablement
MAJ = VIDER LE CACHE(<-Clicable)
/!\Les mises à jour de Domoticz sont souvent sources de difficultés, ne sautez pas dessus
modules.lua

Un ex domoticzien
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: Encore un script d'alarme

Message par lost »

freulon9292 a écrit : 05 janv. 2020, 21:22 pour faire mon original, je vous soumet un script d'alarme.
Et je demande un peu d'aide : la partie "effraction" de mon script ne se déclenche pas (et je ne vois pas pourquoi !)
C'est quasiment un copier/coller de l'autre... Alors sauf a avoir un pb lié au préfixe??? Moi je factoriserais déjà cela pour éviter des ennuis évitables et simplifier les ajouts futurs.

Par ailleurs, pourquoi lire/additionner les poids d'alarme lié aux capteurs de mouvement (+3 à chaque déclenchement, il en faut 3 pour atteindre le seuil alarme) et d'effraction (+8, seuil atteint direct) séparément au début du script de manière inconditionnelle?

Cela fait des opérations au mieux inutiles à chaque fois que le script device déclenche (y compris hors ces types de capteurs), même si ce n'est remis dans la variable utilisateur que si un capteur a tilté, chargeant le système inutilement.

Je ne voit pas non plus ce qui remets à 0 la variable utilisateur de poids de déclenchement global? Via un autre script?

Sinon, le principe de poids lié à la nature d'un capteur est bon (j'ai fait de même)!
freulon9292
Messages : 45
Inscription : 03 nov. 2018, 22:53

Re: Encore un script d'alarme

Message par freulon9292 »

Merci pour ces retours ....

avec l'ajout proposé par vil1driver, on voit que le script saute la partie effraction joyeusement ... alors qu'il fait tout le reste !
J'ai ajouté après les variables et avant les if ... (donc applicable à tous les capteurs) :

Code : Tout sélectionner

print(tc)
print(v:sub(1,6))
print(v:sub(1,10))
et on voit dans les log le resultat pour le capteur Light/Switch (motion Motion Sensor Entrée)
mais pour le Light/Switch (effraction Motion sensor Entrée), rien !?

Code : Tout sélectionner

2020-01-08 11:00:41.893 Status: dzVents: Info: oo Alarme oo -> Etat de l'alarme : Armed Away
2020-01-08 11:00:41.893 Status: dzVents: Info: ------ Finished Alarme.lua
2020-01-08 11:00:41.894 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2020-01-08 11:00:41.924 Status: Notification: L'alarme vient de passer à l'état :Armed Away
2020-01-08 11:00:41.997 Status: LUA: Domoticz Security Panel
2020-01-08 11:00:43.291 (clef zwave) Light/Switch (effraction Motion sensor Entrée)
2020-01-08 11:00:43.436 Notification sent (email) => Success
2020-01-08 11:00:43.516 (clef zwave) Light/Switch (motion Motion Sensor Entrée)
2020-01-08 11:00:43.669 Status: LUA: motion Motion Sensor Entrée
2020-01-08 11:00:43.783 Status: LUA: motion
2020-01-08 11:00:43.783 Status: LUA: motion Mot
2020-01-08 11:00:43.783 Status: LUA: oo Alarme oo -> Détecteur motion Motion Sensor Entrée activé
2020-01-08 11:00:43.783 Status: LUA: oo Alarme oo -> Seuil déclenchement Alarme atteint suite détection
2020-01-08 11:00:43.783 Status: LUA: oo Alarme oo -> Declenchement de la sirene
2020-01-08 11:00:45.144 (Dummy) Light/Switch (Dummy_Sirene)
2020-01-08 11:00:45.127 Status: EventSystem: Script event triggered: /home/pi/domoticz/scripts/lua/script_device_Motion.lua
2020-01-08 11:00:45.135 Status: Notification: Siréne activée
le mystère est plus épais que ce que j'envisageais !

sinon, les pondérations 3 et 8 sont temporaires, je les affinerai plus tard en fonction du nombre de capteurs, et en prenant en compte qu'un capteur collé au plafond doit pouvoir tomber sans déclencher l'alarme (motion x1 + effraction x1 ) mais que le même mouvement + 1 impact sur un autre détecteur doit déclencher immédiatement. (le scotch double face qui faiblit, ça m'est arrivé !)
J'ai 2 autres scripts qui sont liés : un qui déclenche l'alarme et remet les compteurs à 0,
et un qui fait décroitre le compteur de 1 toutes les minutes (de sorte que si l'alarme tourne 15j, elle n'ait pas plus de probabilité de se déclencher au bout de 15j parce qu'un chat est passé devant ma fenêtre au jour 1 !).
freulon9292
Messages : 45
Inscription : 03 nov. 2018, 22:53

Re: Encore un script d'alarme

Message par freulon9292 »

Je ne pige pas ...
j'ai modifié mon script :

Code : Tout sélectionner

commandArray = {}

local counter = 'Niveau_Alerte_counter'
local detection = (tonumber(uservariables[counter] +3))  -- +3 = coeff de modification
local seuil = 8 -- <=8 un seuil de declenchement, soit 3 detections
local dureesirene = 3 -- duree de la gueulante
local effraction = (tonumber(uservariables[counter] +8))  -- +8 = coeff de modification
local log = 'oo Alarme oo ->   '
local cmd ="tail -n 1000 /tmp/domoticz.txt |grep \'oo Alarme oo\'|sed 's/$/<BR>/'"
tc=next(devicechanged)
v=tostring(tc)

--print(tc)
--print(v:sub(1,6))
print(v:sub(1,10))

if (tostring(globalvariables['Security']):sub(1,5) == 'Armed') then  -- print ('Alarme On')

        print ('Alarme activée')
        print(tc)
--      print(v:sub(1,6))
        print(v:sub(1,10))

if  (v:sub(1,10) == 'effraction')  then  print ('Alarme effraction')
        print (log..'effraction détecteur '..v)
        -- increment compteur/sensibilité
        commandArray['Variable:Niveau_Alerte_counter']= tostring(effraction)
                if (effraction <= seuil) then -- print ("****** effraction detecteur " ..v)
                else print (log.."Seuil déclenchement Alarme atteint suite effraction")
                        -- seuil sensibilité/compteur atteint -- déclenchement sirene si alarme activée
                        if otherdevices['Dummy_Sirene'] =='On' then -- print (log.."La sirene sonne deja")
                        else print (log.."Déclenchement de la sirene")
                        commandArray['Dummy_Sirene'] = 'On FOR ' ..dureesirene
                                local f = assert(io.popen(cmd,'r'))
                                local retourf = assert(f:read('*a'))
                                commandArray ['SendEmail'] = log..'#Declenchement de l\'alarme dans la maison : '..tc..'<BR>Les logs : <BR>'..retourf..'#xxxx@xxxxxx'


                        end
                end
else



if (v:sub(1,6)== 'motion') then  -- print ('Alarme motion')
        print (log..'Détecteur '..v..' activé')
        -- increment compteur/sensibilité
        commandArray['Variable:Niveau_Alerte_counter']= tostring(detection)
                if (detection <= seuil) then    --print ("****** passage devant detecteur " ..v)
                else print (log.."Seuil déclenchement Alarme atteint suite détection")
                        -- seuil sensibilité/compteur atteint -- déclenchement sirene alarme
                        if otherdevices['Dummy_Sirene'] =='On' then -- print (log.."La sirene sonne deja")
                        else print (log.."Declenchement de la sirene")
                        commandArray['Dummy_Sirene'] = 'On FOR ' ..dureesirene
                                -- Envoi log par mail
                                local f = assert(io.popen(cmd,'r'))
                                local retourf = assert(f:read('*a'))
                                commandArray ['SendEmail'] = log..'#Declenchement de l\'alarme dans la maison : <BR> ' ..tc..'<BR>Les logs : <BR>'..retourf..'#xxx@xxxx'
                                                        end
                end
end

end
else
        print ('Alarme désactivée')
end




return commandArray

           
2020-01-11 09:10:23.180 (clef zwave) Light/Switch (effraction Motion sensor Entrée)
2020-01-11 09:10:42.109 (clef zwave) Lux (Motion Sensor xxx Lux)
2020-01-11 09:10:42.281 Status: LUA: Motion Sen
2020-01-11 09:10:42.281 Status: LUA: Alarme activée
2020-01-11 09:10:42.281 Status: LUA: Motion Sensor xxx Lux
2020-01-11 09:10:42.281 Status: LUA: Motion Sen
2020-01-11 09:10:42.397 Status: LUA: Motion Sen
2020-01-11 09:10:42.397 Status: LUA: Alarme activée
2020-01-11 09:10:42.397 Status: LUA: Motion Sensor xxx Lux
2020-01-11
Je ne comprends pas, mon switch 'effraction' apparait déclenché dans les logs, mais ne passe pas dans le script.
et encore plus fort, alors que je vois bien le changement d'état dans les logs, je vois un dernier contact il y a 3 jours dans les dispositifs ?

et si j'essaie de l'activer depuis le dashboard :
Erreur d'envoi de la commande à l’interrupteur, vérifiez le dispositif/matériel !
La vérité est ailleurs ?
Sur ce coup là, je sèche !
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: Encore un script d'alarme

Message par lost »

freulon9292 a écrit : 11 janv. 2020, 09:23 Je ne comprends pas, mon switch 'effraction' apparait déclenché dans les logs, mais ne passe pas dans le script.
et encore plus fort, alors que je vois bien le changement d'état dans les logs, je vois un dernier contact il y a 3 jours dans les dispositifs ?

et si j'essaie de l'activer depuis le dashboard :
Erreur d'envoi de la commande à l’interrupteur, vérifiez le dispositif/matériel !
A priori, c'est la partie "Lux" (donc capteur de luminosité) qui semble déclencher non la partie ouverture ou autre côté logs.
Pour ce qui est de tenter de commander le switch ouverture, normal que cela ne fonctionne pas: C'est une lecture seule, c'est le capteur qui envoie l'état ouvert/fermé que l'on ne peut imposer. Si on cherche à le faire, le module (qui en prime sera en sommeil quand il n'a rien à envoyer pour économiser la pile) ne réponds pas (et probablement, ne reçoit même pas, endormi/ayant coupé sa réception radio): Il faut tester en ouvrant/passant devant le capteur selon son type.

Pour moi, il y a une erreur d'interprétation des logs: Sur un module PIR/ouverture ayant des fonctions annexes ( mesures de luminosité/température typiquement) ne pas se fier qu'au nom du module dans les logs pour savoir ce qui déclenche.

Il y a probablement aussi soit une erreur d'identification du switch lié à la fonction de base (ouverture/PIR) dans l'onglet matériel, soit un dysfonctionnement (ce switch ne remonte jamais de changement d'état)?

Pour identifier, le plus simple est souvent de classer les matériels par dernier vu, éventuellement avec en prime un filtre texte sur une partie du nom donné au matériel... et d'aller le déclencher puis rafraîchir la page web. On a alors le bon qui est en haut.

Sinon, il serait bien de refactoriser le code pour aider à sa lisibilité et maintenance future, voir optimiser les perf:

Eviter de dérouler systématiquement des comparaisons quand elles ne sont pas utiles aide à la réactivité. Par exemple, ici, si on n'est pas dans l'état "Armed" on peut faire direct le "return commandArray" non modifié. Ca évite de passer dans les comparaisons de noms de capteurs suivants.

Comme sur ces derniers il n'y a que le poids qui dépende du préfixe/nom, partir d'une variable d'incrément initialisée à 0 que l'on mettra à jour à 3 ou 8 selon le type de capteur déclenché, la MAJ de la variable utilisateur de poids d'alarme global peut alors se retrouver dans une section de code unique dans laquelle on ne passe que si l'incrément est non nul.
freulon9292
Messages : 45
Inscription : 03 nov. 2018, 22:53

Re: Encore un script d'alarme

Message par freulon9292 »

Bonjour,

je ne suis pas sur d'avoir tout compris à la factorisation ....
Mais j'ai réussi à faire plus court !

A la réflexion, je laisse tomber la différence entre détection et effraction (de toute façon, le second entrainera le premier !).
Les pondérations de détection et déclenchement restent à définir (sachant que je diminue la valeur de 1 à chaque minute via un autre script : je peux peut-être intégré a dans celui-là !?)

Code : Tout sélectionner

local log = 'oo Alarme oo ->   '
local counter = 'Niveau_Alerte_counter'
local detection = (tonumber(uservariables[counter] +3))  -- +3 = coeff de modification
local seuil = 8 -- <=8 un seuil de declenchement, soit 3 detections
local dureesirene = 3 -- duree de la gueulante
local log = 'oo Alarme oo ->   '
local cmd = "tail -n 1000 /tmp/domoticz.txt |grep \'oo Alarme oo\'|sed 's/$/<BR>/'"
local switch = 'Xiaomi Wireless Switch 1'
local keypad = 'Keypad_Access_Control'
local sirene = 'Dummy_Sirene'
tc=next(devicechanged)
device=tostring(tc)

commandArray = {}

-- test si devicechanged concerne l'alarme :
if (device:sub(1,13) == 'Sensor Motion') or (device:sub(1,14) == 'General Motion') or (device == switch) or (device == keypad) then

-- Mise en fonction de l'alarme :
if (devicechanged[switch]) or (devicechanged[keypad]) then --print (log..'declencheur alarme activé')
        --print (log..'global variable = '..(globalvariables['Security']))
        --print (log..'device calue = '..(deviceValue))
        if  tostring(globalvariables['Security']):sub(1,3) == 'Arm' or deviceValue == "Off" then
            commandArray['Domoticz Security Panel'] = 'Disarm'
            commandArray ['UpdateDevice']='206|Alarme|0'
            commandArray[sirene] = 'Off'
            commandArray[counter]= '0'
            print(log..'Alarme désactivée') else
            commandArray['Domoticz Security Panel'] = 'Arm Away'
            commandArray ['UpdateDevice']='206|Alarme|1'
            print(log..'Alarme activée')
        end
end

-- Test état Alarme :
if (tostring(globalvariables['Security']):sub(1,5) == 'Armed') then  -- print (log..'Alarme On')

-- incrément seuil alarme et déclenchement
if      (device:sub(1,13) == 'Sensor Motion') or (device:sub(1,14) == 'General Motion') then
        print (log..'Détecteur '..device..' activé')
        commandArray['Variable:Niveau_Alerte_counter']= tostring(detection)
        print ('detection = '..detection)
                if (detection >= seuil) then
                print (log.."Seuil déclenchement Alarme atteint suite détection")
                        if otherdevices[sirene] =='On' then --print (log..'La Sirene sonne déja')
                        else print (log.."Déclenchement de la sirene")
                        commandArray['Dummy_Sirene'] = 'On FOR ' ..dureesirene
                                local f = assert(io.popen(cmd,'r'))
                                local retourf = assert(f:read('*a'))
                                commandArray ['SendEmail'] = log..'#Declenchement de l\'alarme dans la maison : '..tc..'<BR>Les logs : <BR>'..retourf..'#xxx@xxx'
                        end
                end
end
end
end

return commandArray
Merci de vos avis attentifs.
Répondre