Freebox

Vous avez crée 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
Placez votre code entre [Quote] et {/Quote]
landaisbenj
Messages : 592
Inscription : 12 mars 2017, 19:24

Freebox

Messagepar landaisbenj » 22 mars 2018, 00:32

Hello.

J'ai commencé a adapter un script que papoo avait ramené ici.
J'ai juste nettoyer un peu et creer trois fonctions:

getOnFreebox(api)
putOnFreebox(api,data)
postOnFreebox(api)

Qui permette respectivement de récupérer des données dans une table en envoyant l'api du site, de charger une table avec l'api du site, et de demander une modification avec l'api du site.
https://dev.freebox.fr/sdk/os/

J'ai aussi réduit un peu une des fonction qui était présente:
getPeripheriquesConnectes() Elle permet de passer une adresse mac en argument et d'activer un switch si l’équipement est connecté.
J'ai aussi créer une fonction pour activer ou non l'ouverture d'un port (NAT ou Portforwarding):
portForwarding() Je souhaitais me servir de ça pour empêcher une connexion extérieur à domoticz. Mais l'autoriser seulement si je suis a hors de la maison. (Si getPeripheriquesConnectes() retourne false portForwarding() envoi true).

Si jamais ca peut interresser, ou si quelqu'un veut aller plus loin ce sera interressant.

[EDIT] Il ne devrait normalement pas avoir besoin de configuration. Le script va verifier que vous avez le droit de vous connecter a la freebox en cherchant une variable utilisateur. Si elle n'existe pas, il l'a créé et fait une demande a la freebox. Vous devez accepter cette demande sur l'ecran de la freebox. Il stock ensuite l'autorisation dans cette variable pour la recuperer a chaque connexion.

Vous pouvez mettre le script en time ou a l'activation d'un device ou autre... Si il n'a jamais ete lancé, alors vous devez au minimum le lancer une fois avant utilisation pour accepter l'autorisation de connexion a la freebox.

Voici le script:

Code : Tout sélectionner


script = ' [Freebox] ' ; commandArray={}
------------------------------------------- Condition d'ouverture ----------------------------------------------

------------------------------------------ Declaration de fonction ---------------------------------------------
debug = 1 -- LOG: nil ou 0:LOG, 1:INFO, 2:DEBUG, 3:ERROR
log('----------------------------------------------------------------------------------------------------------------------',1)
--################################################################################################################################--


--################################################################################################################################--
--##################                                    Declaration des variables                               ##################--
--################################################################################################################################--

-- Declaration des parametres FREEBOX
local FreeboxAPPID = "Domoticz.Freebox.app"
local FreeboxURL = "http://mafreebox.freebox.fr"

-- Declaration des variables
local FreeboxAPI = ""
local FreeboxSESSIONTOKEN = ""

--################################################################################################################################--
--##################                                    Declaration des fonction de base                        ##################--
--################################################################################################################################--
function io.capture(cmd, raw)
  local file = assert(io.popen(cmd, 'r'))
  local result = assert(file:read('*a'))
  file:close()
  if raw then return result end
  result = string.gsub(result, '^%s+', '')
  result = string.gsub(result, '%s+$', '')
  result = string.gsub(result, '[\n\r]+', ' ')
  return result
end

function log(txt,lvl)
    if lvl==nil or lvl==0 then
        print("<font color='green'>" .. script .. '#LOG: ' .. txt .. "</font>")
    elseif lvl>=3 then
        error(script .. ' ' .. txt)
    else
        if lvl<=debug then
            if lvl==1 then
                print("<font color='yellow'>" .. script .. '#INFO:  ' .. txt .. "</font>")
            elseif lvl==2 then
                print("<font color='red'>" .. script .. '#DEBUG: ' .. txt .. "</font>")
            end
        end
    end
end

--################################################################################################################################--
--##################                                    Fonction de connexion Freebox                           ##################--
--################################################################################################################################--

--Fonction de recuperation (Test) de l'API Freebox
--Permet de verifier la presence et l'acces à l'api de la freebox
--Arguments: URL: FreeboxURL.
--Resultats: baseAPI: url+api de base.
function FreeboxBaseAPI()
    log("FreeboxBaseAPI",2)
    local command = 'curl -s -H "Content-Type: application/json" -X GET ' .. FreeboxURL .. '/api_version'
   local output = json:decode(io.capture(command))
    log(command..'\n'..json:encode_pretty(output),2)
   
    local FreeboxBaseAPI = output.api_base_url..'v'..math.floor(tonumber(output.api_version))
   log("FreeboxBaseAPI: OK",1)
   return FreeboxBaseAPI
