Created At

Oct 21, 2017

Last Update

Dec 14, 2018

Platforms

HC 2

Views

11158

Download

239

Function

This virtual device allows to see and control the status of a Husqvarna Automower equipped with the Husqvarna Automower Connect hardware (with a GPRS connection). It is based on the official Husqvarna Automower Connect APP. 

It also pushes errors generated by the Automower. 

 

Configuration

  • Create a new LUA scene with the code below. Note down the "Scene ID".
  • Create the Variables. 
  • Import the Virtual Device. Put the Scene ID in the TCP-port configuration of the virtual device. 

Variables

The following variables should be created as "Predefined variables". The values are not important. 

  • mower1Command
  • mower1Status
  • mower1Token

Scene

The scene below is required and contains the real logic behind the virtual device. Scene should be set on "Manual". 

--[[
%% properties
%% events
%% globals
--]]
local usr = "<INSERT YOUR HUSQVARNA ACCOUNT EMAIL>"
local pwd = "<INSERT YOUR HUSQVARNA ACCOUNT PASSWORD"
local mowerindex = 1 -- 1 = first robot in account
local token_url = "https://iam-api.dss.husqvarnagroup.net/api/v3"
local api_url = "https://amc-api.dss.husqvarnagroup.net/v1"


local MowerConnect = net.HTTPClient()
local aHeaders = {['Content-Type'] = 'application/json'}
local mower_id = ""

function Login()
  local req = '{"data": {"attributes": {"password": "'.. pwd .. '","username": "'.. usr .. '"},"type": "token"}}'
  local value, modificationTime = fibaro:getGlobal('mower1Token')
  local result = json.decode(value)
  
  if (result) then
    if (os.time() < (modificationTime + result.data.attributes.expires_in - (60*60))) then
      -- Token not expired, reuse
      aHeaders = {
          ['Content-Type'] = 'application/json',
          ['Authorization'] = 'Bearer ' .. result.data.id,
          ['Authorization-Provider'] = result.data.attributes.provider
        }
      GetRobot()
      req = nil
    else
      -- Token expired, refresh
      req = '{"data":{"type":"token","attributes":{"refresh_token":"'.. result.data.attributes.refresh_token ..'"}}}'
    end
  end

  if (req) then
    -- Request or refresh token
    MowerConnect:request(token_url .. "/token", {
      options = {
        headers = aHeaders,
        method = "POST",
        data = '{"data": {"attributes": {"password": "'.. pwd .. '","username": "'.. usr .. '"},"type": "token"}}'
      }, 
      success = function(status)
        local result = json.decode(status.data)
        fibaro:setGlobal("mower1Token", status.data)
        fibaro:debug(status.data)
        aHeaders = {
            ['Content-Type'] = 'application/json',
            ['Authorization'] = 'Bearer ' .. result.data.id,
            ['Authorization-Provider'] = result.data.attributes.provider
          }
        GetRobot()
      end, --success
      error = function(error)
        fibaro:setGlobal("mower1Token", '')
      end --error
    }) --request
  end --if
end
  
function GetRobot()
  MowerConnect:request(api_url .. "/mowers", {
    options = {
      headers = aHeaders,
      method = "GET"
    }, 
    success = function(status)
      local prevResult = json.decode(fibaro:getGlobalValue("mower1Status"))
      fibaro:setGlobal("mower1Status", status.data)
      local result = json.decode(status.data)

      if result then
          if result[mowerindex] then
            mower_id = result[mowerindex].id
              
            if result[mowerindex].status.mowerStatus == "ERROR" or result[mowerindex].status.mowerStatus == "ERROR_AT_POWER_UP" then
                if prevResult[mowerindex].status.lastErrorCode ~= result[mowerindex].status.lastErrorCode then
                	-- Push once; only if error changes
	                PushError(result[mowerindex].status.lastErrorCode)
                end
            end
              
            fibaro:debug(status.data)
            local cmd = fibaro:getGlobalValue("mower1Command")
            if cmd ~= "" then
                fibaro:debug(cmd)
                DoCommand(cmd)
            end
          end
      end --if result
    end, --success
    error = function(error)
      fibaro:debug(error)
      fibaro:setGlobal("mower1Token", '')
    end --error
  }) --request
end


-- not used
function GetStatus()
  MowerConnect:request(api_url .. "/mowers/" .. mower_id .. "/status" , {
    options = {
      headers = aHeaders,
      method = "GET"
    }, 
    success = function(status)
      fibaro:debug(status.data)
      result = json.decode(status.data)
    end
})
end

function DoCommand(cmd)
  MowerConnect:request(api_url .. "/mowers/" .. mower_id .. "/control", {
    options = {
      headers = aHeaders,
      method = "POST",
      data = '{"action": "' .. cmd ..'"}}'
    }, 
    success = function(status)
        fibaro:debug(status.data)
        fibaro:setGlobal("mower1Command", "")
      end
})
end

function PushError(err)
  -- err 19: bump probleem front
  -- err 18: bump probleem back
  -- err 15: lifted
  -- err 10: Upside down
  -- err 2: Empty battery
  -- err 1: outside mowing area
    HomeCenter.PopupService.publish({
        title = 'Fout met grasmaaier',
        subtitle = '',
        contentBody = 'Grasmaaier heeft fout gegenereerd: ' .. err,
        img = 'http://husqvarnacdn.azureedge.net//qs_mh=680&mw=680&ver=00000000T000000/_$$_/media/dam/husqvarna/garden%20lawnmowers%20and%20ride-on%20mowers/robotic%20lawnmowers/2014/12/08/20/34/h310-0866.ashx',
        type = 'Warning',
        buttons = {
            { caption = 'Ok', sceneId = 0 }
        }
    })  
end

Login()

Icons

 

See http://virtualstuff.org/fibaro/icons/ for original icons.

 

29 Comments,  Want to add comment please login
4c6b4571cf862dccfc23c0508ace2995

Any update by anyone? For me there is no need to have picture perfect code, better to att least have something that is working. If someone has something that is working I would certainly appreciate if you could share it

A43192f019e76b6d1fef7b6d8a5170ad

Yes, I rewrite the code and managed to rerun it with the new API, now to share I have to also rewrite the code and remove other stuff that I use for other purposes on my HC2, and I will share with You

7e2d17fd75318b782c7fe267458ff5e2

Anyone that found a solution? Seems like the Husqvarna API key / Application is removed as well as the web adress for the api is not valid anymore.

D51f15045800db206626b8f2447d4595

I'm working on it , will be ready for couple of days .....

27f8356cd5f7a0c54a569bbe9c34828d

same problem here