Add support for Neato Connected robot as a switch (#3935)
* Add support for Neato Connected robot as a switch Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com> * Add checklist items Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com> * Add missing docstring Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com> * [Neato] Add update function to retrieve robot state * Add docstring for update function + catch exception when retrieving state * Change type of HTTPError when updating state * Fix pylint errors
This commit is contained in:
parent
fae620f3b3
commit
cb47507002
3 changed files with 152 additions and 0 deletions
|
@ -292,6 +292,7 @@ omit =
|
|||
homeassistant/components/switch/edimax.py
|
||||
homeassistant/components/switch/hikvisioncam.py
|
||||
homeassistant/components/switch/mystrom.py
|
||||
homeassistant/components/switch/neato.py
|
||||
homeassistant/components/switch/netio.py
|
||||
homeassistant/components/switch/orvibo.py
|
||||
homeassistant/components/switch/pulseaudio_loopback.py
|
||||
|
|
148
homeassistant/components/switch/neato.py
Normal file
148
homeassistant/components/switch/neato.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
"""
|
||||
Support for Neato Connected Vaccums.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/switch.neato/
|
||||
"""
|
||||
import time
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from urllib.error import HTTPError
|
||||
from requests.exceptions import HTTPError as req_HTTPError
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (CONF_PASSWORD, CONF_USERNAME, STATE_OFF,
|
||||
STATE_ON, STATE_UNAVAILABLE)
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
REQUIREMENTS = ['https://github.com/jabesq/pybotvac/archive/v0.0.1.zip'
|
||||
'#pybotvac==0.0.1']
|
||||
|
||||
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
|
||||
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
|
||||
|
||||
MIN_TIME_TO_WAIT = timedelta(seconds=10)
|
||||
MIN_TIME_TO_LOCK_UPDATE = 10
|
||||
|
||||
SWITCH_TYPES = {
|
||||
'clean': ['Clean']
|
||||
}
|
||||
|
||||
DOMAIN = 'neato'
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Required(CONF_USERNAME): cv.string,
|
||||
vol.Required(CONF_PASSWORD): cv.string,
|
||||
})
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Neato platform."""
|
||||
from pybotvac import Account
|
||||
|
||||
try:
|
||||
auth = Account(config[CONF_USERNAME], config[CONF_PASSWORD])
|
||||
except HTTPError:
|
||||
_LOGGER.error("Unable to connect to Neato API")
|
||||
return False
|
||||
|
||||
dev = []
|
||||
for robot in auth.robots:
|
||||
for type_name in SWITCH_TYPES:
|
||||
dev.append(NeatoConnectedSwitch(robot, type_name))
|
||||
add_devices(dev)
|
||||
|
||||
|
||||
class NeatoConnectedSwitch(ToggleEntity):
|
||||
"""Neato Connected Switch (clean)."""
|
||||
|
||||
def __init__(self, robot, switch_type):
|
||||
"""Initialize the Neato Connected switch."""
|
||||
self.type = switch_type
|
||||
self.robot = robot
|
||||
self.lock = False
|
||||
self.last_lock_time = None
|
||||
self.graceful_state = False
|
||||
self._state = None
|
||||
|
||||
def lock_update(self):
|
||||
"""Lock the update since Neato clean takes some time to start."""
|
||||
if self.is_update_locked():
|
||||
return
|
||||
self.lock = True
|
||||
self.last_lock_time = time.time()
|
||||
|
||||
def reset_update_lock(self):
|
||||
"""Reset the update lock."""
|
||||
self.lock = False
|
||||
self.last_lock_time = None
|
||||
|
||||
def set_graceful_lock(self, state):
|
||||
"""Set the graceful state."""
|
||||
self.graceful_state = state
|
||||
self.reset_update_lock()
|
||||
self.lock_update()
|
||||
|
||||
def is_update_locked(self):
|
||||
"""Check if the update method is locked."""
|
||||
if self.last_lock_time is None:
|
||||
return False
|
||||
|
||||
if time.time() - self.last_lock_time >= MIN_TIME_TO_LOCK_UPDATE:
|
||||
self.last_lock_time = None
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state."""
|
||||
if not self._state:
|
||||
return STATE_UNAVAILABLE
|
||||
if not self._state['availableCommands']['start'] and \
|
||||
not self._state['availableCommands']['stop'] and \
|
||||
not self._state['availableCommands']['pause'] and \
|
||||
not self._state['availableCommands']['resume'] and \
|
||||
not self._state['availableCommands']['goToBase']:
|
||||
return STATE_UNAVAILABLE
|
||||
return STATE_ON if self.is_on else STATE_OFF
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self.robot.name + ' ' + SWITCH_TYPES[self.type][0]
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if device is on."""
|
||||
if self.is_update_locked():
|
||||
return self.graceful_state
|
||||
if self._state['action'] == 1 and self._state['state'] == 2:
|
||||
return True
|
||||
return False
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the device on."""
|
||||
self.set_graceful_lock(True)
|
||||
self.robot.start_cleaning()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the device off (Return Robot to base)."""
|
||||
self.robot.pause_cleaning()
|
||||
time.sleep(1)
|
||||
self.robot.send_to_base()
|
||||
|
||||
def update(self):
|
||||
"""Refresh Robot state from Neato API."""
|
||||
try:
|
||||
self._state = self.robot.state
|
||||
except req_HTTPError:
|
||||
_LOGGER.error("Unable to retrieve to Robot State.")
|
||||
self._state = None
|
||||
return False
|
|
@ -189,6 +189,9 @@ https://github.com/gadgetreactor/pyHS100/archive/ef85f939fd5b07064a0f34dfa673fa7
|
|||
# homeassistant.components.netatmo
|
||||
https://github.com/jabesq/netatmo-api-python/archive/v0.6.0.zip#lnetatmo==0.6.0
|
||||
|
||||
# homeassistant.components.switch.neato
|
||||
https://github.com/jabesq/pybotvac/archive/v0.0.1.zip#pybotvac==0.0.1
|
||||
|
||||
# homeassistant.components.sensor.sabnzbd
|
||||
https://github.com/jamespcole/home-assistant-nzb-clients/archive/616cad59154092599278661af17e2a9f2cf5e2a9.zip#python-sabnzbd==0.1
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue