示例#1
0
    def check_status_until_done(self, media_id, callback, *args):
        """Upload media, STATUS phase."""
        resp = self.api.request(
            "media/upload",
            {
                "command": "STATUS",
                "media_id": media_id
            },
            method_override="GET",
        )
        if resp.status_code != 200:
            _LOGGER.error("media processing error: %s", resp.json())
        processing_info = resp.json()["processing_info"]

        _LOGGER.debug("media processing %s status: %s", media_id,
                      processing_info)

        if processing_info["state"] in {"succeeded", "failed"}:
            return callback(media_id)

        check_after_secs = processing_info["check_after_secs"]
        _LOGGER.debug("media processing waiting %s seconds to check status",
                      str(check_after_secs))

        when = datetime.now() + timedelta(seconds=check_after_secs)
        myself = partial(self.check_status_until_done, media_id, callback)
        async_track_point_in_time(self.hass, myself, when)
示例#2
0
    def attribute_updated(self, attribute, value):

        try:
            dev_func = self._model.replace(".", "_")
            _parse_attribute = getattr(
                import_module("custom_components.device." + dev_func),
                "_parse_attribute")
        except ImportError:
            _LOGGER.debug("load module %s failed ", dev_func)
        """Handle attribute update from device."""
        (attribute, value) = _parse_attribute(self, attribute, value)
        """ handle trigger events from motion sensor, clear state after re_arm_sec seconds """
        _LOGGER.debug("Attribute updated: %s %s", attribute, value)
        if attribute == self.value_attribute:
            self._state = value
            """ clear state to False"""
            @asyncio.coroutine
            def _async_clear_state(entity):
                _LOGGER.debug("async_clear_state")
                if (entity.invalidate_after == None) or (
                        entity.invalidate_after < dt_util.utcnow()):
                    entity._state = bool(0)
                    #            entity.invalidate_after=None
                    entity.schedule_update_ha_state()

        self.invalidate_after = dt_util.utcnow() + datetime.timedelta(
            seconds=self.re_arm_sec)
        self._device_state_attributes[
            'last detection:'] = self.invalidate_after
        async_track_point_in_time(self.hass, _async_clear_state(self),
                                  self.invalidate_after)
        self.schedule_update_ha_state()
 async def async_get_baidu_token(self, datetimenow):
     """获取百度Token"""
     #加个同步锁,多设备的时候有时请求两次token
     if self._baidu_token_lock:
         return
     self._baidu_token_lock = True
     try:
         getTokenUrl = "https://aip.baidubce.com/oauth/2.0/token"
         payload = {
             'grant_type': 'client_credentials',
             'client_id': self._baidu_client_id,
             'client_secret': self._baidu_client_secret
         }
         _LOGGER.info("时间:%s正在获取百度Token....", datetimenow)
         result = await self.fetch_data(getTokenUrl, payload, "百度Tkoen")
         if result is not None and "error" not in result:
             token = result["access_token"]
             _LOGGER.debug("获取的百度token为:%s", token)
             self._baidu_accessToken = token
             expireTime = int(result['expires_in'])
             dateArray = datetime.datetime.now() + datetime.timedelta(
                 seconds=expireTime)
             _LOGGER.debug("百度token下次更新时间:%s", dateArray)
             #添加一个事件,在指定时间再次获取token
             async_track_point_in_time(hass=self._hass,
                                       action=self.async_get_baidu_token,
                                       point_in_time=dateArray)
         else:
             _LOGGER.error("获取百度Token错误:%s", result)
             self._baidu_accessToken = None
     except Exception:
         raise
     finally:
         self._baidu_token_lock = False
示例#4
0
    def update_sun_events(self, point_in_time):
        _LOGGER.debug("Updating Astral Events from Sun Entity")
        sun = self.hass.states.get(SUN_ENTITY_ID)
        if sun is None:
            _LOGGER.warn("Can't access the Sun Entity, try again in 5 minutes")
            async_track_point_in_time(
                self.hass, self.update_sun_events, point_in_time + timedelta(minutes=5)
            )
            return

        self._calculate_day_events(
            point_in_time,
            dt_util.as_local(dt_util.parse_datetime(sun.attributes[STATE_ATTR_NEXT_DAWN])),
            dt_util.as_local(dt_util.parse_datetime(sun.attributes[STATE_ATTR_NEXT_NOON])),
            dt_util.as_local(dt_util.parse_datetime(sun.attributes[STATE_ATTR_NEXT_DUSK])),
            )

        self._last_sun_update = point_in_time
        self._available = True
        self.async_write_ha_state()

        schedule = self._nighttime + timedelta(minutes=15)
        if point_in_time > schedule:
            schedule = self._nighttime + timedelta(minutes=15)

        _LOGGER.debug("Scheduling next astral for: {}".format(schedule))
        async_track_point_in_time(self.hass, self.update_sun_events, schedule)
