Beispiel #1
0
def async_setup(hass, config):
    """Initialize the DuckDNS component."""
    domain = config[DOMAIN][CONF_DOMAIN]
    token = config[DOMAIN][CONF_ACCESS_TOKEN]
    session = async_get_clientsession(hass)

    result = yield from _update_duckdns(session, domain, token)

    if not result:
        return False

    @asyncio.coroutine
    def update_domain_interval(now):
        """Update the DuckDNS entry."""
        yield from _update_duckdns(session, domain, token)

    @asyncio.coroutine
    def update_domain_service(call):
        """Update the DuckDNS entry."""
        yield from _update_duckdns(session, domain, token,
                                   txt=call.data[ATTR_TXT])

    async_track_time_interval(hass, update_domain_interval, INTERVAL)
    hass.services.async_register(
        DOMAIN, SERVICE_SET_TXT, update_domain_service,
        schema=SERVICE_TXT_SCHEMA)

    return result
Beispiel #2
0
        def register():
            """Post connection initialize."""
            self.async_db_ready.set_result(True)

            def shutdown(event):
                """Shut down the Recorder."""
                if not hass_started.done():
                    hass_started.set_result(shutdown_task)
                self.queue.put(None)
                self.join()

            self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                            shutdown)

            if self.hass.state == CoreState.running:
                hass_started.set_result(None)
            else:
                @callback
                def notify_hass_started(event):
                    """Notify that hass has started."""
                    hass_started.set_result(None)

                self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START,
                                                notify_hass_started)

            if self.purge_days is not None:
                @callback
                def do_purge(now):
                    """Event listener for purging data."""
                    self.queue.put(purge_task)

                async_track_time_interval(self.hass, do_purge,
                                          timedelta(days=2))
    def __init__(self, hass, name, heater_entity_id, sensor_entity_id,
                 min_temp, max_temp, target_temp, ac_mode, min_cycle_duration,
                 tolerance, keep_alive):
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self.heater_entity_id = heater_entity_id
        self.ac_mode = ac_mode
        self.min_cycle_duration = min_cycle_duration
        self._tolerance = tolerance
        self._keep_alive = keep_alive

        self._active = False
        self._cur_temp = None
        self._min_temp = min_temp
        self._max_temp = max_temp
        self._target_temp = target_temp
        self._unit = hass.config.units.temperature_unit

        async_track_state_change(
            hass, sensor_entity_id, self._async_sensor_changed)
        async_track_state_change(
            hass, heater_entity_id, self._async_switch_changed)

        if self._keep_alive:
            async_track_time_interval(
                hass, self._async_keep_alive, self._keep_alive)

        sensor_state = hass.states.get(sensor_entity_id)
        if sensor_state:
            self._async_update_temp(sensor_state)
async def _login(hass, modem_data, password):
    """Log in and complete setup."""
    await modem_data.modem.login(password=password)

    def fire_sms_event(sms):
        """Send an SMS event."""
        data = {
            ATTR_HOST: modem_data.host,
            ATTR_SMS_ID: sms.id,
            ATTR_FROM: sms.sender,
            ATTR_MESSAGE: sms.message,
        }
        hass.bus.async_fire(EVENT_SMS, data)

    await modem_data.modem.add_sms_listener(fire_sms_event)

    await modem_data.async_update()
    hass.data[DATA_KEY].modem_data[modem_data.host] = modem_data

    async def cleanup(event):
        """Clean up resources."""
        await modem_data.modem.logout()

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, cleanup)

    async def _update(now):
        """Periodic update."""
        await modem_data.async_update()

    async_track_time_interval(hass, _update, SCAN_INTERVAL)
Beispiel #5
0
async def async_setup(hass, config):
    """Set up the Speedtest.net component."""
    conf = config[DOMAIN]
    data = hass.data[DOMAIN] = SpeedtestData(hass, conf.get(CONF_SERVER_ID))

    if not conf[CONF_MANUAL]:
        async_track_time_interval(
            hass, data.update, conf[CONF_SCAN_INTERVAL]
        )

    def update(call=None):
        """Service call to manually update the data."""
        data.update()

    hass.services.async_register(DOMAIN, 'speedtest', update)

    hass.async_create_task(
        async_load_platform(
            hass,
            SENSOR_DOMAIN,
            DOMAIN,
            conf[CONF_MONITORED_CONDITIONS],
            config
        )
    )

    return True
Beispiel #6
0
def async_setup_scanner_platform(hass: HomeAssistantType, config: ConfigType,
                                 scanner: Any, async_see_device: Callable,
                                 platform: str):
    """Set up the connect scanner-based platform to device tracker.

    This method must be run in the event loop.
    """
    interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
    update_lock = asyncio.Lock(loop=hass.loop)
    scanner.hass = hass

    # Initial scan of each mac we also tell about host name for config
    seen = set()  # type: Any

    @asyncio.coroutine
    def async_device_tracker_scan(now: dt_util.dt.datetime):
        """Handle interval matches."""
        if update_lock.locked():
            _LOGGER.warning(
                "Updating device list from %s took longer than the scheduled "
                "scan interval %s", platform, interval)
            return

        with (yield from update_lock):
            found_devices = yield from scanner.async_scan_devices()

        for mac in found_devices:
            if mac in seen:
                host_name = None
            else:
                host_name = yield from scanner.async_get_device_name(mac)
                seen.add(mac)

            try:
                extra_attributes = (yield from
                                    scanner.async_get_extra_attributes(mac))
            except NotImplementedError:
                extra_attributes = dict()

            kwargs = {
                'mac': mac,
                'host_name': host_name,
                'source_type': SOURCE_TYPE_ROUTER,
                'attributes': {
                    'scanner': scanner.__class__.__name__,
                    **extra_attributes
                }
            }

            zone_home = hass.states.get(zone.ENTITY_ID_HOME)
            if zone_home:
                kwargs['gps'] = [zone_home.attributes[ATTR_LATITUDE],
                                 zone_home.attributes[ATTR_LONGITUDE]]
                kwargs['gps_accuracy'] = 0

            hass.async_add_job(async_see_device(**kwargs))

    async_track_time_interval(hass, async_device_tracker_scan, interval)
    hass.async_add_job(async_device_tracker_scan(None))
Beispiel #7
0
    def __init__(self, hass, session, devices, async_see):
        """Initialize the automatic device scanner."""
        self.hass = hass
        self.devices = devices
        self.session = session
        self.async_see = async_see

        async_track_time_interval(hass, self.update, timedelta(seconds=30))
Beispiel #8
0
 async def async_added_to_hass(self):
     """Run when about to be added to hass."""
     await super().async_added_to_hass()
     await self.async_accept_signal(
         self._on_off_channel, SIGNAL_ATTR_UPDATED, self.async_set_state)
     if self._level_channel:
         await self.async_accept_signal(
             self._level_channel, SIGNAL_SET_LEVEL, self.set_level)
     async_track_time_interval(self.hass, self.refresh, SCAN_INTERVAL)
