script présence non fiable

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 <\>.
jec_44
Messages : 16
Inscription : 09 déc. 2015, 11:29

Re: script présence non fiable

Message par jec_44 »

Bonjour,
Je souhaite aussi utiliser ma Livebox 4 pour la détection de présence avec le script le ce très bon script
https://github.com/vzwingma/domotique/b ... status.lua

Mais j'ai un problème ici :
local commandeurl="curl -s -X POST -H 'Cache-Control: no-cache' -d '' " .. apiLiveBox .. "/sysbus/Devices:get"

et lorsque je lance http:\livebox\sysbus/Devices:get dans un navigateur, j'ai une erreur avec "permission denied". Il faut surement intégrer dans le script LUA les paramètres d'authentification ? J'ai lu sur des forum qu'Orange avait apporté des changement dans leur API sur l'authentification !

Quelqu'un aurait la solution ? (ou une piste) :)

Merci
Raspberry PI / Domoticz version stable / Sondes Oregon / Freebox / Harmony Companion / Synology DS215J / Fibaro / Dlink / Di-o / Philips Hue
papoo
Messages : 2029
Inscription : 10 janv. 2016, 11:29
Localisation : Limoges (87)
Contact :

Re: script présence non fiable

Message par papoo »

pour ceux que ça intéresse j'ai modifier le script afin de mettre à jour les devices que sur changement d'état et activation/désactivation automatique de l'alarme

Code : Tout sélectionner

--[[
source : https://sites.google.com/site/au66bis/domoticz/scripts-lua/script_time_network_status 
https://easydomoticz.com/forum/viewtopic.php?f=10&t=3825&p=46712#p46712
http://pon.fr/network-status-via-freebox-en-lua/
Procédure pour obtenir APPTOKEN http://easydomoticz.com/forum/viewtopic.php?f=7&t=289&p=5042&hilit=freebox#p5042
MAJ : 23/12/2017
]]--
--------------------------------------------
------------ Variables à éditer ------------
-------------------------------------------- 
local nom_script = "FreeBox Network Status"
local version = "1.3"
local debugging = true  			-- true pour voir les logs dans la console log Dz ou false pour ne pas les voir
freebox_appid="Domoticz.app" --uservariables["freebox_appid"]
-- Créer une variable "freebox_mac_adress_smartphones" avec les MAC ADDRESS des smartphones. Le séparateur est ";"
freebox_mac_adress_smartphones=uservariables["freebox_mac_adress_smartphones"]
freebox_mac_adress_surveillance=uservariables["freebox_mac_adress_surveillance"]
-- Créer une variable "freebox_mac_adress_surveillance" avec les MAC ADDRESS des Smartphones N' entrant PAS en compte pour l'alarme. Le séparateur est ";"
freebox_apptoken=uservariables["freebox_apptoken"]
-- URL des API A CHANGER
apiFreeboxv4="http://mafreebox.freebox.fr/api/v4"
apiDomoticz="http://127.0.0.1:8080/json.htm?"
-- Session Token
session_token=""
--------------------------------------------
----------- Fin variables à éditer ---------
--------------------------------------------
local patternMacAdresses = string.format("([^%s]+)", ";")

--------------------------------------------
---------------- Fonctions -----------------
--------------------------------------------   
package.path = package.path..";/home/pi/domoticz/scripts/lua/fonctions/?.lua"
require('fonctions_perso')

function readAll(file)
    local f = io.open(file, "rb")
	if(f == nil) then
		return ""
	else
		local content = f:read("*all")
		f:close()
		return content
	end
