def test_track_point_in_time(self): """Test track point in time.""" before_birthday = datetime(1985, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) birthday_paulus = datetime(1986, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) after_birthday = datetime(1987, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) runs = [] track_point_in_utc_time( self.hass, lambda x: runs.append(1), birthday_paulus) self._send_time_changed(before_birthday) self.hass.pool.block_till_done() self.assertEqual(0, len(runs)) self._send_time_changed(birthday_paulus) self.hass.pool.block_till_done() self.assertEqual(1, len(runs)) # A point in time tracker will only fire once, this should do nothing self._send_time_changed(birthday_paulus) self.hass.pool.block_till_done() self.assertEqual(1, len(runs)) track_point_in_time( self.hass, lambda x: runs.append(1), birthday_paulus) self._send_time_changed(after_birthday) self.hass.pool.block_till_done() self.assertEqual(2, len(runs))
def update(now): """Update status from Volkswagen Carnet""" try: # check if we can login again if not connection.logged_in: connection._login() if not connection.logged_in: _LOGGER.warning( 'Could not login to volkswagen carnet, please check your credentials' ) return False else: if not connection.update(request_data=False): _LOGGER.warning( "Could not query update from volkswagen carnet") return False else: _LOGGER.debug("Updating data from volkswagen carnet") for vehicle in connection.vehicles: if vehicle.vin not in data.vehicles: _LOGGER.info( "Adding data for VIN: %s from carnet" % vehicle.vin.lower()) discover_vehicle(vehicle) for entity in data.entities[vehicle.vin]: entity.schedule_update_ha_state() dispatcher_send(hass, SIGNAL_STATE_UPDATED, vehicle) return True finally: track_point_in_utc_time(hass, update, utcnow() + interval)
def track_point_in_utc_time(self, action, point_in_time): """Deprecated method as of 8/4/2015 to track point in UTC time.""" _LOGGER.warning( 'hass.track_point_in_utc_time is deprecated. ' 'Please use homeassistant.helpers.event.track_point_in_utc_time') import homeassistant.helpers.event as helper helper.track_point_in_utc_time(self, action, point_in_time)
def run(self): """Start processing events to save.""" self._setup_connection() self._setup_run() if self.purge_days is not None: track_point_in_utc_time(self.hass, lambda now: self._purge_old_data(), dt_util.utcnow() + timedelta(minutes=5)) while True: event = self.queue.get() if event == self.quit_object: self._close_run() self._close_connection() self.queue.task_done() return elif event.event_type == EVENT_TIME_CHANGED: self.queue.task_done() continue event_id = self.record_event(event) if event.event_type == EVENT_STATE_CHANGED: self.record_state(event.data['entity_id'], event.data.get('new_state'), event_id) self.queue.task_done()
def _start_moving_device(self, animation: AnimationValue): """Start the update loop.""" if self._moving_state == MovingState.STILL: _LOGGER.debug("not moving still device %s", self._uuid) return keyframes = len(animation.keyframes) keyframe = animation.keyframes[keyframes - 1] current_time = time.time() end_time = animation.start + keyframe.duration + keyframe.delay delta = end_time - current_time moving = current_time < end_time _LOGGER.debug( "moving device %s with current_time %s and end_time %s: %s", self._uuid, current_time, end_time, moving, ) if moving: track_point_in_utc_time( self.hass, self._end_moving_device, utcnow() + timedelta(seconds=delta + INCREASED_INTERVAL_DELTA), ) else: _LOGGER.debug("end moving device %s due to too old data", self._uuid) self._end_moving_device()
def run(self): """Start processing events to save.""" self._setup_connection() self._setup_run() if self.purge_days is not None: track_point_in_utc_time(self.hass, lambda now: self._purge_old_data(), dt_util.utcnow() + timedelta(minutes=5)) while True: event = self.queue.get() if event == self.quit_object: self._close_run() self._close_connection() self.queue.task_done() return elif event.event_type == EVENT_TIME_CHANGED: self.queue.task_done() continue event_id = self.record_event(event) if event.event_type == EVENT_STATE_CHANGED: self.record_state( event.data['entity_id'], event.data.get('new_state'), event_id) self.queue.task_done()
def point_in_time_listener(self, now): """Called when the state of the sun has changed.""" self.update_as_of(now) self.update_ha_state() # Schedule next update at next_change+1 second so sun state has changed track_point_in_utc_time(self.hass, self.point_in_time_listener, self.next_change + timedelta(seconds=1))
def _workout_text(now=None): nonlocal workout_text nonlocal last_workout_time last_workout = endomondo.get_workouts()[0] if not now: now = dt_util.utcnow() now = dt_util.as_local(now) if (now - dt_util.as_local( last_workout.start_time)).total_seconds() > 3600 * 24: workout_text = None return last_workout_time = last_workout.start_time workout_text = "Bra jobbet Daniel! I dag har du trent i " + str( int(last_workout.duration / 3600)) + " timer og " + str( int((last_workout.duration - int(last_workout.duration / 3600) * 3600) / 60)) + " minutter. Distanse " + num2str( last_workout.distance ) + " kilometer. Du har forbrent " + num2str( last_workout.burgers_burned) + " burgere. \n" if last_workout.live: track_point_in_utc_time(hass, _workout_text, now + timedelta(seconds=30))
def update(now): """Update the car on every interval time.""" try: for tracker in trackers: tracker.update() finally: track_point_in_utc_time(hass, update, now + interval)
def point_in_time_listener(self, now): """Called when the state of the sun has changed.""" self.update_as_of(now) self.update_ha_state() # Schedule next update at next_change+1 second so sun state has changed track_point_in_utc_time(self.hass, self.point_in_time_listener, self.next_change + timedelta(seconds=1))
def update(self, *args): """Periodically poll the servers for current state.""" _LOGGER.debug("Updating") try: self._sync() finally: track_point_in_utc_time( self._hass, self.update, utcnow() + self._interval)
def update(self, now): """Schedule & process the scanner data.""" _LOGGER.debug("Update") try: self.process() except RuntimeError as error: _LOGGER.error("Error updating BLE data: %s", error) track_point_in_utc_time(self._hass, self.update, dt.utcnow() + timedelta(seconds=self._period))
def update_ble(now): """Lookup Bluetooth LE devices and update status.""" period = config[CONF_PERIOD] _LOGGER.debug("update_ble called") try: discover_ble_devices(config, aeskeys, whitelist) except RuntimeError as error: _LOGGER.error("Error during Bluetooth LE scan: %s", error) track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + timedelta(seconds=period))
def update_ble(now): period = config[CONF_PERIOD] try: discover_ble_device(config) except RuntimeError as error: _LOGGER.error("Error during Bluetooth LE scan: %s", error) track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + timedelta(seconds=period))
def run(self): """Start processing events to save.""" from homeassistant.components.recorder.models import Events, States import sqlalchemy.exc while True: try: self._setup_connection() self._setup_run() break except sqlalchemy.exc.SQLAlchemyError as e: log_error(e, retry_wait=CONNECT_RETRY_WAIT, rollback=False, message="Error during connection setup: %s") if self.purge_days is not None: def purge_ticker(event): """Rerun purge every second day.""" self._purge_old_data() track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(days=2)) track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(minutes=5)) while True: event = self.queue.get() if event == self.quit_object: self._close_run() self._close_connection() # pylint: disable=global-statement global _INSTANCE _INSTANCE = None self.queue.task_done() return if event.event_type == EVENT_TIME_CHANGED: self.queue.task_done() continue dbevent = Events.from_event(event) self._commit(dbevent) if event.event_type != EVENT_STATE_CHANGED: self.queue.task_done() continue dbstate = States.from_event(event) dbstate.event_id = dbevent.event_id self._commit(dbstate) self.queue.task_done()
def _setup_listeners(): """Ensure we test the non-async version.""" utc_now = dt_util.utcnow() with pytest.raises(TypeError): track_point_in_utc_time("nothass", run_callback, utc_now) unsub1 = hass.helpers.event.track_point_in_utc_time( run_callback, utc_now + timedelta(seconds=0.1)) hass.helpers.event.track_point_in_utc_time( run_callback, utc_now + timedelta(seconds=0.1)) unsub1()
def update(now): """Update status from the online service.""" try: if not connection.update(): _LOGGER.warning("Could not query server") return False for vehicle in connection.vehicles: update_vehicle(vehicle) return True finally: track_point_in_utc_time(hass, update, utcnow() + interval)
def update(now): """Update status from the online service.""" try: if not connection.update(): _LOGGER.warning('Could not query server') return False for vehicle in connection.vehicles: update_vehicle(vehicle) return True finally: track_point_in_utc_time(hass, update, utcnow() + interval)
def update_ble_loop(now) -> None: """Lookup Bluetooth LE devices and update status.""" _LOGGER.debug("update_ble_loop called") try: # Time to make the dounuts update_ble_devices(config) except RuntimeError as error: _LOGGER.error("Error during Bluetooth LE scan: %s", error) time_offset = dt_util.utcnow() + timedelta(seconds=config[CONF_PERIOD]) # update_ble_loop() will be called again after time_offset track_point_in_utc_time(hass, update_ble_loop, time_offset)
def run(self): """Start processing events to save.""" from homeassistant.components.recorder.models import Events, States import sqlalchemy.exc while True: try: self._setup_connection() self._setup_run() break except sqlalchemy.exc.SQLAlchemyError as e: log_error(e, retry_wait=CONNECT_RETRY_WAIT, rollback=False, message="Error during connection setup: %s") if self.purge_days is not None: def purge_ticker(event): """Rerun purge every second day.""" self._purge_old_data() track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(days=2)) track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(minutes=5)) while True: event = self.queue.get() if event == self.quit_object: self._close_run() self._close_connection() # pylint: disable=global-statement global _INSTANCE _INSTANCE = None self.queue.task_done() return if event.event_type == EVENT_TIME_CHANGED: self.queue.task_done() continue dbevent = Events.from_event(event) self._commit(dbevent) if event.event_type != EVENT_STATE_CHANGED: self.queue.task_done() continue dbstate = States.from_event(event) dbstate.event_id = dbevent.event_id self._commit(dbstate) self.queue.task_done()
def update_bluetooth(now): """Lookup bluetooth device and update status.""" try: for mac in devs_to_track: _LOGGER.debug("Scanning " + mac) result = bluetooth.lookup_name(mac, timeout=5) if not result: # Could not lookup device name continue see_device((mac, result)) except bluetooth.BluetoothError: _LOGGER.exception('Error looking up bluetooth device!') track_point_in_utc_time(hass, update_bluetooth, now + timedelta(seconds=interval))
def update_devices(self) -> None: """Update iCloud devices.""" if self.api is None: return api_devices = {} try: api_devices = self.api.devices except PyiCloudNoDevicesException: _LOGGER.error("No iCloud device found") return except Exception as err: # pylint: disable=broad-except _LOGGER.error("Unknown iCloud error: %s", err) self._fetch_interval = 5 dispatcher_send(self.hass, SERVICE_UPDATE) track_point_in_utc_time( self.hass, self.keep_alive, utcnow() + timedelta(minutes=self._fetch_interval), ) return # Gets devices infos for device in api_devices: status = device.status(DEVICE_STATUS_SET) device_id = status[DEVICE_ID] device_name = status[DEVICE_NAME] if self._devices.get(device_id, None) is not None: # Seen device -> updating _LOGGER.debug("Updating iCloud device: %s", device_name) self._devices[device_id].update(status) else: # New device, should be unique _LOGGER.debug( "Adding iCloud device: %s [model: %s]", device_name, status[DEVICE_RAW_DEVICE_MODEL], ) self._devices[device_id] = IcloudDevice(self, device, status) self._devices[device_id].update(status) self._fetch_interval = self._determine_interval() dispatcher_send(self.hass, SERVICE_UPDATE) track_point_in_utc_time( self.hass, self.keep_alive, utcnow() + timedelta(minutes=self._fetch_interval), )
def update(now): """Update status from the online service.""" _LOGGER.info("Updating") try: res, vehicles = connection.update() if not res: _LOGGER.error("Could not query server") return False for vehicle in vehicles: _see_vehicle(vehicle) return True finally: track_point_in_utc_time(hass, update, now + interval)
def update(now): """Update status from the online service.""" _LOGGER.info("Updating") try: res, vehicles = connection.update() if not res: _LOGGER.error("Could not query server") return False for vehicle in vehicles: _see_vehicle(vehicle) return True finally: track_point_in_utc_time(hass, update, now + interval)
def set_blind_position(self, blind, position): self._pending_blind_positions[blind.encoded_mac] = position if self._cancel_pending_blind_position_timer is not None: self._cancel_pending_blind_position_timer() self._cancel_pending_blind_position_timer = track_point_in_utc_time( self._hass, self._set_blind_positions, utcnow() + timedelta(seconds=POSITION_BATCHING_DELAY_SEC))
def __init__(self, hass, username, password): from . import smartblinds #from smartblinds_client import SmartBlindsClient self._hass = hass #self._sbclient = SmartBlindsClient(username=username, password=password) self._sbclient = smartblinds.SmartBlindsClient(username=username, password=password) self._blinds = [] self._rooms = [] self._blind_states = {} self._blinds_by_mac = {} self._pending_blind_positions = {} self._cancel_pending_blind_position_timer = None self.entities = [] track_time_interval(hass, self._update_periodic, timedelta(minutes=POLLING_INTERVAL_MINUTES)) track_point_in_utc_time(hass, self._update_periodic, utcnow() + timedelta(seconds=10))
def _update_callback(self, msg): """Update the sensor's state, if needed.""" _LOGGER.debug("Callback signal from: %s", msg) if self._delay > 0 and not self.is_on: # Set timer to wait until updating the state def _delay_update(now): """Timer callback for sensor update.""" _LOGGER.debug("%s Called delayed (%ssec) update", self._name, self._delay) self.schedule_update_ha_state() self._timer = None if self._timer is not None: self._timer() self._timer = None self._timer = track_point_in_utc_time( self._hass, _delay_update, utcnow() + timedelta(seconds=self._delay)) elif self._delay > 0 and self.is_on: # For delayed sensors kill any callbacks on true events and update if self._timer is not None: self._timer() self._timer = None self.schedule_update_ha_state() else: self.schedule_update_ha_state()
def scheduled(retry=0, untrack=None, event=None): """Call the target method. It is called directly at the first time and then called scheduled within the Hass mainloop. """ if untrack is not None: wrapper._retry_queue.remove(untrack) # pylint: disable=broad-except try: method(*args, **kwargs) except Exception as ex: if retry == self.retry_limit: raise if len(wrapper._retry_queue) >= self.queue_limit: last = wrapper._retry_queue.pop(0) if 'remove' in last: func = last['remove'] func() if 'exc' in last: _LOGGER.error( "Retry queue overflow, drop oldest entry: %s", str(last['exc'])) target = utcnow() + self.retry_delay tracking = {'target': target} remove = track_point_in_utc_time(self.hass, partial(scheduled, retry + 1, tracking), target) tracking['remove'] = remove tracking["exc"] = ex wrapper._retry_queue.append(tracking)
def _update_callback(self, msg): """Update the sensor's state, if needed.""" _LOGGER.debug('Callback signal from: %s', msg) if self._delay > 0 and not self.is_on: # Set timer to wait until updating the state def _delay_update(now): """Timer callback for sensor update.""" _LOGGER.debug("%s Called delayed (%ssec) update", self._name, self._delay) self.schedule_update_ha_state() self._timer = None if self._timer is not None: self._timer() self._timer = None self._timer = track_point_in_utc_time( self._hass, _delay_update, utcnow() + timedelta(seconds=self._delay)) elif self._delay > 0 and self.is_on: # For delayed sensors kill any callbacks on true events and update if self._timer is not None: self._timer() self._timer = None self.schedule_update_ha_state() else: self.schedule_update_ha_state()
def update_ble(now): """Lookup Bluetooth LE devices and update status.""" devs = discover_ble_devices() if devs_track_battery: adapter = hass.data[DATA_BLE][DATA_BLE_ADAPTER] for mac in devs_to_track: if mac not in devs: continue if devs[mac] is None: devs[mac] = mac battery = None if (mac in devs_track_battery and now > devs_track_battery[mac] + battery_track_interval): handle = None try: adapter.start(reset_on_start=False) _LOGGER.debug("Reading battery for Bluetooth LE device %s", mac) bt_device = adapter.connect(mac) # Try to get the handle; it will raise a BLEError exception if not available handle = bt_device.get_handle(BATTERY_CHARACTERISTIC_UUID) battery = ord( bt_device.char_read(BATTERY_CHARACTERISTIC_UUID)) devs_track_battery[mac] = now except pygatt.exceptions.NotificationTimeout: _LOGGER.warning( "Timeout when trying to get battery status") except pygatt.exceptions.BLEError as err: _LOGGER.warning("Could not read battery status: %s", err) if handle is not None: # If the device does not offer battery information, there is no point in asking again later on. # Remove the device from the battery-tracked devices, so that their battery is not wasted # trying to get an unavailable information. del devs_track_battery[mac] finally: adapter.stop() see_device(mac, devs[mac], battery=battery) if track_new: for address in devs: if address not in devs_to_track and address not in devs_donot_track: _LOGGER.info("Discovered Bluetooth LE device %s", address) see_device(address, devs[address], new_device=True) track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + interval)
def trigger_sunset(hass, action, offset): """ Trigger action at next sun set. """ def next_set(): """ Returns next sunrise. """ next_time = sun.next_setting_utc(hass) + offset while next_time < dt_util.utcnow(): next_time = next_time + timedelta(days=1) return next_time def sunset_automation_listener(now): """ Called when it's time for action. """ track_point_in_utc_time(hass, sunset_automation_listener, next_set()) action() track_point_in_utc_time(hass, sunset_automation_listener, next_set())
def update_sleepcycle(now): """Look for Sleep Cycle hosts and update status.""" if track_new: for dev in discover_devices(): if dev[0] not in devs_to_track and \ dev[0] not in devs_donot_track: devs_to_track.append(dev[0]) for mac in devs_to_track: _LOGGER.debug("Scanning " + mac) result = bluetooth.lookup_name(mac, timeout=5) if not result: # Could not lookup device name continue see_device((mac, result)) track_point_in_utc_time(hass, update_bluetooth, dt_util.utcnow() + interval)
def lose_control_temp(self): if self._delete_bri_control_timer is not None: self._delete_bri_control_timer() self._controlTemp = False self._delete_bri_control_timer = track_point_in_utc_time( self.hass, self.gain_control_all, utcnow() + timedelta(seconds=self._seconds_to_control))
def update_bluetooth(now): """Lookup bluetooth device and update status.""" try: if track_new: for dev in discover_devices(): if dev[0] not in devs_to_track and dev[0] not in devs_donot_track: devs_to_track.append(dev[0]) for mac in devs_to_track: _LOGGER.debug("Scanning " + mac) result = bluetooth.lookup_name(mac, timeout=5) if not result: # Could not lookup device name continue see_device((mac, result)) except bluetooth.BluetoothError: _LOGGER.exception("Error looking up bluetooth device!") track_point_in_utc_time(hass, update_bluetooth, now + timedelta(seconds=interval))
def turn_on(self, **kwargs): """Turn the light on.""" self._state = True if self._delete_timer is not None: self._delete_timer() service_data = {"entity_id": self._lightId} if ATTR_TRANSITION in kwargs: service_data[ATTR_TRANSITION] = int(str(kwargs[ATTR_TRANSITION])) else: service_data[ATTR_TRANSITION] = self._default_transition if ATTR_RGB_COLOR in kwargs: service_data[ATTR_RGB_COLOR] = kwargs[ATTR_RGB_COLOR] if ATTR_COLOR_TEMP in kwargs: service_data[ATTR_COLOR_TEMP] = kwargs[ATTR_COLOR_TEMP] self.lose_control_temp() elif self._controlTemp: service_data[ATTR_COLOR_TEMP] = self.get_temp( service_data[ATTR_TRANSITION]) _LOGGER.error(str(service_data[ATTR_COLOR_TEMP])) if ATTR_BRIGHTNESS in kwargs: service_data[ATTR_BRIGHTNESS] = kwargs[ATTR_BRIGHTNESS] self.lose_control_bri() elif self._controlBrightness: service_data[ATTR_BRIGHTNESS] = self.get_brightness( service_data[ATTR_TRANSITION]) if ATTR_XY_COLOR in kwargs: service_data[ATTR_XY_COLOR] = kwargs[ATTR_XY_COLOR] if ATTR_WHITE_VALUE in kwargs: service_data[ATTR_WHITE_VALUE] = kwargs[ATTR_WHITE_VALUE] if ATTR_EFFECT in kwargs: service_data[ATTR_EFFECT] = kwargs[ATTR_EFFECT] self._delete_timer = track_point_in_utc_time( self.hass, self.refresh, utcnow().replace(microsecond=0) + timedelta( seconds=service_data[ATTR_TRANSITION] + self._time_between)) if service_data[ATTR_TRANSITION] == 1: del service_data[ATTR_TRANSITION] # service_data[''] self.hass.bus.fire('call_service', { "service": "turn_on", "domain": "light", "service_data": service_data }) # As we have disabled polling, we need to inform # Home Assistant about updates in our state ourselves. self.schedule_update_ha_state()
def _yr_precipitation(now=None): url = "http://api.met.no/weatherapi/nowcast/0.9/" urlparams = { 'lat': str(hass.config.latitude), 'lon': str(hass.config.longitude) } if not now: now = dt_util.utcnow() try: with requests.Session() as sess: response = sess.get(url, params=urlparams) except requests.RequestException: track_point_in_utc_time(hass, _yr_precipitation, now + timedelta(minutes=2)) return if response.status_code != 200: track_point_in_utc_time(hass, _yr_precipitation, now + timedelta(minutes=2)) return text = response.text nonlocal nowcast_precipitation nonlocal yr_precipitation nowcast_precipitation = 0 try: data = xmltodict.parse(text)['weatherdata'] model = data['meta']['model'] if '@nextrun' not in model: model = model[0] nextrun = dt_util.parse_datetime(model['@nextrun']) nextrun = nextrun if ( nextrun > now) else now + timedelta(minutes=2) for time_entry in data['product']['time']: loc_data = time_entry['location'] time = dt_util.parse_datetime(time_entry['@to']) #print(loc_data['precipitation']['@value']) #print(dt_util.as_local(time)) value = float(loc_data['precipitation']['@value']) if time > now and time < now + timedelta(hours=1): nowcast_precipitation += value yr_precipitation[time] = value for time in yr_precipitation.copy().keys(): if time < now - timedelta(hours=3): del yr_precipitation[time] except (ExpatError, IndexError) as err: track_point_in_utc_time(hass, _yr_precipitation, now + timedelta(minutes=2)) return track_point_in_utc_time(hass, _yr_precipitation, nextrun + timedelta(seconds=2))
def update_ble(now): """Lookup Bluetooth LE devices and update status.""" devs = discover_ble_devices() for mac in devs_to_track: _LOGGER.debug("Checking " + mac) result = mac in devs if not result: # Could not lookup device name continue see_device(mac, devs[mac]) if track_new: for address in devs: if address not in devs_to_track and address not in devs_donot_track: _LOGGER.info("Discovered Bluetooth LE device %s", address) see_device(address, devs[address], new_device=True) track_point_in_utc_time(hass, update_ble, now + timedelta(seconds=interval))
def update_ble(now): """Lookup Bluetooth LE devices and update status.""" devs = discover_ble_devices() for mac in devs_to_track: if mac not in devs: continue if devs[mac] is None: devs[mac] = mac see_device(mac, devs[mac]) if track_new: for address in devs: if address not in devs_to_track and address not in devs_donot_track: _LOGGER.info("Discovered Bluetooth LE device %s", address) see_device(address, devs[address], new_device=True) track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + interval)
def update_ble(now): """Lookup Bluetooth LE devices and update status.""" devs = discover_ble_devices() for mac in devs_to_track: if mac not in devs: continue if devs[mac] is None: devs[mac] = mac see_device(mac, devs[mac]) if track_new: for address in devs: if address not in devs_to_track and \ address not in devs_donot_track: _LOGGER.info("Discovered Bluetooth LE device %s", address) see_device(address, devs[address], new_device=True) track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + interval)
def _start_timer(self): """ Registers a countdown timer that will trigger no occupancy when fired. Sets the state to STATE_COUNTDOWN. """ if self.timer is not None: _LOGGER.info('timer already set: %s', self) return self.timer = helper.track_point_in_utc_time(self.hass, self._timer_expired, date_util.utcnow() + self.timeout) _LOGGER.info('set timer %s', self)
def wrapper(self, *args): """Start async timer.""" debounce_params = self.debounce.pop(func.__name__, None) if debounce_params: debounce_params[0]() # remove listener remove_listener = track_point_in_utc_time( self.hass, partial(call_later_listener, self), dt_util.utcnow() + timedelta(seconds=DEBOUNCE_TIMEOUT)) self.debounce[func.__name__] = (remove_listener, *args) logger.debug('%s: Start %s timeout', self.entity_id, func.__name__.replace('set_', ''))
def pressed(): """Handle the press of the LiteJet switch's button.""" nonlocal cancel_pressed_more_than, pressed_time nonlocal held_less_than, held_more_than pressed_time = dt_util.utcnow() if held_more_than is None and held_less_than is None: hass.add_job(call_action) if held_more_than is not None and held_less_than is None: cancel_pressed_more_than = track_point_in_utc_time( hass, pressed_more_than_satisfied, dt_util.utcnow() + held_more_than)
def update(now): """Update status from the online service.""" _LOGGER.debug("Updating") status = query("status", vehicle_url) position = query("position", vehicle_url) see(dev_id=dev_id, host_name=host_name, gps=(position["position"]["latitude"], position["position"]["longitude"]), attributes=dict( tank_volume=attributes["fuelTankVolume"], washer_fluid=status["washerFluidLevel"], brake_fluid=status["brakeFluid"], service_warning=status["serviceWarningStatus"], fuel=status["fuelAmount"], odometer=status["odometer"], range=status["distanceToEmpty"])) track_point_in_utc_time(hass, update, now + timedelta(seconds=interval))
def update_bluetooth(now): """Lookup Bluetooth device and update status.""" try: if track_new: for dev in discover_devices(): if dev[0] not in devs_to_track and \ dev[0] not in devs_donot_track: devs_to_track.append(dev[0]) for mac in devs_to_track: _LOGGER.debug("Scanning %s", mac) result = bluetooth.lookup_name(mac, timeout=5) rssi = None if request_rssi: rssi = BluetoothRSSI(mac).request_rssi() if result is None: # Could not lookup device name continue see_device(mac, result, rssi) except bluetooth.BluetoothError: _LOGGER.exception("Error looking up Bluetooth device") track_point_in_utc_time( hass, update_bluetooth, dt_util.utcnow() + interval)
def run(self, variables: Optional[Sequence]=None) -> None: """Run script.""" with self._lock: if self._cur == -1: self._log('Running script') self._cur = 0 # Unregister callback if we were in a delay but turn on is called # again. In that case we just continue execution. self._remove_listener() for cur, action in islice(enumerate(self.sequence), self._cur, None): if CONF_DELAY in action: # Call ourselves in the future to continue work def script_delay(now): """Called after delay is done.""" self._unsub_delay_listener = None self.run(variables) delay = action[CONF_DELAY] if isinstance(delay, template.Template): delay = vol.All( cv.time_period, cv.positive_timedelta)( delay.render()) self._unsub_delay_listener = track_point_in_utc_time( self.hass, script_delay, date_util.utcnow() + delay) self._cur = cur + 1 if self._change_listener: self._change_listener() return elif CONF_CONDITION in action: if not self._check_condition(action, variables): break elif CONF_EVENT in action: self._fire_event(action) else: self._call_service(action, variables) self._cur = -1 self.last_action = None if self._change_listener: self._change_listener()
def test_track_point_in_time(self): """Test track point in time.""" before_birthday = datetime(1985, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) birthday_paulus = datetime(1986, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) after_birthday = datetime(1987, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) runs = [] track_point_in_utc_time( self.hass, callback(lambda x: runs.append(1)), birthday_paulus) self._send_time_changed(before_birthday) self.hass.block_till_done() assert 0 == len(runs) self._send_time_changed(birthday_paulus) self.hass.block_till_done() assert 1 == len(runs) # A point in time tracker will only fire once, this should do nothing self._send_time_changed(birthday_paulus) self.hass.block_till_done() assert 1 == len(runs) track_point_in_time( self.hass, callback(lambda x: runs.append(1)), birthday_paulus) self._send_time_changed(after_birthday) self.hass.block_till_done() assert 2 == len(runs) unsub = track_point_in_time( self.hass, callback(lambda x: runs.append(1)), birthday_paulus) unsub() self._send_time_changed(after_birthday) self.hass.block_till_done() assert 2 == len(runs)
def update_bluetooth(now): """Lookup Bluetooth device and update status.""" try: if track_new: for dev in discover_devices(): if dev[0] not in devs_to_track and \ dev[0] not in devs_donot_track: devs_to_track.append(dev[0]) for mac in devs_to_track: if hass.states.get(DOMAIN + '.' + ENTITY_ID).state != STATE_ON: continue _LOGGER.debug("Scanning %s", mac) result = bluetooth.lookup_name(mac, timeout=5) if not result: # Could not lookup device name continue see_device((mac, result)) except bluetooth.BluetoothError: _LOGGER.exception("Error looking up Bluetooth device") track_point_in_utc_time( hass, update_bluetooth, dt_util.utcnow() + interval)
def _update_callback(self): """Update the sensor's state, if needed.""" self.update() if self._timer is not None: self._timer() self._timer = None if self._delay > 0 and not self.is_on: # Set timer to wait until updating the state def _delay_update(now): """Timer callback for sensor update.""" _LOGGER.debug("%s Called delayed (%s sec) update.", self._name, self._delay) self.schedule_update_ha_state() self._timer = None self._timer = track_point_in_utc_time( self.hass, _delay_update, utcnow() + timedelta(seconds=self._delay)) else: self.schedule_update_ha_state()
def turn_on(self, **kwargs): """Turn the entity on.""" _LOGGER.info("Executing script %s", self._name) with self._lock: if self._cur == -1: self._cur = 0 # Unregister callback if we were in a delay but turn on is called # again. In that case we just continue execution. self._remove_listener() for cur, action in islice(enumerate(self.sequence), self._cur, None): if validate_service_call(action) is None: self._call_service(action) elif CONF_EVENT in action: self._fire_event(action) elif CONF_DELAY in action: # Call ourselves in the future to continue work def script_delay(now): """Called after delay is done.""" self._listener = None self.turn_on() timespec = action[CONF_DELAY] or action.copy() timespec.pop(CONF_DELAY, None) delay = timedelta(**timespec) self._listener = track_point_in_utc_time( self.hass, script_delay, date_util.utcnow() + delay) self._cur = cur + 1 self.update_ha_state() return self._cur = -1 self._last_action = None self.update_ha_state()
def sunset_automation_listener(now): """ Called when it's time for action. """ track_point_in_utc_time(hass, sunset_automation_listener, next_set()) action()
def update_bluetooth(_): """Update Bluetooth and set timer for the next update.""" update_bluetooth_once() track_point_in_utc_time( hass, update_bluetooth, dt_util.utcnow() + interval)
def update(now): """Update all the hosts on every interval time.""" for host in hosts: host.update(see) track_point_in_utc_time(hass, update, util.dt.utcnow() + interval) return True
def run(self): """Start processing events to save.""" from homeassistant.components.recorder.models import Events, States import sqlalchemy.exc while True: try: self._setup_connection() self._setup_run() break except sqlalchemy.exc.SQLAlchemyError as e: log_error(e, retry_wait=CONNECT_RETRY_WAIT, rollback=False, message="Error during connection setup: %s") if self.purge_days is not None: def purge_ticker(event): """Rerun purge every second day.""" self._purge_old_data() track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(days=2)) track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(minutes=5)) while True: event = self.queue.get() if event is None: self._close_run() self._close_connection() self.queue.task_done() return if event.event_type == EVENT_TIME_CHANGED: self.queue.task_done() continue if ATTR_ENTITY_ID in event.data: entity_id = event.data[ATTR_ENTITY_ID] domain = split_entity_id(entity_id)[0] # Exclude entities OR # Exclude domains, but include specific entities if (entity_id in self.exclude) or \ (domain in self.exclude and entity_id not in self.include_e): self.queue.task_done() continue # Included domains only (excluded entities above) OR # Include entities only, but only if no excludes if (self.include_d and domain not in self.include_d) or \ (self.include_e and entity_id not in self.include_e and not self.exclude): self.queue.task_done() continue dbevent = Events.from_event(event) self._commit(dbevent) if event.event_type != EVENT_STATE_CHANGED: self.queue.task_done() continue dbstate = States.from_event(event) dbstate.event_id = dbevent.event_id self._commit(dbstate) self.queue.task_done()
def purge_ticker(event): """Rerun purge every second day.""" self._purge_old_data() track_point_in_utc_time(self.hass, purge_ticker, dt_util.utcnow() + timedelta(days=2))