Beispiel #9
0
def async_setup(hass, config):
    """Set up the camera component."""
    component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)

    hass.http.register_view(CameraImageView(component.entities))
    hass.http.register_view(CameraMjpegStream(component.entities))

    yield from component.async_setup(config)

    @callback
    def update_tokens(time):
        """Update tokens of the entities."""
        for entity in component.entities.values():
            entity.async_update_token()
            hass.async_add_job(entity.async_update_ha_state())

    async_track_time_interval(hass, update_tokens, TOKEN_CHANGE_INTERVAL)

    @asyncio.coroutine
    def async_handle_camera_service(service):
        """Handle calls to the camera services."""
        target_cameras = component.async_extract_from_service(service)

        for camera in target_cameras:
            if service.service == SERVICE_EN_MOTION:
                yield from camera.async_enable_motion_detection()
            elif service.service == SERVICE_DISEN_MOTION:
                yield from camera.async_disable_motion_detection()

        update_tasks = []
        for camera in target_cameras:
            if not camera.should_poll:
                continue

            update_coro = hass.async_add_job(
                camera.async_update_ha_state(True))
            if hasattr(camera, 'async_update'):
                update_tasks.append(update_coro)
            else:
                yield from update_coro

        if update_tasks:
            yield from asyncio.wait(update_tasks, loop=hass.loop)

    descriptions = yield from hass.async_add_job(
        load_yaml_config_file, os.path.join(
            os.path.dirname(__file__), 'services.yaml'))

    hass.services.async_register(
        DOMAIN, SERVICE_EN_MOTION, async_handle_camera_service,
        descriptions.get(SERVICE_EN_MOTION), schema=CAMERA_SERVICE_SCHEMA)
    hass.services.async_register(
        DOMAIN, SERVICE_DISEN_MOTION, async_handle_camera_service,
        descriptions.get(SERVICE_DISEN_MOTION), schema=CAMERA_SERVICE_SCHEMA)

    return True
Beispiel #10
0
    async def async_init(self):
        """Further initialize connection to Traccar."""
        await self._api.test_connection()
        if self._api.authenticated:
            await self._async_update()
            async_track_time_interval(self._hass,
                                      self._async_update,
                                      DEFAULT_SCAN_INTERVAL)

        return self._api.authenticated
Beispiel #11
0
    def __init__(self, hass: HomeAssistantType, config_entry: ConfigEntry,
                 session):
        """Initialize the Minut data object."""
        self._known_devices = []
        self._hass = hass
        self._config_entry = config_entry
        self._is_available = True
        self._client = session

        async_track_time_interval(self._hass, self.update, SCAN_INTERVAL)
Beispiel #12
0
    def async_added_to_hass(self):
        """Load data init callbacks."""
        # Load data
        async_track_time_interval(
            self.hass, self._update_hub, SCAN_INTERVAL_HUB)
        yield from self.hass.async_add_job(self._update_hub, None)

        if self._use_variables:
            async_track_time_interval(
                self.hass, self._update_variables, SCAN_INTERVAL_VARIABLES)
            yield from self.hass.async_add_job(self._update_variables, None)
 async def async_init(self):
     """Further initialize connection to Google Home."""
     await self.client.update_info(self.host)
     data = self.hass.data[GOOGLEHOME_DOMAIN][self.host]
     info = data.get('info', {})
     connected = bool(info)
     if connected:
         await self.async_update()
         async_track_time_interval(self.hass,
                                   self.async_update,
                                   DEFAULT_SCAN_INTERVAL)
     return connected
    def __init__(self, hass, name, heater_entity_id, sensor_entity_id,
                 min_temp, max_temp, target_temp, ac_mode, min_cycle_duration,
                 cold_tolerance, hot_tolerance, keep_alive,
                 initial_operation_mode, away_temp, precision):
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self.heater_entity_id = heater_entity_id
        self.ac_mode = ac_mode
        self.min_cycle_duration = min_cycle_duration
        self._cold_tolerance = cold_tolerance
        self._hot_tolerance = hot_tolerance
        self._keep_alive = keep_alive
        self._initial_operation_mode = initial_operation_mode
        self._saved_target_temp = target_temp if target_temp is not None \
            else away_temp
        self._temp_precision = precision
        if self.ac_mode:
            self._current_operation = STATE_COOL
            self._operation_list = [STATE_COOL, STATE_OFF]
        else:
            self._current_operation = STATE_HEAT
            self._operation_list = [STATE_HEAT, STATE_OFF]
        if initial_operation_mode == STATE_OFF:
            self._enabled = False
            self._current_operation = STATE_OFF
        else:
            self._enabled = True
        self._active = False
        self._cur_temp = None
        self._temp_lock = asyncio.Lock()
        self._min_temp = min_temp
        self._max_temp = max_temp
        self._target_temp = target_temp
        self._unit = hass.config.units.temperature_unit
        self._support_flags = SUPPORT_FLAGS
        if away_temp is not None:
            self._support_flags = SUPPORT_FLAGS | SUPPORT_AWAY_MODE
        self._away_temp = away_temp
        self._is_away = False

        async_track_state_change(
            hass, sensor_entity_id, self._async_sensor_changed)
        async_track_state_change(
            hass, heater_entity_id, self._async_switch_changed)

        if self._keep_alive:
            async_track_time_interval(
                hass, self._async_control_heating, self._keep_alive)

        sensor_state = hass.states.get(sensor_entity_id)
        if sensor_state and sensor_state.state != STATE_UNKNOWN:
            self._async_update_temp(sensor_state)
Beispiel #15
0
async def async_setup_platform(hass, config, async_add_entities,
                               discovery_info=None):
    """Set up the CityBikes platform."""
    if PLATFORM not in hass.data:
        hass.data[PLATFORM] = {MONITORED_NETWORKS: {}}

    latitude = config.get(CONF_LATITUDE, hass.config.latitude)
    longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
    network_id = config.get(CONF_NETWORK)
    stations_list = set(config.get(CONF_STATIONS_LIST, []))
    radius = config.get(CONF_RADIUS, 0)
    name = config[CONF_NAME]
    if not hass.config.units.is_metric:
        radius = distance.convert(radius, LENGTH_FEET, LENGTH_METERS)

    # Create a single instance of CityBikesNetworks.
    networks = hass.data.setdefault(
        CITYBIKES_NETWORKS, CityBikesNetworks(hass))

    if not network_id:
        network_id = await networks.get_closest_network_id(latitude, longitude)

    if network_id not in hass.data[PLATFORM][MONITORED_NETWORKS]:
        network = CityBikesNetwork(hass, network_id)
        hass.data[PLATFORM][MONITORED_NETWORKS][network_id] = network
        hass.async_create_task(network.async_refresh())
        async_track_time_interval(hass, network.async_refresh, SCAN_INTERVAL)
    else:
        network = hass.data[PLATFORM][MONITORED_NETWORKS][network_id]

    await network.ready.wait()

    devices = []
    for station in network.stations:
        dist = location.distance(
            latitude, longitude, station[ATTR_LATITUDE],
            station[ATTR_LONGITUDE])
        station_id = station[ATTR_ID]
        station_uid = str(station.get(ATTR_EXTRA, {}).get(ATTR_UID, ''))

        if radius > dist or stations_list.intersection(
                (station_id, station_uid)):
            if name:
                uid = "_".join([network.network_id, name, station_id])
            else:
                uid = "_".join([network.network_id, station_id])
            entity_id = async_generate_entity_id(
                ENTITY_ID_FORMAT, uid, hass=hass)
            devices.append(CityBikesStation(network, station_id, entity_id))

    async_add_entities(devices, True)
