[DzVents] Freebox

Vous avez créé un script LUA dont vous êtes fier, un .sh génial, un programme Python hors du commun, un Tuto, c'est ici que vous pouvez les partager.
Soyez précis quant aux prérequis, les manips à faire pour que votre bijou fonctionne (des chmod ?, un apt-get à faire ...)
Décrivez précisément son fonctionnement.
Merci d'utiliser la balise correspondante à votre sujet : [Tuto], [Plugin], [DzVents], [LUA], [Python], [Bash] ...
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
didier3164
Messages : 15
Inscription : 02 nov. 2018, 11:28

[DzVents] Freebox

Message par didier3164 »

Bonjour,
Comme je ne connais rien à la réalisation d'un plugin python, je me suis développé un script pour gérer la Freebox que je viens partager avec ceux qui serait intéressés.
Ce script permet:
- de recevoir une notification sur votre téléphone lors d'un appel manqué.
- Eteindre/Allumer le Wifi
- Redémarrer les Freeplugs
- Redémarrer la Freebox
Je l'ai adapté à mon besoin mais vous pourrez aisément le modifier.
Tout d'abord, openssl doit être installé.
Il faut d'abord créer 5 dispositifs et saisir leur nom ou identifiant dans les variables xxxxxxxxx_idx.
Au lancement du script (la première fois uniquement) il faudra accepter l'accès de l'application sur l'écran de la Freebox.
En suivant l'exemple de la fonction de lecture des appels manqués on peut facilement accéder aux autres fonctions de l'API freebox disponible à cette adresse https://dev.freebox.fr/sdk/os/.

Code : Tout sélectionner

local appelManque_idx = xxx -- Texte
local wifiOnOff_idx = xxx -- Interrupteur wifi
local freeboxReboot_idx = xxx -- Interrupteur Bouton poussoir Reboot Freebox
local freeplugReboot_idx = xxx -- Interrupteur Bouton poussoir Reboot Freeplug
local indesirable_idx = xxx


local freeboxURL = 'http://mafreebox.freebox.fr'
return {
	on = {
	    timer = { 'every minute' },
	    devices = {wifiOnOff_idx, freeboxReboot_idx, freeplugReboot_idx},
		httpResponses = {
			'freeboxData',
			'authorisation',
			'auth_Status',
			'opensession',
			'challenge',
			'readcalls',
			'updatenewcall',
			'closesession',
			'rebootfreeplug'
		},
        shellCommandResponses = { 'password' },
	},
	logging = {
		-- level	 =   domoticz.LOG_DEBUG, -- Seulement un niveau peut être actif; commenter les autres
	    -- level	=   domoticz.LOG_INFO, 
		-- level	=   domoticz.LOG_ERROR,											
		-- level	=   domoticz.LOG_DEBUG,
		-- level	=   domoticz.LOG_MODULE_EXEC_INFO,
		marker = 'Freebox appels manqués',
	},
	data = {
	    api_request_url = { initial = '' },
	    app_token = { initial = '' },
	    track_id = { initial = 0 },
	    session_token = { initial = '' },
	    action = { initial = 0 },
	},
	execute = function(domoticz, item)
              
		if (item.isTimer or item.isDevice) then
		    if (domoticz.data.app_token == '') then
		        -- Lecture des données de la Freebox
		        domoticz.log('Lecture des données de la Freebox',domoticz.LOG_INFO)
    			domoticz.openURL({
    				url = freeboxURL..'/api_version',
    				method = 'GET',
    				callback = 'freeboxData',
    			})
	        else
    	        if item.isDevice then
                    domoticz.data.action = item.id
                end
                -- Obtenir la valeur challenge
	            domoticz.log('Obtention de la valeur challenge',domoticz.LOG_INFO)
	            domoticz.log('App_token: '..domoticz.data.app_token,domoticz.LOG_INFO)
    			domoticz.openURL({
    				url = domoticz.data.api_request_url..'/login/',
    				method = 'GET',
    				callback = 'challenge',
    			})
			end
		end
        
		if (item.isHTTPResponse) then
            -- domoticz.utils.dumpTable(item)
			if (item.ok) then
				if (item.isJSON) then
                    --domoticz.utils.dumpTable(item.json)
                    if item.callback == 'freeboxData' then
                        local major_api_version = math.floor(item.json.api_version)
                        domoticz.data.api_request_url = 'https://'..item.json.api_domain..':'..item.json.https_port..item.json.api_base_url..'v'..major_api_version
                        domoticz.log('URL des requêtes: '..domoticz.data.api_request_url,domoticz.LOG_INFO)
                        -- Demande d'authorisation
                        domoticz.log('Demande authorisation',domoticz.LOG_INFO)
            			domoticz.openURL({
            				url = domoticz.data.api_request_url..'/login/authorize/',
            				method = 'POST',
            				callback = 'authorisation',
                            postData = {
                               app_id = 'fr.freebox.domoticz',
                               app_name = 'freeboxicz',
                               app_version = '1.0.0',
                               device_name = 'Domoticz'
                            }
            			})
        		    elseif item.json.success then
    			        if item.callback == 'authorisation' then
    			            -- Lecture de status de l'authorisation
    			            domoticz.log('Token: '..item.json.result.app_token,domoticz.LOG_INFO)
    			            domoticz.log('track_id: '..item.json.result.track_id,domoticz.LOG_INFO)
        			        domoticz.data.app_token = item.json.result.app_token
        			        domoticz.data.track_id = item.json.result.track_id
        			        domoticz.log('Attente authorisation',domoticz.LOG_INFO)
                			domoticz.openURL({
                				url = domoticz.data.api_request_url..'/login/authorize/'..domoticz.data.track_id,
                				method = 'GET',
                				callback = 'auth_Status',
                			})
    			        elseif item.callback == 'auth_Status' then
    			            if item.json.result.status == 'granted' then
    			                -- Fin d'enregistrement
    			                domoticz.log('Accès autorisé',domoticz.LOG_INFO)
    			            elseif item.json.result.status == 'pending' then
    			                domoticz.log('Demande authorisation en attente',domoticz.LOG_INFO)
    			                -- Boucle de lecture du statut
                    			domoticz.openURL({
                    				url = domoticz.data.api_request_url..'/login/authorize/'..domoticz.data.track_id,
                    				method = 'GET',
                    				callback = 'auth_Status',
                    			})
                		    --elseif item.json.status == 'timeout' then
                		    --elseif item.json.status == 'denied' then
                		    else
                		        -- Erreur
                		        domoticz.log('Authorisation refusée code: '..item.json.result.status,domoticz.LOG_INFO)
                		        domoticz.data.app_token = ''
    		                end
                        elseif item.callback == 'challenge' then
                            -- Calcul du mot de passe
                            --password = hmac-sha1(app_token, challenge)
                            domoticz.log('Challenge: '..item.json.result.challenge,domoticz.LOG_INFO)
                            domoticz.log('Calcul du mot de passe avec openssl',domoticz.LOG_INFO)
                            domoticz.executeShellCommand(
                            {
                                command = 'echo -n "'..item.json.result.challenge..'" | openssl sha1 -hmac "'..domoticz.data.app_token..'" | sed "s/(stdin)= //"',
                                callback = 'password',
                                timeout = 5,
                            })
                            -- Ouverture de la session dans shellCommandResponses: Password
    	                elseif item.callback == 'opensession' then
        	                domoticz.data.session_token = item.json.result.session_token
    	                    if domoticz.data.action == 0 then
        	                    -- Lecture des appels
        	                    --   Mise a jour nouvel appel: new = false
        	                    -- puis fermeture de la session
        	                    domoticz.log('Lecture de tous les appels',domoticz.LOG_INFO)
                    			domoticz.openURL({
                                    url = domoticz.data.api_request_url..'/call/log/',
                                    method = 'GET',
                                    callback = 'readcalls',
                                    headers = { ['X-Fbx-App-Auth'] = item.json.result.session_token},
                                 })
                            elseif domoticz.data.action == wifiOnOff_idx then
                                local wifi = false
                                if domotic.devices(wifiOnOff_idx).state == 'On' then wifi = true end
                    			domoticz.openURL({
                                    url = domoticz.data.api_request_url..'/wifi/config/',
                                    method = 'PUT',
                                    postData = { ['enabled'] = wifi},
                                    callback = 'closesession',
                                    headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token},
                                 })
                            elseif domoticz.data.action == freeboxReboot_idx then
                    			domoticz.openURL({
                                    url = domoticz.data.api_request_url..'/system/reboot/',
                                    method = 'POST',
                                    callback = 'closesession',
                                    headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token},
                                 })
                            elseif domoticz.data.action == freeplugReboot_idx then
                                domoticz.log('Lecture de la liste des Freeplug',domoticz.LOG_INFO)
                    			domoticz.openURL({
                                    url = domoticz.data.api_request_url..'/freeplug/',
                                    method = 'GET',
                                    callback = 'rebootfreeplug',
                                    headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token},
                                 })
                            end
                            domoticz.data.action = 0
                        elseif item.callback == 'rebootfreeplug' then
                            domoticz.log('Initialisation des Freeplug',domoticz.LOG_INFO)
                            domoticz.utils.dumpTable(item.json.result)
                            for _, members in ipairs(item.json.result) do
                                domoticz.utils.dumpTable(members)
                                for _, freeplug in ipairs(members) do
                                
                                    domoticz.log('Initialisation du Freeplug: '..freeplug.id,domoticz.LOG_INFO)
                                    
                                    domoticz.openURL({
                                        url = domoticz.data.api_request_url..'/freeplug/'..freeplug.id..'/reset/',
                                        method = 'POST',
                                        headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token},
                                     })
                                end
                            end
                            domoticz.log('Fermeture de session après initialisation des Freeplugs',domoticz.LOG_INFO)
                			domoticz.openURL({
    				            url = domoticz.data.api_request_url..'/login/logout/',
                				method = 'POST',
                			}).afterSec(10)
                        elseif item.callback == 'closesession' then
    	                    -- Fermeture de la session
                			domoticz.openURL({
    				            url = domoticz.data.api_request_url..'/login/logout/',
                				method = 'POST',
                			})
    	                elseif item.callback == 'readcalls' then
    	                    -- Recherche du derniel appel manqué
    	                    -- Ecriture du dernier appel manqué dans un device "Text"
    	                    
    	                    local nouvelappel = 0
    				        for _, appel in ipairs(item.json.result) do
				                local appeltxt = appel.name
				                    ..' le '..os.date("%d-%m-%Y à %H:%M:%S",appel.datetime)
    				            
    				            --domoticz.utils.dumpTable(appel)
    				            --domoticz.utils.dumpTable(appel)
    				            if appel.type == 'missed' and appel.new then
    				                print(appeltxt)
        				            if appel.contact_id ~= 0 then
        				                domoticz.log('Appel manqué.',domoticz.LOG_INFO)
        				                --domoticz.utils.dumpTable(appel)
        				                nouvelappel = appel.id
        				                local texte = appel.name
        				                    ..' le '..os.date("%d-%m-%Y à %H:%M:%S",appel.datetime)
        				                domoticz.notify('Appel manqué',texte,domoticz.PRIORITY_HIGH, ' ', ' ', domoticz.NSS_FIREBASE_CLOUD_MESSAGING)
        				                domoticz.log(texte,domoticz.LOG_INFO)
        				                domoticz.devices(appelManque_idx).updateText(appel.name)
        				                break
        				            else
        				                domoticz.log('Appels indésirable de '..appel.name,domoticz.LOG_INFO)
        				                domoticz.devices(indesirable_idx).updateCounter(domoticz.devices(indesirable_idx).counter + 1)
    				                end
				                end
                            end
                            domoticz.log('Fin de recherche des appels manqués de nos contacts',domoticz.LOG_INFO)
                            if nouvelappel ~= 0 then
                                --Passer ce nouvel appel à lu: appel.new = false
                                domoticz.log('URL: '..domoticz.data.api_request_url..'/call/log/'..nouvelappel,domoticz.LOG_DEBUG)
                    			domoticz.openURL({
                                    url = domoticz.data.api_request_url..'/call/log/'..nouvelappel,
                                    method = 'PUT',
                                    postData = { ['new'] = false},
                                    callback = 'updatenewcall',
                                    headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token},
                                 })
                            else
        	                    -- Fermeture de la session
                    			domoticz.openURL({
        				            url = domoticz.data.api_request_url..'/login/logout/',
                    				method = 'POST',
                    				headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token},
                    			})
        			        end
            			    
    		            elseif item.callback == 'updatenewcall' then
    		                domoticz.log('Mise à jour nouvel appel manqué',domoticz.LOG_INFO)
    	                    -- Fermeture de la session
                			domoticz.openURL({
    				            url = domoticz.data.api_request_url..'/login/logout/',
                				method = 'POST',
                				headers = { ['X-Fbx-App-Auth'] = domoticz.data.session_token}
                			})
    			        else
    			            print('Retour: '..item.callback..' non géré.')
        			    end
    			    else
    			        domoticz.utils.dumpTable(item.json)
    			        domoticz.log(item.json.msg, domoticz.LOG_ERROR)
        	        end
				end
			else
				domoticz.log('There was a problem handling the request', domoticz.LOG_ERROR)
				domoticz.utils.dumpTable(item)
				domoticz.log(item, domoticz.LOG_ERROR)
                -- Fermeture de la session
    			domoticz.openURL({
		            url = domoticz.data.api_request_url..'/login/logout/',
    				method = 'POST',
    			})
			end
        elseif item.isShellCommandResponse then
            domoticz.log('Ouverture de la session. Password = '..item.data,domoticz.LOG_INFO)
            -- Ouverture de la session
			domoticz.openURL({
				url = domoticz.data.api_request_url..'/login/session/',
				method = 'POST',
				callback = 'opensession',
                postData = {
                    app_id = 'fr.freebox.domoticz',
                    password = item.data
                }
			})
		end

	end
}

floflobal
Messages : 9
Inscription : 29 oct. 2020, 13:51

Re: [DzVents] Freebox

Message par floflobal »

Bonjour Didier3164,

j'ai posté une demande d'aide pour créer un script qui redémarre mes freeplugs en cas de perte de connexion entre mes deux domoticz, peut-être pourras-tu m'aider vu que tu sembles gérer grave Dzevent (et la freebox) au vu de ton script.
C'est ici:
viewtopic.php?t=13305

D'avance merci si tu peux m'aider.

flo
Répondre