mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Bump pybotvac and use new exceptions (#27249)
* Bump pybotvac * Fix tests * Remove super calls * Surround some more statements * Correct logger message for vacuum
This commit is contained in:
parent
1059cea28f
commit
dae8cd8801
@ -13,7 +13,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_credentials": "Invalid credentials"
|
"invalid_credentials": "Invalid credentials",
|
||||||
|
"unexpected_error": "Unexpected error"
|
||||||
},
|
},
|
||||||
"create_entry": {
|
"create_entry": {
|
||||||
"default": "See [Neato documentation]({docs_url})."
|
"default": "See [Neato documentation]({docs_url})."
|
||||||
|
@ -3,7 +3,7 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from requests.exceptions import HTTPError, ConnectionError as ConnError
|
from pybotvac.exceptions import NeatoException, NeatoLoginException, NeatoRobotException
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT
|
from homeassistant.config_entries import SOURCE_IMPORT
|
||||||
@ -20,6 +20,7 @@ from .const import (
|
|||||||
NEATO_ROBOTS,
|
NEATO_ROBOTS,
|
||||||
NEATO_PERSISTENT_MAPS,
|
NEATO_PERSISTENT_MAPS,
|
||||||
NEATO_MAP_DATA,
|
NEATO_MAP_DATA,
|
||||||
|
SCAN_INTERVAL_MINUTES,
|
||||||
VALID_VENDORS,
|
VALID_VENDORS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -103,7 +104,12 @@ async def async_setup_entry(hass, entry):
|
|||||||
_LOGGER.debug("Failed to login to Neato API")
|
_LOGGER.debug("Failed to login to Neato API")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
await hass.async_add_executor_job(hub.update_robots)
|
try:
|
||||||
|
await hass.async_add_executor_job(hub.update_robots)
|
||||||
|
except NeatoRobotException:
|
||||||
|
_LOGGER.debug("Failed to connect to Neato API")
|
||||||
|
return False
|
||||||
|
|
||||||
for component in ("camera", "vacuum", "switch"):
|
for component in ("camera", "vacuum", "switch"):
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.async_forward_entry_setup(entry, component)
|
hass.config_entries.async_forward_entry_setup(entry, component)
|
||||||
@ -144,17 +150,19 @@ class NeatoHub:
|
|||||||
self.config[CONF_USERNAME], self.config[CONF_PASSWORD], self._vendor
|
self.config[CONF_USERNAME], self.config[CONF_PASSWORD], self._vendor
|
||||||
)
|
)
|
||||||
self.logged_in = True
|
self.logged_in = True
|
||||||
except (HTTPError, ConnError):
|
|
||||||
_LOGGER.error("Unable to connect to Neato API")
|
_LOGGER.debug("Successfully connected to Neato API")
|
||||||
|
self._hass.data[NEATO_ROBOTS] = self.my_neato.robots
|
||||||
|
self._hass.data[NEATO_PERSISTENT_MAPS] = self.my_neato.persistent_maps
|
||||||
|
self._hass.data[NEATO_MAP_DATA] = self.my_neato.maps
|
||||||
|
except NeatoException as ex:
|
||||||
|
if isinstance(ex, NeatoLoginException):
|
||||||
|
_LOGGER.error("Invalid credentials")
|
||||||
|
else:
|
||||||
|
_LOGGER.error("Unable to connect to Neato API")
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
return
|
|
||||||
|
|
||||||
_LOGGER.debug("Successfully connected to Neato API")
|
@Throttle(timedelta(minutes=SCAN_INTERVAL_MINUTES))
|
||||||
self._hass.data[NEATO_ROBOTS] = self.my_neato.robots
|
|
||||||
self._hass.data[NEATO_PERSISTENT_MAPS] = self.my_neato.persistent_maps
|
|
||||||
self._hass.data[NEATO_MAP_DATA] = self.my_neato.maps
|
|
||||||
|
|
||||||
@Throttle(timedelta(seconds=300))
|
|
||||||
def update_robots(self):
|
def update_robots(self):
|
||||||
"""Update the robot states."""
|
"""Update the robot states."""
|
||||||
_LOGGER.debug("Running HUB.update_robots %s", self._hass.data[NEATO_ROBOTS])
|
_LOGGER.debug("Running HUB.update_robots %s", self._hass.data[NEATO_ROBOTS])
|
||||||
|
@ -2,13 +2,21 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from pybotvac.exceptions import NeatoRobotException
|
||||||
|
|
||||||
from homeassistant.components.camera import Camera
|
from homeassistant.components.camera import Camera
|
||||||
|
|
||||||
from .const import NEATO_DOMAIN, NEATO_MAP_DATA, NEATO_ROBOTS, NEATO_LOGIN
|
from .const import (
|
||||||
|
NEATO_DOMAIN,
|
||||||
|
NEATO_MAP_DATA,
|
||||||
|
NEATO_ROBOTS,
|
||||||
|
NEATO_LOGIN,
|
||||||
|
SCAN_INTERVAL_MINUTES,
|
||||||
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=10)
|
SCAN_INTERVAL = timedelta(minutes=SCAN_INTERVAL_MINUTES)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||||
@ -37,9 +45,9 @@ class NeatoCleaningMap(Camera):
|
|||||||
"""Initialize Neato cleaning map."""
|
"""Initialize Neato cleaning map."""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.robot = robot
|
self.robot = robot
|
||||||
self._robot_name = "{} {}".format(self.robot.name, "Cleaning Map")
|
self.neato = hass.data[NEATO_LOGIN] if NEATO_LOGIN in hass.data else None
|
||||||
|
self._robot_name = f"{self.robot.name} Cleaning Map"
|
||||||
self._robot_serial = self.robot.serial
|
self._robot_serial = self.robot.serial
|
||||||
self.neato = hass.data[NEATO_LOGIN]
|
|
||||||
self._image_url = None
|
self._image_url = None
|
||||||
self._image = None
|
self._image = None
|
||||||
|
|
||||||
@ -50,16 +58,31 @@ class NeatoCleaningMap(Camera):
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Check the contents of the map list."""
|
"""Check the contents of the map list."""
|
||||||
self.neato.update_robots()
|
if self.neato is None:
|
||||||
image_url = None
|
_LOGGER.error("Error while updating camera")
|
||||||
map_data = self.hass.data[NEATO_MAP_DATA]
|
self._image = None
|
||||||
image_url = map_data[self._robot_serial]["maps"][0]["url"]
|
self._image_url = None
|
||||||
if image_url == self._image_url:
|
|
||||||
_LOGGER.debug("The map image_url is the same as old")
|
|
||||||
return
|
return
|
||||||
image = self.neato.download_map(image_url)
|
|
||||||
self._image = image.read()
|
_LOGGER.debug("Running camera update")
|
||||||
self._image_url = image_url
|
try:
|
||||||
|
self.neato.update_robots()
|
||||||
|
|
||||||
|
image_url = None
|
||||||
|
map_data = self.hass.data[NEATO_MAP_DATA][self._robot_serial]["maps"][0]
|
||||||
|
image_url = map_data["url"]
|
||||||
|
if image_url == self._image_url:
|
||||||
|
_LOGGER.debug("The map image_url is the same as old")
|
||||||
|
return
|
||||||
|
|
||||||
|
image = self.neato.download_map(image_url)
|
||||||
|
self._image = image.read()
|
||||||
|
self._image_url = image_url
|
||||||
|
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato camera connection error: %s", ex)
|
||||||
|
self._image = None
|
||||||
|
self._image_url = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from requests.exceptions import HTTPError, ConnectionError as ConnError
|
from pybotvac.exceptions import NeatoLoginException, NeatoRobotException
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
@ -106,7 +106,9 @@ class NeatoConfigFlow(config_entries.ConfigFlow, domain=NEATO_DOMAIN):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
Account(username, password, this_vendor)
|
Account(username, password, this_vendor)
|
||||||
except (HTTPError, ConnError):
|
except NeatoLoginException:
|
||||||
return "invalid_credentials"
|
return "invalid_credentials"
|
||||||
|
except NeatoRobotException:
|
||||||
|
return "unexpected_error"
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -9,6 +9,8 @@ NEATO_CONFIG = "neato_config"
|
|||||||
NEATO_MAP_DATA = "neato_map_data"
|
NEATO_MAP_DATA = "neato_map_data"
|
||||||
NEATO_PERSISTENT_MAPS = "neato_persistent_maps"
|
NEATO_PERSISTENT_MAPS = "neato_persistent_maps"
|
||||||
|
|
||||||
|
SCAN_INTERVAL_MINUTES = 5
|
||||||
|
|
||||||
VALID_VENDORS = ["neato", "vorwerk"]
|
VALID_VENDORS = ["neato", "vorwerk"]
|
||||||
|
|
||||||
MODE = {1: "Eco", 2: "Turbo"}
|
MODE = {1: "Eco", 2: "Turbo"}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/neato",
|
"documentation": "https://www.home-assistant.io/integrations/neato",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"pybotvac==0.0.15"
|
"pybotvac==0.0.16"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_credentials": "Invalid credentials"
|
"invalid_credentials": "Invalid credentials",
|
||||||
|
"unexpected_error": "Unexpected error"
|
||||||
},
|
},
|
||||||
"create_entry": {
|
"create_entry": {
|
||||||
"default": "See [Neato documentation]({docs_url})."
|
"default": "See [Neato documentation]({docs_url})."
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
from pybotvac.exceptions import NeatoRobotException
|
||||||
|
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON
|
from homeassistant.const import STATE_OFF, STATE_ON
|
||||||
from homeassistant.helpers.entity import ToggleEntity
|
from homeassistant.helpers.entity import ToggleEntity
|
||||||
|
|
||||||
from .const import NEATO_DOMAIN, NEATO_LOGIN, NEATO_ROBOTS
|
from .const import NEATO_DOMAIN, NEATO_LOGIN, NEATO_ROBOTS, SCAN_INTERVAL_MINUTES
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=10)
|
SCAN_INTERVAL = timedelta(minutes=SCAN_INTERVAL_MINUTES)
|
||||||
|
|
||||||
SWITCH_TYPE_SCHEDULE = "schedule"
|
SWITCH_TYPE_SCHEDULE = "schedule"
|
||||||
|
|
||||||
@ -44,8 +44,8 @@ class NeatoConnectedSwitch(ToggleEntity):
|
|||||||
"""Initialize the Neato Connected switches."""
|
"""Initialize the Neato Connected switches."""
|
||||||
self.type = switch_type
|
self.type = switch_type
|
||||||
self.robot = robot
|
self.robot = robot
|
||||||
self.neato = hass.data[NEATO_LOGIN]
|
self.neato = hass.data[NEATO_LOGIN] if NEATO_LOGIN in hass.data else None
|
||||||
self._robot_name = "{} {}".format(self.robot.name, SWITCH_TYPES[self.type][0])
|
self._robot_name = f"{self.robot.name} {SWITCH_TYPES[self.type][0]}"
|
||||||
self._state = None
|
self._state = None
|
||||||
self._schedule_state = None
|
self._schedule_state = None
|
||||||
self._clean_state = None
|
self._clean_state = None
|
||||||
@ -53,17 +53,20 @@ class NeatoConnectedSwitch(ToggleEntity):
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the states of Neato switches."""
|
"""Update the states of Neato switches."""
|
||||||
_LOGGER.debug("Running switch update")
|
if self.neato is None:
|
||||||
self.neato.update_robots()
|
_LOGGER.error("Error while updating switches")
|
||||||
try:
|
|
||||||
self._state = self.robot.state
|
|
||||||
except (
|
|
||||||
requests.exceptions.ConnectionError,
|
|
||||||
requests.exceptions.HTTPError,
|
|
||||||
) as ex:
|
|
||||||
_LOGGER.warning("Neato connection error: %s", ex)
|
|
||||||
self._state = None
|
self._state = None
|
||||||
return
|
return
|
||||||
|
|
||||||
|
_LOGGER.debug("Running switch update")
|
||||||
|
try:
|
||||||
|
self.neato.update_robots()
|
||||||
|
self._state = self.robot.state
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato switch connection error: %s", ex)
|
||||||
|
self._state = None
|
||||||
|
return
|
||||||
|
|
||||||
_LOGGER.debug("self._state=%s", self._state)
|
_LOGGER.debug("self._state=%s", self._state)
|
||||||
if self.type == SWITCH_TYPE_SCHEDULE:
|
if self.type == SWITCH_TYPE_SCHEDULE:
|
||||||
_LOGGER.debug("State: %s", self._state)
|
_LOGGER.debug("State: %s", self._state)
|
||||||
@ -104,9 +107,15 @@ class NeatoConnectedSwitch(ToggleEntity):
|
|||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the switch on."""
|
"""Turn the switch on."""
|
||||||
if self.type == SWITCH_TYPE_SCHEDULE:
|
if self.type == SWITCH_TYPE_SCHEDULE:
|
||||||
self.robot.enable_schedule()
|
try:
|
||||||
|
self.robot.enable_schedule()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato switch connection error: %s", ex)
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the switch off."""
|
"""Turn the switch off."""
|
||||||
if self.type == SWITCH_TYPE_SCHEDULE:
|
if self.type == SWITCH_TYPE_SCHEDULE:
|
||||||
self.robot.disable_schedule()
|
try:
|
||||||
|
self.robot.disable_schedule()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato switch connection error: %s", ex)
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
from pybotvac.exceptions import NeatoRobotException
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.vacuum import (
|
from homeassistant.components.vacuum import (
|
||||||
@ -41,11 +42,12 @@ from .const import (
|
|||||||
NEATO_MAP_DATA,
|
NEATO_MAP_DATA,
|
||||||
NEATO_PERSISTENT_MAPS,
|
NEATO_PERSISTENT_MAPS,
|
||||||
NEATO_ROBOTS,
|
NEATO_ROBOTS,
|
||||||
|
SCAN_INTERVAL_MINUTES,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=5)
|
SCAN_INTERVAL = timedelta(minutes=SCAN_INTERVAL_MINUTES)
|
||||||
|
|
||||||
SUPPORT_NEATO = (
|
SUPPORT_NEATO = (
|
||||||
SUPPORT_BATTERY
|
SUPPORT_BATTERY
|
||||||
@ -154,22 +156,26 @@ class NeatoConnectedVacuum(StateVacuumDevice):
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the states of Neato Vacuums."""
|
"""Update the states of Neato Vacuums."""
|
||||||
_LOGGER.debug("Running Neato Vacuums update")
|
if self.neato is None:
|
||||||
if self._robot_stats is None:
|
_LOGGER.error("Error while updating vacuum")
|
||||||
self._robot_stats = self.robot.get_robot_info().json()
|
|
||||||
|
|
||||||
self.neato.update_robots()
|
|
||||||
try:
|
|
||||||
self._state = self.robot.state
|
|
||||||
self._available = True
|
|
||||||
except (
|
|
||||||
requests.exceptions.ConnectionError,
|
|
||||||
requests.exceptions.HTTPError,
|
|
||||||
) as ex:
|
|
||||||
_LOGGER.warning("Neato connection error: %s", ex)
|
|
||||||
self._state = None
|
self._state = None
|
||||||
self._available = False
|
self._available = False
|
||||||
return
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
_LOGGER.debug("Running Neato Vacuums update")
|
||||||
|
if self._robot_stats is None:
|
||||||
|
self._robot_stats = self.robot.get_robot_info().json()
|
||||||
|
self.neato.update_robots()
|
||||||
|
self._state = self.robot.state
|
||||||
|
self._available = True
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
if self._available: # print only once when available
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
self._state = None
|
||||||
|
self._available = False
|
||||||
|
return
|
||||||
|
|
||||||
_LOGGER.debug("self._state=%s", self._state)
|
_LOGGER.debug("self._state=%s", self._state)
|
||||||
if "alert" in self._state:
|
if "alert" in self._state:
|
||||||
robot_alert = ALERTS.get(self._state["alert"])
|
robot_alert = ALERTS.get(self._state["alert"])
|
||||||
@ -313,33 +319,51 @@ class NeatoConnectedVacuum(StateVacuumDevice):
|
|||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Start cleaning or resume cleaning."""
|
"""Start cleaning or resume cleaning."""
|
||||||
if self._state["state"] == 1:
|
try:
|
||||||
self.robot.start_cleaning()
|
if self._state["state"] == 1:
|
||||||
elif self._state["state"] == 3:
|
self.robot.start_cleaning()
|
||||||
self.robot.resume_cleaning()
|
elif self._state["state"] == 3:
|
||||||
|
self.robot.resume_cleaning()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
"""Pause the vacuum."""
|
"""Pause the vacuum."""
|
||||||
self.robot.pause_cleaning()
|
try:
|
||||||
|
self.robot.pause_cleaning()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
|
||||||
def return_to_base(self, **kwargs):
|
def return_to_base(self, **kwargs):
|
||||||
"""Set the vacuum cleaner to return to the dock."""
|
"""Set the vacuum cleaner to return to the dock."""
|
||||||
if self._clean_state == STATE_CLEANING:
|
try:
|
||||||
self.robot.pause_cleaning()
|
if self._clean_state == STATE_CLEANING:
|
||||||
self._clean_state = STATE_RETURNING
|
self.robot.pause_cleaning()
|
||||||
self.robot.send_to_base()
|
self._clean_state = STATE_RETURNING
|
||||||
|
self.robot.send_to_base()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
|
||||||
def stop(self, **kwargs):
|
def stop(self, **kwargs):
|
||||||
"""Stop the vacuum cleaner."""
|
"""Stop the vacuum cleaner."""
|
||||||
self.robot.stop_cleaning()
|
try:
|
||||||
|
self.robot.stop_cleaning()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
|
||||||
def locate(self, **kwargs):
|
def locate(self, **kwargs):
|
||||||
"""Locate the robot by making it emit a sound."""
|
"""Locate the robot by making it emit a sound."""
|
||||||
self.robot.locate()
|
try:
|
||||||
|
self.robot.locate()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
|
||||||
def clean_spot(self, **kwargs):
|
def clean_spot(self, **kwargs):
|
||||||
"""Run a spot cleaning starting from the base."""
|
"""Run a spot cleaning starting from the base."""
|
||||||
self.robot.start_spot_cleaning()
|
try:
|
||||||
|
self.robot.start_spot_cleaning()
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
|
||||||
def neato_custom_cleaning(self, mode, navigation, category, zone=None, **kwargs):
|
def neato_custom_cleaning(self, mode, navigation, category, zone=None, **kwargs):
|
||||||
"""Zone cleaning service call."""
|
"""Zone cleaning service call."""
|
||||||
@ -355,4 +379,7 @@ class NeatoConnectedVacuum(StateVacuumDevice):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._clean_state = STATE_CLEANING
|
self._clean_state = STATE_CLEANING
|
||||||
self.robot.start_cleaning(mode, navigation, category, boundary_id)
|
try:
|
||||||
|
self.robot.start_cleaning(mode, navigation, category, boundary_id)
|
||||||
|
except NeatoRobotException as ex:
|
||||||
|
_LOGGER.error("Neato vacuum connection error: %s", ex)
|
||||||
|
@ -1102,7 +1102,7 @@ pyblackbird==0.5
|
|||||||
# pybluez==0.22
|
# pybluez==0.22
|
||||||
|
|
||||||
# homeassistant.components.neato
|
# homeassistant.components.neato
|
||||||
pybotvac==0.0.15
|
pybotvac==0.0.16
|
||||||
|
|
||||||
# homeassistant.components.nissan_leaf
|
# homeassistant.components.nissan_leaf
|
||||||
pycarwings2==2.9
|
pycarwings2==2.9
|
||||||
|
@ -297,7 +297,7 @@ pyMetno==0.4.6
|
|||||||
pyblackbird==0.5
|
pyblackbird==0.5
|
||||||
|
|
||||||
# homeassistant.components.neato
|
# homeassistant.components.neato
|
||||||
pybotvac==0.0.15
|
pybotvac==0.0.16
|
||||||
|
|
||||||
# homeassistant.components.cast
|
# homeassistant.components.cast
|
||||||
pychromecast==4.0.1
|
pychromecast==4.0.1
|
||||||
|
@ -103,11 +103,11 @@ async def test_abort_if_already_setup(hass, account):
|
|||||||
|
|
||||||
async def test_abort_on_invalid_credentials(hass):
|
async def test_abort_on_invalid_credentials(hass):
|
||||||
"""Test when we have invalid credentials."""
|
"""Test when we have invalid credentials."""
|
||||||
from requests.exceptions import HTTPError
|
from pybotvac.exceptions import NeatoLoginException
|
||||||
|
|
||||||
flow = init_config_flow(hass)
|
flow = init_config_flow(hass)
|
||||||
|
|
||||||
with patch("pybotvac.Account", side_effect=HTTPError()):
|
with patch("pybotvac.Account", side_effect=NeatoLoginException()):
|
||||||
result = await flow.async_step_user(
|
result = await flow.async_step_user(
|
||||||
{
|
{
|
||||||
CONF_USERNAME: USERNAME,
|
CONF_USERNAME: USERNAME,
|
||||||
@ -127,3 +127,31 @@ async def test_abort_on_invalid_credentials(hass):
|
|||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "invalid_credentials"
|
assert result["reason"] == "invalid_credentials"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_abort_on_unexpected_error(hass):
|
||||||
|
"""Test when we have an unexpected error."""
|
||||||
|
from pybotvac.exceptions import NeatoRobotException
|
||||||
|
|
||||||
|
flow = init_config_flow(hass)
|
||||||
|
|
||||||
|
with patch("pybotvac.Account", side_effect=NeatoRobotException()):
|
||||||
|
result = await flow.async_step_user(
|
||||||
|
{
|
||||||
|
CONF_USERNAME: USERNAME,
|
||||||
|
CONF_PASSWORD: PASSWORD,
|
||||||
|
CONF_VENDOR: VENDOR_NEATO,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["errors"] == {"base": "unexpected_error"}
|
||||||
|
|
||||||
|
result = await flow.async_step_import(
|
||||||
|
{
|
||||||
|
CONF_USERNAME: USERNAME,
|
||||||
|
CONF_PASSWORD: PASSWORD,
|
||||||
|
CONF_VENDOR: VENDOR_NEATO,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
|
assert result["reason"] == "unexpected_error"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user