async def async_setup(hass, config):
    """Set up the iperf3 component."""
    import iperf3

    hass.data[DOMAIN] = {}

    conf = config[DOMAIN]
    for host in conf[CONF_HOSTS]:
        host_name = host[CONF_HOST]

        client = iperf3.Client()
        client.duration = host[CONF_DURATION]
        client.server_hostname = host_name
        client.port = host[CONF_PORT]
        client.num_streams = host[CONF_PARALLEL]
        client.protocol = host[CONF_PROTOCOL]
        client.verbose = False

        data = hass.data[DOMAIN][host_name] = Iperf3Data(hass, client)

        if not conf[CONF_MANUAL]:
            async_track_time_interval(
                hass, data.update, conf[CONF_SCAN_INTERVAL]
            )

    def update(call):
        """Service call to manually update the data."""
        called_host = call.data[ATTR_HOST]
        if called_host in hass.data[DOMAIN]:
            hass.data[DOMAIN][called_host].update()
        else:
            for iperf3_host in hass.data[DOMAIN].values():
                iperf3_host.update()

    hass.services.async_register(
        DOMAIN, 'speedtest', update, schema=SERVICE_SCHEMA
    )

    hass.async_create_task(
        async_load_platform(
            hass,
            SENSOR_DOMAIN,
            DOMAIN,
            conf[CONF_MONITORED_CONDITIONS],
            config
        )
    )

    return True
    def async_add_entities(self, new_entities, update_before_add=False):
        """Add entities for a single platform async.

        This method must be run in the event loop.
        """
        # handle empty list from component/platform
        if not new_entities:
            return

        @asyncio.coroutine
        def async_process_entity(new_entity):
            """Add entities to StateMachine."""
            new_entity.parallel_updates = self.parallel_updates
            ret = yield from self.component.async_add_entity(
                new_entity, self, update_before_add=update_before_add
            )
            if ret:
                self.platform_entities.append(new_entity)

        tasks = [async_process_entity(entity) for entity in new_entities]

        yield from asyncio.wait(tasks, loop=self.component.hass.loop)
        self.component.async_update_group()

        if self._async_unsub_polling is not None or \
           not any(entity.should_poll for entity
                   in self.platform_entities):
            return

        self._async_unsub_polling = async_track_time_interval(
            self.component.hass, self._update_entity_states, self.scan_interval
        )
    async def async_init(self):
        """Further initialize connection to the Tile servers."""
        from pytile.errors import TileError

        try:
            await self._client.async_init()
        except TileError as err:
            _LOGGER.error('Unable to set up Tile scanner: %s', err)
            return False

        await self._async_update()

        async_track_time_interval(
            self._hass, self._async_update, DEFAULT_SCAN_INTERVAL)

        return True
Beispiel #19
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""
    from luftdaten import Luftdaten
    from luftdaten.exceptions import LuftdatenError

    session = async_get_clientsession(hass)

    try:
        luftdaten = LuftDatenData(
            Luftdaten(
                config_entry.data[CONF_SENSOR_ID], hass.loop, session),
            config_entry.data.get(CONF_SENSORS, {}).get(
                CONF_MONITORED_CONDITIONS, list(SENSORS)))
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = \
            luftdaten
    except LuftdatenError:
        raise ConfigEntryNotReady

    hass.async_create_task(hass.config_entries.async_forward_entry_setup(
        config_entry, 'sensor'))

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass, refresh_sensors,
            hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL))

    return True
    def async_add_entities(self, new_entities, update_before_add=False):
        """Add entities for a single platform async.

        This method must be run in the event loop.
        """
        # handle empty list from component/platform
        if not new_entities:
            return

        component_entities = set(entity.entity_id for entity
                                 in self.component.entities)

        tasks = [
            self._async_add_entity(entity, update_before_add,
                                   component_entities)
            for entity in new_entities]

        yield from asyncio.wait(tasks, loop=self.component.hass.loop)
        self.component.async_update_group()

        if self._async_unsub_polling is not None or \
           not any(entity.should_poll for entity
                   in self.entities.values()):
            return

        self._async_unsub_polling = async_track_time_interval(
            self.component.hass, self._update_entity_states, self.scan_interval
        )
async def async_setup(hass, config):
    """Set up the IQVIA component."""
    hass.data[DOMAIN] = {}
    hass.data[DOMAIN][DATA_CLIENT] = {}
    hass.data[DOMAIN][DATA_LISTENER] = {}

    conf = config[DOMAIN]

    websession = aiohttp_client.async_get_clientsession(hass)

    try:
        iqvia = IQVIAData(
            Client(conf[CONF_ZIP_CODE], websession),
            conf[CONF_MONITORED_CONDITIONS])
        await iqvia.async_update()
    except IQVIAError as err:
        _LOGGER.error('Unable to set up IQVIA: %s', err)
        return False

    hass.data[DOMAIN][DATA_CLIENT] = iqvia

    hass.async_create_task(
        async_load_platform(hass, 'sensor', DOMAIN, {}, config))

    async def refresh(event_time):
        """Refresh IQVIA data."""
        _LOGGER.debug('Updating IQVIA data')
        await iqvia.async_update()
        async_dispatcher_send(hass, TOPIC_DATA_UPDATE)

    hass.data[DOMAIN][DATA_LISTENER] = async_track_time_interval(
        hass, refresh, DEFAULT_SCAN_INTERVAL)

    return True
Beispiel #22
0
async def async_setup(hass, config):
    """Set up the OpenUV component."""
    from pyopenuv import Client
    from pyopenuv.errors import OpenUvError

    conf = config[DOMAIN]
    api_key = conf[CONF_API_KEY]
    elevation = conf.get(CONF_ELEVATION, hass.config.elevation)
    latitude = conf.get(CONF_LATITUDE, hass.config.latitude)
    longitude = conf.get(CONF_LONGITUDE, hass.config.longitude)

    try:
        websession = aiohttp_client.async_get_clientsession(hass)
        openuv = OpenUV(
            Client(
                api_key, latitude, longitude, websession, altitude=elevation),
            conf[CONF_BINARY_SENSORS][CONF_MONITORED_CONDITIONS] +
            conf[CONF_SENSORS][CONF_MONITORED_CONDITIONS])
        await openuv.async_update()
        hass.data[DOMAIN] = openuv
    except OpenUvError as err:
        _LOGGER.error('An error occurred: %s', str(err))
        hass.components.persistent_notification.create(
            'Error: {0}<br />'
            'You will need to restart hass after fixing.'
            ''.format(err),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    for component, schema in [
            ('binary_sensor', conf[CONF_BINARY_SENSORS]),
            ('sensor', conf[CONF_SENSORS]),
    ]:
        hass.async_create_task(
            discovery.async_load_platform(
                hass, component, DOMAIN, schema, config))

    async def refresh_sensors(event_time):
        """Refresh OpenUV data."""
        _LOGGER.debug('Refreshing OpenUV data')
        await openuv.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    async_track_time_interval(hass, refresh_sensors, conf[CONF_SCAN_INTERVAL])

    return True
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """这个协程是程序的入口,其中add_devices函数也变成了异步版本."""
    _LOGGER.info("setup platform sensor.Heweather...")

    city = config.get(CONF_CITY)
    appkey = config.get(CONF_APPKEY)
    # 这里通过 data 实例化class weatherdata,并传入调用API所需信息
    data = WeatherData(hass, city, appkey)  
    # 调用data实例中的异步更新函数,yield 现在我简单的理解为将后面函数变成一个生成器,减小内存占用?
    yield from data.async_update(dt_util.now()) 
    async_track_time_interval(hass, data.async_update, TIME_BETWEEN_UPDATES)

    # 根据配置文件options中的内容,添加若干个设备
    dev = []
    for option in config[CONF_OPTIONS]:
        dev.append(HeweatherWeatherSensor(data, option))
    async_add_devices(dev, True)
Beispiel #24
0
def async_setup(hass, config):
    """Set up the camera component."""
    component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)

    hass.http.register_view(CameraImageView(component.entities))
    hass.http.register_view(CameraMjpegStream(component.entities))

    yield from component.async_setup(config)

    @callback
    def update_tokens(time):
        """Update tokens of the entities."""
        for entity in component.entities.values():
            entity.async_update_token()
            hass.async_add_job(entity.async_update_ha_state())

    async_track_time_interval(hass, update_tokens, TOKEN_CHANGE_INTERVAL)
    return True
Beispiel #25
0
def async_setup_platform(hass, config, async_add_devices,
                         discovery_info=None):
    """Set up the CityBikes platform."""
    if DOMAIN not in hass.data:
        hass.data[DOMAIN] = {MONITORED_NETWORKS: {}}

    latitude = config.get(CONF_LATITUDE, hass.config.latitude)
    longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
    network_id = config.get(CONF_NETWORK)
    stations_list = set(config.get(CONF_STATIONS_LIST, []))
    radius = config.get(CONF_RADIUS, 0)
    name = config.get(CONF_NAME)
    if not hass.config.units.is_metric:
        radius = distance.convert(radius, LENGTH_FEET, LENGTH_METERS)

    if not network_id:
        network_id = yield from CityBikesNetwork.get_closest_network_id(
            hass, latitude, longitude)

    if network_id not in hass.data[DOMAIN][MONITORED_NETWORKS]:
        network = CityBikesNetwork(hass, network_id)
        hass.data[DOMAIN][MONITORED_NETWORKS][network_id] = network
        hass.async_add_job(network.async_refresh)
        async_track_time_interval(hass, network.async_refresh,
                                  SCAN_INTERVAL)
    else:
        network = hass.data[DOMAIN][MONITORED_NETWORKS][network_id]

    yield from network.ready.wait()

    devices = []
    for station in network.stations:
        dist = location.distance(latitude, longitude,
                                 station[ATTR_LATITUDE],
                                 station[ATTR_LONGITUDE])
        station_id = station[ATTR_ID]
        station_uid = str(station.get(ATTR_EXTRA, {}).get(ATTR_UID, ''))

        if radius > dist or stations_list.intersection((station_id,
                                                        station_uid)):
            devices.append(CityBikesStation(network, station_id, name))

    async_add_devices(devices, True)
Beispiel #26
0
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the recorder."""
    conf = config.get(DOMAIN, {})
    purge_days = conf.get(CONF_PURGE_KEEP_DAYS)
    purge_interval = conf.get(CONF_PURGE_INTERVAL)

    db_url = conf.get(CONF_DB_URL, None)
    if not db_url:
        db_url = DEFAULT_URL.format(
            hass_config_path=hass.config.path(DEFAULT_DB_FILE))

    include = conf.get(CONF_INCLUDE, {})
    exclude = conf.get(CONF_EXCLUDE, {})
    instance = hass.data[DATA_INSTANCE] = Recorder(
        hass, uri=db_url, include=include, exclude=exclude)
    instance.async_initialize()
    instance.start()

    @asyncio.coroutine
    def async_handle_purge_interval(now):
        """Handle purge interval."""
        instance.do_purge(purge_days)

    @asyncio.coroutine
    def async_handle_purge_service(service):
        """Handle calls to the purge service."""
        instance.do_purge(service.data[ATTR_KEEP_DAYS])

    descriptions = yield from hass.async_add_job(
        conf_util.load_yaml_config_file, path.join(
            path.dirname(__file__), 'services.yaml'))

    if purge_interval and purge_days:
        async_track_time_interval(hass, async_handle_purge_interval,
                                  timedelta(days=purge_interval))

    hass.services.async_register(DOMAIN, SERVICE_PURGE,
                                 async_handle_purge_service,
                                 descriptions.get(SERVICE_PURGE),
                                 schema=SERVICE_PURGE_SCHEMA)

    return (yield from instance.async_db_ready)
Beispiel #27
0
async def async_setup(hass, config):
    """Initialize the namecheap DNS component."""
    host = config[DOMAIN][CONF_HOST]
    domain = config[DOMAIN][CONF_DOMAIN]
    password = config[DOMAIN][CONF_PASSWORD]

    session = async_get_clientsession(hass)

    result = await _update_namecheapdns(session, host, domain, password)

    if not result:
        return False

    async def update_domain_interval(now):
        """Update the namecheap DNS entry."""
        await _update_namecheapdns(session, host, domain, password)

    async_track_time_interval(hass, update_domain_interval, INTERVAL)

    return result
def async_setup(hass, config):
    """Initialize the NamecheapDNS component."""
    host = config[DOMAIN][CONF_HOST]
    domain = config[DOMAIN][CONF_DOMAIN]
    token = config[DOMAIN][CONF_ACCESS_TOKEN]
    session = async_get_clientsession(hass)

    result = yield from _update_namecheapdns(session, host, domain, token)

    if not result:
        return False

    @asyncio.coroutine
    def update_domain_interval(now):
        """Update the NamecheapDNS entry."""
        yield from _update_namecheapdns(session, host, domain, token)

    async_track_time_interval(hass, update_domain_interval, INTERVAL)

    return result
Beispiel #29
0
def async_setup_sabnzbd(hass, sab_api, config, name):
    """Setup SABnzbd sensors and services."""
    sab_api_data = SabnzbdApiData(sab_api, name, config.get(CONF_SENSORS, {}))

    if config.get(CONF_SENSORS):
        hass.data[DATA_SABNZBD] = sab_api_data
        hass.async_add_job(
            discovery.async_load_platform(hass, 'sensor', DOMAIN, {}, config))

    async def async_service_handler(service):
        """Handle service calls."""
        if service.service == SERVICE_PAUSE:
            await sab_api_data.async_pause_queue()
        elif service.service == SERVICE_RESUME:
            await sab_api_data.async_resume_queue()
        elif service.service == SERVICE_SET_SPEED:
            speed = service.data.get(ATTR_SPEED)
            await sab_api_data.async_set_queue_speed(speed)

    hass.services.async_register(DOMAIN, SERVICE_PAUSE,
                                 async_service_handler,
                                 schema=vol.Schema({}))

    hass.services.async_register(DOMAIN, SERVICE_RESUME,
                                 async_service_handler,
                                 schema=vol.Schema({}))

    hass.services.async_register(DOMAIN, SERVICE_SET_SPEED,
                                 async_service_handler,
                                 schema=SPEED_LIMIT_SCHEMA)

    async def async_update_sabnzbd(now):
        """Refresh SABnzbd queue data."""
        from pysabnzbd import SabnzbdApiException
        try:
            await sab_api.refresh_data()
            async_dispatcher_send(hass, SIGNAL_SABNZBD_UPDATED, None)
        except SabnzbdApiException as err:
            _LOGGER.error(err)

    async_track_time_interval(hass, async_update_sabnzbd, UPDATE_INTERVAL)
async def async_setup(hass, config):
    """Set up the Fast.com component."""
    conf = config[DOMAIN]
    data = hass.data[DOMAIN] = SpeedtestData(hass)

    if not conf[CONF_MANUAL]:
        async_track_time_interval(
            hass, data.update, conf[CONF_SCAN_INTERVAL]
        )

    def update(call=None):
        """Service call to manually update the data."""
        data.update()

    hass.services.async_register(DOMAIN, 'speedtest', update)

    hass.async_create_task(
        async_load_platform(hass, 'sensor', DOMAIN, {}, config)
    )

    return True
    async def async_added_to_hass(self) -> None:
        """Register callbacks when entity is added."""
        await super().async_added_to_hass()

        # Register callback for when config entry is updated.
        self.async_on_remove(
            self._config_entry.add_update_listener(
                self._async_send_update_options_signal))

        # Register callback for update event
        self.async_on_remove(
            async_dispatcher_connect(self.hass, self._config_entry.entry_id,
                                     self._async_update_options))

        # Update state when coordinator updates
        self.async_on_remove(
            self._coordinator.async_add_listener(self.async_write_ha_state))

        # Manually set an update interval so we can disable it if needed
        self.async_on_remove(
            async_track_time_interval(self._hass, self._async_update,
                                      timedelta(seconds=30)))

        if self.id:
            try:
                self._profile = await self._api.async_get_contact_user_profile(
                    self.id)
                status = self._profile["presence_status"]
                _LOGGER.debug("Retrieved initial Zoom status: %s", status)
                self._set_state(status)
                self.async_write_ha_state()
            except HTTPUnauthorized:
                _LOGGER.debug(
                    "User is unauthorized to query presence status, restoring state.",
                    exc_info=True,
                )
                await self._restore_state()
            except:
                _LOGGER.warning(
                    "Error retrieving initial zoom status, restoring state.",
                    exc_info=True,
                )
                await self._restore_state()
        else:
            _LOGGER.debug("ID is unknown, restoring state.")
            await self._restore_state()
Beispiel #32
0
    async def _async_sensor_changed(self, entity_id, old_state, new_state):
        """Handle ambient humidity changes."""
        if new_state is None:
            return

        if self._sensor_stale_duration:
            if self._remove_stale_tracking:
                self._remove_stale_tracking()
            self._remove_stale_tracking = async_track_time_interval(
                self.hass,
                self._async_sensor_not_responding,
                self._sensor_stale_duration,
            )

        await self._async_update_humidity(new_state.state)
        await self._async_operate()
        await self.async_update_ha_state()
    async def async_init(self):
        """Schedule initial and regular updates based on configured time interval."""

        for component in COMPONENTS:
            self._hass.async_create_task(
                self._hass.config_entries.async_forward_entry_setup(
                    self._config_entry, component))

        async def update(event_time):
            """Update."""
            await self.async_update()

        # Trigger updates at regular intervals.
        self._track_time_remove_callback = async_track_time_interval(
            self._hass, update, self._scan_interval)

        _LOGGER.debug("Feed entity manager initialized")
Beispiel #34
0
    async def async_init(self, triggered=None):
        """Initialize the player async."""
        try:
            if self._retry_remove is not None:
                self._retry_remove()
                self._retry_remove = None

            await self.force_update_sync_status(self._init_callback, True)
        except (asyncio.TimeoutError, ClientError):
            _LOGGER.info("Node %s:%s is offline, retrying later", self.host,
                         self.port)
            self._retry_remove = async_track_time_interval(
                self._hass, self.async_init, NODE_RETRY_INITIATION)
        except Exception:
            _LOGGER.exception("Unexpected when initiating error in %s:%s",
                              self.host, self.port)
            raise
Beispiel #35
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Cloudflare from a config entry."""
    cfupdate = CloudflareUpdater(
        async_get_clientsession(hass),
        entry.data[CONF_API_TOKEN],
        entry.data[CONF_ZONE],
        entry.data[CONF_RECORDS],
    )

    try:
        zone_id = await cfupdate.get_zone_id()
    except CloudflareAuthenticationException:
        _LOGGER.error("API access forbidden. Please reauthenticate")
        return False
    except CloudflareConnectionException as error:
        raise ConfigEntryNotReady from error

    async def update_records(now):
        """Set up recurring update."""
        try:
            await _async_update_cloudflare(cfupdate, zone_id)
        except CloudflareException as error:
            _LOGGER.error("Error updating zone %s: %s", entry.data[CONF_ZONE],
                          error)

    async def update_records_service(call):
        """Set up service for manual trigger."""
        try:
            await _async_update_cloudflare(cfupdate, zone_id)
        except CloudflareException as error:
            _LOGGER.error("Error updating zone %s: %s", entry.data[CONF_ZONE],
                          error)

    update_interval = timedelta(minutes=DEFAULT_UPDATE_INTERVAL)
    undo_interval = async_track_time_interval(hass, update_records,
                                              update_interval)

    hass.data[DOMAIN][entry.entry_id] = {
        DATA_UNDO_UPDATE_INTERVAL: undo_interval,
    }

    hass.services.async_register(DOMAIN, SERVICE_UPDATE_RECORDS,
                                 update_records_service)

    return True
Beispiel #36
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""

    if not isinstance(config_entry.data[CONF_SENSOR_ID], int):
        _async_fixup_sensor_id(hass, config_entry,
                               config_entry.data[CONF_SENSOR_ID])

    if (config_entry.data[CONF_SENSOR_ID] in duplicate_stations(hass)
            and config_entry.source == SOURCE_IMPORT):
        _LOGGER.warning(
            "Removing duplicate sensors for station %s",
            config_entry.data[CONF_SENSOR_ID],
        )
        hass.async_create_task(
            hass.config_entries.async_remove(config_entry.entry_id))
        return False

    try:
        luftdaten = LuftDatenData(
            Luftdaten(config_entry.data[CONF_SENSOR_ID]),
            config_entry.data.get(CONF_SENSORS,
                                  {}).get(CONF_MONITORED_CONDITIONS,
                                          SENSOR_KEYS),
        )
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][
            config_entry.entry_id] = luftdaten
    except LuftdatenError as err:
        raise ConfigEntryNotReady from err

    hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass,
            refresh_sensors,
            hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL),
        )

    return True
Beispiel #37
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up WLED from a config entry."""

    # Create WLED instance for this entry
    session = async_get_clientsession(hass)
    wled = WLED(entry.data[CONF_HOST], session=session)

    # Ensure we can connect and talk to it
    try:
        await wled.update()
    except WLEDConnectionError as exception:
        raise ConfigEntryNotReady from exception

    hass.data.setdefault(DOMAIN, {})
    hass.data[DOMAIN][entry.entry_id] = {DATA_WLED_CLIENT: wled}

    # For backwards compat, set unique ID
    if entry.unique_id is None:
        hass.config_entries.async_update_entry(
            entry, unique_id=wled.device.info.mac_address
        )

    # Set up all platforms for this device/entry.
    for component in WLED_COMPONENTS:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component)
        )

    async def interval_update(now: dt_util.dt.datetime = None) -> None:
        """Poll WLED device function, dispatches event after update."""
        try:
            await wled.update()
        except WLEDError:
            _LOGGER.debug("An error occurred while updating WLED", exc_info=True)

        # Even if the update failed, we still send out the event.
        # To allow entities to make themselves unavailable.
        async_dispatcher_send(hass, DATA_WLED_UPDATED, entry.entry_id)

    # Schedule update interval
    hass.data[DOMAIN][entry.entry_id][DATA_WLED_TIMER] = async_track_time_interval(
        hass, interval_update, SCAN_INTERVAL
    )

    return True
Beispiel #38
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""
    from luftdaten import Luftdaten
    from luftdaten.exceptions import LuftdatenError

    if not isinstance(config_entry.data[CONF_SENSOR_ID], int):
        _async_fixup_sensor_id(hass, config_entry,
                               config_entry.data[CONF_SENSOR_ID])

    if (config_entry.data[CONF_SENSOR_ID] in
            duplicate_stations(hass) and config_entry.source == SOURCE_IMPORT):
        _LOGGER.warning("Removing duplicate sensors for station %s",
                        config_entry.data[CONF_SENSOR_ID])
        hass.async_create_task(hass.config_entries.async_remove(
            config_entry.entry_id))
        return False

    session = async_get_clientsession(hass)

    try:
        luftdaten = LuftDatenData(
            Luftdaten(
                config_entry.data[CONF_SENSOR_ID], hass.loop, session),
            config_entry.data.get(CONF_SENSORS, {}).get(
                CONF_MONITORED_CONDITIONS, list(SENSORS)))
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = \
            luftdaten
    except LuftdatenError:
        raise ConfigEntryNotReady

    hass.async_create_task(hass.config_entries.async_forward_entry_setup(
        config_entry, 'sensor'))

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass, refresh_sensors,
            hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL))

    return True
Beispiel #39
0
    def async_start_exchange(self) -> None:
        """Start the device auth exchange flow polling."""
        _LOGGER.debug("Starting exchange flow")
        max_timeout = dt.utcnow() + datetime.timedelta(
            seconds=EXCHANGE_TIMEOUT_SECONDS)
        # For some reason, oauth.step1_get_device_and_user_codes() returns a datetime
        # object without tzinfo. For the comparison below to work, it needs one.
        user_code_expiry = self._device_flow_info.user_code_expiry.replace(
            tzinfo=datetime.timezone.utc)
        expiration_time = min(user_code_expiry, max_timeout)

        self._exchange_task_unsub = async_track_time_interval(
            self._hass,
            self._async_poll_attempt,
            datetime.timedelta(seconds=self._device_flow_info.interval),
        )
        self._timeout_unsub = async_track_point_in_utc_time(
            self._hass, self._async_timeout, expiration_time)
Beispiel #40
0
    def async_init(self):
        """Initiate the player async."""
        try:
            if self._retry_remove is not None:
                self._retry_remove()
                self._retry_remove = None

            yield from self._internal_update_sync_status(
                self._init_callback, True)
        except (asyncio.TimeoutError, ClientError):
            _LOGGER.info("Bluesound node %s is offline, retrying later",
                         self.host)
            self._retry_remove = async_track_time_interval(
                self._hass, self.async_init, NODE_RETRY_INITIATION)
        except:
            _LOGGER.exception("Unexpected when initiating error in %s",
                              self.host)
            raise
Beispiel #41
0
    async def async_register_api_interest(self, sensor_type):
        """Increment the number of entities with data needs from an API category."""
        # If this is the first registration we have, start a time interval:
        if not self._async_cancel_time_interval_listener:
            self._async_cancel_time_interval_listener = async_track_time_interval(
                self._hass,
                self._async_update_listener_action,
                DEFAULT_SCAN_INTERVAL,
            )

        api_category = async_get_api_category(sensor_type)
        self._api_category_count[api_category] += 1

        # If a sensor registers interest in a particular API call and the data doesn't
        # exist for it yet, make the API call and grab the data:
        async with self._api_category_locks[api_category]:
            if api_category not in self.data:
                await self._async_get_data_from_api(api_category)
Beispiel #42
0
    async def async_start(self) -> None:
        """Start the scanner."""
        self.description_manager = DescriptionManager(self.hass)
        self.flow_dispatcher = FlowDispatcher(self.hass)
        for source_ip in await self._async_build_source_set():
            self._ssdp_listeners.append(
                SSDPListener(async_callback=self._async_process_entry,
                             source_ip=source_ip))

        self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                        self.async_stop)
        self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED,
                                        self.flow_dispatcher.async_start)
        await asyncio.gather(
            *[listener.async_start() for listener in self._ssdp_listeners])
        self._cancel_scan = async_track_time_interval(self.hass,
                                                      self.async_scan,
                                                      SCAN_INTERVAL)
Beispiel #43
0
 async def async_added_to_hass(self):
     """Run when about to be added to hass."""
     await super().async_added_to_hass()
     self.async_accept_signal(self._on_off_channel, SIGNAL_ATTR_UPDATED,
                              self.async_set_state)
     if self._level_channel:
         self.async_accept_signal(self._level_channel, SIGNAL_SET_LEVEL,
                                  self.set_level)
     refresh_interval = random.randint(*(x * 60
                                         for x in self._REFRESH_INTERVAL))
     self._cancel_refresh_handle = async_track_time_interval(
         self.hass, self._refresh, timedelta(seconds=refresh_interval))
     self.async_accept_signal(
         None,
         SIGNAL_LIGHT_GROUP_STATE_CHANGED,
         self._maybe_force_refresh,
         signal_override=True,
     )
Beispiel #44
0
    async def async_setup(self):
        """Start interacting with the NAS."""
        self._dsm = SynologyDSM(
            self._host,
            self._port,
            self._username,
            self._password,
            self._use_ssl,
            dsm_version=self._api_version,
        )
        self.information = self._dsm.information
        self.utilisation = self._dsm.utilisation
        self.storage = self._dsm.storage

        await self.update()

        self._unsub_dispatcher = async_track_time_interval(
            self._hass, self.update, SCAN_INTERVAL)
Beispiel #45
0
async def async_setup_entry(hass, config_entry):
    """Set up OpenUV as config entry."""
    from pyopenuv import Client
    from pyopenuv.errors import OpenUvError

    try:
        websession = aiohttp_client.async_get_clientsession(hass)
        openuv = OpenUV(
            Client(config_entry.data[CONF_API_KEY],
                   config_entry.data.get(CONF_LATITUDE, hass.config.latitude),
                   config_entry.data.get(CONF_LONGITUDE,
                                         hass.config.longitude),
                   websession,
                   altitude=config_entry.data.get(CONF_ELEVATION,
                                                  hass.config.elevation)),
            config_entry.data.get(CONF_BINARY_SENSORS,
                                  {}).get(CONF_MONITORED_CONDITIONS,
                                          list(BINARY_SENSORS)),
            config_entry.data.get(CONF_SENSORS,
                                  {}).get(CONF_MONITORED_CONDITIONS,
                                          list(SENSORS)))
        await openuv.async_update()
        hass.data[DOMAIN][DATA_OPENUV_CLIENT][config_entry.entry_id] = openuv
    except OpenUvError as err:
        _LOGGER.error('Config entry failed: %s', err)
        raise ConfigEntryNotReady

    for component in ('binary_sensor', 'sensor'):
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(
                config_entry, component))

    async def refresh(event_time):
        """Refresh OpenUV data."""
        _LOGGER.debug('Refreshing OpenUV data')
        await openuv.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_OPENUV_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass, refresh,
            timedelta(seconds=config_entry.data[CONF_SCAN_INTERVAL]))

    return True
Beispiel #46
0
    def __init__(
        self,
        hass: HomeAssistant,
        zigpy_device: zha_typing.ZigpyDeviceType,
        zha_gateway: zha_typing.ZhaGatewayType,
    ) -> None:
        """Initialize the gateway."""
        self.hass = hass
        self._zigpy_device = zigpy_device
        self._zha_gateway = zha_gateway
        self._available = False
        self._available_signal = f"{self.name}_{self.ieee}_{SIGNAL_AVAILABLE}"
        self._checkins_missed_count = 0
        self.unsubs = []
        self.quirk_applied = isinstance(self._zigpy_device, zigpy.quirks.CustomDevice)
        self.quirk_class = (
            f"{self._zigpy_device.__class__.__module__}."
            f"{self._zigpy_device.__class__.__name__}"
        )

        if self.is_mains_powered:
            self.consider_unavailable_time = async_get_zha_config_value(
                self._zha_gateway.config_entry,
                ZHA_OPTIONS,
                CONF_CONSIDER_UNAVAILABLE_MAINS,
                CONF_DEFAULT_CONSIDER_UNAVAILABLE_MAINS,
            )
        else:
            self.consider_unavailable_time = async_get_zha_config_value(
                self._zha_gateway.config_entry,
                ZHA_OPTIONS,
                CONF_CONSIDER_UNAVAILABLE_BATTERY,
                CONF_DEFAULT_CONSIDER_UNAVAILABLE_BATTERY,
            )

        keep_alive_interval = random.randint(*_UPDATE_ALIVE_INTERVAL)
        self.unsubs.append(
            async_track_time_interval(
                self.hass, self._check_available, timedelta(seconds=keep_alive_interval)
            )
        )
        self._ha_device_id = None
        self.status = DeviceStatus.CREATED
        self._channels = channels.Channels(self)
Beispiel #47
0
async def async_setup_entry(hass, config_entry):
    """Set up SimpliSafe as config entry."""
    from simplipy import API
    from simplipy.errors import InvalidCredentialsError, SimplipyError

    websession = aiohttp_client.async_get_clientsession(hass)

    try:
        simplisafe = await API.login_via_token(
            config_entry.data[CONF_TOKEN], websession)
    except InvalidCredentialsError:
        _LOGGER.error('Invalid credentials provided')
        return False
    except SimplipyError as err:
        _LOGGER.error('Config entry failed: %s', err)
        raise ConfigEntryNotReady

    _async_save_refresh_token(hass, config_entry, simplisafe.refresh_token)

    systems = await simplisafe.get_systems()
    hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = systems

    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(
            config_entry, 'alarm_control_panel'))

    async def refresh(event_time):
        """Refresh data from the SimpliSafe account."""
        for system in systems:
            _LOGGER.debug('Updating system data: %s', system.system_id)
            await system.update()
            async_dispatcher_send(hass, TOPIC_UPDATE.format(system.system_id))

            if system.api.refresh_token_dirty:
                _async_save_refresh_token(
                    hass, config_entry, system.api.refresh_token)

    hass.data[DOMAIN][DATA_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass,
            refresh,
            timedelta(seconds=config_entry.data[CONF_SCAN_INTERVAL]))

    return True
Beispiel #48
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Atag integration from a config entry."""
    session = async_get_clientsession(hass)
    atag = AtagDataStore(session, paired=True, **entry.data)

    try:
        await atag.async_update()
        if not atag.sensordata:
            raise ConfigEntryNotReady
    except AtagException:
        raise ConfigEntryNotReady
    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = atag

    device_registry = await dr.async_get_registry(hass)
    device_registry.async_get_or_create(
        config_entry_id=entry.entry_id,
        identifiers={(DOMAIN, atag.device, atag.config.host)},
        manufacturer=PROJECT_URL,
        name="Atag",
        model="Atag One",
        sw_version=atag.apiversion,
    )

    for platform in PLATFORMS:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, platform)
        )

    async def refresh(event_time):
        """Poll Atag for latest data"""
        await atag.async_update()
        dispatcher.async_dispatcher_send(hass, SIGNAL_UPDATE_ATAG)

    async def async_close_session(event):
        """Close the session on shutdown."""
        await atag.async_close()

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_close_session)

    hass.data.setdefault(DATA_LISTENER, {})[entry.entry_id] = async_track_time_interval(
        hass, refresh, timedelta(seconds=entry.data[CONF_SCAN_INTERVAL])
    )

    return True
