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
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)
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
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))
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))
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)
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
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
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)
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)
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
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
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)
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
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)
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)
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
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()
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")
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
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
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
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
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
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)
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
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)
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)
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, )
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)
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
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)
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
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
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()
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
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
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
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')
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, )
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), )
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 )
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) )
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)
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)