end

local FreeboxBaseAPI = FreeboxBaseAPI()

function FreeboxAppTokenRequestTrack(app_token,track_id)
   log("FreeboxAppTokenRequestTrack",2)
    local command = 'curl -s -H "Content-Type: application/json" -X GET ' .. FreeboxURL .. FreeboxBaseAPI .. '/login/authorize/'..track_id
   local output = json:decode(io.capture(command))
   log(command..'\n'..json:encode_pretty(output),2)
   
   
   log("FreeboxAppTokenRequestTrack: OK",1)
   local status = output.result.status
    if output.success then
       
      local FreeboxAPPToken = 'app_token:'..app_token..';track_id:'..track_id..";status:"..output.result.status
        local url = 'curl "http://'..os.execute('hostname')..'/json.htm?type=command&param=updateuservariable&vname=FreeboxAPPToken&vtype=2&vvalue='..url_encode(FreeboxAPPToken)..'" &'
        os.execute(url)
      log(FreeboxAPPToken,1)
      if status=='granted' then
          return app_token
        elseif status=='pending' then
            error("L'administrateur doit autoriser la demande d'authentification sur l'ecran de la Freebox")
        elseif status=='timeout' then
        --local url = 'curl "http://'..os.execute('hostname')..'/json.htm?type=command&param=updateuservariable&vname=FreeboxAPPToken&vtype=2&vvalue=timeout" &'
        --os.execute(url)
            error("L'administrateur n'a pas autorisé l'authentification à temps. Veuillez supprimer le FreeboxAPPToken et recommencer")
        elseif status=='unknown' then
        --local url = 'curl "http://'..os.execute('hostname')..'/json.htm?type=command&param=updateuservariable&vname=FreeboxAPPToken&vtype=2&vvalue=unknown" &'
        --os.execute(url)
            error("L'app token est invalide ou a été révoqué")
        elseif status=='denied' then
        --local url = 'curl "http://'..os.execute('hostname')..'/json.htm?type=command&param=updateuservariable&vname=FreeboxAPPToken&vtype=2&vvalue=denied" &'
        --os.execute(url)
            error("L'administrateur a refusé votre accés à la Freebox")
        else
            error('Autre erreur.')
        end
    else
        log('FreeboxAppTokenRequestTrack Erreur'..output.error_code..' - '..output.msg)
    end
end

function FreeboxAppTokenRequest()
   local auth = {}
   auth["app_id"]=FreeboxAPPID
   auth["app_name"]="Domoticz"
   auth["app_version"]="0.1"
   auth["device_name"]=io.capture('hostname')
   local jsonAuth = json:encode_pretty(auth)
   
   log("FreeboxAppTokenRequest",2)
   local command = 'curl -s -H "Content-Type: application/json" -X POST -d \'' .. jsonAuth .. '\' ' .. FreeboxURL .. FreeboxBaseAPI .. '/login/authorize/'
   local output = json:decode(io.capture(command))
   log(command..'\n'..json:encode_pretty(output),2)
   
   local app_token = output.result.app_token
   local track_id = output.result.track_id
   log("FreeboxAppTokenRequest: OK",1)
   FreeboxAppTokenRequestTrack(app_token,track_id)
end
   
--Authentification pour récupérer le Token De Session-------------------------------------------------------------------------------
--Variable: FreeboxURL; FreeboxAPPTOKEN; FreeboxAPPID
--Retourne: FreeboxSessionToken
function FreeboxConnect()
   log("Connexion à la Freebox")
   
    local FreeboxAPPToken = FreeboxAPPToken()

--Recuperation du Challenge
   log("Recuperation du challenge",2)
   local url = 'curl -s ' .. FreeboxAPI .. '/login'
   local output = json:decode(io.capture(url, false))
   log("Challenge : " .. output.result.challenge,2)
   
   local FreeboxCHALLENGE = output.result.challenge

--Hashage en sha1 du Mot De Passe via l'os
   log("Calcul du mot de passe",2)
   local url = 'echo -n ' .. FreeboxCHALLENGE .. ' | openssl dgst -sha1 -hmac ' .. FreeboxAPPToken .. ' | cut -c10-200 '
   local output = io.capture(url, false)
   log("Password : " .. output,2)
   
   local FreeboxPWD = output:gsub("\n", "")
   
