Negative time on screen

Hello,

There are lights on the facade of my house which I turn on in the evening at sun set, but I made it possitble to do that with an offset of time (before or after sun set).

So I created 2 helpers : an input.select where I can chose + or - and a input.time with the amount of time (before or after sun set).

Now, I display it as this

Schermafbeelding 2022-01-14 160706

Do you see a nicer way to portray this? A time-slider that can go negative would of course be ideal, but…

I would use picture entities card and “design” something.
Not sure how input_select works on the card but you could use two booleans, one for + and one for - and color the one that is active.
Or hide the one that is not active.

Regarding the actual time, how fine tuned does it need to be?
You could have + and - buttons to add/subtract 10-15 minutes per click.

On mobile it doesn’t get scaled correctly and the icon is placed too low but here is my “guests” card where I can set what time all automations should start running as normal again.

I add/subtract one hour per click, but I understand yours need a better fine tuning.

Indeed nice, but in my case too big. It’s a parameter that I won’t change every day.

But I found another simpler solution, a custom slider with a specific input_select :

Schermafbeelding 2022-01-15 142114

`offset_test:
  name: ''
  options:
    - '- 01:00'
    - '- 00:55'
    - '- 00:50'
    - '- 00:45'
    - '- 00:40'
    - '- 00:35'
    - '- 00:30'
    - '- 00:25'
    - '- 00:20'
    - '- 00:15'
    - '- 00:10'
    - '- 00:05'
    - '  00:00'
    - '+ 00:05'
    - '+ 00:10'
    - '+ 00:15'
    - '+ 00:20'
    - '+ 00:25'
    - '+ 00:30'
    - '+ 00:35'
    - '+ 00:40'
    - '+ 00:45'
    - '+ 00:50'
    - '+ 00:55'
    - '+ 01:00'
  initial: '  00:00'
`

I created a sensor :

- trigger:
  - platform: time
    at: '00:00:00'
  - platform: event
    event_type: event_template_reloaded
  - platform: homeassistant
    event: start
  sensor:
  - name: 'Test'
    unique_id: 'sensor_test'
    state: >
      {% set x = states('input_select.offset_test') %}
      {% set y = x.split(' ') %}
      {% set plusmin = y[0] %}
      {% set time = y[1].split(':') %} %}
      {% if (plusmin == '+') %}
        {{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(hours=time[0]|int, minutes=time[1]|int, seconds=0) }}
      {% elif (plusmin == '-') %}
          {{ state_attr('sun.sun', 'next_setting') | as_datetime - timedelta(hours=time[0]|int, minutes=time[0]|int) }}
      {% else %}
          {{ state_attr('sun.sun', 'next_setting') | as_datetime }}
      {% endif %}
    device_class: timestamp

It seems to work :

But after restarting HA / rebuild templates the entity’s state is unknown…

Any idea ?

I’m quite sure the picture element card is the size you make it.

Not sure about the error.

@123 Can you perhaps have a look (modification of the implementation we did yesterday in another topic) ?

This version works for me:

Offset amount is in minutes.

  offset_test:
    name: 'Offset Test'
    options:
    - '-60'
    - '-55'
    - '-50'
    - '-45'
    - '-40'
    - '-35'
    - '-30'
    - '-25'
    - '-20'
    - '-15'
    - '-10'
    - '-5'
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
    initial: '0'

Trigger-based Template Sensor updates on startup, Reload Template Entities, at midnight, and when the input_select changes (for the case where you may want to manually adjust the offset).

- trigger:
  - platform: time
    at: '00:00:00'
  - platform: event
    event_type: event_template_reloaded
  - platform: homeassistant
    event: start
  - platform: state
    entity_id: input_select.offset_test
  sensor:
  - name: 'Offset Test'
    unique_id: 'offset_test'
    state: "{{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(minutes = states('input_select.offset_test')|int(0)) }}"
    device_class: timestamp

There’s no need to check if the offset value is negative or positive. A negative value for the timedelta object will automatically serve as a subtraction instead of an addition.

NOTE

I’m not sure why you included initial: '0' for the input_select but I left it as-is. It will cause the input_select’s value to always revert to 0 on startup (so if you manually set the input_select to -15 it will revert to 0 after a restart).

If you don’t want that behavior, remove initial: '0' from its configuration. The input_select's initial value will be its first option (-60). Simply manually set it to something else and it will retain that value after a restart.

Thank you for this !

Good tip in connection with the “initial”, came with my copy-paste :upside_down_face:

That’s a good one too :

  - platform: state
    entity_id: input_select.offset_test

Can I mention various entities (comma seperated), cause I have different sensors ?

I suppose I can expand the list with 65, 70, 75,… (positive and negative) ?

So you don’t know what the problem was with my version ? I must admit, it’s strange…

I don’t understand your question.

Where do you want to specify a comma-separated list of entities and what “sensors” are you referring to?

I mean like this (old version of yesterday) :

- trigger:
  - platform: time
    at: '00:00:00'
  - platform: event
    event_type: event_template_reloaded
  - platform: homeassistant
    event: start
  - platform: state
    entity_id: **input_select.select_offset_sfeer_morgen, input_datetime.tijdstip_offset_sfeer_avond, input_datetime.tijdstip_offset_rolluik_morgen**
  sensor:
  - name: 'Sfeer morgen'
    unique_id: 'sensor_sfeer_morgen'
    state: >
      {% set t = 'input_datetime.tijdstip_offset_sfeer_morgen' %}
      {% if (states('input_select.select_offset_sfeer_morgen') == '+') %}
          {{ state_attr('sun.sun', 'next_rising') | as_datetime + timedelta(hours=state_attr(t, 'hour'), minutes=state_attr(t, 'minute'), seconds=state_attr(t, 'second')) }}
      {% else %}
          {{ state_attr('sun.sun', 'next_rising') | as_datetime - timedelta(hours=state_attr(t, 'hour'), minutes=state_attr(t, 'minute'), seconds=state_attr(t, 'second')) }}
      {% endif %}
    device_class: timestamp
  - name: 'Sfeer avond'
    unique_id: 'sensor_sfeer_avond'
    state: >
      {% set t = 'input_datetime.tijdstip_offset_sfeer_avond' %}
      {% if (states('input_select.select_offset_sfeer_avond') == '+') %}
          {{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(hours=state_attr(t, 'hour'), minutes=state_attr(t, 'minute'), seconds=state_attr(t, 'second')) }}
      {% else %}
          {{ state_attr('sun.sun', 'next_setting') | as_datetime - timedelta(hours=state_attr(t, 'hour'), minutes=state_attr(t, 'minute'), seconds=state_attr(t, 'second')) }}
      {% endif %}
    device_class: timestamp
  - name: 'Rolluik morgen'
    unique_id: 'sensor_rolluik_morgen'
    state: >
      {% set t = 'input_datetime.tijdstip_offset_rolluik_morgen' %}
      {% if (states('input_select.select_offset_rolluik_morgen') == '+') %}
          {{ state_attr('sun.sun', 'next_rising') | as_datetime + timedelta(hours=state_attr(t, 'hour'), minutes=state_attr(t, 'minute'), seconds=state_attr(t, 'second')) }}
      {% else %}
          {{ state_attr('sun.sun', 'next_rising') | as_datetime - timedelta(hours=state_attr(t, 'hour'), minutes=state_attr(t, 'minute'), seconds=state_attr(t, 'second')) }}
      {% endif %}
    device_class: timestamp
...

Yes, as a comma-separated string or as a list as shown in the documentation for State Trigger.

  - platform: state
    entity_id:
      - input_select.select_offset_sfeer_morgen
      - input_datetime.tijdstip_offset_sfeer_avond
      - input_datetime.tijdstip_offset_rolluik_morgen

Keep in mind that changing the state of any one of the three input_select entities will cause all three Template Sensors to be updated (because they are triggered by a shared State Trigger). For this application, there’s no negative impact to this behavior.

Oh no…back to my initial problem ?

- trigger:
  - platform: time
    at: '00:00:00'
  - platform: event
    event_type: event_template_reloaded
  - platform: homeassistant
    event: start
  - platform: state
    entity_id:
      - input_select.offset_sfeer_morgen
      - input_select.offset_sfeer_avond
      - input_select.offset_rolluik_morgen
      - input_select.offset_rolluik_avond
      - input_select.offset_voorgevel_avond
  sensor:
  - name: 'Sunset'
    unique_id: 'sensor_sunset'
    state: "{{ state_attr('sun.sun', 'next_setting') | as_datetime }}"
    device_class: timestamp
  - name: 'Sunrise'
    unique_id: 'sensor_sunrise'
    state: "{{ state_attr('sun.sun', 'next_rising') | as_datetime }}"
    device_class: timestamp
  - name: 'Sunset Offset Random'
    unique_id: 'sensor_sunset_offset_random'
    state: "{{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(minutes=range(-25, 26) | random) }}"
    device_class: timestamp
  - name: 'Sunrise Offset Random'
    unique_id: 'sensor_sunrise_offset_random'
    state: "{{ state_attr('sun.sun', 'next_rising') | as_datetime + timedelta(minutes=range(-25, 26) | random) }}"
    device_class: timestamp
  - name: 'Sfeer morgen'
    unique_id: 'sensor_sfeer_morgen'
    state: >
      {{ state_attr('sun.sun', 'next_rising') | as_datetime + timedelta(minutes = states('input_select.offset_sfeer_morgen')|int(0)) }}"
    device_class: timestamp
  - name: 'Sfeer avond'
    unique_id: 'sensor_sfeer_avond'
    state: >
      {{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(minutes = states('input_select.offset_sfeer_avond')|int(0)) }}"
    device_class: timestamp
  - name: 'Rolluik morgen'
    unique_id: 'sensor_rolluik_morgen'
    state: >
      {{ state_attr('sun.sun', 'next_rising') | as_datetime + timedelta(minutes = states('input_select.offset_rolluik_morgen')|int(0)) }}"
    device_class: timestamp
  - name: 'Rolluik avond'
    unique_id: 'sensor_rolluik_avond'
    state: >
      {{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(minutes = states('input_select.offset_rolluik_avond')|int(0)) }}"
    device_class: timestamp
  - name: 'Voorgevel avond'
    unique_id: 'sensor_voorgevel_avond'
    state: >
      {{ state_attr('sun.sun', 'next_setting') | as_datetime + timedelta(minutes = states('input_select.offset_voorgevel_avond')|int(0)) }}"
    device_class: timestamp

offset_voorgevel_avond:
  name: ''
  options:
    - '-60'
    - '-55'
    - '-50'
    - '-45'
    - '-40'
    - '-35'
    - '-30'
    - '-25'
    - '-20'
    - '-15'
    - '-10'
    - '-5'
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
    - '45'
    - '50'
    - '55'
    - '60'

offset_rolluik_morgen:
  name: ''
  options:
    - '-60'
    - '-55'
    - '-50'
    - '-45'
    - '-40'
    - '-35'
    - '-30'
    - '-25'
    - '-20'
    - '-15'
    - '-10'
    - '-5'
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
    - '45'
    - '50'
    - '55'
    - '60'

offset_rolluik_avond:
  name: ''
  options:
    - '-60'
    - '-55'
    - '-50'
    - '-45'
    - '-40'
    - '-35'
    - '-30'
    - '-25'
    - '-20'
    - '-15'
    - '-10'
    - '-5'
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
    - '45'
    - '50'
    - '55'
    - '60'

offset_sfeer_morgen:
  name: ''
  options:
    - '-60'
    - '-55'
    - '-50'
    - '-45'
    - '-40'
    - '-35'
    - '-30'
    - '-25'
    - '-20'
    - '-15'
    - '-10'
    - '-5'
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
    - '45'
    - '50'
    - '55'
    - '60'

offset_sfeer_avond:
  name: ''
  options:
    - '-60'
    - '-55'
    - '-50'
    - '-45'
    - '-40'
    - '-35'
    - '-30'
    - '-25'
    - '-20'
    - '-15'
    - '-10'
    - '-5'
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
    - '45'
    - '50'
    - '55'
    - '60'

Is it reporting unknown immediately after a restart?

If not on startup, then when?

I first did a YAML configuration reloading of the imput selects and templates.

After checking the states in the developer tools (unknown) I did a restart of HA, but without any better results.

The steps you described are the same ones I did but I don’t get unknown so I can’t reproduce your failure scenario. The implication is that you’re doing something else wrong somewhere. Do the Template Sensors exist when you look in Developer Tools > States?

Yes, they do…

Sorry, I can’t reproduce the failure you’re experiencing. In my case, restarting/reloading always results in the sensor having a proper value (not unknown). :man_shrugging:

Check the log for any related warnings or errors.

I found something in the log !

When deleting this sensor :

  - name: 'Sfeer morgen'
    unique_id: 'sensor_sfeer_morgen'
    state: >
      {{ state_attr('sun.sun', 'next_rising') | as_datetime + timedelta(minutes = states('input_select.offset_sfeer_morgen')|int(0)) }}"
    device_class: timestamp

And doing an rebuild of the templates, I get an error on the next sensor (sensor_sfeer_avond).

What is the version of Home Assistant you are using? I tested it with 2021.12.7.

Last version : Home Assistant 2021.12.9

When I change the sensor to this :

  - name: 'Sfeer morgen'
    unique_id: 'sensor_sfeer_morgen'
    state: >
      {{ timedelta(minutes = states('input_select.offset_sfeer_morgen')|int(0)) }}"
    device_class: timestamp

I still get the error :

Schermafbeelding 2022-01-16 072150

Same problem with the other part :

  - name: 'Sfeer morgen'
    unique_id: 'sensor_sfeer_morgen'
    state: >
      {{ state_attr('sun.sun', 'next_rising') | as_datetime }}"
    device_class: timestamp

I upgraded to 2021.12.9 and confirmed the Template Sensor continues to work properly.

I just noticed that when you changed the template from a single-line to multi-line, you removed the leading double-quote but forgot to remove the trailing double-quote.

    state: >
      {{ state_attr('sun.sun', 'next_rising') | as_datetime }}"
                                                              ^
                                                              |
                          Remove this -------------------------

That double-quote is appended to the datetime and is what causes the datetime to be invalid.
Remove it.