示例#5
0
 async def _async_reset_meter(self, event):
     """Determine cycle - Helper function for larger than daily cycles."""
     now = dt_util.now().date()
     if self._cron_pattern is not None:
         async_track_point_in_time(
             self.hass,
             self._async_reset_meter,
             croniter(self._cron_pattern, dt_util.now()).get_next(datetime),
         )
     elif (self._period == WEEKLY and now !=
           now - timedelta(days=now.weekday()) + self._period_offset):
         return
     elif (self._period == MONTHLY
           and now != date(now.year, now.month, 1) + self._period_offset):
         return
     elif (self._period == BIMONTHLY
           and now != date(now.year, ((
               (now.month - 1) // 2) * 2 + 1), 1) + self._period_offset):
         return
     elif (self._period == QUARTERLY
           and now != date(now.year, ((
               (now.month - 1) // 3) * 3 + 1), 1) + self._period_offset):
         return
     elif (self._period == YEARLY
           and now != date(now.year, 1, 1) + self._period_offset):
         return
     await self.async_reset_meter(self._tariff_entity)
    def update(time):
        """Fetch data from the redy box and update sensors."""
        host = config[CONF_HOST]

        try:

            # get the data from the box
            data_html = requests.get('http://{}:1234/api/devices'.format(host))

            html_parser = RedyHTMLParser()
            html_parser.feed(
                data_html.content.decode(data_html.apparent_encoding))
            html_parser.close()
            html_json = html_parser.json()
            j = json.loads(html_json)

            new_sensors_list.clear()
            parse_data(j)
            if len(new_sensors_list) > 0:
                async_add_devices(new_sensors_list)

        except requests.exceptions.RequestException as error:
            _LOGGER.error("Failed to get data from redy box: %s", error)
        except Exception as ex:
            _LOGGER.error("WTF? %s    >    %s", type(ex).__name__, ex)

        # schedule next update
        async_track_point_in_time(hass, update, time + timedelta(
            seconds=config[CONF_UPDATE_INTERVAL]))
示例#7
0
    def attribute_updated(self, attribute, value):
        """ handle trigger events from motion sensor.
        clear state after re_arm_sec seconds."""
        _LOGGER.debug("Attribute updated: %s %s", attribute, value)
        if self._custom_module.get('_parse_attribute', None) is not None:
            (attribute,
             value) = self._custom_module['_parse_attribute'](self, attribute,
                                                              value,
                                                              self._model)

        @asyncio.coroutine
        def _async_clear_state(entity):
            _LOGGER.debug("async_clear_state")
            if (entity.invalidate_after is None
                    or entity.invalidate_after < dt_util.utcnow()):
                entity._state = bool(0)
                entity.schedule_update_ha_state()

        if attribute == self.value_attribute:
            self._state = value
            self.invalidate_after = dt_util.utcnow() + datetime.timedelta(
                seconds=self.re_arm_sec)
            self._device_state_attributes['last detection:'] \
                = self.invalidate_after
            async_track_point_in_time(self.hass, _async_clear_state(self),
                                      self.invalidate_after)
        self.schedule_update_ha_state()
示例#8
0
    def attribute_updated(self, attribute, value):
        """ handle trigger events from motion sensor.
        clear state after re_arm_sec seconds."""
        _LOGGER.debug("Attribute received: %s %s", attribute, value)
        (attribute, value) = self._entity._parse_attribute(self._entity, attribute, value, self._entity._model, cluster_id=self._cluster.cluster_id)

        @asyncio.coroutine
        def _async_clear_state(entity):
            _LOGGER.debug("async_clear_state")
            if (entity.invalidate_after is None
                    or entity.invalidate_after < dt_util.utcnow()):
                entity._entity._state = bool(0)
                entity._entity.schedule_update_ha_state()

        if attribute == self.value_attribute:
            self._entity._state = value
            self.invalidate_after = dt_util.utcnow() + datetime.timedelta(
                seconds=self.re_arm_sec)
            self._entity._device_state_attributes['last detection'] \
                = dt_util.utcnow()
            async_track_point_in_time(
                self._entity.hass, _async_clear_state(self),
                self.invalidate_after)
            self._entity.hass.bus.fire('alarm', {
                    'entity_id': self._entity.entity_id,
                    'channel': self._identifier,
                    'command': "motion",
                   })

        self._entity.schedule_update_ha_state()
示例#9
0
文件: __init__.py 项目: Igor-kr/hass
    def load_timers(self):
        if self._db.state == STATE_OFF:
            do = self._db.get_head()
            self.do = do
            if self._debug:
               _LOGGER.error(" start start {} ".format(self.do)) 
            #trigger 3 events 
            if do.e - do.s < datetime.timedelta(days=1):
                 _LOGGER.error(" hebcal something wrong with the record {} ".format(self.do)) 

            event.async_track_point_in_time(
                self.hass, self._pre_on, do.s - timedelta(minutes=10))
            event.async_track_point_in_time(
                self.hass, self._on, do.s)
            event.async_track_point_in_time(
                self.hass, self._off, do.e)
    
        else:
            self._db.state = STATE_OFF
            do = self._db.get_head() 
          
            event.async_track_point_in_time(
                self.hass, self._pre_on, dt_util.now())
            event.async_track_point_in_time(
                self.hass, self._off, do.e)
示例#10
0
    def update_adjusted_run_time_from_event(self):
        """Update the adjusted run time. Should only be called from _bucket_update and _force_mode_toggled event handlers."""
        _LOGGER.info("updated_adjusted_run_time_from_event called.")
        result = self.calculate_water_budget_and_adjusted_run_time(
            self.bucket, self.type)
        _LOGGER.info(
            "updated_adjusted_run_time_from_event: got result: {}. Setting attributes of daily adjusted run time (including result['wb']) and state == result['art']"
            .format(result))
        art_entity_id = self.coordinator.entities[TYPE_ADJUSTED_RUN_TIME]
        attr = self.get_attributes_for_daily_adjusted_run_time(
            self.bucket, result["wb"], result["art"])
        self.hass.states.set(
            art_entity_id,
            result["art"],
            attr,
        )

        # make sure to fire the 'we need to start irrigation now' event in time so we finish just before sunrise
        sun_state = self.hass.states.get("sun.sun")
        if sun_state is not None:
            sun_rise = sun_state.attributes.get("next_rising")
            if sun_rise is not None:
                sun_rise = datetime.datetime.strptime(
                    sun_rise, "%Y-%m-%dT%H:%M:%S.%f%z")
                _LOGGER.info("sun_rise: {}".format(sun_rise))
                async_track_point_in_time(self.hass,
                                          self._fire_start_event,
                                          point_in_time=sun_rise)
                time_to_fire = sun_rise - datetime.timedelta(
                    seconds=result["art"])
                event_to_fire = f"{self.coordinator.name}_{EVENT_IRRIGATE_START}"
                _LOGGER.info("{} will fire at {}".format(
                    event_to_fire, time_to_fire))
示例#11
0
    async def async_update_prices(self, *_args):
        """Update electricity prices from the ESIOS API."""
        localized_now = dt_util.utcnow().astimezone(_REFERENCE_TZ)
        data = await self._download_official_data(localized_now.date())
        if not data and self._data_source_available:
            self._num_retries += 1
            if self._num_retries > 2:
                _LOGGER.error(
                    "Repeated bad data update, mark component as unavailable source"
                )
                self._data_source_available = False
                return

            _LOGGER.warning(
                "Bad update[retry:%d], will try again in %d s",
                self._num_retries,
                3 * self._timeout,
            )
            async_track_point_in_time(
                self.hass,
                self.async_update_prices,
                dt_util.now() + timedelta(seconds=3 * self._timeout),
            )
            return

        if not data:
            _LOGGER.debug(
                "Data source unavailable since %s",
                self.hass.states.get(self.entity_id).last_changed,
            )
            return

        tariff_number = TARIFFS.index(self._tariff) + 1
        prices = extract_prices_for_tariff(data, tariff_number)
        self._num_retries = 0
        self._current_prices.update(prices)
        if not self._data_source_available:
            self._data_source_available = True
            _LOGGER.warning(
                "Component has recovered data access. Was unavailable since %s",
                self.hass.states.get(self.entity_id).last_changed,
            )
            self.async_schedule_update_ha_state(True)

        # At evening, it is possible to retrieve next day prices
        if localized_now.hour >= 20:
            next_day = (localized_now + timedelta(days=1)).date()
            data_next_day = await self._download_official_data(next_day)
            if data_next_day:
                prices_fut = extract_prices_for_tariff(data_next_day,
                                                       tariff_number)
                self._current_prices.update(prices_fut)

        _LOGGER.debug(
            "Download done for %s, now with %d prices from %s UTC",
            self.entity_id,
            len(self._current_prices),
            list(self._current_prices)[0].strftime("%Y-%m-%d %Hh"),
        )
示例#12
0
    def start_recording(self, duration):

        def _stop_recording(_now):
            self.stop_recording()

        if self._camera.get_stream() is not None:
            self._camera.start_recording()
            async_track_point_in_time(self.hass, _stop_recording, dt_util.utcnow() + timedelta(seconds=duration))
示例#13
0
    def device_left(self, device):
        self.controller._state = 'Left ' + str(device._ieee)
        self.controller.async_schedule_update_ha_state()

        async def _async_clear_state(entity):
            entity._state = 'Run'
            entity.async_schedule_update_ha_state()
        async_track_point_in_time(
            self.controller.hass, _async_clear_state(self.controller),
            dt_util.utcnow() + datetime.timedelta(seconds=5))
async def schedule_future_update(hass, sensors, midnight_time,
                                 prayer_times_data):
    """Schedule future update for sensors.

    Midnight is a calculated time.  The specifics of the calculation
    depends on the method of the prayer time calculation.  This calculated
    midnight is the time at which the time to pray the Isha prayers have
    expired.

    Calculated Midnight: The Islamic midnight.
    Traditional Midnight: 12:00AM

    Update logic for prayer times:

    If the Calculated Midnight is before the traditional midnight then wait
    until the traditional midnight to run the update.  This way the day
    will have changed over and we don't need to do any fancy calculations.

    If the Calculated Midnight is after the traditional midnight, then wait
    until after the calculated Midnight.  We don't want to update the prayer
    times too early or else the timings might be incorrect.

    Example:
    calculated midnight = 11:23PM (before traditional midnight)
    Update time: 12:00AM

    calculated midnight = 1:35AM (after traditional midnight)
    update time: 1:36AM.
    """
    _LOGGER.debug("Scheduling next update for Islamic prayer times")

    now = dt_util.as_local(dt_util.now())
    today = now.date()

    midnight_dt_str = '{}::{}'.format(str(today), midnight_time)
    midnight_dt = datetime.strptime(midnight_dt_str, '%Y-%m-%d::%H:%M')

    if now > dt_util.as_local(midnight_dt):
        _LOGGER.debug("Midnight is after day the changes so schedule update "
                      "for after Midnight the next day")

        next_update_at = midnight_dt + timedelta(days=1, minutes=1)
    else:
        _LOGGER.debug(
            "Midnight is before the day changes so schedule update for the "
            "next start of day")

        tomorrow = now + timedelta(days=1)
        next_update_at = dt_util.start_of_local_day(tomorrow)

    _LOGGER.debug("Next update scheduled for: %s", str(next_update_at))

    async_track_point_in_time(hass,
                              update_sensors(hass, sensors, prayer_times_data),
                              next_update_at)
示例#15
0
文件: __init__.py 项目: jcgoette/core
 async def open_connection(now=None):
     """Open a connection to AlarmDecoder."""
     try:
         await hass.async_add_executor_job(controller.open, baud)
     except NoDeviceError:
         _LOGGER.debug("Failed to connect. Retrying in 5 seconds")
         async_track_point_in_time(
             hass, open_connection, dt_util.utcnow() + timedelta(seconds=5)
         )
         return
     _LOGGER.debug("Established a connection with the alarmdecoder")
     hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = True
    def schedule_light_turn_on(entity, old_state, new_state):
        """The moment sun sets we want to have all the lights on.

        We will schedule to have each light start after one another
        and slowly transition in.
        """
        start_point = calc_time_for_light_when_sunset()
        if not start_point:
            return

        for index, light_id in enumerate(light_ids):
            async_track_point_in_time(
                hass, async_turn_on_factory(light_id),
                start_point + index * LIGHT_TRANSITION_TIME)
示例#17
0
    def schedule_light_turn_on(entity, old_state, new_state):
        """The moment sun sets we want to have all the lights on.

        We will schedule to have each light start after one another
        and slowly transition in.
        """
        start_point = calc_time_for_light_when_sunset()
        if not start_point:
            return

        for index, light_id in enumerate(light_ids):
            async_track_point_in_time(
                hass, async_turn_on_factory(light_id),
                start_point + index * LIGHT_TRANSITION_TIME)
示例#18
0
    def binary_sensor_update(self, event):
        """Call for control updates from the w800rf32 gateway."""
        import W800rf32 as w800rf32mod

        if not isinstance(event, w800rf32mod.W800rf32Event):
            return

        dev_id = event.device
        command = event.command

        _LOGGER.debug(
            "BinarySensor update (Device ID: %s Command %s ...)",
            dev_id, command)

        # Update the w800rf32 device state
        if command in ('On', 'Off'):
            is_on = command == 'On'
            self.update_state(is_on)

        if (self.is_on and self._off_delay is not None and
                self._delay_listener is None):

            self._delay_listener = evt.async_track_point_in_time(
                self.hass, self._off_delay_listener,
                dt_util.utcnow() + self._off_delay)
示例#19
0
 def _schedule_notify(self):
     """Schedule a notification."""
     delay = self._delay[self._next_delay]
     next_msg = datetime.now() + delay
     self._cancel = \
         event.async_track_point_in_time(self.hass, self._notify, next_msg)
     self._next_delay = min(self._next_delay + 1, len(self._delay) - 1)
示例#20
0
    async def async_reset_workday_timer(self):
        """the workday polling timer has finished"""
        @callback
        async def async_workday_timer_finished(_now):
            """perform daily polling of the workday entity"""
            _LOGGER.debug("Performing daily update of workday sensor")
            await self.async_reset_workday_timer()
            async_dispatcher_send(self.hass,
                                  const.EVENT_WORKDAY_SENSOR_UPDATED)

        now = dt_util.as_local(dt_util.utcnow())
        ts = dt_util.find_next_time_expression_time(now,
                                                    seconds=[0],
                                                    minutes=[5],
                                                    hours=[0])
        today = now.date()
        while ts.date() == today:
            # ensure the timer is set for the next day
            now = now + datetime.timedelta(days=1)
            ts = dt_util.find_next_time_expression_time(now,
                                                        seconds=[0],
                                                        minutes=[5],
                                                        hours=[0])

        if self._workday_timer:
            self._workday_timer()

        self._workday_timer = async_track_point_in_time(
            self.hass, async_workday_timer_finished, ts)
示例#21
0
    def update_entity_trigger(entity_id, new_state=None):
        """Update the entity trigger for the entity_id."""
        # If a listener was already set up for entity, remove it.
        remove = entities.get(entity_id)
        if remove:
            remove()
            removes.remove(remove)
            remove = None

        # Check state of entity. If valid, set up a listener.
        if new_state:
            has_date = new_state.attributes["has_date"]
            if has_date:
                year = new_state.attributes["year"]
                month = new_state.attributes["month"]
                day = new_state.attributes["day"]
            has_time = new_state.attributes["has_time"]
            if has_time:
                hour = new_state.attributes["hour"]
                minute = new_state.attributes["minute"]
                second = new_state.attributes["second"]
            else:
                # If no time then use midnight.
                hour = minute = second = 0

            if has_date:
                # If input_datetime has date, then track point in time.
                trigger_dt = dt_util.DEFAULT_TIME_ZONE.localize(
                    datetime(year, month, day, hour, minute, second)
                )
                # Only set up listener if time is now or in the future.
                if trigger_dt >= dt_util.now():
                    remove = async_track_point_in_time(
                        hass,
                        partial(
                            time_automation_listener,
                            f"time set in {entity_id}",
                            entity_id=entity_id,
                        ),
                        trigger_dt,
                    )
            elif has_time:
                # Else if it has time, then track time change.
                remove = async_track_time_change(
                    hass,
                    partial(
                        time_automation_listener,
                        f"time set in {entity_id}",
                        entity_id=entity_id,
                    ),
                    hour=hour,
                    minute=minute,
                    second=second,
                )

        # Was a listener set up?
        if remove:
            removes.append(remove)

        entities[entity_id] = remove
示例#22
0
 def _schedule_notify(self):
     """Schedule a notification."""
     delay = self._delay[self._next_delay]
     next_msg = datetime.now() + delay
     self._cancel = \
         event.async_track_point_in_time(self.hass, self._notify, next_msg)
     self._next_delay = min(self._next_delay + 1, len(self._delay) - 1)
示例#23
0
    def async_set_timer(self, delay: datetime.timedelta, cb_func):
        self.async_cancel_timer()
        now = dt_util.utcnow()

        self._timer = async_track_point_in_time(
            self._hass, cb_func, now + delay
        )
示例#24
0
    def binary_sensor_update(self, event):
        """Call for control updates from the w800rf32 gateway."""
        import W800rf32 as w800rf32mod

        if not isinstance(event, w800rf32mod.W800rf32Event):
            return

        dev_id = event.device
        command = event.command

        _LOGGER.debug(
            "BinarySensor update (Device ID: %s Command %s ...)",
            dev_id, command)

        # Update the w800rf32 device state
        if command in ('On', 'Off'):
            is_on = command == 'On'
            self.update_state(is_on)

        if (self.is_on and self._off_delay is not None and
                self._delay_listener is None):

            self._delay_listener = evt.async_track_point_in_time(
                self.hass, self._off_delay_listener,
                dt_util.utcnow() + self._off_delay)
示例#25
0
    def setListener(self):
        @callback
        def _date_listener_callback(_):
            self.setListener()  #重设定时器
            self.notify()  #执行通知

        self._listener = None
        # now_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        notify_dates = []
        now = datetime.datetime.utcnow() + timedelta(hours=8)
        #_notify_times 要保证按时间顺序,否则这里的逻辑容易出错
        for notify_time in self._notify_times:
            notify_date_str = now.strftime('%Y-%m-%d') + ' ' + str(
                notify_time)  #目前预设是每天9点通知
            notify_date = datetime.datetime.strptime(notify_date_str,
                                                     "%Y-%m-%d %H:%M:%S")
            notify_dates.append(notify_date)

        notify_d = None
        for date in notify_dates:

            # notify_date = now + timedelta(seconds=10)
            if date > now:
                notify_d = date
                break

        if not notify_d:
            #上面发现预设的提醒时间已经没有今天的了,那么拿最小的时间加1天也就是第二天再提醒,所以_notify_times要保证按顺序
            notify_d = notify_dates[0]
            _LOGGER.info('小于')
            notify_d = notify_d + timedelta(days=1)  #已经过了就设置为明天的时间
            _LOGGER.info('notify_date')
            _LOGGER.info(notify_d)
        self._listener = evt.async_track_point_in_time(
            self._hass, _date_listener_callback, notify_d)
示例#26
0
    async def async_schedule_future_update(self):

        _LOGGER.debug("Scheduling next update for Mawaqit prayer times")

        now = dt_util.utcnow()

        midnight_dt = self.prayer_times_info["Midnight"]

        if now > dt_util.as_utc(midnight_dt):
            next_update_at = midnight_dt + timedelta(days=1, minutes=1)
            _LOGGER.debug(
                "Midnight is after day the changes so schedule update for after Midnight the next day"
            )
        else:
            _LOGGER.debug(
                "Midnight is before the day changes so schedule update for the next start of day"
            )
            next_update_at = dt_util.start_of_local_day(now +
                                                        timedelta(days=1))

        _LOGGER.info("Next update scheduled for: %s", next_update_at)

        self.event_unsub = async_track_point_in_time(self.hass,
                                                     self.async_update,
                                                     next_update_at)
示例#27
0
    async def async_update_and_sched(time):
        update_success = await session.async_update()

        if update_success:
            dispatcher.async_dispatcher_send(hass, DATA_UPDATE_TOPIC)

            nonlocal platform_loaded
            if not platform_loaded:
                for component in ['sensor', 'switch']:
                    await discovery.async_load_platform(hass, component,
                                                        DOMAIN, {}, config)
                platform_loaded = True

        # schedule next update
        async_track_point_in_time(hass, async_update_and_sched,
                                  time + timedelta(seconds=UPDATE_INTERVAL))
示例#28
0
    def permit(service):
        """Allow devices to join this network."""
        duration = service.data.get(ATTR_DURATION)
        _LOGGER.info("Permitting joins for %ss", duration)
        zha_controller._state = 'Permit'
        zha_controller.async_schedule_update_ha_state()
        yield from APPLICATION_CONTROLLER.permit(duration)

        async def _async_clear_state(entity):
            if entity._state == 'Permit':
                entity._state = 'Run'
            entity.async_schedule_update_ha_state()

        async_track_point_in_time(
            zha_controller.hass, _async_clear_state(zha_controller),
            dt_util.utcnow() + datetime.timedelta(seconds=duration))
示例#29
0
    async def async_update_and_sched(time):
        update_success = await session.async_update()

        if update_success:
            nonlocal platform_loaded
            # pylint: disable=used-before-assignment
            if not platform_loaded:
                for component in ['sensor', 'switch']:
                    await discovery.async_load_platform(hass, component,
                                                        DOMAIN, {}, config)
                platform_loaded = True

            dispatcher.async_dispatcher_send(hass, DATA_UPDATE_TOPIC)

        # schedule next update
        async_track_point_in_time(hass, async_update_and_sched,
                                  time + timedelta(seconds=UPDATE_INTERVAL))
示例#30
0
async def activate_scene(
    hass,
    entity_id,
    point_in_time: Optional[datetime] = None,
    service="scene.turn_on",
):
    domain, service_name = service.split(".", 1)

    async def call_service(*args, **kwargs):
        LOGGER.info("%s : Calling service: {}, entity_id: {}".format(
            entity_id, service, entity_id))
        await hass.services.async_call(
            domain, service_name, service_data={ATTR_ENTITY_ID: entity_id})

    if point_in_time is not None:
        async_track_point_in_time(hass, call_service, point_in_time)
    else:
        await call_service()
示例#31
0
    async def async_update_and_sched(time):
        update_success = await session.async_update()

        if update_success:
            nonlocal platform_loaded
            # pylint: disable=used-before-assignment
            if not platform_loaded:
                for component in ["sensor", "switch"]:
                    await discovery.async_load_platform(
                        hass, component, DOMAIN, {}, config
                    )
                platform_loaded = True

            dispatcher.async_dispatcher_send(hass, DATA_UPDATE_TOPIC)

        # schedule next update
        async_track_point_in_time(
            hass, async_update_and_sched, time + timedelta(seconds=UPDATE_INTERVAL)
        )
示例#32
0
    def async_set_timer(self, delay, cb_func):
        if self._timer:
            self._timer()
        now = dt_util.utcnow()

        if not isinstance(delay, datetime.timedelta):
            delay = datetime.timedelta(seconds=delay)

        self._timer = async_track_point_in_time(self.hass, cb_func,
                                                now + delay)
示例#33
0
    def update_state(self, observed_entity_state):
        if observed_entity_state == STATE_UNKNOWN:
            return

        try:
            obs_value = float(observed_entity_state)
        except ValueError:
            _LOGGER.warning("Value cannot be processed as a number: %s",
                            observed_entity_state)
            return

        """If we are already in the correct state, no need to do anything"""
        if self._is_on:
            if obs_value > self._value_off:
                self._pending = False
                return
        else:
            if obs_value < self._value_on:
                self._pending = False
                return

        if self._pending:
            time_pending = dt_util.utcnow() - self._pending_since
            if self._is_on:
                time_remaining = self._time_off - time_pending
            else:
                time_remaining = self._time_on - time_pending

            if time_remaining.total_seconds() <= 0:
                self._is_on = not self._is_on
                self._pending = False
                self.schedule_update_ha_state()
        else:
            # enter pending mode (start counting time to change state)
            self._pending_since = dt_util.utcnow()
            self._pending = True

            time_to_expire = dt_util.utcnow() + (
                self._time_off if self._is_on else self._time_on)

            async_track_point_in_time(self._hass, self.async_pending_expired,
                                      time_to_expire)
    def _schedule_pit_callback(self):
        # First remove a possible previous outdated listener
        self._async_remove_pit_listener()

        # Check if and when to trigger the next point in time
        if self._timestamps:
            last_update_ts = max(self._timestamps.values())
            pit = last_update_ts + timedelta(minutes=self._threshold)
            _LOGGER.debug("Schedule next sensor state check @ %s", pit)
            self._remove_pit_listener = async_track_point_in_time(
                self.hass, self._async_pit_callback, pit)
示例#35
0
    def check_status_until_done(self, media_id, callback, *args):
        """Upload media, STATUS phase."""
        resp = self.api.request('media/upload',
                                {'command': 'STATUS', 'media_id': media_id},
                                method_override='GET')
        if resp.status_code != 200:
            _LOGGER.error("media processing error: %s", resp.json())
        processing_info = resp.json()['processing_info']

        _LOGGER.debug("media processing %s status: %s", media_id,
                      processing_info)

        if processing_info['state'] in {u'succeeded', u'failed'}:
            return callback(media_id)

        check_after_secs = processing_info['check_after_secs']
        _LOGGER.debug("media processing waiting %s seconds to check status",
                      str(check_after_secs))

        when = datetime.now() + timedelta(seconds=check_after_secs)
        myself = partial(self.check_status_until_done, media_id, callback)
        async_track_point_in_time(self.hass, myself, when)
    def _async_setup_platform(self, platform_type, platform_config,
                              discovery_info=None, tries=0):
        """Set up a platform for this component.

        This method must be run in the event loop.
        """
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (
            platform_config.get(CONF_SCAN_INTERVAL) or
            getattr(platform, 'SCAN_INTERVAL', None) or self.scan_interval)
        parallel_updates = getattr(
            platform, 'PARALLEL_UPDATES',
            int(not hasattr(platform, 'async_setup_platform')))

        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            entity_platform = self._platforms[key] = EntityPlatform(
                self, platform_type, scan_interval, parallel_updates,
                entity_namespace)
        else:
            entity_platform = self._platforms[key]

        self.logger.info("Setting up %s.%s", self.domain, platform_type)
        warn_task = self.hass.loop.call_later(
            SLOW_SETUP_WARNING, self.logger.warning,
            "Setup of platform %s is taking over %s seconds.", platform_type,
            SLOW_SETUP_WARNING)

        try:
            if getattr(platform, 'async_setup_platform', None):
                task = platform.async_setup_platform(
                    self.hass, platform_config,
                    entity_platform.async_schedule_add_entities, discovery_info
                )
            else:
                # This should not be replaced with hass.async_add_job because
                # we don't want to track this task in case it blocks startup.
                task = self.hass.loop.run_in_executor(
                    None, platform.setup_platform, self.hass, platform_config,
                    entity_platform.schedule_add_entities, discovery_info
                )
            yield from asyncio.wait_for(
                asyncio.shield(task, loop=self.hass.loop),
                SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
            yield from entity_platform.async_block_entities_done()
            self.hass.config.components.add(
                '{}.{}'.format(self.domain, platform_type))
        except PlatformNotReady:
            tries += 1
            wait_time = min(tries, 6) * 30
            self.logger.warning(
                'Platform %s not ready yet. Retrying in %d seconds.',
                platform_type, wait_time)
            async_track_point_in_time(
                self.hass, self._async_setup_platform(
                    platform_type, platform_config, discovery_info, tries),
                dt_util.utcnow() + timedelta(seconds=wait_time))
        except asyncio.TimeoutError:
            self.logger.error(
                "Setup of platform %s is taking longer than %s seconds."
                " Startup will proceed without waiting any longer.",
                platform_type, SLOW_SETUP_MAX_WAIT)
        except Exception:  # pylint: disable=broad-except
            self.logger.exception(
                "Error while setting up platform %s", platform_type)
        finally:
            warn_task.cancel()
示例#37
0
async def schedule_future_update(hass, sensors, midnight_time,
                                 prayer_times_data):
    """Schedule future update for sensors.

    Midnight is a calculated time.  The specifics of the calculation
    depends on the method of the prayer time calculation.  This calculated
    midnight is the time at which the time to pray the Isha prayers have
    expired.

    Calculated Midnight: The Islamic midnight.
    Traditional Midnight: 12:00AM

    Update logic for prayer times:

    If the Calculated Midnight is before the traditional midnight then wait
    until the traditional midnight to run the update.  This way the day
    will have changed over and we don't need to do any fancy calculations.

    If the Calculated Midnight is after the traditional midnight, then wait
    until after the calculated Midnight.  We don't want to update the prayer
    times too early or else the timings might be incorrect.

    Example:
    calculated midnight = 11:23PM (before traditional midnight)
    Update time: 12:00AM

    calculated midnight = 1:35AM (after traditional midnight)
    update time: 1:36AM.
    """
    _LOGGER.debug("Scheduling next update for Islamic prayer times")

    now = dt_util.as_local(dt_util.now())
    today = now.date()

    midnight_dt_str = '{}::{}'.format(str(today), midnight_time)
    midnight_dt = datetime.strptime(midnight_dt_str, '%Y-%m-%d::%H:%M')

    if now > dt_util.as_local(midnight_dt):
        _LOGGER.debug("Midnight is after day the changes so schedule update "
                      "for after Midnight the next day")

        next_update_at = midnight_dt + timedelta(days=1, minutes=1)
    else:
        _LOGGER.debug(
            "Midnight is before the day changes so schedule update for the "
            "next start of day")

        tomorrow = now + timedelta(days=1)
        next_update_at = dt_util.start_of_local_day(tomorrow)

    _LOGGER.debug("Next update scheduled for: %s", str(next_update_at))

    async def update_sensors(_):
        """Update sensors with new prayer times."""
        # Update prayer times
        prayer_times = prayer_times_data.get_new_prayer_times()

        _LOGGER.debug("New prayer times retrieved.  Updating sensors.")

        # Update all prayer times sensors
        for sensor in sensors:
            sensor.async_schedule_update_ha_state(True)

        # Schedule next update
        await schedule_future_update(hass, sensors, prayer_times['Midnight'],
                                     prayer_times_data)

    async_track_point_in_time(hass,
                              update_sensors,
                              next_update_at)