--Recuperation d'un Token avec FreeboxPWD + FreeboxAPPID
   local session = {}
   session["app_id"]=FreeboxAPPID
   session["password"]=FreeboxPWD
   local jsonSession = json:encode_pretty(session)
   --Connexion à la session
   
   
   log("Recuperation du token de session",2)
   local command = 'curl -s -H "Content-Type: application/json" -X POST -d \'' .. jsonSession .. '\' ' .. FreeboxURL .. FreeboxBaseAPI .. '/login/session/'
   local output = json:decode(io.capture(command, false))
   log("Session Token : " .. output.result.session_token,1)
   
   FreeboxSessionToken = output.result.session_token
end


--Fonction de deconnexion de la Freebox-------------------------------------------------------------------------------------------
--Variable: FreeboxSessionToken; FreeboxAPI
--retour table: output
function FreeboxDisconnect()
    local command = 'curl -s -H "Content-Type: application/json" -H "X-Fbx-App-Auth: ' .. FreeboxSessionToken .. '" -X POST '..FreeboxURL .. FreeboxBaseAPI .. '/login/logout'
   local output = json:decode(io.capture(command, false))
   log('Deconnexion: '..tostring(output.success),1)
end   

----------------------------------------------------------------------------------------------------------------------
function FreeboxAPPToken()
    if uservariables['FreeboxAPPToken']==nil then
       local url = 'curl "http://'..os.execute('hostname')..'/json.htm?type=command&param=saveuservariable&vname=FreeboxAPPToken&vtype=2&vvalue=" &'
        os.execute(url)
    end
   
    local FreeboxAPPToken=uservariables['FreeboxAPPToken']
    if FreeboxAPPToken:find('status') then
        log('test')
        local key = 'status'
        local status = FreeboxAPPToken:match(key..':([^;]+)')
        local key = 'app_token'
        local app_token = FreeboxAPPToken:match(key..':([^;]+)')
        local key = 'track_id'
        local track_id = FreeboxAPPToken:match(key..':([^;]+)')
        log('app_token:'..app_token..';track_id:'..track_id..";status:"..status,1)
        if status=='granted' then
            return app_token
        else
            FreeboxAppTokenRequestTrack(app_token,track_id)
        end
    else
        FreeboxAppTokenRequest()
    end
end


--################################################################################################################################--
--##################                                    Fonction de controle Freebox                            ##################--
--################################################################################################################################--

--Fonction de recuperation de parametre freebox-----------------------------------------------------------------------------------------
--Parametre:
    --api (string) correspond à l'api du site 'https://dev.freebox.fr/sdk/os/#api-list' ex:
        -- '/api/v4/fw/redir/' (Recupere la liste du routage de port 'NAT')
--Variable: FreeboxSessionToken; FreeboxURL
--retour table: output
function getOnFreebox(api)
   local url = 'curl -s -H "Content-Type: application/json" -H "X-Fbx-App-Auth: ' .. FreeboxSessionToken .. '" -X GET ' .. FreeboxURL .. api
   local output = json:decode(io.capture(url, false))
    log('Recuperation de données freebox',1)
   log('URL: '..url..'\nRetour:\n'..json:encode_pretty(output),2)
   return output
end

--Fonction de modification de parametre freebox-----------------------------------------------------------------------------------------
--Parametre:
    --api (string) correspond à l'api du site 'https://dev.freebox.fr/sdk/os/#api-list' ex:
        -- '/api/v4/fw/redir/1' (Modifie le port avec ID=1)
    --data (table) correspond au parametre a passer dans l'api ex:
        -- data={"enabled": false} (desactive le routage de port)
--Variable: FreeboxSessionToken; FreeboxURL
--retour table: output
function putOnFreebox(api,data)
   local data = json:encode_pretty(data)
   local url = 'curl -s -H "Content-Type: application/json" -H "X-Fbx-App-Auth: ' .. FreeboxSessionToken .. '" -X PUT -d \'' .. data .. '\' '.. FreeboxURL .. api
   local output = json:decode(io.capture(url, false))
    log('Insertion de données freebox',1)
   log('URL: '..url..'\nDonnées insérées: \n'..json:encode_pretty(data)..'\nRetour:\n'..json:encode_pretty(output),2)
   return output
end

--Fonction POST parametre freebox-----------------------------------------------------------------------------------------
--Parametre:
    --api (string) correspond à l'api du site 'https://dev.freebox.fr/sdk/os/#api-list' ex:
        -- /api/v4/system/reboot/' (Reboot la freebox)
