How to limit value template?

Hi there,

I am trying to make my Aqara Cube controller of sun screen.
All runs nice but changing position of the screen depends on turning defrees from the cube and there is an issue: degrees can be a value >100 and screen position is limited to 100.

How to setup a limit for value added with below template so even if the cube will show 150* value added to cover position will be 100?

service: cover.set_cover_position
data_template:
  entity_id: cover.sun_screen
  position: >-
    {% if trigger.payload_json.action_angle | int > 0 %} {{ 
    states.cover.sun_screen.attributes.position | int +
    (trigger.payload_json.action_angle | int) /2 }} {% else %} {{ 
    states.cover.sun_screen.attributes.position | int +
    (trigger.payload_json.action_angle | int) /2 }} {% endif %}  

First, I’m curious. Why do both the if and else parts have the exact same equation? I.e., why the if statement in the first place?

How about this:

service: cover.set_cover_position
data:
  entity_id: cover.sun_screen
  position: >
    {{ [state_attr('cover.sun_screen', 'position') | int +
        trigger.payload_json.action_angle | int / 2,
        100] | min }}

Your code is working perfectly, thank you very much! Now I just have to play around with divider to make a good scale between comfortable turning the cube and opening/closing the sun screen.

Regarding my mixed code this is purely caused by my very limited knowledge about templating. To be hones I’m just learning by playing with different parameters and templates made by others helping myself with HA documentation.

Would you be so kind to explain me shortly last part of your template especially about limiting?
What difference is between [state_attr('cover.sun_screen', 'position')] and states.cover.sun_screen.attributes.position ?

The difference between:

states.cover.sun_screen.attributes.position

and

state_attr('cover.sun_screen', 'position')

is explained here. Basically, the former will cause an error (preventing the service call from succeeding) if either the entity cover.sun_screen does not exist, or possibly more importantly, the attribute position does not exist, whereas the latter will not cause an error, but will rather simply return the value None. (Note further that if None is returned, the “| int” filter will simply return zero.)

In this particular case that may not be an issue, but it’s good to get into the habit of using the states(), state_attr(), is_state(), etc. functions.

The brackets are used to form a list. In this case the first element of the list is the result of the equation, and the second element is the value 100. Then the filter “| min” is used to take the minimum value from the list. If the equation results in a value of less than 100, then that will be the result. If, however, it is more than (or equal to) 100, then the result will be 100. So using the list with the min filter is one way to limit the resulting value.

Can I somehow add option max (if this would be correct) to prevent value from going below 0?

Yes you can.

  position: >
    {{ [ 0, [state_attr('cover.sun_screen', 'position') | int +
        trigger.payload_json.action_angle | int / 2,
        100] | min ] | max }}

However there is a smarter way.

  position: >
      {{ ([0, state_attr('cover.sun_screen', 'position') | int, 100]|sort)[1] }}

This sorts the list of your position, 0 and 100 in increasing order and picks the middle value.

Kudos to 123 for sharing this idea.

2 Likes

Now I see. I’ve added 0 at the end of equation but this should sorted like 1…10 (logic…)

Thanks a lot for patience and valuable lesson :wink:

Really appreciate!