This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Husqvarna lawn robot mover API
#1
Hi @all,

I want to connect my Husqvarna lawn robot to LM. 

There is an existing API which is documented here: https://developer.husqvarnagroup.cloud/a...onnect-api

I think I'm not fare away from the goal to start and stop the robot via LM but I struggling with the payload. 

After I registrated to Husqvarna development portal I created a script to find out the mover-id:

Code:
local https = require('ssl.https')
local json = require('json')

-- Husqvarna Authentication API
local authEndpoint = 'https://api.authentication.husqvarnagroup.dev/v1/oauth2/token'
local clientId = 'XXX'
local clientSecret = 'XXX

-- Husqvarna Automower Connect API
local mowersEndpoint = 'https://api.amc.husqvarna.dev/v1/mowers'

local accessToken

-- Funktion zum Erhalten eines Zugriffstokens
function getAccessToken()
    local requestBody = 'grant_type=client_credentials'
        .. '&client_id=' .. clientId
        .. '&client_secret=' .. clientSecret

    local response_body = {}
    local _, code, _, _ = https.request{
        url = authEndpoint,
        method = 'POST',
        headers = {
            ['Content-Type'] = 'application/x-www-form-urlencoded',
            ['Content-Length'] = #requestBody
        },
        source = ltn12.source.string(requestBody),
        sink = ltn12.sink.table(response_body)
    }
log (code, status, headers, response_body)


    if code == 200 then
        local response = table.concat(response_body)
        local jsonResponse = json.decode(response)
        accessToken = jsonResponse.access_token
    else
        -- Fehlerbehandlung
        print('Fehler beim Abrufen des Zugriffstokens:', code)
    end
end

-- Funktion zum Abrufen der Mower-IDs
function getMowerIds()
    local response_body = {}
    local _, code, _, _ = https.request{
        url = mowersEndpoint,
        method = 'GET',
        headers = {
            ['Authorization'] = 'Bearer ' .. accessToken,
            ['X-Api-Key'] = clientId,
            ['Authorization-Provider'] = 'husqvarna'
        },
        sink = ltn12.sink.table(response_body)
    }
log (code, status, headers, response_body)



    if code == 200 then
        local response = table.concat(response_body)
    log(response)
        local jsonResponse = json.decode(response)
       
        for _, mower in ipairs(jsonResponse.data) do
            local mowerId = mower.id
            -- Verarbeiten Sie die Mower-ID hier nach Bedarf
            print('Mower-ID:', mowerId)
           
        log(mowerId)
        end
    else
        -- Fehlerbehandlung
        print('Fehler beim Abrufen der Mower-IDs:', code)
    end
end

-- Beispielaufrufe
getAccessToken()
getMowerIds()

In the second step I tried to write a script to start and stop the robot:

Code:
local https = require('ssl.https')
local json = require('json')

-- Husqvarna Authentication API
local authEndpoint = 'https://api.authentication.husqvarnagroup.dev/v1/oauth2/token'
local clientId = 'xxx
local clientSecret = 'xxx'
local moverID = 'xxx'

-- Husqvarna Automower Connect API
local connectEndpoint = 'https://api.amc.husqvarna.dev/v1/mowers/ba15739b-0449-411a-9eb9-9ad866362075/actions'
local accessToken

-- Funktion zum Erhalten eines Zugriffstokens
function getAccessToken()
    local requestBody = 'grant_type=client_credentials'
        .. '&client_id=' .. clientId
        .. '&client_secret=' .. clientSecret

    local response_body = {}
    local _, code, _, _ = https.request{
        url = authEndpoint,
        method = 'POST',
        headers = {
            ['Content-Type'] = 'application/x-www-form-urlencoded',
            ['Content-Length'] = #requestBody
        },
        source = ltn12.source.string(requestBody),
        sink = ltn12.sink.table(response_body)
    }

    if code == 200 then
        local response = table.concat(response_body)
        local jsonResponse = json.decode(response)
        accessToken = jsonResponse.access_token
    else
        -- Fehlerbehandlung
        log('Fehler beim Abrufen des Zugriffstokens:', code)
    end
end

-- Funktion zum Senden des Startbefehls
function sendStartCommand()
    local requestBody = '{"action":"start"}'

    local response_body = {}
    local _, code, _, _ = https.request{
        url = connectEndpoint,
        method = 'POST',
        headers = {
            ['Authorization'] = 'Bearer ' .. accessToken,
            ['X-Api-Key'] = clientId,
            ['Authorization-Provider'] = 'husqvarna',
            ['Content-Type'] = 'application/json',
            ['Content-Length'] = #requestBody
        },
        source = ltn12.source.string(requestBody),
        sink = ltn12.sink.table(response_body)
    }
   
log (code, status, headers, response_body)



    if code == 200 then
        -- Erfolgreich gestartet
        log('Automower wurde gestartet.')
    else
        -- Fehlerbehandlung
        log('Fehler beim Starten des Automowers:', code)
    end
end

-- Funktion zum Senden des Stopbefehls
function sendStopCommand()
    local requestBody = '{"name": "stop"}'

    local response_body = {}
    local _, code, _, _ = https.request{
        url = connectEndpoint,
        method = 'POST',
        headers = {
            ['Authorization'] = 'Bearer ' .. accessToken,
            ['X-Api-Key'] = clientId,
            ['Authorization-Provider'] = 'husqvarna',
            ['Content-Type'] = 'application/json',
            ['Content-Length'] = #requestBody
        },
        source = ltn12.source.string(requestBody),
        sink = ltn12.sink.table(response_body)
    }
    log (code, status, headers, response_body)



    if code == 200 then
        -- Erfolgreich gestoppt
        log('Automower wurde gestoppt.')
    else
        -- Fehlerbehandlung
        log('Fehler beim Stoppen des Automowers:', code)
    end
end

-- Beispielaufrufe
getAccessToken()
sendStartCommand()


If I call the script to start the robot I getting the following failures:

Code:
Automover  10.06.2023 15:12:33
* arg: 1
  * number: 400
* arg: 2
  * nil
* arg: 3
  * nil
* arg: 4
  * table:
   [1]
    * string: {"errors":[{"id":"f211fb25-ae93-44e7-820f-ccb35adb2484","status":"400","code":"illegal.argument","title":"Illegal argument","detail":"Unsupported Media Type. Likely an invalid Content-Type header value. Use 'application/vnd.api+json' or 'application/json' depending on endpoint."}]}
Automover  10.06.2023 15:12:33
* arg: 1
  * string: Fehler beim Starten des Automowers:
* arg: 2
  * number: 400

Do you have any idea what I making wrong and need to change? 

Many thanks for your help!

Best Regards
Steffen
Reply


Messages In This Thread
Husqvarna lawn robot mover API - by pioneersteffen - 10.06.2023, 13:15
RE: Husqvarna lawn robot mover API - by admin - 12.06.2023, 12:27
RE: Husqvarna lawn robot mover API - by admin - 16.06.2023, 07:33
RE: Husqvarna lawn robot mover API - by Joep - 31.07.2023, 14:40
RE: Husqvarna lawn robot mover API - by admin - 19.06.2023, 08:00
RE: Husqvarna lawn robot mover API - by Joep - 06.09.2023, 15:38

Forum Jump: