Create a time offset in template value?

I have a sensor, filled with an alarm time from my iphone. It’s pushed with a shortcut. Now I want to use the last alarm time, to trigger the parabolic wakeup light, BUT with a 30min offset, so it ends when the last alarm goes off.

My idea was to do it like this. Snippet from my configuration.yaml:

# helper: Push iPhone alarm to HA
template:
  - sensor:
    - name: "Alarm"
      icon: mdi:clock
      state: "{{ states('input_boolean.alarm') }}"
  - sensor:
    - name: "First Alarm"
      icon: mdi:alarm-snooze
      state: "{{ state_attr('input_datetime.first_alarm', 'timestamp') | timestamp_custom('%H:%M', None) }}"
  - sensor:
    - name: "Last Alarm"
      icon: mdi:alarm-snooze
      state: "{{ state_attr('input_datetime.last_alarm', 'timestamp') | timestamp_custom('%H:%M', None) }}"
  - sensor:
    - name: "Wakeup Light - 1st try"
      icon: mdi:weather-sunset-up
      state: "{{ states('input_datetime.last_alarm') - (timedelta(minutes=30).strftime('%H:%M')) }}"
  - sensor:
    - name: "Wakeup Light - 2nd try"
      icon: mdi:weather-sunset-up
      state: "{{ sensor.last_alarm - (timedelta(minutes=30).strftime('%H:%M')) }}"

My inspiration came from here: Using an input_datetime sensor offset value in an automation

None of them worked… Any further ideas? I’m always getting “Not Available” in the dashboard:

image

States are always strings. This obviously goes for your input_datetime helpers as well.

You cannot perform calculations on strings, you must first convert them into a datetime object or a timestamp.

Use either of the as_datetime or as_timestamp filters on the state, or use the timestamp attribute to get it directly.

(Personally I consider calculations on datetime objects to be a hassle, much easier to only work with timestamps…)

Currently, a Time Trigger can offset a sensor’s value (if the sensor’s device_class is timestamp).

triggers:
  - trigger: time
    at: sensor.whatever
    offset: '-00:30:00'

So if the requirement is to simply trigger at a time before or after a sensor’s value, it can be done by a Time Trigger (i.e. the calculation doesn’t have to be performed by a Template Sensor).

There’s a PR in the Core repo that will enhance the Time Trigger to support Input Datetime helpers with an offset value.

So you will be able to do this:

triggers:
  - trigger: time
    at: input_datetime.whatever
    offset: '-00:30:00'

The reason to not use this Time Trigger feature (offset) is if you want to display/record the computed offset time as apart of an entity (like a Template Sensor).

Eventough I appreciate your suggestion with using the PRs functionalities, I opted for a traditional solution, as suggested by Magnus:

  - sensor:
    - name: "Wakeup Light Time"
      icon: mdi:weather-sunset-up
      state: "{{ ((state_attr('input_datetime.first_alarm', 'timestamp') | int)
                 - (30 * 60)) | timestamp_custom('%H:%M', None) }}"

Using Developer Tools → Templates greatly helped with troubleshooting.

I recommend changing that to.

{{ states('input_datetime.first_alarm') | as_datetime | as_local - timedelta(minutes=30) }}

Then you can use it as a trigger…

- trigger: time
  at: sensor.wakeup_light_time

It won’t show as a nice HH:MM in the UI, however it will be really easy to use with time triggers.

Lastly, I recommend avoid using the old school timestamp_custom functions, the template engine has evolved into using datetime objects which are easier to use with timezones.

Trying this in the Dev Tools results in

AttributeError: 'NoneType' object has no attribute 'tzinfo

But you’re correct. With my solution, I’m not able to use it as trigger… At least it does not show up as input_datetime:

Change the blueprint to accept a sensor with device_class timestamp and add device_class: timestamp to your configuration.

  - sensor:
    - name: "Wakeup Light Time"
      icon: mdi:weather-sunset-up
      device_class: timestamp
      state: >
        {{ states('input_datetime.first_alarm') | as_datetime | as_local - timedelta(minutes=30) }}

blueprint

...
   selector:
     entity:
       multiple: True
       filter:
       - domain: input_datetime
       - domain: sensor
         device_class: timestamp
...

Sorry for the delay. I was not able to look into it earlier. I set it up exactly like you suggested, but the automation is not being triggered at all by the sensor.wakeup_light_time. For example, when I set the alarm in the iphone to 5:30am, I expect the automation to be triggered at 5:00am, so it’s finished, when the first alarm goes off. Do you have some further ideas? :slight_smile:

image

did you alter the template like I posted or did you leave it to your output format?

Yes, I have done that. If I hadn’t done that, the screenshot would have looked different.

can you post the output of the sensor in developer tools → states page?

It says “unavailable”.

This is my current configuration.yaml:

template:
  - binary_sensor:
    - name: "Alarm Status"
      icon: mdi:clock
      state: "{{ is_state('input_boolean.alarm', 'on') }}"
  - sensor:
    - name: "Alarm"
      icon: mdi:clock
      state: "{{ states('input_boolean.alarm') }}"
  - sensor:
    - name: "Erster Alarm"
      icon: mdi:alarm-snooze
      state: "{{ state_attr('input_datetime.first_alarm', 'timestamp') | timestamp_custom('%H:%M', None) }}"
  - sensor:
    - name: "Letzter Alarm"
      icon: mdi:alarm-snooze
      state: "{{ state_attr('input_datetime.last_alarm', 'timestamp') | timestamp_custom('%H:%M', None) }}"
  - sensor:
    - name: "Wakeup Light Time"
      icon: mdi:weather-sunset-up
      device_class: timestamp
      state: >
        {{ states('input_datetime.first_alarm') | as_datetime | as_local - timedelta(minutes=30) }}

This is the parabolic_alarm.yaml:

blueprint:
  name: Parabolic Alarm Automation
  description: Turn a light on based on detected motion
  domain: automation
  input:
    alarm_start_time:
      name: Start Time
      description: Datetime helper for alarm to start. Use time only and Workday sensor
        to determine what days to run.
      selector:
        entity:
          multiple: True
          filter:
          - domain: input_datetime
          - domain: sensor
            device_class: timestamp
    workday_sensor:
      name: Workday Sensor
      description: Binary Sensor for determining whether it should run. Typically
        from Workday Integration
      selector:
        entity:
....

You don’t have unique_id’s are you sure you’re looking at the correct entity? It being unavailable is why it’s not working.

Is it a time only input_datetime?

I’m totally new to HA, but fast-learning. I just did it like described here and manually created helpers:

Yes it is a time-only field. No date.

ok, then the template is

{{ today_at(states('input_datetime.first_alarm')) - timedelta(minutes=30) }}

working! Just the wrong format. %H:%M is enough…

It won’t be that format, HA needs the state format in order to use it as a trigger.

If you look at it in the UI (not states page), it will say “xx ago” or “in xx minutes”

1 Like

Do you happen to answer me one more question?

I want to hide the marked ones or gray them out, when alarm is off:
image

That will likely require an additional binary_sensor that compares the time to current time (now()) and then use that as a visibility condition on the card.