I had problems with the HACS integration for my Gardena Smart Sileno mower, and noticed that others had too. I found out a simple way to just use sensors that pull data from the API. So far I just pull data, but I will try to add automations for start & stop buttons.
This code will show status and error messages in swedish.
Edit: This will probably NOT work if you have other smart Gardena devices. Unless you make a few changes to extract correct data from the json reply.
First register at Husqvarna Developer Portal
You will then get YOUR_API_KEY and YOUR_API_SECRET.
configuration.yaml:
# Get gardena token
- platform: rest
name: gardena_token
resource: https://api.authentication.husqvarnagroup.dev/v1/oauth2/token
method: POST
scan_interval: 86400 # token expires after 24 hours
headers:
Content-Type: application/x-www-form-urlencoded
payload: grant_type=client_credentials&client_id=YOUR_API_KEY&client_secret=YOUR_API_SECRET
json_attributes:
- access_token
- token_type
- expires_in
value_template: 'ok'
# Get your gardena location ID. This value will usually never change.
- platform: command_line
name: gardena_location
scan_interval: 86460 # we do no want this to update often, because of API limit
command: >-
curl -X GET -H "Authorization:Bearer {{states.sensor.gardena_token.attributes["access_token"]}}" -H "X-Api-Key:YOUR_API_KEY" https://api.smart.gardena.dev/v1/locations
value_template: '{{ value_json.data[0].id }}'
# Get mower status and store all values as attributes in a sensor
- platform: command_line
name: gardena_status
scan_interval: 1200 # Make sure not to exceed 700 calls/week (including commands) or your api-key will be permanently disabled by the provider
command: >-
curl -H "Authorization:Bearer {{states.sensor.gardena_token.attributes["access_token"]}}" -H "X-Api-Key:YOUR_API_KEY" https://api.smart.gardena.dev/v1/locations/{{states.sensor.gardena_location.state}}
| jq '{"activity": .included[1].attributes.activity.value, "timestamp": .included[1].attributes.activity.timestamp, "operatingHours": .included[1].attributes.operatingHours.value, "status": .included[1].attributes.state.value, "batteryLevel": .included[2].attributes.batteryLevel.value, "rfLinkLevel": .included[2].attributes.rfLinkLevel.value, "lastErrorCode": (.included[1].attributes.lastErrorCode.value // "none"), "location": .data.id, "serviceId": .included[0].relationships.services.data[0].id}'
json_attributes:
- status
- activity
- timestamp
- operatingHours
- batteryLevel
- rfLinkLevel
- lastErrorCode
- location
- serviceId
value_template: '{{ value_json.activity }}'
# Make a set of sensors with values from the attributes of the gardena_status sensor
template:
- sensor:
- name: gardena_activity
state: >-
{% set mapper = {
'PAUSED' : 'Pausad med luckan stängd',
'OK_CUTTING' : 'Klipper pĂĄ schema',
'OK_CUTTING_TIMER_OVERRIDDEN' : 'Klipper utanför schema',
'OK_SEARCHING' : 'Letar efter laddstationen',
'OK_LEAVING' : 'Lämnar laddstationen',
'OK_CHARGING' : 'Fortsätter klippa när batteriet är laddat',
'PARKED_TIMER' : 'Väntar på start enligt schema',
'PARKED_PARK_SELECTED' : 'Tillsagd att inte klippa',
'PARKED_AUTOTIMER' : 'Gräset är redan välklippt',
'NONE' : 'Ett fel har inträffat' } %}
{% set state = states.sensor.gardena_status.attributes["activity"] %}
{{ mapper[state] if state in mapper else 'Unknown' }}
- name: gardena_battery
device_class: battery
unit_of_measurement: '%'
state: '{{states.sensor.gardena_status.attributes["batteryLevel"]}}'
- name: gardena_state
state: '{{states.sensor.gardena_status.attributes["status"]}}'
- name: gardena_hours
device_class: duration
unit_of_measurement: 'timmar'
state: '{{states.sensor.gardena_status.attributes["operatingHours"]}}'
- name: gardena_error
state: >-
{% set mapper = {
'none' : 'Inget',
'OUTSIDE_WORKING_AREA' : 'Utanför arbetsområdet',
'NO_LOOP_SIGNAL' : 'Ingen signal frĂĄn slingan',
'WRONG_LOOP_SIGNAL' : 'Fel slingsignal',
'WRONG_PIN_CODE' : 'Fel PIN-kod',
'TRAPPED' : 'Instängd',
'UPSIDE_DOWN' : 'Vält omkull',
'EMPTY_BATTERY' : 'Tomt batteri',
'TEMPORARILY_LIFTED' : 'Tillfälligt lyft från marken',
'LIFTED' : 'Blivit lyft frĂĄn marken',
'STUCK_IN_CHARGING_STATION' : 'Fast i laddstation',
'CHARGING_STATION_BLOCKED' : 'Laddstation blockerad',
'CUTTING_MOTOR_DRIVE_DEFECT' : 'Klippsystemet blockerat',
'CUTTING_SYSTEM_BLOCKED' : 'Klippsystemet blockerat',
'CHARGING_SYSTEM_PROBLEM' : 'Problem med laddsystemet',
'MOWER_TILTED' : 'Gräsklipparen lutad',
'ALARM_MOWER_SWITCHED_OFF' : 'Larm: Avstängd',
'ALARM_MOWER_STOPPED' : 'Larm: Stannat',
'ALARM_MOWER_LIFTED' : 'Larm: Lyfts',
'ALARM_MOWER_TILTED' : 'Larm: Lutats',
'ALARM_MOWER_IN_MOTION' : 'Larm: Flyttas',
'ALARM_OUTSIDE_GEOFENCE' : 'Larm: Utanför geofence',
'SLIPPED' : 'Gräsklipparen har halkat.',
'OFF_DISABLED' : 'Avstängd med strömbrytaren',
'OFF_HATCH_OPEN' : 'Väntar med luckan öppen',
'OFF_HATCH_CLOSED' : 'Väntar med luckan stängd',
'PARKED_DAILY_LIMIT_REACHED' : 'Max tillåten klipptid för idag' } %}
{% set state = states.sensor.gardena_status.attributes["lastErrorCode"] %}
{{ mapper[state] if state in mapper else 'Okänt fel' }}
- name: gardena_last_change
device_class: timestamp
state: '{{states.sensor.gardena_status.attributes["timestamp"]}}'
- name: gardena_signal
device_class: signal_strength
unit_of_measurement: '%'
state: '{{states.sensor.gardena_status.attributes["rfLinkLevel"]}}'
The code has a problem: On reboot of Home Assistant, all three sensors try to update at once. That will not work, as they are dependent of each other. So on reboot we need to update sensor gardena_location with a delay, and then gardena_status with an even longer delay. These two automations does the trick:
alias: Uppdatera Gardena location vid reboot
description: ""
trigger:
- platform: homeassistant
event: start
condition: []
action:
- delay: "00:00:30"
- service: homeassistant.update_entity
target:
entity_id: sensor.gardena_location
data: {}
mode: single
alias: Uppdatera Gardena status vid reboot
description: ""
trigger:
- platform: homeassistant
event: start
condition: []
action:
- delay: "00:00:59"
- service: homeassistant.update_entity
target:
entity_id: sensor.gardena_status
data: {}
mode: single
Finaly, make a lovelace card to show the data. I’m using some swedish here:
type: entities
entities:
- entity: sensor.gardena_activity
name: Aktivitet
icon: mdi:robot-mower
- entity: sensor.gardena_last_change
name: Sedan
- entity: sensor.gardena_battery
name: Laddning
- entity: sensor.gardena_signal
name: Signalstyrka
- entity: sensor.gardena_hours
name: Drifttid
- entity: sensor.gardena_error
name: Felmeddelande
icon: mdi:alert-circle
Result: