Binary sensor checking time ok, how to add offset?

Hi.
I have my garage door controlled by an automation that at a selected time checks if it’s still opened and, if so, it send a telegram alert to my mobile, with option to close it immediately or wait automatic closing in 15 minutes.

The automation is triggered when this sensor goes on:

chiusura_automatica_box:
        value_template: >
          {% if states.input_select.orario_chiusura.state is defined %}
            {{states.input_select.orario_chiusura.state == states.sensor.time.state}}
          {% else %}
            False
          {% endif %}
        friendly_name: 'Chiusura Automatica Box'

The second automation should be triggered 15 minutes later, by another sensor that goes on.
But this sensore never goes on:

chiusura_automatica_box_quindici_minuti:
       value_template: >
          {% if states.input_select.orario_chiusura.state is defined %}
            {{ ( states.input_select.orario_chiusura.state | int + 900 ) == ( states.sensor.time.state | int ) }}
          {% else %}
            False
          {% endif %}
        friendly_name: 'Chiusura Automatica Box Dopo 15 Minuti'

What’s wrong in the second sensor?
Thanks.

Oooh ! Goody.!

You don’t need the false statement in the first automation so we can simplify

Give me a sec on the second …

… You are not using initialisation proof syntax for : -

states.input_select.orario_chiusura.state

It should be : - 

states('input_select.orario_chiusura') 