--Variable: FreeboxSESSIONTOKEN; FreeboxURL
--retour table: output
function postOnFreebox(api)
   local data = json:encode_pretty(data)
   local url = 'curl -s -H "Content-Type: application/json" -H "X-Fbx-App-Auth: ' .. FreeboxSessionToken .. '" -X POST '.. FreeboxURL .. api
   local output = json:decode(io.capture(url, false))
    log('Insertion de données freebox',1)
   log('URL: '..url..'\nRetour:\n'..json:encode_pretty(output),2)
   return output
end

--################################################################################################################################--
--##################                                    Fonction spécifique                                     ##################--
--################################################################################################################################--

-- Fonction de recherche de périphérique connecté
-- Connexion à lan/browser/pub/ recuperer l'etat de connexion d'une adresse mac
-- parametre table: user (user et mac adresse)
-- retour aucun; Activation d'un device propre à l'user
function getPeripheriquesConnectes(user)
    for user,device in pairs(user) do
        result = getOnFreebox('/api/v4/lan/browser/pub/ether-' .. device)
        if not otherdevices['Smartphone'..user] then
            --creation du device
            error('Device Smartphone '..user..': Non créé')
        end
       
        if result.l3connectivities.reachable then
            if otherdevices['Smartphone'..user]=='Off' then
                commandArray['Smartphone'..user]='On'
            end
        else
            if otherdevices['Smartphone'..user]=='On' then
                commandArray['Smartphone'..user]='Off'
            end
        end
    end
end



-- Fonction d'activation d'un routage de port (NAT)
-- parametre: id correspond a l'id de la regle; true ou false pour activer ou desactiver la regle
-- retour booleen: true ou false si succes
function portForwarding(id,enabled)
    log('Port Forwarding Ecriture',1)
   local data = {}
   data["enabled"]=enabled
   local data = json:encode_pretty(data)
    result = putOnFreebox('/api/v4/fw/redir/' .. id,data)
    return result.success
end


--################################################################################################################################--
--##################                                    Boucle principale                                       ##################--
--################################################################################################################################--
local init = false

if init then
   FreeboxConnect() -- obligatoire
   
   
   api='/api/v4/system/'
   system=getOnFreebox(api)
log('Uptime: '..system.result.uptime..' Version: '..system.result.firmware_version)
user={}
user["Benjamin"]="FF:FF:FF:FF:FF";
user["Celine"]="AA:AA:AA:AA:AA"
getPeripheriquesConnectes(user)

    --Recuperer la totalité des equipements connectés
   --api='/api/v4/lan/browser/pub'
   --getOnFreebox(api)
      
    --portForwarding(1,false)

   FreeboxDisconnect() -- obligatoire
end




log('----------------------------------------------------------------------------------------------------------------------',1) ; return commandArray



J’espère qu'on pourra en discuter pour l’agrémenter.
Dernière édition par landaisbenj le 29 mars 2018, 13:53, édité 6 fois.
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

Disable adblock

This site is supported by ads and donations.
If you see this text you are blocking our ads.
Please consider a Donation to support the site.


landaisbenj
Messages : 592
Inscription : 12 mars 2017, 19:24

Re: Freebox

Messagepar landaisbenj » 22 mars 2018, 10:56

En exemple de ce qui est possible de faire avec getOnFreebox(api):

Si on passe "/api/v4/system/" en argument api alors on aura en retour la table output:

{
"success": true,
"result": {
"mac": "F4:CA:E5:5C:EA:14",
"box_flavor": "light",
"temp_cpub": 63,
"disk_status": "active",
"box_authenticated": true,
"board_name": "fbxgw1r",
"fan_rpm": 1832,
"temp_sw": 52,
"uptime": "6 jours 22 heures 9 minutes 46 secondes",
"uptime_val": 598186,
"user_main_storage": "Disque 1",
"temp_cpum": 62,
"serial": "805400T144100853",
"firmware_version": "6.6.6"
}
}


Il suffira donc de parser output en json pour avoir des infos.
Exemple, pour recuperer l'uptime et la version de la freebox:

Code : Tout sélectionner

   
   connectToFreebox()
   api='/api/v4/system/'
   system=getOnFreebox(api)
   log('Uptime: '..system.result.uptime..' Version: '..system.result.firmware_version)
   disconnectToFreebox()
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway


Revenir vers « La Bibliothèque Scripts et Tutos »

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 3 invités