Beispiel #49
0
    async def async_start(self) -> None:
        """Start the scanners."""
        session = async_get_clientsession(self.hass)
        requester = AiohttpSessionRequester(session, True, 10)
        self._description_cache = DescriptionCache(requester)
        self._flow_dispatcher = FlowDispatcher(self.hass)

        await self._async_start_ssdp_listeners()

        self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                        self.async_stop)
        self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED,
                                        self._flow_dispatcher.async_start)
        self._cancel_scan = async_track_time_interval(self.hass,
                                                      self.async_scan,
                                                      SCAN_INTERVAL)

        # Trigger the initial-scan.
        await self.async_scan()
Beispiel #50
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""
    hass.data.setdefault(
        DOMAIN,
        {
            DATA_LUFTDATEN_CLIENT: {},
            DATA_LUFTDATEN_LISTENER: {},
        },
    )

    # For backwards compat, set unique ID
    if config_entry.unique_id is None:
        hass.config_entries.async_update_entry(
            config_entry, unique_id=config_entry.data[CONF_SENSOR_ID])

    try:
        luftdaten = LuftDatenData(
            Luftdaten(config_entry.data[CONF_SENSOR_ID]),
            config_entry.data.get(CONF_SENSORS,
                                  {}).get(CONF_MONITORED_CONDITIONS,
                                          SENSOR_KEYS),
        )
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][
            config_entry.entry_id] = luftdaten
    except LuftdatenError as err:
        raise ConfigEntryNotReady from err

    hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass,
            refresh_sensors,
            hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL),
        )

    return True
Beispiel #51
0
async def async_setup(hass, config):
    """Iniatilize ATAG Component"""
    conf = config[DOMAIN]
    hass.data[DOMAIN] = {}
    host = conf.get(CONF_HOST)
    email = conf.get(CONF_EMAIL)
    interface = conf.get(CONF_INTERFACE)
    port = conf.get(CONF_PORT)
    scan_interval = conf.get(CONF_SCAN_INTERVAL)
    sensors = conf.get(CONF_SENSORS)
    session = async_get_clientsession(hass)

    _LOGGER.debug('Initializing ATAG...')
    from pyatag.gateway import AtagDataStore
    atagunit = AtagDataStore(host=host,
                             port=port,
                             mail=email,
                             interface=interface,
                             session=session)

    hass.data[DOMAIN][ATAG_HANDLE] = atagunit
    _LOGGER.debug('Datastore initialized')
    for platform in ('sensor', 'climate', 'water_heater'):
        hass.async_create_task(
            async_load_platform(hass, platform, DOMAIN, {'sensors': sensors},
                                config))

    async def async_hub_refresh(event_time):  # pylint: disable=unused-argument
        """Call Atag to refresh information."""
        await hass.data[DOMAIN][ATAG_HANDLE].async_update()
        async_dispatcher_send(hass, SIGNAL_UPDATE_ATAG)

    async def async_close_atag(event):  # pylint: disable=unused-argument
        """Close Atag connection on HA Stop."""
        _LOGGER.debug('Closing connection to ATAG...')
        await hass.data[DOMAIN][ATAG_HANDLE].async_close()

    hass.services.async_register(DOMAIN, 'update', async_hub_refresh)
    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_close_atag)

    hass.data[DOMAIN][DATA_LISTENER] = async_track_time_interval(
        hass, async_hub_refresh, scan_interval)
    return True
