예제 #1
0
async def validate_gw_input(hass: core.HomeAssistant, data):
    """
    Validate whether the user input allows us to connect to the gateray.

    Data has the keys from _base_gw_schema() with values provided by the user.
    """
    websession = async_get_clientsession(hass, verify_ssl=False)

    api = Smile(
        host=data[CONF_HOST],
        password=data[CONF_PASSWORD],
        port=data[CONF_PORT],
        username=data[CONF_USERNAME],
        timeout=30,
        websession=websession,
    )

    try:
        await api.connect()
    except Smile.InvalidAuthentication as err:
        raise InvalidAuth from err
    except Smile.PlugwiseError as err:
        raise CannotConnect from err

    return api
예제 #2
0
    async def connect(self, broken=False, timeout=False, put_timeout=False):
        """Connect to a smile environment and perform basic asserts."""
        port = aiohttp.test_utils.unused_port()

        # Happy flow
        app = await self.setup_app(broken, timeout, put_timeout)

        server = aiohttp.test_utils.TestServer(
            app, port=port, scheme="http", host="127.0.0.1"
        )
        await server.start_server()

        client = aiohttp.test_utils.TestClient(server)
        websession = client.session

        url = "{}://{}:{}/core/locations".format(
            server.scheme, server.host, server.port
        )
        resp = await websession.get(url)

        assumed_status = 200
        if broken:
            assumed_status = 500
        if timeout:
            assumed_status = 504
        assert resp.status == assumed_status

        if not broken and not timeout:
            text = await resp.text()
            assert "xml" in text

        smile = Smile(
            host=server.host,
            username="******",
            password="******",
            port=server.port,
            websession=websession,
        )

        if not timeout:
            assert smile._timeout == 30  # pylint: disable=protected-access
        assert smile._domain_objects is None  # pylint: disable=protected-access
        assert smile.smile_type is None

        # Connect to the smile
        try:
            connection_state = await smile.connect()
            assert connection_state
            assert smile.smile_type is not None
            return server, smile, client
        except (Smile.DeviceTimeoutError, Smile.InvalidXMLError) as e:
            await self.disconnect(server, client)
            raise e
예제 #3
0
async def validate_input(hass: core.HomeAssistant, data):
    """
    Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """
    websession = async_get_clientsession(hass, verify_ssl=False)
    api = Smile(
        host=data["host"], password=data["password"], timeout=30, websession=websession
    )

    try:
        await api.connect()
    except Smile.InvalidAuthentication:
        raise InvalidAuth
    except Smile.ConnectionFailedError:
        raise CannotConnect

    return api
