Time condition - inclusive or exclusive?

I don’t, but here’s the bin collection one as an example. Uses Python’s BeautifulSoup module to scrape the council website, which is a bit more complex than HA’s scrape sensor can cope with; and creates/updates the three timestamp sensors that show the next collection dates for my bins:

import hassapi as hass
from bs4 import BeautifulSoup
import datetime
from dateutil import parser
import requests

class BinCollection(hass.Hass):

    def initialize(self):
        """Sets up the uprn and the first run"""

        self.log("Bin collection app running")
        self.uprn = 'xxxxxx'
        self.run_in(self.refresh, 5)

    def refresh(self, kwargs):
        """Looks up the data, sets next run at 2am tomorrow"""

        url = "https://www.lichfielddc.gov.uk/homepage/6/" \
              f"bin-collection-dates?uprn={self.uprn}"
        page = requests.get(url)

        if page.status_code != 200:
            return None

        soup = BeautifulSoup(page.text, 'html.parser')

        bh3s = soup.find_all('h3', class_="bin-collection-tasks__heading")
        bpds = soup.find_all('p', class_="bin-collection-tasks__date")

        for i in range(len(bpds)):
            bin_colour = bh3s[i].contents[1].split(' ')[0].lower()
            bin_date = parser.parse(bpds[i].contents[0]).strftime('%Y-%m-%d')
            self.log(f"{bin_date}: {bin_colour} bin")
            self.set_state(f"sensor.{bin_colour}_bin",
                           state=bin_date,
                           attributes={'device_class': 'timestamp'})

        tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
        next_run = tomorrow.replace(hour=2, minute=0, second=0, microsecond=0)

        self.log(f"Scheduling next run for {next_run.isoformat()}")

        self.run_at(self.refresh, next_run)
entities:
  - entity: sensor.black_bin
    icon: 'mdi:trash-can-outline'
    name: Black
  - entity: sensor.blue_bin
    icon: 'mdi:recycle'
    name: Blue
  - entity: sensor.brown_bin
    icon: 'mdi:flower'
    name: Brown
style: |-
  ha-card { border-radius: 8px; }
  div.entity:nth-of-type(1) { color: black; }
  div.entity:nth-of-type(2) { color: blue; }
  div.entity:nth-of-type(3) { color: brown; }
title: Bin collections
type: glance

image

1 Like

I finally found myself needing to re-visit this and did a test to “prove” it by setting up several automations and observing which fired.

I’ll let the results speak for themselves…

  - alias: 'Test event - 1'
    trigger:
    - platform: time
      at: '20:00:00'
    condition:
    - condition: time
      after: '20:00:00'
      before: '20:00:00'
    action:
      service: notify.telegram_send
      data:
        message: 'Test event 1 - 20:00:00 - 20:00:00'

  - alias: 'Test event - 2'
    trigger:
    - platform: time
      at: '20:00:00'
    condition:
    - condition: time
      after: '20:00:00'
      before: '20:00:01'
    action:
      service: notify.telegram_send
      data:
        message: 'Test event 2 - 20:00:00 - 20:00:01'

  - alias: 'Test event - 3'
    trigger:
    - platform: time
      at: '20:00:00'
    condition:
    - condition: time
      after: '19:59:59'
      before: '20:00:00'
    action:
      service: notify.telegram_send
      data:
        message: 'Test event 3 - 19:59:59 - 20:00:00'

  - alias: 'Test event - 4'
    trigger:
    - platform: time
      at: '20:00:00'
    condition:
    - condition: time
      after: '19:59:59'
      before: '20:00:01'
    action:
      service: notify.telegram_send
      data:
        message: 'Test event 4 - 19:59:59 - 20:00:01'

Result:

Home Assistant, [4/2/22 8:00 PM]
Test event 4 - 19:59:59 - 20:00:01

Home Assistant, [4/2/22 8:00 PM]
Test event 1 - 20:00:00 - 20:00:00

Home Assistant, [4/2/22 8:00 PM]
Test event 2 - 20:00:00 - 20:00:01
2 Likes

@mmiller7 Did you ever work out whether before and after are exclusive or inclusive?

So, if you did this:

  - choose:
      - conditions:
          - condition: time
            after: "00:00:00"
            before: "01:00:00"
        sequence:
          - service: scene.turn_on
            target:
              entity_id: scene.master_bedroom_00_00_00_59
            metadata: {}
      - conditions:
          - condition: time
            after: "01:00:00"
            before: "02:00:00"
        sequence:
          - service: scene.turn_on
            target:
              entity_id: scene.master_bedroom_01_00_01_59
            metadata: {}

would either of those two scenes be activated at exactly 01:00:00, and if not, what would be the way to efficiently make one of them activate at exactly 01:00:00 ?

Apparently “choose” is a new thing I haven’t seen yet…but you could do a similar test I’d imagine to work out what it does

@mmiller7 conditions work the same everywhere, so the result would be the same for your tests. It doesn’t matter whether it’s an automation’s condition, a choose or an if.

@jsh the answer is right before your post: after is inclusive and before is exclusive. But, because of the ambiguity and readability in some cases, I just opt for a template condition to make it explicit (using the various comparison operators).

1 Like

To provide an example, this is completely unambiguous to me:

{% set within_window = today_at('03:30') <= now() <= today_at('11:30') %}

This looks to me like after is inclusive and before is exclusive.

Meaning a condition of “after 20:00” will be true at 20:00, but if you trigger an event at 20:01 and you have “before 20:01”, it will be false.

EDIT: Looks like @parautenbach clarified this in an earlier post.

1 Like