end
-- Fonction de la connexion à la Freebox
-- Authentification pour récupérer le tokenDeSession
function connectToFreebox()
	voir_les_logs("Connexion a la Freebox",debugging)
	local TMPDIR_CHALLENGE = "/media/Freebox/Trend/challenge.tmp"
	local TMPDIR_APPTOKEN =  "/media/Freebox/Trend/apptoken.tmp"
	local TMPDIR_SESSIONTOKEN =  "/media/Freebox/Trend/sessiontoken.tmp"	
	-- CHALLENGE : Appel de login pour charger le challenge
	os.execute("curl -s " .. apiFreeboxv4 .. "/login > " .. TMPDIR_CHALLENGE)
	local json_challenge = JSON:decode(readAll(TMPDIR_CHALLENGE))
	local challenge = json_challenge.result.challenge
	voir_les_logs("  Challenge : " .. challenge,debugging)
	-- APP  TOKEN : Calcul du mot de passe
	voir_les_logs("Calcul HMAC SHA1",debugging)
	voir_les_logs("  AppToken : " .. freebox_apptoken,debugging)
	os.execute("echo -n " .. challenge .. " | openssl dgst -sha1 -hmac " .. freebox_apptoken .. " | cut -c10-200 > " .. TMPDIR_APPTOKEN)
	local password = readAll(TMPDIR_APPTOKEN)
	password=password:gsub("\n", "")
	voir_les_logs("  Password : " .. password,debugging)	
	-- CONNEXION Session Connect
	local table_app_session = {}
	table_app_session["app_id"]=freebox_appid
	table_app_session["password"]=password
	local json_app_session = JSON:encode_pretty(table_app_session)
	--	connexion à la session
	os.execute("curl -s -H \"Content-Type: application/json\" -X POST -d '" .. json_app_session .. "' " .. apiFreeboxv4 .. "/login/session/ > " .. TMPDIR_SESSIONTOKEN)
	local json_session_token = JSON:decode(readAll(TMPDIR_SESSIONTOKEN))
	session_token=json_session_token.result.session_token
	voir_les_logs("  Session Token : " .. session_token,debugging)
end
-- Fonction de la deconnexion à la Freebox
function disconnectToFreebox()
	local TMPDIR_DISCONNECT = "/media/Freebox/Trend/challenge.tmp" --"/tmp/challenge.tmp" 
	os.execute("curl -m 5 -s -H \"X-Fbx-App-Auth: " .. session_token .. "\" -X POST " .. apiFreeboxv4 .. "/login/logout > " .. TMPDIR_DISCONNECT)
	local disconnect = readAll(TMPDIR_DISCONNECT)
	voir_les_logs("  Deconnexion Freebox API : " .. disconnect)
end
-- Fonction de recherche des périphériques connectés
-- Connexion à lan/browser/pub/ pour lister les périphériques
-- @param session_token : token de session Freebox
-- @return périphériques connectés ?
function getPeripheriquesConnectes() -- liste les périphériques utilisés pour l'activation/désactivation automatique de l'alarme
	local TMP_PERIPHERIQUES = "/media/Freebox/Trend/peripheriques.tmp"
	--  Appel sur la liste des périphériques
	voir_les_logs("Recherche des peripheriques connus de la Freebox",debugging)
	local commandeurl="curl -s -H \"Content-Type: application/json\" -H \"X-Fbx-App-Auth: " .. session_token .. "\" -X GET " .. apiFreeboxv4 .. "/lan/browser/pub/"
	os.execute(commandeurl .. " > " .. TMP_PERIPHERIQUES)
	local json_peripheriques = JSON:decode(readAll(TMP_PERIPHERIQUES))
	local etatSmartphone = false
	-- Liste des périphériques
	for index, peripherique in pairs(json_peripheriques.result) do	
		for mac in string.gmatch(freebox_mac_adress_smartphones, patternMacAdresses) do
			local peripherique_mac_adress = "ether-" .. mac:lower()
			if(peripherique_mac_adress == peripherique.id)
			then
				voir_les_logs("Statut du peripherique ".. peripherique.primary_name.." [" .. mac .. "]  =>  actif:" .. tostring((peripherique.active and peripherique.reachable)),debugging)
				if(peripherique.active and peripherique.reachable) then
					etatSmartphone = true
                        if otherdevices[peripherique.primary_name] == 'Off' then
							commandArray [peripherique.primary_name]='On'
                            voir_les_logs("--- --- --- [FREEBOX] Activation de : " .. peripherique.primary_name .."  --- --- --- ",debugging)
						
                        end
							else
                        if otherdevices[peripherique.primary_name] == 'On' then    
							commandArray [peripherique.primary_name]='Off'
                            voir_les_logs("--- --- --- [FREEBOX] DesActivation de : " .. peripherique.primary_name .."  --- --- --- ",debugging)
						
                        end   
				end		
			end
		end
	end
return etatSmartphone
end
	
