Beispiel #1
0
    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))
Beispiel #2
0
    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)
Beispiel #3
0
 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)
Beispiel #4
0
    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()
Beispiel #6
0
    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()
Beispiel #7
0
    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))
Beispiel #9
0
 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)
Beispiel #10
0
    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))
Beispiel #13
0
 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))
Beispiel #14
0
    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))
Beispiel #15
0
    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()
Beispiel #16
0
    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()
Beispiel #17
0
    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)
Beispiel #18
0
    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)
Beispiel #20
0
    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()
Beispiel #21
0
 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))
Beispiel #22
0
    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),
        )
Beispiel #23
0
    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)
Beispiel #24
0
    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)
Beispiel #25
0
 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))
Beispiel #26
0
    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()
Beispiel #28
0
            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()
Beispiel #30
0
    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)
Beispiel #31
0
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)
Beispiel #33
0
    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))
Beispiel #35
0
    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()
Beispiel #36
0
    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)
Beispiel #40
0
 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)
Beispiel #45
0
    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()
Beispiel #46
0
    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)
Beispiel #48
0
    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()
Beispiel #49
0
    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()
Beispiel #50
0
 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)
Beispiel #52
0
 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
Beispiel #53
0
    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()
Beispiel #54
0
 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))