Add Landroid mower
3
.gitignore
vendored
@ -10,6 +10,8 @@
|
|||||||
!*.skel
|
!*.skel
|
||||||
!alexa_*.sh
|
!alexa_*.sh
|
||||||
!/config/
|
!/config/
|
||||||
|
!/custom_components/
|
||||||
|
!/packages/
|
||||||
!/scripts/
|
!/scripts/
|
||||||
!/tileboard/
|
!/tileboard/
|
||||||
!/www/
|
!/www/
|
||||||
@ -17,6 +19,7 @@
|
|||||||
# "Force" Disallow
|
# "Force" Disallow
|
||||||
.storage/
|
.storage/
|
||||||
android/
|
android/
|
||||||
|
/custom_components/fcm-android/
|
||||||
ssh-key/
|
ssh-key/
|
||||||
|
|
||||||
ip_bans.yaml
|
ip_bans.yaml
|
||||||
|
302
config/views/landroid.yaml
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
title: Mäheroboter
|
||||||
|
path: mower
|
||||||
|
badges: []
|
||||||
|
icon: 'mdi:robot-vacuum-variant'
|
||||||
|
cards:
|
||||||
|
- type: vertical-stack
|
||||||
|
cards:
|
||||||
|
- elements:
|
||||||
|
- entity: sensor.landroid_wifi
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
left: 0%
|
||||||
|
opacity: 1
|
||||||
|
top: 0%
|
||||||
|
transform: none
|
||||||
|
title: WLAN Qualität
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_wifi
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
left: 9%
|
||||||
|
opacity: 1
|
||||||
|
top: 1%
|
||||||
|
transform: none
|
||||||
|
title: WLAN Qualität
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_bat
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
opacity: 1
|
||||||
|
right: 0%
|
||||||
|
top: 0%
|
||||||
|
transform: none
|
||||||
|
title: Akku Status
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_hans_dieter_battery
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
opacity: 1
|
||||||
|
right: 8%
|
||||||
|
top: 1%
|
||||||
|
transform: none
|
||||||
|
title: Akkuladung
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_hans_dieter_status
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-size: 150%
|
||||||
|
font-weight: bold
|
||||||
|
left: 0%
|
||||||
|
opacity: 1
|
||||||
|
top: 7%
|
||||||
|
transform: none
|
||||||
|
title: Status
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_hans_dieter_error
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-size: 150%
|
||||||
|
font-weight: bold
|
||||||
|
left: 0%
|
||||||
|
opacity: 1
|
||||||
|
top: 13%
|
||||||
|
transform: none
|
||||||
|
title: Status
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_pitch
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
opacity: 1
|
||||||
|
right: 0%
|
||||||
|
top: 9%
|
||||||
|
transform: none
|
||||||
|
title: Nicken/Тангаж
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_pitch
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
opacity: 1
|
||||||
|
right: 8%
|
||||||
|
top: 10%
|
||||||
|
transform: none
|
||||||
|
title: Nicken/Тангаж
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_roll
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
opacity: 1
|
||||||
|
right: 0%
|
||||||
|
top: 18%
|
||||||
|
transform: none
|
||||||
|
title: Rollen/Крен
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_roll
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
opacity: 1
|
||||||
|
right: 8%
|
||||||
|
top: 19%
|
||||||
|
transform: none
|
||||||
|
title: Rollen/Крен
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_yaw
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
opacity: 1
|
||||||
|
right: 0%
|
||||||
|
top: 26%
|
||||||
|
transform: none
|
||||||
|
title: Gieren/Рысканье
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_yaw
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
opacity: 1
|
||||||
|
right: 8%
|
||||||
|
top: 27%
|
||||||
|
transform: none
|
||||||
|
title: Gieren/Рысканье
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_dist_km
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
left: 31%
|
||||||
|
opacity: 1
|
||||||
|
top: 26%
|
||||||
|
transform: none
|
||||||
|
title: Gesamte Distanz
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_dist_km
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
left: 40%
|
||||||
|
opacity: 1
|
||||||
|
top: 27%
|
||||||
|
transform: none
|
||||||
|
title: Gesamte Distanz
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_totaltime
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
left: 31%
|
||||||
|
opacity: 1
|
||||||
|
top: 41%
|
||||||
|
transform: none
|
||||||
|
title: Gesamte Arbeitszeit
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_totaltime
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
left: 40%
|
||||||
|
opacity: 1
|
||||||
|
top: 40%
|
||||||
|
transform: none
|
||||||
|
title: Gesamte Arbeitszeit
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_totaltime_h
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-size: 10px
|
||||||
|
font-style: italic
|
||||||
|
font-weight: bold
|
||||||
|
left: 40%
|
||||||
|
opacity: 1
|
||||||
|
top: 45%
|
||||||
|
transform: none
|
||||||
|
title: Gesamte Arbeitszeit
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_bladetime_h
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(3, 169, 244)'
|
||||||
|
left: 31%
|
||||||
|
opacity: 1
|
||||||
|
top: 56%
|
||||||
|
transform: none
|
||||||
|
title: Klingenarbeitszeit
|
||||||
|
type: state-icon
|
||||||
|
- entity: sensor.landroid_bladetime
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-weight: bold
|
||||||
|
left: 40%
|
||||||
|
opacity: 1
|
||||||
|
top: 55%
|
||||||
|
transform: none
|
||||||
|
title: Klingenarbeitszeit
|
||||||
|
type: state-label
|
||||||
|
- entity: sensor.landroid_bladetime_h
|
||||||
|
style:
|
||||||
|
color: 'rgb(3, 169, 244)'
|
||||||
|
font-size: 10px
|
||||||
|
font-style: italic
|
||||||
|
font-weight: bold
|
||||||
|
left: 40%
|
||||||
|
opacity: 1
|
||||||
|
top: 60%
|
||||||
|
transform: none
|
||||||
|
title: Klingenarbeitszeit
|
||||||
|
type: state-label
|
||||||
|
- entity: input_boolean.landroid_sched_settings
|
||||||
|
image: /local/mower/timer-off.png
|
||||||
|
state_filter:
|
||||||
|
'off': brightness(100%) saturate(1)
|
||||||
|
'on': brightness(90%) saturate(1)
|
||||||
|
state_image:
|
||||||
|
'on': /local/mower/timer.png
|
||||||
|
style:
|
||||||
|
bottom: 4%
|
||||||
|
left: 45%
|
||||||
|
transform: 'translate(-280%, 25%) scale(0.7, 0.7)'
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
title: Mähplan
|
||||||
|
type: image
|
||||||
|
- entity: input_boolean.landroid_raindelay_settings
|
||||||
|
image: /local/mower/rainy-off.png
|
||||||
|
state_filter:
|
||||||
|
'off': brightness(100%) saturate(1)
|
||||||
|
'on': brightness(90%) saturate(1)
|
||||||
|
state_image:
|
||||||
|
'on': /local/mower/rainy.png
|
||||||
|
style:
|
||||||
|
bottom: 4%
|
||||||
|
left: 45%
|
||||||
|
transform: 'translate(-280%, -115%) scale(0.7, 0.7)'
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
title: Regenverzögerung
|
||||||
|
type: image
|
||||||
|
- icon: 'mdi:play'
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(250, 250, 250)'
|
||||||
|
bottom: 4%
|
||||||
|
left: 45%
|
||||||
|
transform: 'translate(-260%, 0%) scale(1.6, 1.6)'
|
||||||
|
tap_action:
|
||||||
|
action: call-service
|
||||||
|
service: script.landroid_start
|
||||||
|
title: Mähen
|
||||||
|
type: icon
|
||||||
|
- icon: 'mdi:pause'
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(250, 250, 250)'
|
||||||
|
bottom: 4%
|
||||||
|
left: 45%
|
||||||
|
transform: 'translate(0%, 0%) scale(1.6, 1.6)'
|
||||||
|
tap_action:
|
||||||
|
action: call-service
|
||||||
|
service: script.landroid_pause
|
||||||
|
title: Pause
|
||||||
|
type: icon
|
||||||
|
- icon: 'mdi:home'
|
||||||
|
style:
|
||||||
|
'--iron-icon-fill-color': 'rgb(250, 250, 250)'
|
||||||
|
bottom: 4%
|
||||||
|
left: 45%
|
||||||
|
transform: 'translate(260%, 0%) scale(1.6, 1.6)'
|
||||||
|
tap_action:
|
||||||
|
action: call-service
|
||||||
|
service: script.landroid_stop
|
||||||
|
title: Stop & Nach Hause fahren
|
||||||
|
type: icon
|
||||||
|
- entity: input_boolean.landroid_info_toggle
|
||||||
|
image: /local/mower/info-off.png
|
||||||
|
state_filter:
|
||||||
|
'off': brightness(100%) saturate(1)
|
||||||
|
'on': brightness(90%) saturate(1)
|
||||||
|
state_image:
|
||||||
|
'on': /local/mower/information.png
|
||||||
|
style:
|
||||||
|
bottom: 4%
|
||||||
|
left: 45%
|
||||||
|
transform: 'translate(240%, 25%) scale(0.7, 0.7)'
|
||||||
|
tap_action:
|
||||||
|
action: toggle
|
||||||
|
title: Information
|
||||||
|
type: image
|
||||||
|
image: /local/mower/landroid_flower.png
|
||||||
|
type: picture-elements
|
||||||
|
- card:
|
||||||
|
entities:
|
||||||
|
- entity: sensor.landroid_ip
|
||||||
|
- entity: sensor.landroid_sn
|
||||||
|
- entity: sensor.landroid_mac
|
||||||
|
- entity: sensor.landroid_lastupdate
|
||||||
|
- type: divider
|
||||||
|
- entity: automation.landroid_error_notification
|
||||||
|
- entity: automation.landroid_status_notification
|
||||||
|
show_header_toggle: false
|
||||||
|
title: Information
|
||||||
|
type: entities
|
||||||
|
conditions:
|
||||||
|
- entity: input_boolean.landroid_info_toggle
|
||||||
|
state: 'on'
|
||||||
|
type: conditional
|
@ -14,6 +14,8 @@ homeassistant:
|
|||||||
- ::1
|
- ::1
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
- fd00::/8
|
- fd00::/8
|
||||||
|
# landroid
|
||||||
|
packages: !include_dir_named packages
|
||||||
|
|
||||||
config:
|
config:
|
||||||
conversation:
|
conversation:
|
||||||
|
247
custom_components/landroid_cloud/__init__.py
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
"""Support for Worx Landroid Cloud based lawn mowers."""
|
||||||
|
from datetime import timedelta
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.discovery import load_platform
|
||||||
|
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||||
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
|
from homeassistant.util import slugify as util_slugify
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DEFAULT_VERIFY_SSL = True
|
||||||
|
DEFAULT_NAME = "landroid"
|
||||||
|
DOMAIN = "landroid_cloud"
|
||||||
|
LANDROID_API = "landroid_cloud_api"
|
||||||
|
SCAN_INTERVAL = timedelta(seconds=30)
|
||||||
|
FORCED_UPDATE = timedelta(minutes=30)
|
||||||
|
UPDATE_SIGNAL = "landroid_cloud_update_signal"
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
|
{
|
||||||
|
DOMAIN: vol.All(
|
||||||
|
cv.ensure_list,
|
||||||
|
[
|
||||||
|
vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_EMAIL): cv.string,
|
||||||
|
vol.Required(CONF_PASSWORD): cv.string,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_START = "start"
|
||||||
|
SERVICE_PAUSE = "pause"
|
||||||
|
SERVICE_HOME = "home"
|
||||||
|
SERVICE_CONFIG = "config"
|
||||||
|
|
||||||
|
|
||||||
|
API_WORX_SENSORS = {
|
||||||
|
"battery": {
|
||||||
|
"state": {
|
||||||
|
"battery_percent": "state",
|
||||||
|
"battery_voltage": "battery_voltage",
|
||||||
|
"battery_temperature": "battery_temperature",
|
||||||
|
"battery_charge_cycles": "charge_cycles",
|
||||||
|
"battery_charging": "charging",
|
||||||
|
},
|
||||||
|
"icon": "mdi:battery",
|
||||||
|
"unit": "%",
|
||||||
|
"device_class": None,
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"state": {"error_description": "state", "error": "error_id"},
|
||||||
|
"icon": None,
|
||||||
|
"unit": None,
|
||||||
|
"device_class": None,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"state": {
|
||||||
|
"id": "id",
|
||||||
|
"status_description": "state",
|
||||||
|
"blade_time": "blade_time",
|
||||||
|
"work_time": "work_time",
|
||||||
|
"distance": "distance",
|
||||||
|
"status": "status_id",
|
||||||
|
"updated": "last_update",
|
||||||
|
"rssi": "rssi",
|
||||||
|
"yaw": "yaw",
|
||||||
|
"roll": "roll",
|
||||||
|
"pitch": "pitch",
|
||||||
|
"gps_latitude": "latitude",
|
||||||
|
"gps_longitude": "longitude",
|
||||||
|
"rain_delay": "raindelay",
|
||||||
|
"schedule_variation": "timeextension",
|
||||||
|
"firmware": "firmware_version",
|
||||||
|
},
|
||||||
|
"icon": None,
|
||||||
|
"unit": None,
|
||||||
|
"device_class": None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
client = []
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass, config):
|
||||||
|
"""Set up the Worx Landroid Cloud component."""
|
||||||
|
import pyworxcloud
|
||||||
|
|
||||||
|
hass.data[LANDROID_API] = {}
|
||||||
|
dev = 0
|
||||||
|
|
||||||
|
for cloud in config[DOMAIN]:
|
||||||
|
cloud_email = cloud[CONF_EMAIL]
|
||||||
|
cloud_password = cloud[CONF_PASSWORD]
|
||||||
|
|
||||||
|
master = pyworxcloud.WorxCloud()
|
||||||
|
auth = await master.initialize(cloud_email, cloud_password)
|
||||||
|
|
||||||
|
if not auth:
|
||||||
|
_LOGGER.warning("Error in authentication!")
|
||||||
|
return False
|
||||||
|
|
||||||
|
num_dev = await hass.async_add_executor_job(master.enumerate)
|
||||||
|
|
||||||
|
for device in range(num_dev):
|
||||||
|
client.append(dev)
|
||||||
|
_LOGGER.debug("Connecting to device ID %s (%s)", device, cloud_email)
|
||||||
|
client[dev] = pyworxcloud.WorxCloud()
|
||||||
|
await client[dev].initialize(cloud_email, cloud_password)
|
||||||
|
await hass.async_add_executor_job(client[dev].connect, device, False)
|
||||||
|
|
||||||
|
api = WorxLandroidAPI(hass, dev, client[dev], config)
|
||||||
|
await api.async_force_update()
|
||||||
|
async_track_time_interval(hass, api.async_update, SCAN_INTERVAL)
|
||||||
|
async_track_time_interval(hass, api.async_force_update, FORCED_UPDATE)
|
||||||
|
hass.data[LANDROID_API][dev] = api
|
||||||
|
dev += 1
|
||||||
|
|
||||||
|
async def handle_start(call):
|
||||||
|
"""Handle start service call."""
|
||||||
|
if "id" in call.data:
|
||||||
|
ID = call.data["id"]
|
||||||
|
|
||||||
|
for cli in client:
|
||||||
|
attrs = vars(cli)
|
||||||
|
if attrs["id"] == ID:
|
||||||
|
cli.start()
|
||||||
|
else:
|
||||||
|
client[0].start()
|
||||||
|
|
||||||
|
hass.services.async_register(DOMAIN, SERVICE_START, handle_start)
|
||||||
|
|
||||||
|
async def handle_pause(call):
|
||||||
|
"""Handle pause service call."""
|
||||||
|
if "id" in call.data:
|
||||||
|
ID = call.data["id"]
|
||||||
|
|
||||||
|
for cli in client:
|
||||||
|
attrs = vars(cli)
|
||||||
|
if attrs["id"] == ID:
|
||||||
|
cli.pause()
|
||||||
|
else:
|
||||||
|
client[0].pause()
|
||||||
|
|
||||||
|
hass.services.async_register(DOMAIN, SERVICE_PAUSE, handle_pause)
|
||||||
|
|
||||||
|
async def handle_home(call):
|
||||||
|
"""Handle pause service call."""
|
||||||
|
if "id" in call.data:
|
||||||
|
ID = call.data["id"]
|
||||||
|
|
||||||
|
for cli in client:
|
||||||
|
attrs = vars(cli)
|
||||||
|
if attrs["id"] == ID:
|
||||||
|
cli.stop()
|
||||||
|
else:
|
||||||
|
client[0].stop()
|
||||||
|
|
||||||
|
hass.services.async_register(DOMAIN, SERVICE_HOME, handle_home)
|
||||||
|
|
||||||
|
async def handle_config(call):
|
||||||
|
"""Handle config service call."""
|
||||||
|
id = 0
|
||||||
|
sendData = False
|
||||||
|
tmpdata = {}
|
||||||
|
|
||||||
|
if "id" in call.data:
|
||||||
|
_LOGGER.debug("Data from Home Assistant: %s", call.data["id"])
|
||||||
|
|
||||||
|
for cli in client:
|
||||||
|
attrs = vars(cli)
|
||||||
|
if (attrs["id"] == call.data["id"]):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
id += 1
|
||||||
|
|
||||||
|
if "raindelay" in call.data:
|
||||||
|
tmpdata["rd"] = call.data["raindelay"]
|
||||||
|
_LOGGER.debug("Setting rain_delay for %s to %s", client[id].name, call.data["raindelay"])
|
||||||
|
sendData = True
|
||||||
|
|
||||||
|
if "timeextension" in call.data:
|
||||||
|
tmpdata["sc"] = {}
|
||||||
|
tmpdata["sc"]["p"] = call.data["timeextension"]
|
||||||
|
data = json.dumps(tmpdata)
|
||||||
|
_LOGGER.debug("Setting time_extension for %s to %s", client[id].name, call.data["timeextension"])
|
||||||
|
sendData = True
|
||||||
|
|
||||||
|
if sendData:
|
||||||
|
data = json.dumps(tmpdata)
|
||||||
|
_LOGGER.debug("Sending: %s", data)
|
||||||
|
client[id].sendData(data)
|
||||||
|
|
||||||
|
hass.services.async_register(DOMAIN, SERVICE_CONFIG, handle_config)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class WorxLandroidAPI:
|
||||||
|
"""Handle the API calls."""
|
||||||
|
|
||||||
|
def __init__(self, hass, device, client, config):
|
||||||
|
"""Set up instance."""
|
||||||
|
self._hass = hass
|
||||||
|
self._client = client
|
||||||
|
self._device = device
|
||||||
|
self.config = config
|
||||||
|
|
||||||
|
sensor_info = []
|
||||||
|
info = {}
|
||||||
|
info["name"] = util_slugify(f"{DEFAULT_NAME}_{self._client.name}")
|
||||||
|
info["friendly"] = self._client.name
|
||||||
|
info["id"] = self._device
|
||||||
|
sensor_info.append(info)
|
||||||
|
|
||||||
|
load_platform(self._hass, "sensor", DOMAIN, sensor_info, self.config)
|
||||||
|
|
||||||
|
def get_data(self, sensor_type):
|
||||||
|
"""Get data from state cache."""
|
||||||
|
methods = API_WORX_SENSORS[sensor_type]
|
||||||
|
data = {}
|
||||||
|
for prop, attr in methods["state"].items():
|
||||||
|
if hasattr(self._client, prop):
|
||||||
|
prop_data = getattr(self._client, prop)
|
||||||
|
data[attr] = prop_data
|
||||||
|
return data
|
||||||
|
|
||||||
|
async def async_update(self, now=None):
|
||||||
|
"""Update the state cache from Landroid API."""
|
||||||
|
#await self._hass.async_add_executor_job(self._client.getStatus)
|
||||||
|
dispatcher_send(self._hass, UPDATE_SIGNAL)
|
||||||
|
|
||||||
|
async def async_force_update(self, now=None):
|
||||||
|
"""Try forcing update."""
|
||||||
|
_LOGGER.debug("Forcing update for %s", self._client.name)
|
||||||
|
await self._hass.async_add_executor_job(self._client.getStatus)
|
7
custom_components/landroid_cloud/manifest.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"domain": "landroid_cloud",
|
||||||
|
"name": "Worx Landroid Cloud",
|
||||||
|
"documentation": "https://www.home-assistant.io/integrations/landroid_cloud/",
|
||||||
|
"requirements": ["pyworxcloud==1.2.17"],
|
||||||
|
"codeowners": ["@MTrab"]
|
||||||
|
}
|
127
custom_components/landroid_cloud/sensor.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
"""Support for monitoring Worx Landroid Sensors."""
|
||||||
|
import async_timeout
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.components import sensor
|
||||||
|
from homeassistant.const import STATE_UNKNOWN
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
|
from . import API_WORX_SENSORS, LANDROID_API, UPDATE_SIGNAL
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
STATE_INITIALIZING = "Initializing"
|
||||||
|
STATE_OFFLINE = "Offline"
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||||
|
"""Set up the available sensors for Worx Landroid."""
|
||||||
|
if discovery_info is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
entities = []
|
||||||
|
|
||||||
|
info = discovery_info[0]
|
||||||
|
for tSensor in API_WORX_SENSORS:
|
||||||
|
name = "{}_{}".format(info["name"].lower(), tSensor.lower())
|
||||||
|
friendly_name = "{} {}".format(info["friendly"], tSensor)
|
||||||
|
dev_id = info["id"]
|
||||||
|
api = hass.data[LANDROID_API][dev_id]
|
||||||
|
sensor_type = tSensor
|
||||||
|
_LOGGER.debug("Init Landroid %s sensor for %s", sensor_type, info["friendly"])
|
||||||
|
entity = LandroidSensor(api, name, sensor_type, friendly_name, dev_id)
|
||||||
|
entities.append(entity)
|
||||||
|
|
||||||
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
|
|
||||||
|
class LandroidSensor(Entity):
|
||||||
|
"""Class to create and populate a Landroid Sensor."""
|
||||||
|
|
||||||
|
def __init__(self, api, name, sensor_type, friendly_name, dev_id):
|
||||||
|
"""Init new sensor."""
|
||||||
|
|
||||||
|
self._api = api
|
||||||
|
self._attributes = {}
|
||||||
|
self._available = False
|
||||||
|
self._name = friendly_name
|
||||||
|
self._state = STATE_INITIALIZING
|
||||||
|
self._sensor_type = sensor_type
|
||||||
|
self._dev_id = dev_id
|
||||||
|
self.entity_id = sensor.ENTITY_ID_FORMAT.format(name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return True if entity is available."""
|
||||||
|
return self._available
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Return sensor attributes."""
|
||||||
|
return self._attributes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the sensor."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unit_of_measurement(self):
|
||||||
|
"""Return the unit of measurement of this entity, if any."""
|
||||||
|
return API_WORX_SENSORS[self._sensor_type]["unit"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Icon to use in the frontend."""
|
||||||
|
return API_WORX_SENSORS[self._sensor_type]["icon"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""Return False as entity is updated from the component."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
"""Return sensor state."""
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def update_callback(self):
|
||||||
|
"""Get new data and update state."""
|
||||||
|
self.async_schedule_update_ha_state(True)
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Connect update callbacks."""
|
||||||
|
async_dispatcher_connect(self.hass, UPDATE_SIGNAL, self.update_callback)
|
||||||
|
|
||||||
|
def _get_data(self):
|
||||||
|
"""Return new data from the api cache."""
|
||||||
|
data = self._api.get_data(self._sensor_type)
|
||||||
|
self._available = True
|
||||||
|
return data
|
||||||
|
|
||||||
|
async def async_update(self):
|
||||||
|
"""Update the sensor."""
|
||||||
|
_LOGGER.debug("Updating %s", self.entity_id)
|
||||||
|
data = self._get_data()
|
||||||
|
if "state" in data:
|
||||||
|
_LOGGER.debug(data)
|
||||||
|
state = data.pop("state")
|
||||||
|
_LOGGER.debug("Mower %s State %s", self._name, state)
|
||||||
|
self._attributes.update(data)
|
||||||
|
self._state = state
|
||||||
|
else:
|
||||||
|
_LOGGER.debug("No data received for %s", self.entity_id)
|
||||||
|
reachable = self._api._client.online
|
||||||
|
if not reachable:
|
||||||
|
if "_battery" in self.entity_id:
|
||||||
|
self._state = "Unknown"
|
||||||
|
else:
|
||||||
|
self._state = STATE_OFFLINE
|
||||||
|
#else:
|
||||||
|
# attrs = vars(self._api._client)
|
||||||
|
# for item in attrs:
|
||||||
|
# _LOGGER.debug("%s : %s", item, attrs[item])
|
30
custom_components/landroid_cloud/services.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
start:
|
||||||
|
description: Start mowing
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
description: Landroid ID. Found as attribute on the Landroid status sensor
|
||||||
|
example: 123435
|
||||||
|
pause:
|
||||||
|
description: Pause mowing
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
description: Landroid ID. Found as attribute on the Landroid status sensor
|
||||||
|
example: 123435
|
||||||
|
home:
|
||||||
|
description: Send Landroid home
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
description: Landroid ID. Found as attribute on the Landroid status sensor
|
||||||
|
example: 123435
|
||||||
|
config:
|
||||||
|
description: Set config parameters
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
description: Landroid ID. Found as attribute on the Landroid status sensor
|
||||||
|
example: 123435
|
||||||
|
raindelay:
|
||||||
|
description: Set rain delay. Time in minutes ranging from 0 to 300. 0 = Disabled
|
||||||
|
example: 30
|
||||||
|
timeextension:
|
||||||
|
description: Set time extension. Extension in % ranging from -100 to 100
|
||||||
|
example: -23
|
355
packages/landroid.yaml
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
# Worx Landroid (M500 WR141E) package
|
||||||
|
# https://github.com/Barma-lej/halandroid
|
||||||
|
# Based on Landroid Bridge @MTrab virtualzone
|
||||||
|
# https://github.com/MTrab/landroid_cloud
|
||||||
|
|
||||||
|
# Cloud #############################################################
|
||||||
|
landroid_cloud:
|
||||||
|
email: !secret landroid_mail
|
||||||
|
password: !secret landroid_pass
|
||||||
|
|
||||||
|
# Switch ############################################################
|
||||||
|
switch:
|
||||||
|
- platform: template
|
||||||
|
switches:
|
||||||
|
landroid_mowing:
|
||||||
|
value_template: "{{ is_state_attr('sensor.landroid_hans_dieter_status', 'status_id', 7) }}"
|
||||||
|
turn_on:
|
||||||
|
service: script.landroid_start
|
||||||
|
turn_off:
|
||||||
|
service: script.landroid_stop
|
||||||
|
|
||||||
|
# Sensor ############################################################
|
||||||
|
# sensor.landroid_hans_dieter_battery
|
||||||
|
# sensor.landroid_hans_dieter_error
|
||||||
|
# sensor.landroid_hans_dieter_status
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
sensors:
|
||||||
|
|
||||||
|
# Info ############
|
||||||
|
landroid_ip:
|
||||||
|
friendly_name: "IP Address"
|
||||||
|
value_template: !secret landroid_ip
|
||||||
|
icon_template: "mdi:ip-network"
|
||||||
|
|
||||||
|
landroid_sn:
|
||||||
|
friendly_name: "Landroid SN"
|
||||||
|
value_template: !secret landroid_sn
|
||||||
|
icon_template: "mdi:numeric"
|
||||||
|
|
||||||
|
landroid_mac:
|
||||||
|
friendly_name: "Landroid MAC"
|
||||||
|
value_template: !secret landroid_mac
|
||||||
|
icon_template: "mdi:barcode"
|
||||||
|
|
||||||
|
# Battery #########
|
||||||
|
# landroid_batvoltage:
|
||||||
|
# friendly_name: "Landroid BatVoltage"
|
||||||
|
# value_template: "{{ state_attr('sensor.landroid_hans_dieter_battery', 'battery_voltage') }}"
|
||||||
|
# icon_template: "mdi:battery-charging-100"
|
||||||
|
# unit_of_measurement: "V"
|
||||||
|
|
||||||
|
# landroid_battemp:
|
||||||
|
# friendly_name: "Landroid BatTemp"
|
||||||
|
# value_template: "{{ state_attr('sensor.landroid_hans_dieter_battery', 'battery_temperature') }}"
|
||||||
|
# unit_of_measurement: "°C"
|
||||||
|
# device_class: "temperature"
|
||||||
|
|
||||||
|
# landroid_batchargecycles:
|
||||||
|
# friendly_name: "Landroid batChargeCycles"
|
||||||
|
# value_template: "{{ state_attr('sensor.landroid_hans_dieter_battery', 'charge_cycles') }}"
|
||||||
|
# icon_template: "mdi:power-plug"
|
||||||
|
|
||||||
|
# landroid_batcharging:
|
||||||
|
# friendly_name: "Landroid BatCharging"
|
||||||
|
# value_template: "{{ state_attr('sensor.landroid_hans_dieter_battery', 'charging') }}"
|
||||||
|
|
||||||
|
landroid_bat:
|
||||||
|
friendly_name: "Battery level"
|
||||||
|
value_template: >-
|
||||||
|
{% if is_state_attr('sensor.landroid_hans_dieter_battery', 'charging', 1) -%}Lädt
|
||||||
|
{%- else -%}Entlädt
|
||||||
|
{%- endif %}
|
||||||
|
icon_template: >-
|
||||||
|
{% if is_state_attr('sensor.landroid_hans_dieter_battery', 'charging', 1) -%}
|
||||||
|
{%- if states('sensor.landroid_hans_dieter_battery')|float > 99 -%}mdi:battery-charging-100
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 89 -%}mdi:battery-charging-90
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 79 -%}mdi:battery-charging-80
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 69 -%}mdi:battery-charging-70
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 59 -%}mdi:battery-charging-60
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 49 -%}mdi:battery-charging-50
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 39 -%}mdi:battery-charging-40
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 29 -%}mdi:battery-charging-30
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 19 -%}mdi:battery-charging-20
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 9 -%}mdi:battery-charging-10
|
||||||
|
{%- else -%}mdi:battery-charging-outline
|
||||||
|
{%- endif %}
|
||||||
|
{%- else -%}
|
||||||
|
{%- if states('sensor.landroid_hans_dieter_battery')|float > 99 -%}mdi:battery
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 89 -%}mdi:battery-90
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 79 -%}mdi:battery-80
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 69 -%}mdi:battery-70
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 59 -%}mdi:battery-60
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 49 -%}mdi:battery-50
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 39 -%}mdi:battery-40
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 29 -%}mdi:battery-30
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 19 -%}mdi:battery-20
|
||||||
|
{%- elif states('sensor.landroid_hans_dieter_battery')|float > 9 -%}mdi:battery-10
|
||||||
|
{%- else -%}mdi:battery-outline
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# Status ##########
|
||||||
|
landroid_bladetime:
|
||||||
|
friendly_name: "Landroid BladeTime"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'blade_time') }}"
|
||||||
|
icon_template: "mdi:fan"
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
|
||||||
|
landroid_bladetime_h:
|
||||||
|
friendly_name: "Landroid BladeTime"
|
||||||
|
value_template: >
|
||||||
|
{% set t = states('sensor.landroid_bladetime') | int %}
|
||||||
|
{% if t == 0 %}
|
||||||
|
Unavailable
|
||||||
|
{% elif t > 60 %}
|
||||||
|
{{ t // 1440 }} Tg. {{ (t % 1440) // 60 }} Std. {{ t % 60 }} Min.
|
||||||
|
{% endif %}
|
||||||
|
icon_template: "mdi:fan"
|
||||||
|
unit_of_measurement: ""
|
||||||
|
|
||||||
|
landroid_totaltime:
|
||||||
|
friendly_name: "Landroid TotalTime"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'work_time') }}"
|
||||||
|
icon_template: "mdi:bus-clock"
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
|
||||||
|
landroid_totaltime_h:
|
||||||
|
friendly_name: "Landroid TotalTime"
|
||||||
|
value_template: >
|
||||||
|
{% set t = states('sensor.landroid_totaltime') | int %}
|
||||||
|
{% if t == 0 %}
|
||||||
|
Unavailable
|
||||||
|
{% elif t > 60 %}
|
||||||
|
{{ t // 1440 }} Tg. {{ (t % 1440) // 60 }} Std. {{ t % 60 }} Min.
|
||||||
|
{% endif %}
|
||||||
|
icon_template: "mdi:bus-clock"
|
||||||
|
unit_of_measurement: ""
|
||||||
|
|
||||||
|
landroid_dist:
|
||||||
|
friendly_name: "Landroid Dist"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'distance') }}"
|
||||||
|
icon_template: "mdi:map-marker-distance"
|
||||||
|
unit_of_measurement: "m"
|
||||||
|
|
||||||
|
landroid_dist_km:
|
||||||
|
friendly_name: "Landroid Dist"
|
||||||
|
value_template: "{{ (states('sensor.landroid_dist') | float) / 1000 }}"
|
||||||
|
icon_template: "mdi:map-marker-distance"
|
||||||
|
unit_of_measurement: "km"
|
||||||
|
|
||||||
|
landroid_lastupdate:
|
||||||
|
friendly_name: "Last update"
|
||||||
|
value_template: "{{ as_timestamp(strptime( state_attr('sensor.landroid_hans_dieter_status', 'last_update'), '%H:%M:%S %d/%m/%Y')) | timestamp_custom('%d.%m.%Y %H:%M:%S') }}"
|
||||||
|
icon_template: "mdi:clock"
|
||||||
|
|
||||||
|
# -55 or higher: 4 bars
|
||||||
|
# -56 to -66: 3 bars
|
||||||
|
# -67 to -77: 2 bars
|
||||||
|
# -78 to -88: 1 bar
|
||||||
|
# -89 or lower: 0 bars
|
||||||
|
landroid_wifi:
|
||||||
|
friendly_name: "Wifi quality"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'rssi') }}"
|
||||||
|
icon_template: >-
|
||||||
|
{% if state_attr('sensor.landroid_hans_dieter_status', 'rssi')|float > -56 -%}mdi:wifi-strength-4
|
||||||
|
{% elif state_attr('sensor.landroid_hans_dieter_status', 'rssi')|float > -67 -%}mdi:wifi-strength-3
|
||||||
|
{% elif state_attr('sensor.landroid_hans_dieter_status', 'rssi')|float > -78 -%}mdi:wifi-strength-2
|
||||||
|
{% elif state_attr('sensor.landroid_hans_dieter_status', 'rssi')|float > -89 -%}mdi:wifi-strength-1
|
||||||
|
{%- else -%}mdi:wifi-strength-outline
|
||||||
|
{%- endif %}
|
||||||
|
unit_of_measurement: "dBm"
|
||||||
|
|
||||||
|
landroid_yaw:
|
||||||
|
friendly_name: "Landroid Yaw"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'yaw') }}"
|
||||||
|
icon_template: "mdi:axis-z-rotate-clockwise"
|
||||||
|
unit_of_measurement: "°"
|
||||||
|
|
||||||
|
landroid_roll:
|
||||||
|
friendly_name: "Landroid Roll"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'roll') }}"
|
||||||
|
icon_template: "mdi:axis-x-rotate-clockwise"
|
||||||
|
unit_of_measurement: "°"
|
||||||
|
|
||||||
|
landroid_pitch:
|
||||||
|
friendly_name: "Landroid Pitch"
|
||||||
|
value_template: "{{ state_attr('sensor.landroid_hans_dieter_status', 'pitch') }}"
|
||||||
|
icon_template: "mdi:seat-flat-angled"
|
||||||
|
unit_of_measurement: "°"
|
||||||
|
|
||||||
|
# Input Boolean #####################################################
|
||||||
|
input_boolean:
|
||||||
|
landroid_raindelay_settings:
|
||||||
|
name: Raindelay Settings
|
||||||
|
icon: "mdi:file-hidden"
|
||||||
|
initial: false
|
||||||
|
landroid_timext_settings:
|
||||||
|
name: TimeExt Settings
|
||||||
|
icon: "mdi:file-hidden"
|
||||||
|
initial: false
|
||||||
|
landroid_sched_settings:
|
||||||
|
name: Scheduler Settings
|
||||||
|
icon: "mdi:file-hidden"
|
||||||
|
initial: false
|
||||||
|
landroid_info_toggle:
|
||||||
|
name: Info toggle
|
||||||
|
icon: "mdi:file-hidden"
|
||||||
|
initial: false
|
||||||
|
|
||||||
|
# Automations #######################################################
|
||||||
|
automation:
|
||||||
|
- id: "landroid_status_notify"
|
||||||
|
alias: "Landroid Status Notification"
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: sensor.landroid_hans_dieter_status
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.to_state.state != trigger.from_state.state }}"
|
||||||
|
action:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data_template:
|
||||||
|
title: Lanroid Status
|
||||||
|
message: "{{ trigger.from_state.state }} -> {{ trigger.to_state.state }} - {{ states('sensor.date_time') }}"
|
||||||
|
|
||||||
|
- id: "landroid_error_notify"
|
||||||
|
alias: "Landroid Error Notification"
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: sensor.landroid_hans_dieter_error
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.to_state.state != trigger.from_state.state }}"
|
||||||
|
action:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data_template:
|
||||||
|
title: Lanroid Status
|
||||||
|
message: "{{ trigger.from_state.state }} -> {{ trigger.to_state.state }} - {{ states('sensor.date_time') }}"
|
||||||
|
|
||||||
|
# Scripts ###########################################################
|
||||||
|
script:
|
||||||
|
# landroid_cloud.start
|
||||||
|
# landroid_cloud.stop
|
||||||
|
# landroid_cloud.pause
|
||||||
|
|
||||||
|
# Starts the mower
|
||||||
|
landroid_start:
|
||||||
|
alias: "Start the mower"
|
||||||
|
sequence:
|
||||||
|
service: landroid_cloud.start
|
||||||
|
data:
|
||||||
|
id: 473913
|
||||||
|
|
||||||
|
# Stops the mower and sends it home
|
||||||
|
landroid_stop:
|
||||||
|
alias: "Stop the mower"
|
||||||
|
sequence:
|
||||||
|
service: landroid_cloud.stop
|
||||||
|
data:
|
||||||
|
id: 473913
|
||||||
|
|
||||||
|
# Pause the mower
|
||||||
|
landroid_pause:
|
||||||
|
alias: "Pause the mower"
|
||||||
|
sequence:
|
||||||
|
service: landroid_cloud.pause
|
||||||
|
data:
|
||||||
|
id: 473913
|
||||||
|
|
||||||
|
# Customize #########################################################
|
||||||
|
homeassistant:
|
||||||
|
customize:
|
||||||
|
# Sensor ##########
|
||||||
|
sensor.landroid_hans_dieter_battery:
|
||||||
|
friendly_name: "Akkuladung"
|
||||||
|
sensor.landroid_hans_dieter_error:
|
||||||
|
friendly_name: "Fehler"
|
||||||
|
sensor.landroid_hans_dieter_status:
|
||||||
|
friendly_name: "Status"
|
||||||
|
|
||||||
|
sensor.landroid_ip:
|
||||||
|
friendly_name: "IP-Adresse"
|
||||||
|
sensor.landroid_sn:
|
||||||
|
friendly_name: "Seriennummer"
|
||||||
|
sensor.landroid_mac:
|
||||||
|
friendly_name: "MAC-Adresse"
|
||||||
|
|
||||||
|
# sensor.landroid_batvoltage:
|
||||||
|
# friendly_name: "Akkuspannung"
|
||||||
|
# sensor.landroid_battemp:
|
||||||
|
# friendly_name: "Akkutemperatur"
|
||||||
|
# sensor.landroid_batchargecycles:
|
||||||
|
# friendly_name: "Akkuladungen"
|
||||||
|
# sensor.landroid_batcharging:
|
||||||
|
# friendly_name: "Akkustatus"
|
||||||
|
sensor.landroid_bat:
|
||||||
|
friendly_name: "Akkuladung"
|
||||||
|
|
||||||
|
sensor.landroid_bladetime:
|
||||||
|
friendly_name: "Klingenarbeitszeit"
|
||||||
|
sensor.landroid_bladetime_h:
|
||||||
|
friendly_name: "Klingenarbeitszeit"
|
||||||
|
sensor.landroid_totaltime:
|
||||||
|
friendly_name: "Arbeitszeit"
|
||||||
|
sensor.landroid_totaltime_h:
|
||||||
|
friendly_name: "Arbeitszeit"
|
||||||
|
sensor.landroid_dist:
|
||||||
|
friendly_name: "Ges. Distanz"
|
||||||
|
sensor.landroid_dist_km:
|
||||||
|
friendly_name: "Ges. Distanz"
|
||||||
|
sensor.landroid_lastupdate:
|
||||||
|
friendly_name: "Aktualisiert seit"
|
||||||
|
icon: "mdi:update"
|
||||||
|
sensor.landroid_wifi:
|
||||||
|
friendly_name: "WLAN Qualität"
|
||||||
|
sensor.landroid_pitch:
|
||||||
|
friendly_name: "Nicken/Тангаж"
|
||||||
|
sensor.landroid_roll:
|
||||||
|
friendly_name: "Rollen/Крен"
|
||||||
|
sensor.landroid_yaw:
|
||||||
|
friendly_name: "Gieren/Рысканье"
|
||||||
|
|
||||||
|
# Input Boolean ###
|
||||||
|
input_boolean.landroid_raindelay_settings:
|
||||||
|
friendly_name: "Regenverzögerung"
|
||||||
|
input_boolean.landroid_timext_settings:
|
||||||
|
friendly_name: "Zeiterhöhung"
|
||||||
|
input_boolean.landroid_sched_settings:
|
||||||
|
friendly_name: "Mähplan"
|
||||||
|
input_boolean.landroid_info_toggle:
|
||||||
|
friendly_name: "Information"
|
||||||
|
|
||||||
|
# Automation ######
|
||||||
|
automation.landroid_status_notification:
|
||||||
|
friendly_name: "Landroid Status Benachrichtigung"
|
||||||
|
icon: "mdi:bell"
|
||||||
|
automation.landroid_error_notification:
|
||||||
|
friendly_name: "Landroid Fehler Benachrichtigung"
|
||||||
|
icon: "mdi:bell"
|
||||||
|
|
||||||
|
# Scripts #########
|
||||||
|
script.landroid_start:
|
||||||
|
friendly_name: "Mähen"
|
||||||
|
icon: "mdi:play"
|
||||||
|
script.landroid_pause:
|
||||||
|
friendly_name: "Mähen pausieren"
|
||||||
|
icon: "mdi:home"
|
||||||
|
script.landroid_stop:
|
||||||
|
friendly_name: "Mähen beenden"
|
||||||
|
icon: "mdi:home"
|
@ -10,6 +10,7 @@ views:
|
|||||||
- !include config/views/spotify.yaml
|
- !include config/views/spotify.yaml
|
||||||
- !include config/views/instagram.yaml
|
- !include config/views/instagram.yaml
|
||||||
- !include config/views/devices.yaml
|
- !include config/views/devices.yaml
|
||||||
|
- !include config/views/landroid.yaml
|
||||||
- !include config/views/cctv.yaml
|
- !include config/views/cctv.yaml
|
||||||
- !include config/views/alerts.yaml
|
- !include config/views/alerts.yaml
|
||||||
|
|
||||||
|
BIN
www/mower/clock-off.png
Normal file
After Width: | Height: | Size: 966 B |
BIN
www/mower/clock-start.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
www/mower/halandroid.png
Normal file
After Width: | Height: | Size: 1011 KiB |
BIN
www/mower/info-off.png
Normal file
After Width: | Height: | Size: 834 B |
BIN
www/mower/information.png
Normal file
After Width: | Height: | Size: 940 B |
BIN
www/mower/landroid_flower.png
Normal file
After Width: | Height: | Size: 574 KiB |
BIN
www/mower/landroid_flower.webp
Normal file
After Width: | Height: | Size: 441 KiB |
BIN
www/mower/rainy-off.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
www/mower/rainy.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www/mower/side_k_lader.jpg
Normal file
After Width: | Height: | Size: 400 KiB |
BIN
www/mower/side_k_lader.webp
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
www/mower/side_m_lader.jpg
Normal file
After Width: | Height: | Size: 940 KiB |
BIN
www/mower/timer-off.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www/mower/timer.png
Normal file
After Width: | Height: | Size: 1.1 KiB |