Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


Recommended Posts

Posted

I'm trying to write QA to Gardena. Using the API, I get a token that is needed for authorization,

then using this token I try to get information about the location but I get a 403.

Doing the same (using the same token), e.g. in the Postman application, gets the data I need. Can anyone tell me what I'm doing wrong?

 

My code

 

Please login or register to see this code.

 

APi documentation 

Please login or register to see this link.

Posted

Maybe use the token in the authorization, like 

 

Please login or register to see this code.

 

Posted

Please login or register to see this code.

  • Topic Author
  • Posted (edited)

    Please login or register to see this code.

     

    Maybe the headers from anwer will help.

    Does anyone know if the home center sends http request directly or through some Fibaro servers?

     

     

    Even from ios shortcuts it works

     

    Please login or register to see this image.

    /monthly_2024_09/image.png.0f350497463daa04c9d0dd3f3ea638f4.png" />

    Edited by marczu_83
    • 8 months later...
    Posted

    any update on this dev ? i am trying todo the same thing and i do have some code ready that catches the refresh token but then indeed to go further it does nothing so also seeking some help.

  • Topic Author
  • Posted

    I don't remember what exactly caused the problem, but something on the DNS side, I used pihole, or adguard. I'm currently connecting to the gardena API, everything works fine

    Posted

    @marczu_83 would you mind sharing your code ? i can also share mine if you want already, i believe many are waiting on a quickapp that works for gardena :-)
    Currently i have a quickapp where you can fill in all your info and it gets you the token but i am a bit stuck since that is where it stops and does not proceed with the next command i give it.

    • 3 weeks later...
    Posted

    @marczu_83
    this is what i got untill now and it does get the token.
    i am now searching how to use the token and go towards the location data so i can then retrieve the data.

     

    -- Generic device type have no default actions to handle
     
    -- To update controls you can use method self:updateView(<component ID>, <component property>, <desired value>). Eg:  
    -- self:updateView("slider", "value", "55")
    -- self:updateView("button1", "text", "MUTE")
    -- self:updateView("label", "text", "TURNED ON")
     
    -- This is QuickApp inital method. It is called right after your QuickApp starts (after each save or on gateway startup).
    -- Here you can set some default values, setup http connection or get QuickApp variables.
    -- To learn more, please visit:
    --    *

    Please login or register to see this link.

    --    *

    Please login or register to see this link.

     
    function QuickApp:onInit()
        self:debug("QuickApp: onInit")
     
        self.username       = self:getVariable("username")
        self.password       = self:getVariable("password")
        self.client_id      = self:getVariable("client_id")
        self.client_secret  = self:getVariable("client_secret")
        self.refresh        = 3000   -- refresh time in seconds
    -- Main loop
        self:loop(self.refresh)
    end
     
    function QuickApp:loop(refresh)
       
        self:oAuthGardena(function(token)
            --self:getGardenadevicedata(token)
        end)
     
        fibaro.setTimeout(refresh * 1000, function()
            self:loop(refresh)
        end)
    end
     
    -- 1 Variables Check & Tokenrequest
     
    function QuickApp:oAuthGardena(func)
     
     local request_body = "grant_type=client_credentials&client_id="..self.client_id.."&client_secret="..self.client_secret
     
        if (self.username == "" or self.password == "" or self.client_id == "" or self.client_secret == "" or
            self.username == "-" or self.password == "-" or self.client_id == "-" or self.client_secret == "-") then
            self:error ("Credentials data is empty!")
            self:updateView("status", "text", "Credentials data is empty!")
            return 0
        end
     
        self:getGardenaResponseData("https://api.authentication.husqvarnagroup.dev/v1/oauth2/token", request_body,
            function(data)
                if (data.access_token ~= nil) then
                    self:debug("Gardena-oAuth ok, Token: "..data.access_token)
                    self:debug("Gardena-oAuth Tokentype: "..data.token_type)
                    self:debug("Gardena-oAuth Expires in: "..data.expires_in)
                    self:debug("Gardena-oAuth Provider: "..data.provider)
                    self:debug("Gardena-oAuth Userid: "..data.user_id)
                    func(data.access_token)
                else
                    self:error("Can't get token")
                end
            end
        )
    end
     
    function QuickApp:getGardenaResponseData(url, body, func)
        --self:debug("HTTP url: "..url.."; body: "..body)
        local http = net.HTTPClient()
        http:request(url, {
            options = {
                checkCertificate = true,
                method = "POST",
                headers = {
                    ['Content-Type'] = "application/x-www-form-urlencoded;charset=UTF-8"
                },
                data = body
            },
            success = function(response)
                if (response.status == 200) then
                    -- self:debug("Response: "..json.encode(response))
                    func(json.decode(response.data))
                else
                    -- self:debug("Response: "..json.encode(response))
                    self:error("Wrong status '"..response.status.."' in response!")
                end
            end,
            error = function(message)
                self:error("Connection error: " .. message)
            end
        })  
    end
     
    -- Getting Data based on one request
  • Topic Author
  • Posted

    Please login or register to see this code.

     

    Posted

    @marczu_83
    how do you update the value 

    Please login or register to see this code.

    here i am still stuck on that so the next request does not do anything.

    also when trying todo the second HTTP request it starts mixing them, not really following the code to be honest.
    could you post the complete code so i can learn ?

     

    here is what i have for the moment.

     

    -- Generic device type have no default actions to handle
     
    -- To update controls you can use method self:updateView(<component ID>, <component property>, <desired value>). Eg:  
    -- self:updateView("slider", "value", "55")
    -- self:updateView("button1", "text", "MUTE")
    -- self:updateView("label", "text", "TURNED ON")
     
    -- This is QuickApp inital method. It is called right after your QuickApp starts (after each save or on gateway startup).
    -- Here you can set some default values, setup http connection or get QuickApp variables.
    -- To learn more, please visit:
    --    *

    Please login or register to see this link.

    --    *

    Please login or register to see this link.

     
    function QuickApp:onInit()
     self:debug("QuickApp: Starting")
     self.username       = self:getVariable("username")
     self.password       = self:getVariable("password")
     self.client_id      = self:getVariable("client_id")
     self.client_secret  = self:getVariable("client_secret")
     self.Location_id    = self:setVariable("Location_id", "")
     
     self.refresh        = 3000   -- refresh time in seconds
    --- MAIN LOOP
     self:loop(self.refresh)
    end
     
    function QuickApp:loop(refresh)
     
        self:CheckFields(function(CheckFields)
        end)
        self:GetGardenaToken(function(GetGardenaToken)
        end)
        self:GetGardenaLocations(function(GetGardenaLocations)
        end)
       
        fibaro.setTimeout(refresh * 3000, function()
            self:loop(refresh)
        end)
    end
    --- CHECKING IF ALL INFORMATION IF FILLED IN
     
    function QuickApp:CheckFields()
    self:debug("Quickapp: Checking Info Fields")
        if (self.username == "" or self.password == "" or self.client_id == "" or self.client_secret == "" or
            self.username == "-" or self.password == "-" or self.client_id == "-" or self.client_secret == "-") then
            self:error ("Credentials data is empty!")
            self:updateView("status", "text", "Credentials data is empty!")
            return 0
            else print("Getting Token")
        end
    end
     
    --- GET GARDENA TOKEN
     
    function QuickApp:GetGardenaToken()
     
    local request_body = "grant_type=client_credentials&client_id="..self.client_id.."&client_secret="..self.client_secret
     
    self:debug("Quickapp: Sending request for token")
     
        local http = net.HTTPClient()
         http:request("https://api.authentication.husqvarnagroup.dev/v1/oauth2/token", {
          options = {
            method = "POST",
            checkCertificate = true,
            headers = {
              ['Content-Type'] = "application/x-www-form-urlencoded;charset=UTF-8"
            },
            data = request_body
          },
          success = function(response)
            local data = json.decode(response.data)
            self:debug(data.scope)
            Token = data.access_token
            --setInterval(function() self:renewToken() end,1000*3600) -- Renew token every hour
            print("Status", response.status)
            print("Data", response.data)
          end,
          error = function(message)
            self:error("error:", message)
          end
        })
    end
     
    function QuickApp:GetGardenaLocations()
        if self.Location_id == nil then
            -- local url = self.smart_host.."/locations"
            local url = "https://api.smart.gardena.dev/v2/locations"
            self:trace("Getting locations")
            local http = net.HTTPClient()
             http:request(url, {
                options = {
                    method = "GET",
                    headers = {
                        ["Accept"] = "application/vnd.api+json",
                        ["X-Api-Key"] = self.client_secret,
                        ["Authorization"] = "Bearer ".."Token"
                    }
                },
                success = function(response)
                    if response.status == 429 then
                        self:debug("Too many requests")
                        return
                    elseif response.status == 200 then
                        local data = json.decode(response.data)
                        self:trace("Request OK")
                        if #data.data > 0 then
                                self.location_id = data.data[1].id
                                self:trace(string.format("Location_id: %s",self.location_id))
                        else self:error("Location missing - user has not setup system")
                        end
                    end
                   
                end,
                error = function(message)
                    self:debug("Location HTTP error:", message)
                end
            })
            else
            self:debug("Location Already OK")
            end
    end

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Create New...