function getPeripheriquesConnectes2() -- liste les périphériques utilisés pour
	local TMP_PERIPHERIQUESHORSALARME = "/media/Freebox/Trend/peripheriques_hors_alarme.tmp"
	--  Appel sur la liste des périphériques
	voir_les_logs("Recherche des peripheriques connus de la Freebox (hors alarme)",debugging)
	local commandeurl="curl -s -H \"Content-Type: application/json\" -H \"X-Fbx-App-Auth: " .. session_token .. "\" -X GET " .. apiFreeboxv4 .. "/lan/browser/pub/"
	os.execute(commandeurl .. " > " .. TMP_PERIPHERIQUESHORSALARME)
	local json_other_peripheriques = JSON:decode(readAll(TMP_PERIPHERIQUESHORSALARME))
	etatPeripheriques = false
    -- Liste des périphériques HORS ALARME
	for index, other_peripherique in pairs(json_other_peripheriques.result) do	
		for mac in string.gmatch(freebox_mac_adress_surveillance, patternMacAdresses) do
			local other_peripherique_mac_adress = "ether-" .. mac:lower()
			if(other_peripherique_mac_adress == other_peripherique.id)
			then
				voir_les_logs("Statut du peripherique ".. other_peripherique.primary_name.." [" .. mac .. "]  =>  actif:" .. tostring((other_peripherique.active and other_peripherique.reachable)),debugging)
				if(other_peripherique.active and other_peripherique.reachable) then
                etatPeripheriques = true
                    if otherdevices[other_peripherique.primary_name] == 'Off' then
                        commandArray [other_peripherique.primary_name]='On'
                        voir_les_logs("--- --- --- [FREEBOX] Activation de : " .. other_peripherique.primary_name .."  --- --- --- ",debugging)
                    end
				else
                    if otherdevices[other_peripherique.primary_name] == 'On' then    
                        commandArray [other_peripherique.primary_name]='Off'
                        voir_les_logs("--- --- --- [FREEBOX] DesActivation de : " .. other_peripherique.primary_name .."  --- --- --- ",debugging)
                    end
				end		
			end
		end
	end	
