Improve Xiaomi Miio error handling (#52009)

* Xiaomi Miio inprove error logging

* improve error handeling

* fix styling

* fix styling

* Update homeassistant/components/xiaomi_miio/device.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/xiaomi_miio/gateway.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/xiaomi_miio/gateway.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* break long line

* Clean up

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
starkillerOG 2021-06-25 21:25:51 +02:00 committed by GitHub
parent 328ab21a05
commit 6bbe477d66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 23 deletions

View file

@ -1,8 +1,10 @@
"""Code to handle a Xiaomi Device.""" """Code to handle a Xiaomi Device."""
import logging import logging
from construct.core import ChecksumError
from miio import Device, DeviceException from miio import Device, DeviceException
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
@ -33,17 +35,24 @@ class ConnectXiaomiDevice:
async def async_connect_device(self, host, token): async def async_connect_device(self, host, token):
"""Connect to the Xiaomi Device.""" """Connect to the Xiaomi Device."""
_LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5]) _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5])
try: try:
self._device = Device(host, token) self._device = Device(host, token)
# get the device info # get the device info
self._device_info = await self._hass.async_add_executor_job( self._device_info = await self._hass.async_add_executor_job(
self._device.info self._device.info
) )
except DeviceException: except DeviceException as error:
if isinstance(error.__cause__, ChecksumError):
raise ConfigEntryAuthFailed(error) from error
_LOGGER.error( _LOGGER.error(
"DeviceException during setup of xiaomi device with host %s", host "DeviceException during setup of xiaomi device with host %s: %s",
host,
error,
) )
return False return False
_LOGGER.debug( _LOGGER.debug(
"%s %s %s detected", "%s %s %s detected",
self._device_info.model, self._device_info.model,

View file

@ -1,6 +1,7 @@
"""Code to handle a Xiaomi Gateway.""" """Code to handle a Xiaomi Gateway."""
import logging import logging
from construct.core import ChecksumError
from micloud import MiCloud from micloud import MiCloud
from miio import DeviceException, gateway from miio import DeviceException, gateway
from miio.gateway.gateway import GATEWAY_MODEL_EU from miio.gateway.gateway import GATEWAY_MODEL_EU
@ -75,19 +76,44 @@ class ConnectXiaomiGateway:
self._gateway_device = gateway.Gateway(self._host, self._token) self._gateway_device = gateway.Gateway(self._host, self._token)
# get the gateway info # get the gateway info
self._gateway_info = self._gateway_device.info() self._gateway_info = self._gateway_device.info()
except DeviceException as error:
if isinstance(error.__cause__, ChecksumError):
raise ConfigEntryAuthFailed(error) from error
# get the connected sub devices _LOGGER.error(
if self._use_cloud or self._gateway_info.model == GATEWAY_MODEL_EU: "DeviceException during setup of xiaomi gateway with host %s: %s",
if ( self._host,
self._cloud_username is None error,
or self._cloud_password is None )
or self._cloud_country is None return False
):
raise ConfigEntryAuthFailed(
"Missing cloud credentials in Xiaomi Miio configuration"
)
# use miio-cloud # get the connected sub devices
use_cloud = self._use_cloud or self._gateway_info.model == GATEWAY_MODEL_EU
if not use_cloud:
# use local query (not supported by all gateway types)
try:
self._gateway_device.discover_devices()
except DeviceException as error:
_LOGGER.info(
"DeviceException during getting subdevices of xiaomi gateway"
" with host %s, trying cloud to obtain subdevices: %s",
self._host,
error,
)
use_cloud = True
if use_cloud:
# use miio-cloud
if (
self._cloud_username is None
or self._cloud_password is None
or self._cloud_country is None
):
raise ConfigEntryAuthFailed(
"Missing cloud credentials in Xiaomi Miio configuration"
)
try:
miio_cloud = MiCloud(self._cloud_username, self._cloud_password) miio_cloud = MiCloud(self._cloud_username, self._cloud_password)
if not miio_cloud.login(): if not miio_cloud.login():
raise ConfigEntryAuthFailed( raise ConfigEntryAuthFailed(
@ -95,16 +121,13 @@ class ConnectXiaomiGateway:
) )
devices_raw = miio_cloud.get_devices(self._cloud_country) devices_raw = miio_cloud.get_devices(self._cloud_country)
self._gateway_device.get_devices_from_dict(devices_raw) self._gateway_device.get_devices_from_dict(devices_raw)
else: except DeviceException as error:
# use local query (not supported by all gateway types) _LOGGER.error(
self._gateway_device.discover_devices() "DeviceException during setup of xiaomi gateway with host %s: %s",
self._host,
except DeviceException: error,
_LOGGER.error( )
"DeviceException during setup of xiaomi gateway with host %s", return False
self._host,
)
return False
return True return True