And what is this anyway, you are treating it as a time and yet merely converting it to an integer (which may be valid (edit: no it won’t be if it’s ‘14:20’ etc.)
But how is it created and what is its value

This is also more complicated than it needs to be, let me get to a workstation …

… Okay the binary sensor (first quoted block) should just be : -

chiusura_automatica_box:
  value_template: "{{states('input_select.orario_chiusura') == states('sensor.time')}}"
  friendly_name: 'Chiusura Automatica Box'

From this I’m guessing that your input select has various values similar to ‘07:30’, ‘14:20’ etc.
And you are comparing this with the time.
The above sensor will be true for 1 minute of the day, I assume from what you have said that is what you wanted ???
But why not just have this as a template trigger in an automation ?

I’m confused by the second one as what you seem to be trying to do is trigger another binary_sensor 900 seconds later ???
Why Bother ?
When the garage door opens, have that trigger another automation that is triggered by ‘garage door open’ for ‘00:15:00’ and then closes the door. This will work in ALL circumstances and not just when you open the door triggered by you binary sensor. (And if you’ve closed the door before 15 minutes then the trigger won’t fire - All good !

If you insist on another binary sensor then : -

Time calculations are a bugger (Thank God for @finity 's EPIC time manipulation thread, though it does need updating to initialisation proof syntax (hint: :rofl: )

chiusura_automatica_box_quindici_minuti:
  value_template: "{{ as_timestamp(states('sensor.date') ~ ' ' ~ states('sensor.time')) == as_timestamp(states('sensor.date') ~ ' ' ~ states('input_select.orario_chiusura')) + 900 }}"
  friendly_name: 'Chiusura Automatica Box Dopo 15 Minuti'

Though I’m sure finity, petro, taras or Phil could make it even shorter

1 Like

Hi.
Let’s see…
Initially the first sensor was like this:
value_template: '{{states.input_select.orario_chiusura.state == states.sensor.time.state}}'

I changed it to check if the value exist trying to avoid warning (or errors?) in the log.
I found that workaround used for giving always a value to the sensor.

From this I’m guessing that your input select has various values similar to ‘07:30’, ‘14:20’ etc.
And you are comparing this with the time.
The above sensor will be true for 1 minute of the day, I assume from what you have said that is what you wanted ???

Yes, at the specified time the automation triggers and notifies me that the garage door is still opened.
As a “night failsafe” I have another automation that triggers every 30 minutes in the evening and it checks the garage door state, and automatically closes it if it’s opened.
Before I put everything in the trigger, but then I read that by using a sensor and using its state as trigger was better, because otherwise the automation would check every minute the time. Maybe I was wrong?

I recap the meaning:
at specified time, let’s say 18:30, the fisrt automation check if the garage door is still open. If so, it sends a telegram message to me, notifying that the door is opened and asking me if I want to close it immediately or disable the automatic closing, with two buttons for choices. If I “select close it now”, the door closes (it works), if I select “disable automatic closing”, the door stays opened until I manually close it.
If I simply ignore the message (or don’t see it), after 15 minutes the second automation triggers and closes it automatically. This second automation check the state of sensor.chiusura_automatica_box_quindici_minuti, that should change its state to on 15 minutes after the time set in input_select.orario_chiusura.

I’ll try your second sensor syntax, even if I can’t understand it very well.
But… why using sensor.date if it has to run everyday? I don’t mind the date…

No, you are not wrong but the binary sensor has to check the condition every minute anyway so you have moved the processing time, not eliminated it.
So it will check every minute of the day, adding the binary sensor adds a check when that fires (on and off) so you are actually adding processing (it is really insignificant though) (Edit: Though I have done exactly that for some of my switches that have 2 on slots, 2 off slots, manual on, automation overide, occupation on and off, which concentrates all processing in one location - that would be fired every minute anyway).
The states(‘thing’) does what you need without the extra test, unless the device is simply missing and I think you’d want notification of that
(Edit: Though you still need to be wary when using attributes (ie not explicitly stated entities) which HAVE to be stated (in certain circumstances) as “states.thing.state” )

It was the only way I could find (this is where petro usually jumps in) to convert a string value of (say) ‘14:20’ to an actual timestamp value so you could add 900 seconds to it. :man_shrugging:

Edit: We ‘could’ do a text manipulation to split the hour and colon from the minute, then add the 15 minutes, but then you need to check for hour wrapping and incrementing the hour AND THEN to see if day wrapping occurs i.e. it’s pointless to wait (if the trigger was set for 23:50) for say 24:05 (time only goes up to 23:59, so … A LOT of checks and corrections.
This way it’s on 1 line, even though it’s a long one.

1 Like

Ok, I’ll try it tonight :slight_smile:
Thanks

Why by another sensor?

The second automation can be triggered by the first sensor and its action can contain a 15-minute delay.

1 Like

Though if he closes the door after 10 mins, then re opens it 2 mins later, won’t it try to imediately close ?

Pro’s/Con’s of For/Timers/Automation delays/Separate Scripts with delays (+cancelling of same) issues :man_shrugging:

I used another automation and another sensor because I need to be able to disable the garage-door auto closing (using the telegram message button in this case).
If I simply put a delay in the action section and then a closing command, it will always close.

Use a condition in the automation.

there’s a condition in the automation, but I can’t put a condition in the action section.

for clarity:

#CHECKS IF THE DOOR IS OPENED
- alias: Controlla_se_sezionale_dimenticato_aperto_alla_sera
    trigger:
      - platform: state
        entity_id: binary_sensor.chiusura_automatica_box
        to: 'on'        
    condition:
      - condition: state
        entity_id: input_boolean.chiusura_automatica
        state: 'on'   
      - condition: state
        entity_id: cover.portone_box
        state: 'open'
    action:
      - service: notify.alex
        data_template:
          message: Hai dimenticato di chiudere il BOX. Puoi scegliere se chiuderlo, disabilitare la chiusura, oppure attendere la chiusura automatica fra 15 minuti.
          title: '*BOX Aperto*'
          data:
            inline_keyboard:
              - "Chiudi BOX Adesso:/ok_chiudi_sezionale, Disabilita Chiusura:/non_chiudi_sezionale"
             
#CLOSES THE DOOR            
  - alias: telegram_chiudi_sezionale
    initial_state: True
    trigger:
      - platform: event
        event_type: telegram_callback
        event_data:
          data: '/ok_chiudi_sezionale'
    action:
      - service: script.chiudi_sezionale
      - service: telegram_bot.delete_message
        data_template:
          message_id: '{{ trigger.event.data.message.message_id }}'
          chat_id: '{{ trigger.event.data.chat_id }}'

#LEAVES THE DOOR OPENED    
  - alias: telegram_non_chiudere_il_sezionale
    initial_state: True
    trigger:
      - platform: event
        event_type: telegram_callback
        event_data:
          data: '/non_chiudi_sezionale'
    action:
      - service: input_boolean.turn_off
        data:
          entity_id: input_boolean.chiusura_automatica
      - service: telegram_bot.delete_message
        data_template:
          message_id: '{{ trigger.event.data.message.message_id }}'
          chat_id: '{{ trigger.event.data.chat_id }}'

#CLOSES AUTOMATICALLY AFTER 15 MINUTES
  - alias: telegram_chiudi_auto_sezionale
    trigger:
      - platform: state
        entity_id: binary_sensor.chiusura_automatica_box_quindici_minuti
        to: 'on' 
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: cover.portone_box
          state: 'open'
        - condition: state
          entity_id: input_boolean.chiusura_automatica
          state: 'on'
    action:
      - service: notify.alex
        data:
          message: Hai dimenticato di chiudere il BOX, lo sto chiudendo io per te.
          title: '*Chiusura BOX in corso*'
      - service: script.chiudi_sezionale
      - service: telegram_bot.delete_message
        data_template:
          message_id: '{{ trigger.event.data.message.message_id }}'
          chat_id: '{{ trigger.event.data.chat_id }}'
      - service: media_player.volume_set
        data_template:
          entity_id: media_player.googlehomemini
          volume_level: 0.8
      - service: tts.google_say
        entity_id: media_player.googlehomemini
        data_template:
          message: 'Ho chiuso il box in automatico'
          language: 'it'

Yes, you can, it’s stated in the docs that you can add conditions to actions.

Otherwise I can put a delay in the action section, and then call a script with a condition inside.
That should work.

If you put a condition in the action, if the condition evaluates to true then the rest of the action is executed. If it’s false then the action halts.

1 Like

I really ignored that :astonished:

Yep, anything you can put in a script, you can put in an action.
Though the converse is not always true.

My god this thread is attracting a LOT of brain power

:rofl:

1 Like

Exactly as in the scripts, but I dind’t know that it could be done in automation… my fault.

It’s becoming more useful than what I expected :slight_smile:

I suggest you consider familiarizing yourself with the Alert sensor. It might be useful for this application or for something else in the future.

Thank you Taras, I really didn’t know about that.

There is a problem with this.
If you do set the time to be ‘23:50’ then it will fire at 23:50 AND it will expect to close the door at 00:05 and off it goes waiting merrily for 00:05 to roll around …
However, as soon as it gets to 00:00 then it’s a new day and it will now think it’s due to operate at 00:05 ‘tomorrow’ … In effect, this will never fire if the time set is in the 15 minutes leading up to midnight.
I think we need @petro
I appreciate that you may not ever intend to fire this between 23:45 to 23:59 but someone else might AND their delay may be bigger and incurr a larger opportunity for failure.
You could use the ‘last triggered’ of the automation to test shutting the door (whatever is fired by the first boolean sensor) or we could store the close time in an input datetime when the trigger runs (that would HAVE to be in an automation /script)

Dunno, I think it needs a good coat of looking at, by another pair of eyes

Either way I think we’d need to replace seconds with 0 (maybe timestamp // 60 * 60 ??? )