return etatPeripheriques
end
-- Mise à jour de l'alarme suivant le statut des périphériques
-- @param : état des périphériques
function updateAlarmeStatus(etat_peripheriques)
	local etatActuelAlarme=otherdevices['Security Panel']
    voir_les_logs("  > Etat du panneau de securite = " .. etatActuelAlarme ,debugging)
	local SEUIL_ALARME = 1 -- temps en minute avant activation de l'alarme
	local TMPDIR_COMPTEUR_OUT = "/media/Freebox/Trend/compteur_smartphone_out.tmp"
	-- Activation de l'alarme au bout de X min
	if(not etat_peripheriques and etatActuelAlarme == "Normal") then
    --if(not etat_peripheriques) then
		compteurOff=readAll(TMPDIR_COMPTEUR_OUT)
		if(compteurOff == "") then
			compteurOff = 0
		end
		compteurOff = compteurOff + 1
		voir_les_logs("  > Compteur de mise en alarme = " .. compteurOff .. " / " .. SEUIL_ALARME,debugging)
		if(compteurOff >= SEUIL_ALARME) then
			voir_les_logs("Activation de l'alarme",debugging)
            commandArray[#commandArray+1] = {['Alarme Out']="On"}
            commandArray[#commandArray+1] = {['test presences']="Off"}          
			compteurOff = 0
		end
		os.execute("echo " .. compteurOff .. " > " .. TMPDIR_COMPTEUR_OUT)
	elseif(etat_peripheriques and etatActuelAlarme == "Arm Away") then
    -- Désactivation immédiate
		
        commandArray[#commandArray+1] = {['Alarme Out']="On"}
        commandArray[#commandArray+1] = {['test presences']="On"}
		voir_les_logs("Desactivation de l'alarme",debugging)

		os.execute("echo 0 > " .. TMPDIR_COMPTEUR_OUT)
	
	elseif(etat_peripheriques) then
		os.execute("echo 0 > " .. TMPDIR_COMPTEUR_OUT)
        commandArray[#commandArray+1] = {['test presences']="On"}
        voir_les_logs("Remise a zero du compte de l'alarme",debugging)
		
	end	
end
--------------------------------------------
-------------- Fin Fonctions ---------------
--------------------------------------------
commandArray = {}
time=os.date("*t")
if time.min ~= 0 then -- execution toutes les minutes sauf à xx:00
		voir_les_logs("[FREEBOX] Statuts des peripheriques reseau Freebox",debugging)
	-- Boucle principale
    
	if( freebox_apptoken == nil or freebox_appid == nil or freebox_mac_adress_smartphones == nil or freebox_mac_adress_surveillance == nil ) then
		error("[FREEBOX] Les variables {freebox_apptoken}, {freebox_appid}, {freebox_mac_adress_smartphones}, {freebox_mac_adress_surveillance} ne sont pas definies dans Domoticz")
		return 512
	else
		voir_les_logs("Test de presence des appareils d'adresses MAC (" .. freebox_mac_adress_smartphones .. ")",debugging)
        voir_les_logs("Test de presence des appareils d'adresses MAC (" .. freebox_mac_adress_surveillance .. ")",debugging)
		JSON = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- one-time load of the routines
		-- Connexion à la Freebox
		connectToFreebox()
		-- Recherche des périphériques connectés
		peripheriques_up = getPeripheriquesConnectes()
		-- Recherche des périphériques connectés  (HORS ALARME)
		getPeripheriquesConnectes2()
		updateAlarmeStatus(peripheriques_up)
		-- Déconnexion à la Freebox
		disconnectToFreebox()
	end
end --if time	
return commandArray
domoticz beta/RaspBerry PI3 stretch
https://pon.fr github
papoo
Messages : 2029
Inscription : 10 janv. 2016, 11:29
Localisation : Limoges (87)
Contact :

Re: script présence non fiable

Message par papoo »

jec_44 a écrit :Bonjour,
Je souhaite aussi utiliser ma Livebox 4 pour la détection de présence avec le script le ce très bon script
https://github.com/vzwingma/domotique/b ... status.lua

Mais j'ai un problème ici :
local commandeurl="curl -s -X POST -H 'Cache-Control: no-cache' -d '' " .. apiLiveBox .. "/sysbus/Devices:get"

et lorsque je lance http:\livebox\sysbus/Devices:get dans un navigateur, j'ai une erreur avec "permission denied". Il faut surement intégrer dans le script LUA les paramètres d'authentification ? J'ai lu sur des forum qu'Orange avait apporté des changement dans leur API sur l'authentification !

Quelqu'un aurait la solution ? (ou une piste) :)

Merci

As tu résolu ton problème?
les paramètres d'authentification de la livebox c'est l'utilisateur admin et le mot de passe d'administration (par défaut les 8 premiers caractères de la clé Wi-Fi). source
je vais bientôt passer sur livebox, il va me falloir faire marcher ce script
domoticz beta/RaspBerry PI3 stretch
https://pon.fr github
cyberbob
Messages : 511
Inscription : 28 nov. 2016, 19:43
Localisation : Belgique

Re: script présence non fiable

Message par cyberbob »

Pour la détection de présence via wifi avec un Samsung J3 fonctionne sans problème.
Par contre avec un Samsung J8 il y a des déconnexion/reconnexion du wifi sans comprendre la raison.

Avez-vous réussis avec ce type de smartphone ? Ou alors il faut oublier la détection wifi avec la nouvelle génération de smartphone ?
Domoticz Stable V4.9700 sur Synology DSM 6.2 / 2 x RFlink V48.4 - 433.92MHz(Dio/Chacon) & 433.42MHz(RTS) / Script en LUA & Blocky
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: script présence non fiable

Message par lost »

cyberbob a écrit :Pour la détection de présence via wifi avec un Samsung J3 fonctionne sans problème.
Par contre avec un Samsung J8 il y a des déconnexion/reconnexion du wifi sans comprendre la raison.
Stratégie d'économie d'énergie plus poussée qui fait couper le wifi, gros consommateur, dès qu'il n'est pas utilisé. Maintenant, peut-être que cela se paramètre...

Sinon, le bluetooth étant un moins gros consommateur il est souvent moins soumis à ce type de stratégie d'économie et reste toujours on quand on l'active.

Maintenant, la portée est plus faible (et varie plus selon les appareils: Le BB de ma femme est topé dès qu'elle se gare devant dans la rue, pratique pour virer à temps les illégales, mon Nokia devant la porte d'entrée et le samsung de ma fille ne l'est parfois que porte à peine ouverte). Chez moi c'est ce que j'utilise et cela impose de laisser au moins un tél au RdC car à l'étage la portée est parfois limite et on peut se retrouver vu absents avec l'alarme qui se déclenche au 1er passage devant un détecteur...

Si cette contrainte est acceptable (ou qu'une déco de temps en temps en déclenche pas une alarme!), c'est sans doute une voie à explorer.
cyberbob
Messages : 511
Inscription : 28 nov. 2016, 19:43
Localisation : Belgique

Re: script présence non fiable

Message par cyberbob »

lost a écrit :Stratégie d'économie d'énergie plus poussée qui fait couper le wifi, gros consommateur, dès qu'il n'est pas utilisé. Maintenant, peut-être que cela se paramètre...
Exact, les nouveaux smatphone comme le S8 désactive le wifi lorsqu'il est en veille et non connecté au chargeur, ce n'est pas modifiable, enfin je n'ai pas trouver le moyen, et fait partie de la stratégie de gestion de consommation pour les batteries d'android 6 et 7.0, la gestion de présence par wifi n'est plus possible alors avec ces smartphone.

Comment as-tu fait la détection bluetooth sur les smartphones ? Tu as suivi ce tuto ? : https://www.domoticz.com/wiki/Presence_ ... gy_Beacon)

Avec quelle clé usb bluetooth ?
J'aimerais le faire via un script LUA sur un Synology.

Merci.
Domoticz Stable V4.9700 sur Synology DSM 6.2 / 2 x RFlink V48.4 - 433.92MHz(Dio/Chacon) & 433.42MHz(RTS) / Script en LUA & Blocky
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: script présence non fiable

Message par lost »

cyberbob a écrit : Comment as-tu fait la détection bluetooth sur les smartphones ? Tu as suivi ce tuto ? : https://www.domoticz.com/wiki/Presence_ ... gy_Beacon)

Avec quelle clé usb bluetooth ?
J'aimerais le faire via un script LUA sur un Synology.
Hello,

J'utilise un raspberry PI3, qui a le BT d'intégré. Donc pas de clef BT nécessaire.

Pour ma part, la détection de présence est faite via un script python qui est hors Domoticz (démarré en service Linux, car il faut conserver les étas présence/absence de chaque tel/personne en continu, ce qui serait un peu pénible en Lua+variables utilisateurs pour conserver ces états d'un appel à l'autre du script... sans compter qu'un script time, c'est une périodicité non configurable de 1mn: trop long) et s'interface avec ce dernier via l'API HTTP, qui permet de remonter les états de présences individuelles et globale (au moins un présent, ce qui agit sur le security panel/alarme) dans des switchs virtuels Domoticz.

Les points auxquels il faut faire attention sont les suivants:
-Nombre d'essais consécutifs (partant d'un état présent, pour éviter les fausses infos d'absence si un tel n'est pas vu de trmps en temps car un peu loin/bouge) & timeout: Prévoir de les régler indépendamment pour chaque tel (pour ma part, un fichier YML a une section de configuration globale et par appareil BT pour ces paramètres ainsi que l'adresse MAC à chercher...), il faut expérimenter un peu...
-Périodicité des essais: Pour ma part, toutes les 10mn partant d'un état "présent" (auquel s'ajoutera le délai du security panel, 2mn, soit activation de l'alarme entre 2 et 12mn après un départ selon comment on tombe) pour ne pas vider les batteries... et toutes les 20s si absents (peut dépendre du nb de tel a checker en boucle/retry configurés): Le BT semble saturer si on fait trop de scan par unités de temps, menant à des détections ne se faisant pas si trop d'essais trop proches.

Je ne fait pour ma part pas une inclusion BT totale, mais des scans. C'est à la fois une faiblesse (sécurité: une adresse MAC est à considérer comme une info publique pour qui est en capacité de l'écouter passivement à proximité) et une force (essayer un appairage complet de plusieurs appareils, avec gestion des retry, sur une boucle de 20s ca ne marche pas... Il faudrait sans doute 1mn ou plus, inutilisable, ca sonnerait à chaque fois qu'on rentre alors que là on est parfois topé devant le portillon, le plus souvent avant de passer la porte d'entrée... et toujours avant d'être à porté du 1er PIR placé un peu en retrait: Cela permet d'écouter si le message d’accueil, via synthèse vocale espeak, pour le possesseur du tél détecté passe tardivement... on attends alors qq secondes avant d'avancer de 2m et être à portée PIR).

Le 1er problème se limite en vérifiant d'autre(s) info(s) liées à l'appareil, pas forcément aisément anticipables par un attaquant malin qui aura spoofé une adresse MAC bluetooth.

Mais c'est aussi ce qui m'empêche de publier un script complet prêt à utiliser... qui gagnerait sans doute à devenir un plugin pour installation automatique des switch en dépendance côté Domoticz etc. Car ca marche bien, mais c'est manuel et sans l'avoir fait soit-même ca peut être un peu difficile. Par contre, c'est stable depuis 1an 1/2 et ajouter un tél c'est une modif du fichier texte yml de config et redémarrer le service...

Le coeur de la détection utilise le module python "bluetooth" et sa fonction bluetooth.lookup_name(MAC, TIMEOUT).
Répondre