Multiple Template Rule based on times for percentage

Please don’t be!
I’ve updated my template to the following which is what I wanted, many thanks again!

  - sensor:
      - name: "current light percentage"
        state: >
            {% if now() >= today_at(states('input_datetime.lightautomation_am_bri_start')) and
               now() <= today_at(states('input_datetime.lightautomation_am_bri_end')) %}
              {{ states('input_number.lights_brightness_am') }}
            {% elif now() >= today_at(states('input_datetime.lightautomation_pm_bri_start')) and
               now() <= today_at(states('input_datetime.lightautomation_pm_bri_end')) %}
              {{ states('input_number.lights_brightness_pm') }}
            {% else %}
              100
            {% endif %}
        icon: >
            {% if now() >= today_at(states('input_datetime.lightautomation_am_bri_start')) and
               now() <= today_at(states('input_datetime.lightautomation_am_bri_end')) %}
              mdi:brightness-5
            {% elif now() >= today_at(states('input_datetime.lightautomation_pm_bri_start')) and
               now() <= today_at(states('input_datetime.lightautomation_pm_bri_end')) %}
              mdi:brightness-7
            {% else %}
              mdi:brightness-percent
            {% endif %}
1 Like

I believe there is an error.

Am_start is 22
Am_end is 07:30

If we use today_at on both of them then now can’t possibly fit in between.

That is also why I used a template that does not use and/or.
If you just use the template I posted before and just and then else 55% (or what it was at night).
Then that will cover all times and you won’t need a else that is 100% since that will never happen.

1 Like

I guess you are right, it corresponds to two periods when you cross a date:
22:00-23:59 and 00:00-7:30
and there should be or between these periods.
But keep the and if the period doesn’t cross another day.

But if the code should be generic and not take into account some special cases where you know that a given period crosses a date, you should define your periods with in the same date, that is you’ll have 3 in stead of 2 periods.

I corrected the post marked as solution.

oh, this is a new one!

Never though of this scenario really as the date doesn’t really apply.

Is there an alternative?

As I said look at the template I posted before and just add an else

  - sensor:
      - name: "current light percentage"
        state: >
            {% if today_at(states('input_datetime.lightautomation_pm_bri_start')) < now() < today_at(states('input_datetime.lightautomation_pm_bri_end'))  %}
              {{ states('input_number.lights_brightness_pm') }}
            {% else %}
              {{ states('input_number.lights_brightness_am') }}
            {% endif %}
1 Like

yes, maybe do a check if start > end then use or else use and.

Let me try. I’ll get back shortly

Here is a new, much more complex version, but I am not sure whether it works properly.
I’ll do some more testing and get back:

    state: >
        {% if 
          (
            (
              states('input_datetime.lightautomation_am_bri_start') < states('input_datetime.lightautomation_am_bri_end')
            ) and 
            (
              now() >= today_at(states('input_datetime.lightautomation_am_bri_start')) and 
              now() <= today_at(states('input_datetime.lightautomation_am_bri_end')) 
            )
          ) or 
          (
            (
              states('input_datetime.lightautomation_am_bri_start') > states('input_datetime.lightautomation_am_bri_end')
            ) and 
            (
              now() >= today_at(states('input_datetime.lightautomation_am_bri_start')) or
              now() <= today_at(states('input_datetime.lightautomation_am_bri_end')) 
            )
          ) %}
          {{ states('input_number.lights_brightness_am') }}
        {% elif 
          (
            (
              states('input_datetime.lightautomation_pm_bri_start') < states('input_datetime.lightautomation_pm_bri_end')
            ) and 
            (
              now() >= today_at(states('input_datetime.lightautomation_pm_bri_start')) and 
              now() <= today_at(states('input_datetime.lightautomation_pm_bri_end')) 
            )
          ) or 
          (
            (
              states('input_datetime.lightautomation_pm_bri_start') > states('input_datetime.lightautomation_pm_bri_end')
            ) and 
            (
              now() >= today_at(states('input_datetime.lightautomation_pm_bri_start')) or
              now() <= today_at(states('input_datetime.lightautomation_pm_bri_end')) 
            )
          ) %}
          {{ states('input_number.lights_brightness_pm') }}
        {% else %}
          100
        {% endif %}
1 Like

Nice, this works, but struggling to add the final 100%… and mirroring that for the icon template.

