Trigger an automation based on time sensor with offset of few seconds

I have an automation which works based of time sensors. The trigger is

trigger:
  - platform: time
    at:
      - sensor.fajr_prayer
      - sensor.dhuhr_prayer
      - sensor.asr_prayer
      - sensor.maghrib_prayer
      - sensor.isha_prayer

This works well since its based on changing times of the sensors. The automation activates the call for prayers which is played on a Google Chromecast.

action:
  - parallel:
      - service: remote.send_command
        data:
          command: Mute
          device: "75603458"
        target:
          entity_id: remote.harmony_hub
      - data:
          media_content_id: >-
            /local/adhan/Mishary_Rashid_{{'Fajr_Adhan' if trigger.entity_id ==
            'sensor.fajr_prayer' else 'Adhan'}}.mp3
          media_content_type: audio/mp3
        service: media_player.play_media
        target:
          entity_id:
            - media_player.basement_receiver

The problem is that automation takes about 2 to 3 seconds “after” the clock turns to the minute, which is understandable. The call for prayers is heard about 3 seconds past the actual sensor time. May be because it takes time for the idle Chromecast to start playing the mp3 file.

Is there a script I could use to maybe create alternate sensors which refer to the above time sensors and are 3 seconds early than the time sensors and then I could use the trigger to reference those offset sensors instead?

So if sensor.fajr_prayer has time value of 5:00AM (5:00:00) the script run offset sensor would be sensor.fajr_prayer_offset - 4:59:57AM (4:59:57). Also, the current prayer sensors show time in HH:MM and not HH:MM:SS… so that’s another hurdle.

I am not great at scripting however any direction in this would be highly appreciated.

You may find this discussion useful here

Thanks for the quick response.

I had researched and tried that earlier. However in that script the trigger fails as it runs every min and does not take into account any time which is not a whole 60 secs/1 min. So 120 secs/2 mins will trigger however if I tried 90secs/1.5 mins or 30 secs it fails to trigger.

At the risk of a kludge answer, could you have your automation trigger 1 minute early and then have a Wait action to wait 57 seconds?

Ahh… that may just work :slight_smile:

How do I modify my trigger to start 1 min early? I have this right now and my action looks for the trigger.entity_id

trigger:
  - platform: time
    at:
      - sensor.fajr_prayer
      - sensor.dhuhr_prayer
      - sensor.asr_prayer
      - sensor.maghrib_prayer
      - sensor.isha_prayer
- data:
          media_content_id: >-
            /local/adhan/Mishary_Rashid_{{'Fajr_Adhan' if trigger.entity_id ==
            'sensor.fajr_prayer' else 'Adhan'}}.mp3
          media_content_type: audio/mp3
        service: media_player.play_media

From the link I gave earlier and modified as follows, maybe:

  trigger:
  - platform: template
    value_template: >
      {% set f = as_timestamp(states('sensor.fajr_prayer'))  - 60 %}
      {% set d = as_timestamp(states('sensor.dhuhr_prayer')) - 60 %}
      {% set a = as_timestamp(states('sensor.asr_prayer'))   - 60 %}
      {% set i = as_timestamp(states('sensor.isha_prayer'))  - 60 %}
      {% set m = as_timestamp(states('sensor.maghrib_prayer')) - 60 %}
      {{ now().timestamp() | int in [f, d, a, i, m] }}

Thank you! This changes the trigger.entity_id … correct? What will be the new ids for the 5 times? f, d, a, m and i ?

I had tried that code earlier while experimenting different ways to trigger… the problem with this was the action failed everytime… since it was looking for triger.entity_id. There are two different mp3 files. One plays only for the first morning call for prayer … thats sensor.fajr_prayer. Rest 4 play for the second mp3 file.

Should I change the code to trigger.entity_id == ‘f’ else ‘Adhan’}}.mp3

I’d split the trugger into 2 and then use a Chose action to decide which mp3 to play. Something like this:

description: ""
mode: single
trigger:
  - platform: template
    value_template: |-
      {% set d = as_timestamp(states('sensor.dhuhr_prayer')) - 60 %}
      {% set a = as_timestamp(states('sensor.asr_prayer'))   - 60 %}
      {% set i = as_timestamp(states('sensor.isha_prayer'))  - 60 %}
      {% set m = as_timestamp(states('sensor.maghrib_prayer')) - 60 %}
      {{ now().timestamp() | int in [d, a, i, m] }}
    id: Morning
  - platform: template
    value_template: |-
      {% set f = as_timestamp(states('sensor.fajr_prayer'))  - 60 %}
      {{ now().timestamp() | int in [f] }}
    id: Remainder
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: Morning
        sequence: []
      - conditions:
          - condition: trigger
            id: Remainder
        sequence: []

Please be aware that I haven’t tested this so it may not work as you wish.

Much appreciated. I will update the script and report back. Thank you again!

This worked perfectly. I was even able to consolidate another related automation into this where I turn on the receiver and chrome cast a min before prayer time and power off immediately after the prayer ends.

Thank you so much and GOD BLESS!!!

1 Like

Thanks for letting me know.

Make five Template Sensors, one for each of the five prayer-time sensors. Each reports a time that’s 3 seconds earlier than the actual prayer time.

