Offset time

You can’t comment out one line of a Jinja2 template using the # symbol.

Jinja2 uses a pair of comment tags:

{# this line is a comment #}

Should this work? even if in the last line letter F is part of the code?

    value_template: >
      {# set f = as_timestamp(states('sensor.fajr_prayer'))  + 1320 #}
      {% set d = as_timestamp(states('sensor.dhuhr_prayer')) + 300 %}
      {% set a = as_timestamp(states('sensor.asr_prayer'))   + 240 %}
      {% set i = as_timestamp(states('sensor.isha_prayer'))  + 420 %}
      {% set m = as_timestamp(states('sensor.maghrib_prayer')) - 1920 %}
      {{ now().timestamp() | int in [f, d, a, i, m] }}

No, it will fail because, as you suspected, the variable called f is referenced in the last line, within a list, but is now undefined because you commented out the first line that defines it.

If you don’t want the template to use the variable f then simply remove its definition and all references to it.

Thanks @123

This is my current setup… How I can change so I for each prayer I decide which speaker to play and volume for that specific prayer?

alias: Adhan
trigger:
  - platform: template
    value_template: >
      {% set f = as_timestamp(states('sensor.fajr_prayer'))  + 1260 %}
      {% set d = as_timestamp(states('sensor.dhuhr_prayer')) + 240 %}
      {% set a = as_timestamp(states('sensor.asr_prayer'))   + 180 %}
      {% set i = as_timestamp(states('sensor.maghrib_prayer')) + 360 %}      
      {% set m = as_timestamp(states('sensor.isha_prayer'))  - 1860 %}
      {{ now().timestamp() | int in [f, d, a, i, m] }}
action:
  - variables:
      players: [ {'player': 'basement_speaker', 'volume': 0.2}, {'player': 'alperxiv_shield_tv', 'volume': 0}, {'player': 'kitchen_speaker', 'volume': 0.2}, {'player': 'family_room_display', 'volume': 0}, {'player': 'hallway_speaker', 'volume': 0} ]
  - repeat:
      count: "{{ players | count }}"
      sequence:
      - variables:
          player: 'media_player.{{ players[repeat.index-1].player }}'
          volume: '{{ players[repeat.index-1].volume }}'
      - service: media_extractor.play_media
        data:
          entity_id: "{{ player }}"
          media_content_id: https://www.youtube.com/watch?v=4s9Y_BSoIYc
          media_content_type: audio/youtube
      - service: media_player.volume_set
        data:
          entity_id: "{{ player }}"
          volume_level: "{{ volume }}"
      - delay: '00:00:00'

The automation’s complexity will increase in order to satisfy this goal.

For example, the action will need to know which prayer time triggered the automation (the current version doesn’t concern itself with that).

Instead of determining the prayer time within the action it is preferable to redesign the trigger. Each prayer time should be a separate Template Trigger. The action can determine which one triggered by referring to trigger.id where the first trigger is '0', the second one is '1', etc.

The players variable will need to be modified. It must also specify the specific prayer expressed as a value corresponding to the Template Trigger, in a new key called “prayer”.

In other words, if sensor.fajr_prayer is in the first Template Trigger, its trigger.id is '0' so that value must be included in the prayer key within the players variable. If sensor.dhuhr_prayer is the second Template Trigger, its trigger.id is '1' and so on and so on.

I hope that helps you get started on changing the automation to meet the new requirements.

I’m not expert but if I understood your recommendations… is my trigger part make sense?

alias: Adhan
trigger:     
  - platform: template
    value_template: {% as_timestamp(states('sensor.fajr_prayer'))  + 1260 %}
   - platform: template
    value_template: {% as_timestamp(states('sensor.dhuhr_prayer')) + 240 %}   
   - platform: template
    value_template: {% as_timestamp(states('sensor.asr_prayer'))   + 180 %}   
   - platform: template
    value_template: {% as_timestamp(states('sensor.maghrib_prayer')) + 360 %}
   - platform: template
    value_template: {% as_timestamp(states('sensor.isha_prayer'))  - 1860 %}
action:
  - variables:

I believe this automation meets your new requirement. However, be advised that it is untested because I don’t have multiple media players. Let me know if it fails to work and, together, we can fix it.

NOTE:
You will need to modify the contents of the variable called players_all. Please read the “How it works” section below to understand what it does and how you need to change it.

alias: Adhan
trigger:     
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.fajr_prayer'))  + 1260 }}"
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.dhuhr_prayer')) + 240 }}"   
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.asr_prayer'))   + 180 }}"   
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.maghrib_prayer')) + 360 }}"
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.isha_prayer'))  - 1860 }}"
action:
  - variables:
      players_all: >
        [ 
          [ {'player': 'basement_speaker', 'volume': 0.2}, {'player': 'family_room_display', 'volume': 0.3} ],
          [ {'player': 'basement_speaker', 'volume': 0.3}, {'player': 'family_room_display', 'volume': 0.4}, {'player': 'alperxiv_shield_tv', 'volume': 0.4} ],
          [ {'player': 'alperxiv_shield_tv', 'volume': 0.4} ],
          [ {'player': 'alperxiv_shield_tv', 'volume': 0.2}, {'player': 'kitchen_speaker', 'volume': 0.3}, {'player': 'family_room_display', 'volume': 0.2} ],
          [ {'player': 'basement_speaker', 'volume': 0.2}, {'player': 'alperxiv_shield_tv', 'volume': 0.2}, {'player': 'kitchen_speaker', 'volume': 0.2}, {'player': 'family_room_display', 'volume': 0.2}, {'player': 'hallway_speaker', 'volume': 0.4} ]
        ]
      players: "{{ players_all[ trigger.id | int ] }}"
  - repeat:
      count: "{{ players | count }}"
      sequence:
      - variables:
          player: 'media_player.{{ players[repeat.index-1].player }}'
          volume: '{{ players[repeat.index-1].volume }}'
      - service: media_extractor.play_media
        data:
          entity_id: "{{ player }}"
          media_content_id: https://www.youtube.com/watch?v=4s9Y_BSoIYc
          media_content_type: audio/youtube
      - service: media_player.volume_set
        data:
          entity_id: "{{ player }}"
          volume_level: "{{ volume }}"

How it works

  • The automation has five triggers where each trigger represents a specific prayer time with your desired offset.

  • Home Assistant reports which one of the five triggers occurred via the trigger.id variable. The first trigger is '0' and the fifth trigger is `‘4’.

  • trigger.id can be used to determine which one of the five prayer times has triggered the automation. Fajr is '0' and Isha is '4'.

  • The variable players_all is a list containing five items where each item represents a specific prayer time. The first item in prayers_all represents Fajr and the fifth item is Isha. Each item in prayers_all contains yet another list. This list contains which players should be used for the corresponding prayer time (and each player’s volume).

  • For example, the first item in prayers_all is this:
    [ {'player': 'basement_speaker', 'volume': 0.2}, {'player': 'family_room_display', 'volume': 0.3} ]
    Because it’s the first item in prayers_all, it corresponds to the first trigger which is Fajr. It means that at Fajr prayer time, adhan will be announced via two players: basement_speaker and family_room_display.

  • Another example: the third item in prayers_all represents Asr and it will be announced via just one player: alperxiv_shield_tv.

  • The information presented in prayers_all is only an example. You will need to modify the contents of prayers_all to suit your preferences of which players are used for each prayer time (and their volume).

Hi, thanks again for helping.
I just used the exact code above for testing… I tried to run automation manually but nothing triggered and no speakers played the YouTube link.

This is what I have in HA logs…

Error while executing automation automation.adhan: UndefinedError: ‘dict object’ has no attribute ‘id’

23:02:20 – (ERROR) Automation

Adhan: Error executing script. Error rendering template for variables at pos 1: UndefinedError: ‘dict object’ has no attribute ‘id’

23:02:20 – (ERROR) Automation

You cannot test this automation by manually executing it. The automation’s action relies on the variable trigger.id which exists only if the automation is triggered normally, not if manually executed. This is explained here: Testing your automation.

Please note that if you click on Trigger of an automation in the frontend, only the action part will be executed by Home Assistant. That means you can’t test your trigger or condition part that way. It also means that if your automation uses some data from triggers, it won’t work properly as well just because trigger is not defined in this scenario.

All this makes that Trigger feature pretty limited and nearly useless for debugging purposes so you need to find another way. Make sure you check and adapt to your circumstances appropriate examples from Automation Trigger, Conditions and Actions.

I was thinking same thing last night… I just checked this morning for basement speaker and family room display which was set to play for Fajr prayer. In the history I don’t see them played the media at Fajr prayer time…

image

The screenshot indicates the basement speaker is unavailable. That doesn’t seem normal.

If you look at the list of your automations in Configuration > Automations, each automation shows the last time it was triggered. The time shown should corresond to the last prayer time.

To help us learn more about the automation’s operation, add the following line to the automation (you can add it as the second line of the automation):

id: adhan_announcement

The name itself is unimportant as long as it is a unique name (i.e. it could just as easily be abc123xyz). Save the automation and then execute Reload Automation. The next time the automation is triggered, Home Assistant will create a “trace” which is a detailed log of the automation’s operation. We can examine the trace and see which trigger was used, the value assigned to each variable, and what was done within the repeat.

To display an automation’s trace, click the icon with the circular arrow and clock-face:

Screenshot_20210705-085106~2

Shows 03:36am which match Fajr prayer time…

That suggests the automation successfully triggered at the correct time. However, if the media_player failed to play anything then either there’s a flaw in the automation’s action or the media_player was not available at the time it was needed.

We will know more after you make the modification I suggested previously. The automation’s trace will reveal more information.

You can also check Configuration > Logs and see if it contains any error messages posted at 03:36 AM.

I added in automation in line 2

id: adhan_announcement

Nothing in Logs for 3:36am
I will monitor again today at Dhuhr scheduled for 1:03pm

This is the only warning I am getting in logs each time I do Restart HAAS

Logger: homeassistant.components.islamic_prayer_times
Source: helpers/config_validation.py:739 
Integration: Islamic Prayer Times (documentation, issues) 
First occurred: 11:45:39 (1 occurrences) 
Last logged: 11:45:39

The 'islamic_prayer_times' option near /config/configuration.yaml:1 is deprecated, please remove it from your configuration

You should do what the message recommends and remove that option. However, it is a separate issue and not related to this automation’s behavior.

The trace that the automation will produce at 1:03 PM will hopefully reveal more information about the automation operation.

So 1:03 was the Dhuhr prayer and here is the error I got from logs… still nothing played from speakers

Logger: homeassistant.components.automation.adhan
Source: helpers/script.py:736 
Integration: Automation (documentation, issues) 
First occurred: 13:04:00 (2 occurrences) 
Last logged: 13:04:00

Adhan: Error executing script. Unexpected error for repeat at pos 2: 'repeat'
While executing automation automation.adhan
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 368, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/trace.py", line 256, in async_wrapper
    await func(*args)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 736, in _async_repeat_step
    del self._variables["repeat"]
KeyError: 'repeat'

I believe I have identified the cause of the error message.

The following version corrects the error. It is not only slightly shorter than the previous version, it also avoids producing an error message if you manually execute it.

If you manually execute this version, it will always default to using the first (fajr) trigger. Anyway, you normally shouldn’t manually trigger the automation but at least it now does allow you to test it by simulating Fajr prayer time.

alias: Adhan
id: adhan_announcement
trigger:     
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.fajr_prayer'))  + 1260 }}"
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.dhuhr_prayer')) + 240 }}"   
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.asr_prayer'))   + 180 }}"   
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.maghrib_prayer')) + 360 }}"
  - platform: template
    value_template: "{{ now().timestamp()|int == as_timestamp(states('sensor.isha_prayer'))  - 1860 }}"
action:
  - variables:
      players: >
        {{[
          [ {'player': 'basement_speaker', 'volume': 0.2}, {'player': 'family_room_display', 'volume': 0.3} ],
          [ {'player': 'basement_speaker', 'volume': 0.3}, {'player': 'family_room_display', 'volume': 0.4}, {'player': 'alperxiv_shield_tv', 'volume': 0.4} ],
          [ {'player': 'alperxiv_shield_tv', 'volume': 0.4} ],
          [ {'player': 'alperxiv_shield_tv', 'volume': 0.2}, {'player': 'kitchen_speaker', 'volume': 0.3}, {'player': 'family_room_display', 'volume': 0.2} ],
          [ {'player': 'basement_speaker', 'volume': 0.2}, {'player': 'alperxiv_shield_tv', 'volume': 0.2}, {'player': 'kitchen_speaker', 'volume': 0.2}, {'player': 'family_room_display', 'volume': 0.2}, {'player': 'hallway_speaker', 'volume': 0.4} ]
          ][trigger.id | default(0) | int]}}
  - repeat:
      count: "{{ players | count }}"
      sequence:
      - variables:
          player: 'media_player.{{ players[repeat.index-1].player }}'
          volume: '{{ players[repeat.index-1].volume }}'
      - service: media_extractor.play_media
        data:
          entity_id: "{{ player }}"
          media_content_id: https://www.youtube.com/watch?v=4s9Y_BSoIYc
          media_content_type: audio/youtube
      - service: media_player.volume_set
        data:
          entity_id: "{{ player }}"
          volume_level: "{{ volume }}"

Perfect, like you said manual trigger works now and by default fajr is triggered. I will let you know with Air prayer at 17:12 if automation will work.

On variables section last prayer is , missing at the end of line? like the first 4 variables at the end of the line I see ],

Glad to hear manually executing the automation no longer results in an error.

That’s an excellent observation but when defining items in a list, the last item doesn’t need a comma.

Example:

[ 'apples', 'oranges', 'bananas' ]

Here’s more information about python’s lists:

Google Developer - Python Lists

1 Like