Just gave this a go and it does work!
Similar to above, struggling with the icon template to mirror.

But when is there supposed to be a 100%? You have already covered every minute of the day, there can’t be an else with 100%. It’s impossible

Please read above…

I added AM & PM ‘Brightness / times’ as I personally found two times that I wanted to control, everything else can be 100%.

These are text based comparisons and will not function the way it’s intended at all times and values.
You seem to use a few of them, and I doubt they will work as intended at all times.

Yes I confirm that it works :slight_smile:

But it seems to works anyway, as the string values are > < corresponding to the time values: ( At least when using the 24 hour notation)
example:
07:05:34 < 19:00:00
20:30:00 > 06:00:00

Do you have any example where this doesn’t apply?

Text based comparisons can only be used when you are comparing == or ===. Anything else is a gamble.

Such as an b is larger than A, or that 10 is not more than 5 and so on.

we are not talking text but datetime.
so 12:35 > 02:31 is true :slight_smile:

In which case will this not work for input_datetime?

I verified that it works independent of using 12 or 24 hours time format.

Any suggestions of doing this comparison in a better way?

There are no states that is datetime. All states are string.
Even input_datetime:

Regardless, I’m learning a lot! … keep going!

On another note, I’m not too fussed as long as it works!
If I need to slightly alter the way its constructed (e.g. with the 100%) I wouldn’t mind altering it.

The main purpose is listed above.

Yep, as you’ve been discussing above…

So the current time is 22:06pm.

The ‘AM Start Time’ is set to 22:00pm and end 07:30am - so should trigger 20%, however is triggering 100 :frowning:

Hi @91JJ

But now 11:42 pm, works fine on my side

one more thing, if you want to use same logic to determine which period you are in, and based on that change icon or do anything else, then I will recommend as in the start of this thread to have separate binary sensors determining whether it is AM PM etc. and in the logic that determines the brightness sensor state, you can use these binary sensors instead of the long if statements. and in case you want do modifications it will be just one place.

So, I made the following new suggestion with three template sensors:

template:
  - binary_sensor:
    - name: light_period_am
      state: >
        {{ ( 
          (
            states('input_datetime.lightautomation_am_bri_start') < states('input_datetime.lightautomation_am_bri_end')
          ) and 
          (
            now() >= today_at(states('input_datetime.lightautomation_am_bri_start')) and 
            now() <= today_at(states('input_datetime.lightautomation_am_bri_end')) 
          )
        ) or 
        (
          (
            states('input_datetime.lightautomation_am_bri_start') > states('input_datetime.lightautomation_am_bri_end')
          ) and 
          (
            now() >= today_at(states('input_datetime.lightautomation_am_bri_start')) or
            now() <= today_at(states('input_datetime.lightautomation_am_bri_end')) 
          )
        )
        }}
    - name: light_period_pm
      state: >
        {{
        ( 
          (
            states('input_datetime.lightautomation_pm_bri_start') < states('input_datetime.lightautomation_pm_bri_end')
          ) and 
          (
            now() >= today_at(states('input_datetime.lightautomation_pm_bri_start')) and 
            now() <= today_at(states('input_datetime.lightautomation_pm_bri_end')) 
          )
        ) or 
        (
          (
            states('input_datetime.lightautomation_pm_bri_start') > states('input_datetime.lightautomation_pm_bri_end')
          ) and 
          (
            now() >= today_at(states('input_datetime.lightautomation_pm_bri_start')) or
            now() <= today_at(states('input_datetime.lightautomation_pm_bri_end')) 
          )
        )
        }}

  - sensor:
    - name: "current light percentage"
      state: >
        {% if is_state('binary_sensor.light_period_am','on') %}
          {{ states('input_number.lights_brightness_am') }}
        {% elif is_state('binary_sensor.light_period_pm','on') %}
          {{ states('input_number.lights_brightness_pm') }}
        {% else %}
          100
        {% endif %}
      icon: >
        {% if is_state('binary_sensor.light_period_am','on') %}
          mdi:brightness-3
        {% elif is_state('binary_sensor.light_period_pm','on') %}
          mdi:brightness-4
        {% else %}
          mdi:brightness-5
        {% endif %}
          
      unit_of_measurement: '%'

And here how these look ike in te lovelace:

And this works too :slight_smile:
Kind regards,
Ghassan

1 Like