예제 #4
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Plugwise Smiles from a config entry."""
    websession = async_get_clientsession(hass, verify_ssl=False)

    api = Smile(
        host=entry.data[CONF_HOST],
        password=entry.data[CONF_PASSWORD],
        port=entry.data.get(CONF_PORT, DEFAULT_PORT),
        timeout=30,
        websession=websession,
    )

    try:
        connected = await api.connect()

        if not connected:
            _LOGGER.error("Unable to connect to Smile")
            raise ConfigEntryNotReady

    except Smile.InvalidAuthentication:
        _LOGGER.error("Invalid Smile ID")
        return False

    except Smile.PlugwiseError as err:
        _LOGGER.error("Error while communicating to device")
        raise ConfigEntryNotReady from err

    except asyncio.TimeoutError as err:
        _LOGGER.error("Timeout while connecting to Smile")
        raise ConfigEntryNotReady from err

    update_interval = timedelta(seconds=entry.options.get(
        CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL[api.smile_type]))

    async def async_update_data():
        """Update data via API endpoint."""
        try:
            async with async_timeout.timeout(10):
                await api.full_update_device()
                return True
        except Smile.XMLDataMissingError as err:
            raise UpdateFailed("Smile update failed") from err

    coordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name="Smile",
        update_method=async_update_data,
        update_interval=update_interval,
    )

    await coordinator.async_refresh()

    if not coordinator.last_update_success:
        raise ConfigEntryNotReady

    api.get_all_devices()

    if entry.unique_id is None:
        if api.smile_version[0] != "1.8.0":
            hass.config_entries.async_update_entry(
                entry, unique_id=api.smile_hostname)

    undo_listener = entry.add_update_listener(_update_listener)

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
        "api": api,
        COORDINATOR: coordinator,
        UNDO_UPDATE_LISTENER: undo_listener,
    }

    device_registry = await dr.async_get_registry(hass)
    device_registry.async_get_or_create(
        config_entry_id=entry.entry_id,
        identifiers={(DOMAIN, api.gateway_id)},
        manufacturer="Plugwise",
        name=entry.title,
        model=f"Smile {api.smile_name}",
        sw_version=api.smile_version[0],
    )

    single_master_thermostat = api.single_master_thermostat()

    platforms = ALL_PLATFORMS
    if single_master_thermostat is None:
        platforms = SENSOR_PLATFORMS

    for component in platforms:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component))

    return True
예제 #5
0
파일: __init__.py 프로젝트: Twtcer/core-1
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Plugwise Smiles from a config entry."""
    websession = async_get_clientsession(hass, verify_ssl=False)
    api = Smile(
        host=entry.data["host"], password=entry.data["password"], websession=websession
    )

    try:
        connected = await api.connect()

        if not connected:
            _LOGGER.error("Unable to connect to Smile")
            raise ConfigEntryNotReady

    except Smile.InvalidAuthentication:
        _LOGGER.error("Invalid Smile ID")
        return False

    except Smile.PlugwiseError:
        _LOGGER.error("Error while communicating to device")
        raise ConfigEntryNotReady

    except asyncio.TimeoutError:
        _LOGGER.error("Timeout while connecting to Smile")
        raise ConfigEntryNotReady

    if api.smile_type == "power":
        update_interval = timedelta(seconds=10)
    else:
        update_interval = timedelta(seconds=60)

    async def async_update_data():
        """Update data via API endpoint."""
        try:
            async with async_timeout.timeout(10):
                await api.full_update_device()
                return True
        except Smile.XMLDataMissingError:
            raise UpdateFailed("Smile update failed")

    coordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name="Smile",
        update_method=async_update_data,
        update_interval=update_interval,
    )

    await coordinator.async_refresh()

    if not coordinator.last_update_success:
        raise ConfigEntryNotReady

    api.get_all_devices()

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
        "api": api,
        "coordinator": coordinator,
    }

    device_registry = await dr.async_get_registry(hass)
    device_registry.async_get_or_create(
        config_entry_id=entry.entry_id,
        identifiers={(DOMAIN, api.gateway_id)},
        manufacturer="Plugwise",
        name=entry.title,
        model=f"Smile {api.smile_name}",
        sw_version=api.smile_version[0],
    )

    platforms = ALL_PLATFORMS

    single_master_thermostat = api.single_master_thermostat()
    if single_master_thermostat is None:
        platforms = SENSOR_PLATFORMS

    for component in platforms:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component)
        )

    return True
예제 #6
0
async def async_setup(hass, config):
    """Add the Plugwise Gateways."""

    conf = config.get(DOMAIN)

    if conf is None:
        raise PlatformNotReady

    _LOGGER.info('Plugwise %s',conf)
    hass.data[DOMAIN] = {}

    for smile_type,smile_config in conf.items():
        _LOGGER.info('Plugwise Smile type %s',smile_type)
        _LOGGER.info('Plugwise Smile setup %s',smile_config)
        hass.data[DOMAIN][smile_type] = {}
        for smile in smile_config:
            _LOGGER.info('Plugwise smile %s',smile)
            smile=smile[0]
            smile['type']=smile_type

            websession = async_get_clientsession(hass, verify_ssl=False)
            plugwise_data_connection = Smile(host=smile[CONF_HOST], password=smile[CONF_PASSWORD], websession=websession, smile_type=smile_type)

            _LOGGER.debug("Plugwise connecting to %s",smile)
            if not await plugwise_data_connection.connect():
                _LOGGER.error("Failed to connect to %s Plugwise Smile",smile_type)
                return

            if smile_type != 'thermostat':
                smile[CONF_HEATER] = False
            if smile_type != 'power':
                smile[CONF_GAS] = False
                smile[CONF_SOLAR] = False

            hass.data[DOMAIN][smile_type][smile[CONF_NAME]] = { 'data_connection': plugwise_data_connection, 'type': smile_type, 'water_heater': smile[CONF_HEATER], 'solar': smile[CONF_SOLAR], 'gas': smile[CONF_GAS], CONF_SCAN_INTERVAL: smile[CONF_SCAN_INTERVAL] }

            _LOGGER.info('Plugwise Smile smile config: %s',smile)

#            async def async_update_data():
#                """Fetch data from Smile"""
#                async with async_timeout.timeout(10):
#                    return await plugwise_data_connection.full_update_device()
#
#            _LOGGER.info('Plugwise scan interval: %s',smile[CONF_SCAN_INTERVAL])
#            coordinator = DataUpdateCoordinator(
#                hass,
#                _LOGGER,
#                name='{}_{}'.format(DOMAIN,smile[CONF_NAME]),
#                update_method=async_update_data,
#                update_interval=smile[CONF_SCAN_INTERVAL],
#            )
#
#            # Fetch initial data so we have data when entities subscribe
#            await coordinator.async_refresh()

    for component in PLUGWISE_COMPONENTS:
        hass.helpers.discovery.load_platform(
            component, DOMAIN, {}, config,
        )


    return True