Beispiel #52
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Gree Climate from a config entry."""
    hass.data.setdefault(DOMAIN, {})
    gree_discovery = DiscoveryService(hass)
    hass.data[DATA_DISCOVERY_SERVICE] = gree_discovery

    hass.data[DOMAIN].setdefault(DISPATCHERS, [])
    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    async def _async_scan_update(_=None):
        await gree_discovery.discovery.scan()

    _LOGGER.debug("Scanning network for Gree devices")
    await _async_scan_update()

    hass.data[DOMAIN][DATA_DISCOVERY_INTERVAL] = async_track_time_interval(
        hass, _async_scan_update, timedelta(seconds=DISCOVERY_SCAN_INTERVAL))

    return True
Beispiel #53
0
    async def listen(self):
        _LOGGER.info(f"Starting to listen connected")

        subscription_data = self.get_subscription_data()
        await self._ws.send_str(subscription_data)

        _LOGGER.info('Subscribed to WS payloads')

        remove_time_tracker = async_track_time_interval(self._hass, self._send_keep_alive, WS_KEEP_ALIVE_INTERVAL)

        async for msg in self._ws:
            continue_to_next = self.handle_next_message(msg)

            if not continue_to_next or not self.is_initialized:
                break

        remove_time_tracker()

        _LOGGER.info(f'Stop listening')
Beispiel #54
0
    def updater_restart(self) -> None:
        log_prefix = self.log_prefix
        scan_interval = self.scan_interval

        self.updater_stop()

        async def _update_entity(*_):
            nonlocal self
            _LOGGER.debug(log_prefix + f"Executing updater on interval")
            await self.async_update_ha_state(force_refresh=True)

        _LOGGER.debug(log_prefix + f"Starting updater "
                      f"(interval: {scan_interval.total_seconds()} seconds, "
                      f"next call: {as_local(utcnow()) + scan_interval})")
        self._entity_updater = async_track_time_interval(
            self.hass,
            _update_entity,
            scan_interval,
        )
Beispiel #55
0
    async def start_exchange_task(
        self, finished_cb: Callable[[Credentials | None], Awaitable[None]]
    ) -> None:
        """Start the device auth exchange flow polling.

        The callback is invoked with the valid credentials or with None on timeout.
        """
        _LOGGER.debug("Starting exchange flow")
        assert not self._exchange_task_unsub
        max_timeout = dt.utcnow() + datetime.timedelta(seconds=EXCHANGE_TIMEOUT_SECONDS)
        # For some reason, oauth.step1_get_device_and_user_codes() returns a datetime
        # object without tzinfo. For the comparison below to work, it needs one.
        user_code_expiry = self._device_flow_info.user_code_expiry.replace(
            tzinfo=datetime.timezone.utc
        )
        expiration_time = min(user_code_expiry, max_timeout)

        def _exchange() -> Credentials:
            return self._oauth_flow.step2_exchange(
                device_flow_info=self._device_flow_info
            )

        async def _poll_attempt(now: datetime.datetime) -> None:
            assert self._exchange_task_unsub
            _LOGGER.debug("Attempting OAuth code exchange")
            # Note: The callback is invoked with None when the device code has expired
            creds: Credentials | None = None
            if now < expiration_time:
                try:
                    creds = await self._hass.async_add_executor_job(_exchange)
                except FlowExchangeError:
                    _LOGGER.debug("Token not yet ready; trying again later")
                    return
            self._exchange_task_unsub()
            self._exchange_task_unsub = None
            await finished_cb(creds)

        self._exchange_task_unsub = async_track_time_interval(
            self._hass,
            _poll_attempt,
            datetime.timedelta(seconds=self._device_flow_info.interval),
        )
Beispiel #56
0
    def _create_updater(self, device_id: DeviceID, commands: Set[str], interval: timedelta) -> Callable:
        """
        Create updater for device.
        :param device_id: Device ID to poll
        :param commands: Commands to send on polling
        :param interval: Interval with which to poll
        :return: Updater cancel function
        """
        async def call_command(*_):
            device = self.devices.get(device_id)
            if device is None:
                _LOGGER.debug('Device with ID "%s" is missing, cannot run updater' % device_id)
                return

            _LOGGER.debug('Running updater for device "%s" with commands: %s' % (device_id, ', '.join(commands)))
            device = self.devices[device_id]
            command_iter = iter(commands)
            first_command = next(command_iter)

            _LOGGER.debug('Running update command: %s' % first_command)
            await device.command(first_command)
            for command in command_iter:
                _LOGGER.debug('Sleeping for %d seconds before running command: %s' % (DEFAULT_SLEEP_INTERVAL, command))
                await asyncio.sleep(DEFAULT_SLEEP_INTERVAL)
                _LOGGER.debug('Running update command: %s' % command)
                await device.command(command)

        len_cmd = len(commands)
        # assumed: 1 second per command, N second(-s) intervals between commands
        min_seconds = len_cmd + (len_cmd - 1) * DEFAULT_SLEEP_INTERVAL
        if interval.seconds < min_seconds:
            _LOGGER.warning('Interval provided for updater (%d seconds) is too low to perform updates! '
                            'Adjusted automatically to %d seconds to prevent hiccups.'
                            % (interval.seconds, min_seconds))
            interval = timedelta(seconds=min_seconds)

        # noinspection PyTypeChecker
        return async_track_time_interval(
            hass=self.hass,
            action=call_command,
            interval=interval
        )
Beispiel #57
0
    async def setup(self) -> None:
        """Set up a AsusWrt router."""
        self._api = get_api(dict(self._entry.data), self._options)

        try:
            await self._api.connection.async_connect()
        except OSError as exp:
            raise ConfigEntryNotReady from exp

        if not self._api.is_connected:
            raise ConfigEntryNotReady

        # System
        model = await _get_nvram_info(self._api, "MODEL")
        if model and "model" in model:
            self._model = model["model"]
        firmware = await _get_nvram_info(self._api, "FIRMWARE")
        if firmware and "firmver" in firmware and "buildno" in firmware:
            self._sw_v = f"{firmware['firmver']} (build {firmware['buildno']})"

        # Load tracked entities from registry
        entity_registry = await self.hass.helpers.entity_registry.async_get_registry()
        track_entries = (
            self.hass.helpers.entity_registry.async_entries_for_config_entry(
                entity_registry, self._entry.entry_id
            )
        )
        for entry in track_entries:
            if entry.domain == TRACKER_DOMAIN:
                self._devices[entry.unique_id] = AsusWrtDevInfo(
                    entry.unique_id, entry.original_name
                )

        # Update devices
        await self.update_devices()

        # Init Sensors
        await self.init_sensors_coordinator()

        self.async_on_close(
            async_track_time_interval(self.hass, self.update_all, SCAN_INTERVAL)
        )
Beispiel #58
0
    async def _start_updater(delay: Union[float, int, timedelta] = 0):
        if not isinstance(delay, timedelta):
            # Convert integers and floats to timedelta objects
            delay = timedelta(seconds=delay)

        # Check whether delay is required
        if delay.total_seconds():
            # Schedule updater to start with a `start_after` delay
            call_at = utcnow() + delay
            _LOGGER.debug('Scheduling updater for account "%s" at %s' % (
                username,
                call_at,
            ))

            def _internal_start_updater(*_):
                _LOGGER.debug(
                    'Executing scheduled updater initialization for account "%s"'
                    % (username, ))
                hass.async_run_job(_start_updater)

            _cancel_updater = async_track_point_in_time(
                hass, _internal_start_updater, call_at)

        else:
            try:
                # Run updater once before establishing schedule
                await _account_changes_updater()

            except PandoraOnlineException:
                _LOGGER.exception('Error occurred while running updater:')

            # Schedule updater to run with configured polling interval
            _cancel_updater = async_track_time_interval(
                hass=hass,
                action=_account_changes_updater,
                interval=pandora_cfg[CONF_POLLING_INTERVAL])

        if username in hass.data[DATA_UPDATERS]:
            # Cancel previous updater schedule
            hass.data[DATA_UPDATERS][username][1]()

        hass.data[DATA_UPDATERS][username] = (_start_updater, _cancel_updater)
Beispiel #59
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Gree Climate from a config entry."""
    hass.data.setdefault(DOMAIN, {})
    gree_discovery = DiscoveryService(hass)
    hass.data[DATA_DISCOVERY_SERVICE] = gree_discovery

    hass.data[DOMAIN].setdefault(DISPATCHERS, [])
    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

    async def _async_scan_update(_=None):
        bcast_addr = list(await async_get_ipv4_broadcast_addresses(hass))
        await gree_discovery.discovery.scan(0, bcast_ifaces=bcast_addr)

    _LOGGER.debug("Scanning network for Gree devices")
    await _async_scan_update()

    hass.data[DOMAIN][DATA_DISCOVERY_INTERVAL] = async_track_time_interval(
        hass, _async_scan_update, timedelta(seconds=DISCOVERY_SCAN_INTERVAL))

    return True
    async def setup(self) -> None:
        """Set up a Freebox router."""
        self._api = await get_api(self.hass, self._host)

        try:
            await self._api.open(self._host, self._port)
        except HttpRequestError:
            _LOGGER.exception("Failed to connect to Freebox")
            return ConfigEntryNotReady

        # System
        fbx_config = await self._api.system.get_config()
        self.mac = fbx_config["mac"]
        self.name = fbx_config["model_info"]["pretty_name"]
        self._sw_v = fbx_config["firmware_version"]

        # Devices & sensors
        await self.update_all()
        self._unsub_dispatcher = async_track_time_interval(
            self.hass, self.update_all, SCAN_INTERVAL)