template:
  - sensor:
      - name: Fajr Prayer Offset 
        device_class: timestamp
        state: "{{ (states('sensor.fajr_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
      - name: Dhuhr Prayer Offset 
        device_class: timestamp
        state: "{{ (states('sensor.dhuhr_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
      - name: Asr Prayer Offset 
        device_class: timestamp
        state: "{{ (states('sensor.asr_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
      - name: Maghrib Prayer Offset 
        device_class: timestamp
        state: "{{ (states('sensor.maghrib_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
      - name: Isha Prayer Offset 
        device_class: timestamp
        state: "{{ (states('sensor.isha_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"

Your automation’s Time Trigger simply uses the five Template Sensors (and will trigger at the precise second specified by the Template Sensor).

trigger:
  - platform: time
    at:
      - sensor.fajr_prayer_offset
      - sensor.dhuhr_prayer_offset
      - sensor.asr_prayer_offset
      - sensor.maghrib_prayer_offset
      - sensor.isha_prayer_offset

If you want to play a different sound file based on the prayer time, simply create separate Time Triggers and specify the sound file’s name in a Trigger Variable.

alias: example 
trigger:
  - platform: time
    at: sensor.fajr_prayer_offset
    variables:
      song: Fajr_Adhan
  - platform: time
    at:
      - sensor.dhuhr_prayer_offset
      - sensor.asr_prayer_offset
      - sensor.maghrib_prayer_offset
      - sensor.isha_prayer_offset
    variables:
      song: Adhan
condition: []
action:
  - service: media_player.play_media
    target:
      entity_id: media_player.your_player
    data:
      media_content_id: "/local/adhan/Mishary_Rashid_{{ song }}.mp3"
      media_content_type: audio/mp3

This is so tempting. I will use this method as well and experiment on the automation and report back. Thank you @123

@123 I have added the offset sensors to the config.yaml and wating for the prayer time to test the trigger.

For the new offset sensors, I would like to move them to the sensors.yaml file as I refer that in my config.yaml. Right now my sensors.yaml file looks like below, however I am not able to move the new offset sensors in there and config check is giving me an error.

Here is my sensor.yaml file…

- platform: systemmonitor
  resources:
    - type: disk_use_percent
      arg: /config
    - type: memory_use_percent
    - type: swap_use_percent
    - type: load_1m
    - type: load_5m
    - type: load_15m
    - type: processor_use
    - type: processor_temperature
    - type: last_boot
    - type: network_in
      arg: enp4s0
    - type: network_out
      arg: enp4s0

You can’t do that with the Template Sensor configuration I posted above.

Template Sensors defined in modern format (as opposed to the older “legacy” format) are part of the template domain, not the sensor domain, so you cannot put them in sensors.yaml.

If you have this line in your configuration.yaml file, then you can put them in the templates.yaml file.

template: !include templates.yaml

For more information, refer to the documentation: Template integration

@123 U da best!

I created a template_sensors.yaml file and added the below sensors plus added a unique_id for each so that I can hide the offset sensor from the dashboard.

- sensor:
  - name: Fajr Prayer Offset 
    unique_id: fajr_prayer_offset
    device_class: timestamp
    state: "{{ (states('sensor.fajr_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
  - name: Dhuhr Prayer Offset 
    unique_id: dhuhr_prayer_offset
    device_class: timestamp
    state: "{{ (states('sensor.dhuhr_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
  - name: Asr Prayer Offset 
    unique_id: asr_prayer_offset
    device_class: timestamp
    state: "{{ (states('sensor.asr_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
  - name: Maghrib Prayer Offset 
    unique_id: maghrib_prayer_offset
    device_class: timestamp
    state: "{{ (states('sensor.maghrib_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"
  - name: Isha Prayer Offset 
    unique_id: isha_prayer_offset
    device_class: timestamp
    state: "{{ (states('sensor.isha_prayer') | as_datetime - timedelta(seconds=3)).isoformat() }}"

After you have had a chance to test it, let me know if what I proposed works properly and meets your requirements.

Yes, I am working on it. For some reason the mp3 did not play for the Asr prayer however other activities in the automation worked properly till the end. Re-doing the media player action… must be some thing with the breaks in the lines. Will definitely report back.

To easily test the service call, go to Developer Tools > Services, switch to YAML mode and copy-paste the following:

service: media_player.play_media
data:
  media_content_type: audio/mp3
  media_content_id: "/local/adhan/Mishary_Rashid_Adhan.mp3"
target:
  entity_id: media_player.your_player

Don’t forget to change media_player.your_player to the entity_id of your actual Media Player.

Thanks. That worked when I gave the straight path to the mp3 file. To make the automation less complex I am using the following template which has worked perfectly in the earlier automation. It changes the file based on trigger.entity_id. Of the 5 prayer times only the morning Fajr prayer is a bit different and around 30 secs lengthy. Rest 4 use the same mp3 as they are all the same. So trying to use one trigger for all 5 times.


data:  
media_content_id: >-    
/local/adhan/Mishary_Rashid_{{'Fajr_Adhan' if trigger.entity_id ==    'sensor.fajr_prayer_offset' else 'Adhan'}}.mp3  
media_content_type: audio/mp3
service: media_player.play_media
target:  
entity_id:    
- media_player.basement_receiver