2020-04-28 23:44:31 +00:00
|
|
|
"""Code to handle a Xiaomi Gateway."""
|
|
|
|
import logging
|
|
|
|
|
|
|
|
from miio import DeviceException, gateway
|
|
|
|
|
2020-07-04 12:56:16 +00:00
|
|
|
from homeassistant.helpers.entity import Entity
|
|
|
|
|
|
|
|
from .const import DOMAIN
|
|
|
|
|
2020-04-28 23:44:31 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class ConnectXiaomiGateway:
|
|
|
|
"""Class to async connect to a Xiaomi Gateway."""
|
|
|
|
|
|
|
|
def __init__(self, hass):
|
|
|
|
"""Initialize the entity."""
|
|
|
|
self._hass = hass
|
|
|
|
self._gateway_device = None
|
|
|
|
self._gateway_info = None
|
|
|
|
|
|
|
|
@property
|
|
|
|
def gateway_device(self):
|
|
|
|
"""Return the class containing all connections to the gateway."""
|
|
|
|
return self._gateway_device
|
|
|
|
|
|
|
|
@property
|
|
|
|
def gateway_info(self):
|
|
|
|
"""Return the class containing gateway info."""
|
|
|
|
return self._gateway_info
|
|
|
|
|
|
|
|
async def async_connect_gateway(self, host, token):
|
|
|
|
"""Connect to the Xiaomi Gateway."""
|
|
|
|
_LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5])
|
|
|
|
try:
|
|
|
|
self._gateway_device = gateway.Gateway(host, token)
|
2020-07-04 12:56:16 +00:00
|
|
|
# get the gateway info
|
2020-04-28 23:44:31 +00:00
|
|
|
self._gateway_info = await self._hass.async_add_executor_job(
|
|
|
|
self._gateway_device.info
|
|
|
|
)
|
2020-07-04 12:56:16 +00:00
|
|
|
# get the connected sub devices
|
|
|
|
await self._hass.async_add_executor_job(
|
|
|
|
self._gateway_device.discover_devices
|
|
|
|
)
|
2020-04-28 23:44:31 +00:00
|
|
|
except DeviceException:
|
|
|
|
_LOGGER.error(
|
|
|
|
"DeviceException during setup of xiaomi gateway with host %s", host
|
|
|
|
)
|
|
|
|
return False
|
|
|
|
_LOGGER.debug(
|
|
|
|
"%s %s %s detected",
|
|
|
|
self._gateway_info.model,
|
|
|
|
self._gateway_info.firmware_version,
|
|
|
|
self._gateway_info.hardware_version,
|
|
|
|
)
|
|
|
|
return True
|
2020-07-04 12:56:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
class XiaomiGatewayDevice(Entity):
|
|
|
|
"""Representation of a base Xiaomi Gateway Device."""
|
|
|
|
|
|
|
|
def __init__(self, sub_device, entry):
|
|
|
|
"""Initialize the Xiaomi Gateway Device."""
|
|
|
|
self._sub_device = sub_device
|
|
|
|
self._entry = entry
|
|
|
|
self._unique_id = sub_device.sid
|
|
|
|
self._name = f"{sub_device.name} ({sub_device.sid})"
|
|
|
|
self._available = None
|
|
|
|
|
|
|
|
@property
|
|
|
|
def unique_id(self):
|
|
|
|
"""Return an unique ID."""
|
|
|
|
return self._unique_id
|
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
|
|
|
"""Return the name of this entity, if any."""
|
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def device_info(self):
|
|
|
|
"""Return the device info of the gateway."""
|
|
|
|
return {
|
|
|
|
"identifiers": {(DOMAIN, self._sub_device.sid)},
|
|
|
|
"via_device": (DOMAIN, self._entry.unique_id),
|
|
|
|
"manufacturer": "Xiaomi",
|
|
|
|
"name": self._sub_device.name,
|
|
|
|
"model": self._sub_device.model,
|
|
|
|
"sw_version": self._sub_device.firmware_version,
|
|
|
|
}
|
|
|
|
|
|
|
|
@property
|
|
|
|
def available(self):
|
|
|
|
"""Return true when state is known."""
|
|
|
|
return self._available
|
|
|
|
|
|
|
|
async def async_update(self):
|
|
|
|
"""Fetch state from the sub device."""
|
|
|
|
try:
|
|
|
|
await self.hass.async_add_executor_job(self._sub_device.update)
|
|
|
|
self._available = True
|
|
|
|
except gateway.GatewayException as ex:
|
|
|
|
self._available = False
|
|
|
|
_LOGGER.error("Got exception while fetching the state: %s", ex)
|