Some help needed in combining multiple window cover automations based on azimuth into one single automation

dear @finity, update from the afternoon: nothing is happening with the cover :slight_smile:

I see the automation being triggered constantly, but the cover is not moving. It’s currently, 15:04, azimuth at 232,43 degree at the moment, cover is at 0% (fully closed)

just to be sure, again the code in it’s currently active version, maybe I’m messing up something:

alias: Cover automatisation test multiple trigger cover7
trigger:
  - platform: state
    entity_id: sun.sun
condition: []
action:
  - service: cover.set_cover_position
    target:
      entity_id: cover.medence_terasz_redny
    data:
      position: >
        {% if states('sensor.sun_azimuth') | float < 80 %}
          0 
        {% elif states('sensor.sun_azimuth') | float >= 80 and
        states('sensor.sun_azimuth') | float <= 170 %}
          100
        {% elif states('sensor.sun_azimuth') | float >= 170 and
        states('sensor.sun_azimuth') | float < 220 %}
          {{ (((-2 * (states('sensor.sun_azimuth') | float )  + 440) / 10) | int) * 10 }}
        {% elif states('sensor.sun_azimuth') | float >= 220 and
        states('sensor.sun_azimuth') | float <= 250 %}
          0
        {% else %}
          {{ ((( 2 * (states('sensor.sun_azimuth') | float )  - 500) / 10) | int) * 10 }}
        {% endif %}
mode: single

Ok, I’m really not sure what is going on then.

try putting the template above into the template editor and see if it gets the correct values.

Also try the others to see if they are or aren’t working as well.

I don’t have any covers that use positions so I can’t test this in real life.

I set up some sensors using the templates above as the values and they all seem to be reading correctly right now but it will take at least a day to track the full range of sun motion to ensure they work correctly.

Also look in the home-assistant.log file for errors relating to the automation.

EDIT:
I did see one other typo.

it was small and only affected anything if the azimuth was EXACTLY 170 but it’s better to correct it now:

{% if states('sensor.sun_azimuth') | float < 80 %}
  0 
{% elif states('sensor.sun_azimuth') | float >= 80 and states('sensor.sun_azimuth') | float < 170 %}
  100
{% elif states('sensor.sun_azimuth') | float >= 170 and states('sensor.sun_azimuth') | float < 220 %}
  {{ (((-2 * (states('sensor.sun_azimuth') | float )  + 440) / 10) | int) * 10 }}
{% elif states('sensor.sun_azimuth') | float >= 220 and states('sensor.sun_azimuth') | float <= 250 %}
  0
{% else %}
  {{ ((( 2 * (states('sensor.sun_azimuth') | float )  - 500) / 10) | int) * 10 }}
{% endif %}

I only changed the “<= 170” to “< 170” in the first “elif” part.

EDIT 2:

I also figured out I completely screwed up cover 6:

I think this should work:

{% if states('sensor.sun_azimuth') | float < 80 %}
  0 
{% elif states('sensor.sun_azimuth') | float >= 80 and states('sensor.sun_azimuth') | float < 170 %}
  100
{% elif states('sensor.sun_azimuth') | float >= 170 and states('sensor.sun_azimuth') | float < 240 %}
  {{ ((( 270 -  (states('sensor.sun_azimuth') | float )) / 10) | int) * 10 }}
{% elif states('sensor.sun_azimuth') | float >= 240 and states('sensor.sun_azimuth') | float < 250 %}
  20
{% elif states('sensor.sun_azimuth') | float >= 250 and states('sensor.sun_azimuth') | float < 260 %}
  0
{% elif states('sensor.sun_azimuth') | float >= 260 and states('sensor.sun_azimuth') | float < 290 %}
  {{ (((4 *  (states('sensor.sun_azimuth') | float) - 1020 ) / 10) | int) * 10 }}
{% else %}
  100
{% endif %}
1 Like

Hi there. me again.

I’m really not a stalker. Trust me. (but isn’t that what a stalker would say…? :wink:)

I have to say the inflection points in your matrix are killing me.

I set those test sensors up and found some more errors in the templates that I’m really trying hard to fix if for nothing else than to make me not look like a complete idiot. :laughing:

And I am kind of a OCD on this kind of and want to get this working correctly for the challenge of it. I doubt I’ll ever use anything like it myself.

But here are some corrected templates.

(If you want me to just let it go just say so. I hope to be helpful not annoying :laughing:)

cover_3_4_5:

{% if states('sensor.sun_azimuth') | float < 80 %}
  0
{% elif states('sensor.sun_azimuth') | float >= 90 and states('sensor.sun_azimuth') | float < 140 %}
  {{ (((-2 * (states('sensor.sun_azimuth') | float )  + 280) / 10) | int) * 10 }}
{% elif states('sensor.sun_azimuth') | float >= 140 and states('sensor.sun_azimuth') | float < 220 %}
  0
{% elif states('sensor.sun_azimuth') | float >= 220 and states('sensor.sun_azimuth') | float <= 240 %}
  {{ ((( 2 * (states('sensor.sun_azimuth') | float )  - 420) / 10) | int) * 10 }}
{% else %}
  100
{% endif %}

cover_6:

{% if states('sensor.sun_azimuth') | float < 80 %}
  0 
{% elif states('sensor.sun_azimuth') | float >= 80 and states('sensor.sun_azimuth') | float < 170 %}
  100
{% elif states('sensor.sun_azimuth') | float >= 170 and states('sensor.sun_azimuth') | float < 240 %}
  {{ ((( 270 -  (states('sensor.sun_azimuth') | float )) / 10) | int) * 10 }}
{% elif states('sensor.sun_azimuth') | float >= 240 and states('sensor.sun_azimuth') | float < 250 %}
  20
{% elif states('sensor.sun_azimuth') | float >= 250 and states('sensor.sun_azimuth') | float < 260 %}
  0
{% elif states('sensor.sun_azimuth') | float >= 260 and states('sensor.sun_azimuth') | float <= 280 %}
  {{ (((4 *  (states('sensor.sun_azimuth') | float) - 1020 ) / 10) | int) * 10 }}
{% else %}
 100
{% endif %}

cover_7_8:

{% if states('sensor.sun_azimuth') | float < 80 %}
  0 
{% elif states('sensor.sun_azimuth') | float >= 80 and states('sensor.sun_azimuth') | float < 170 %}
 100
{% elif states('sensor.sun_azimuth') | float >= 170 and states('sensor.sun_azimuth') | float < 220 %}
  {{ (((-2 * (states('sensor.sun_azimuth') | float )  + 440) / 10) | int) * 10 }}
{% elif states('sensor.sun_azimuth') | float >= 220 and states('sensor.sun_azimuth') | float <= 250 %}
  0
{% elif states('sensor.sun_azimuth') | float > 250 and states('sensor.sun_azimuth') | float <= 300 %}
  {{ ((( 2 * (states('sensor.sun_azimuth') | float )  - 500) / 10) | int) * 10 }}
{% else %}
  100
{% endif %}

Like I said, it’s the different inflection points that are the thing that’s getting me. At least the equations are correct. :slightly_smiling_face:

I’ll check them again 24 hours and see if they work right this time.

1 Like

I’m really not a stalker.

Come on man, don’t say that, you’re the one helping me here, so PLEASE stalk around as much as you wish or you can :smiley:

inflection points in your matrix are killing me.

What’s tricky with them? Can I simplify it somehow? Although I can’t picture a more simple solution to this problem…

And I am kind of a OCD on this kind of and want to get this working correctly for the challenge of it

I’m so happy I bumped into a fellow OCD mate :slight_smile: Can you imagine how many weeks I’ve spent trying to solve this on my own? And how hard was it to admit that I’m never gonna solve it on my own? :smiley:

You can’t imagine how grateful I am for you trying to solve it. I’m gonna test the code today, and report back…

Not really. it’s just the interaction between the different line equations and when exactly to switch between them that I’ve been screwing up.

The issue was (is?) that if the “if/elif” cutoff points are wrong then the resulting values can go on calculating above 100%

like you see here:

ex

ex1

Hopefully it’s all worked out now. But I’m not holding my breath. I thought the same thing a few days ago too. :laughing:

:smiley:

What the correct indentation here? for cover 7 and 8:

{% if states(‘sensor.sun_azimuth’) | float < 80 %}
0
{% elif states(‘sensor.sun_azimuth’) | float >= 80 and states(‘sensor.sun_azimuth’) | float < 170 %}
100
{% elif states(‘sensor.sun_azimuth’) | float >= 170 and states(‘sensor.sun_azimuth’) | float < 220 %}
{{ (((-2 * (states(‘sensor.sun_azimuth’) | float ) + 440) / 10) | int) * 10 }}
{% elif states(‘sensor.sun_azimuth’) | float >= 220 and states(‘sensor.sun_azimuth’) | float <= 250 %}
0
{% elif states(‘sensor.sun_azimuth’) | float > 250 and states(‘sensor.sun_azimuth’) | float <= 300 %}
{{ ((( 2 * (states(‘sensor.sun_azimuth’) | float ) - 500) / 10) | int) * 10 }}
{% else %}
100
{% endif %}

Oh, oops. I put my backticks in the wrong spot.

I need to stop doing this stuff in the middle of the night.

I edited the post above so it’s fixed now.

1 Like

Oh, jeez this is getting ridiculous now…

looking back thru my posts I realized I’ve been posting the templates with the sensor I created to test everything with. So unless you created the same sensor you won’t get anything at all… :cry:

so, everywhere you have “states(‘sensor.sun_azimuth’)” in the above templates replace them with “state_attr(‘sun.sun’, ‘azimuth’)”.

I’m really sorry for all the confusion.

no worries, I also screwed up, using a wrong cover entity ID :slight_smile:

just corrected everything, et voi lá, the cover didn’t instantly go down :smiley: :smiley: :smiley:

so it looks promising so far, the sun just have to reach azi 170 and hope for the miracle to happen :smiley: I’ll report back

take a look plz if you catch anything incorrect:

alias: Cover auto down with multiple azimuth trigger
description: ''
trigger:
  - platform: state
    entity_id: sun.sun
condition: []
action:
  - service: cover.set_cover_position
    target:
      entity_id: cover.medence_terasz_redny
    data:
      position: >
        {% if state_attr('sun.sun', 'azimuth') | float < 80 %}
          0 
        {% elif state_attr('sun.sun', 'azimuth') | float >= 80 and
        state_attr('sun.sun', 'azimuth') | float < 170 %}
         100
        {% elif state_attr('sun.sun', 'azimuth') | float >= 170 and
        state_attr('sun.sun', 'azimuth') | float < 220 %}
          {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 440) / 10) | int) * 10 }}
        {% elif state_attr('sun.sun', 'azimuth') | float >= 220 and
        state_attr('sun.sun', 'azimuth') | float <= 250 %}
          0
        {% elif state_attr('sun.sun', 'azimuth') | float > 250 and
        state_attr('sun.sun', 'azimuth') | float <= 300 %}
          {{ ((( 2 * (state_attr('sun.sun', 'azimuth') | float )  - 500) / 10) | int) * 10 }}
        {% else %}
          100
        {% endif %}
mode: single

1 Like

wohoooooo!!!

seems to be working much better now, well, at least that according to my matrix it SHOULD be open, but before it always went down, right??

now with the automation active, I tried to lower the cover, and BOOM, upon the next azimuth change, it went back to full open, as it should be wide open according to my matrix :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile:

thanks a lot @finity for all your hard work and not giving up on me, this means a lot to me. Hopefully I can tell you in the afternoon that it’s fully doing its job as I imagined, but I’m full with confidence now that it will…

With my past performance I’m not sure I’m the right person to be looking for that! :laughing:

But at least it sounds like we’re on the right track now. Progress is being made!

You’re welcome.

But to add this next step (hopefully I’m not being premature in my optimism…) if you want to have control over your blinds and not have the system always control them (say it’s a dreary day out and you want the blinds to be open when they would otherwise be shut or etc) you will need to use a condition to stop the automation from running or turn the automation off.

If you need help with that then feel free to let me know.

Hopefully everything works so I’ll be waiting for the good report. :+1:

Can I just say thank you to both of you for collaborating on this? I have 8 shades with 6 facing east and 2 facing west. I have been looking to control them based on the azimuth of the sun for a while now and could never fully wrap my head around the automation. Right now I just use elevation of the sun to lower them which isn’t ideal because that changes with the seasons. Side note, I guess I could have had a moving elevation setpoint based on the season.

I love this community.

3 Likes

That’s awesome!

I’m glad someone else can get some benefit out of this too. :slightly_smiling_face:

1 Like

Oh, and @Guesswho620 another tip I noticed from your last full code above is that you can have multiple targets for your “cover.set_cover_position” service call.

So if the templates are the same for the covers then you can use one automation for each group.

example based on your code above assuming that cover.medence_terasz_redny is cover 7 and since cover 7 & 8 use the same position template:

alias: Cover auto down with multiple azimuth trigger
description: ''
trigger:
  - platform: state
    entity_id: sun.sun
condition: []
action:
  - service: cover.set_cover_position
    target:
      entity_id: 
        - cover.medence_terasz_redny
        - cover.cover_8
    data:
      position: >
        {% if state_attr('sun.sun', 'azimuth') | float < 80 %}
          0 
        {% elif state_attr('sun.sun', 'azimuth') | float >= 80 and
        state_attr('sun.sun', 'azimuth') | float < 170 %}
         100
        {% elif state_attr('sun.sun', 'azimuth') | float >= 170 and
        state_attr('sun.sun', 'azimuth') | float < 220 %}
          {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 440) / 10) | int) * 10 }}
        {% elif state_attr('sun.sun', 'azimuth') | float >= 220 and
        state_attr('sun.sun', 'azimuth') | float <= 250 %}
          0
        {% elif state_attr('sun.sun', 'azimuth') | float > 250 and
        state_attr('sun.sun', 'azimuth') | float <= 300 %}
          {{ ((( 2 * (state_attr('sun.sun', 'azimuth') | float )  - 500) / 10) | int) * 10 }}
        {% else %}
          100
        {% endif %}
mode: single

that way you can group covers 1 & 2, covers 3,4 & 5 and covers 7 & 8 to use one automation for each group instead of using a separate automation for each cover. then you will have only four automations instead of 8.

2 Likes

@finity, my friend, it works like a charm, everything seems to be perfect!!! I was watching the cover coming down in 10% incrementals!!! Wohooooo! Now I just have to fine tune azimuth and percentage matrix, I hope I can do it on my own, if I’m lost, I might be asking your help again…

Thank you very much pal, you’re my hero!!!

And you’re totally right, I’m gonna group these little bastards and I’ll be done with 3 automations in total instead of 80 :joy::joy::joy:

You also absolutely have a good point on the condition you mentioned, so to have the possibility for human interference, and by human, I obviously mean WIFE :smiley:
I’ve read here somewhere that you always have to consider the WAF, aka the Wife Acceptance Factor, when building automations :smiley:
I was thinking about a way to cancel the whole automation (for an hour? for 24 hours? until midnight??) IF the switch was pressed on the wall… but I wonder how can I catch that event (as I mentioned, the shutter is controlled by a Shelly 2.5).
To have a weather condition I already set up a cloudiness sensor based on openweather integration, I’m curious how will work out.
To take into account the season (winter, spring, and late autumn I guess I’m gonna use Suns’s elevation, I think that will be a good start, we’ll see…

@squirtbrnr, you can definitely try @finity’s solution, because it does work for this purpose, pretty good. And yes, this is a GREAT community. I’m using HA for a year now, nothing complex that I couldn’t solve on my own, and this was my first post to ask for the community’s help, and boom, here we are, with a great helpful attitude and a perfect solution (I mean, at least for me). Can’t thank enough Finity.

After easter I set up the rest of the covers, watch how the whole thing work out, and report back, and later sum it up in the opening post marking the working solution for future generations :smiley:

Have a happy and relaxing easter, stay safe and healthy wherever you’re in the world, may covid avoid you and the force be with you :wink:

1 Like

Phew! I’m glad it finally worked!

I’m not sure that would work but you could easily create an input_boolean (we’ll call it “Sutter Manual Mode” - input_boolean.shutter_manual_mode) and then use that in a condition of the automation:

condition:
  - condition: state
    entity_id:  input_boolean.shutter_manual_mode
    state: 'off'

then when you turn the boolean on it will stop the actions from executing and you will have total control of the shutters.

And if you really wanted to have it automatically revert to auto mode after a period of time (I personally wouldn’t) it’s easy enough to create an automation to turn the boolean back off after that time.

1 Like

Boolean sensor sounds great, but my question stands: how can you tell the sensor, that the physical switch was pressed? Or, even worse, a logical switch, since the covers are also integrated into Homekit, and most likely it will be manually controlled via homekit, not even the physical switch…

Is the physical switch integrated into HA separately than the cover controller?

IOW, does the physical switch have wires that go to the cover and control them directly or does it supply an input HA/Homekit to then tell some other device to operate the covers?

no no, as I said, via a Shelly 2.5, switch on the wall wired into Shelly relay, and Shelly is integrated into HA via Shelly integration…

@finity, wanted to ask your oppinion on how to tweak further this little automation you made, to follow the seasonal changes. Would it be possible to consider Sun’s elevation somehow in the calculation, to have the automation run a little later in spring, earlier in the summer, and again later in the autumn? Originally I was only planning to have the elevation as a blocking condition, to stop the automation from running in the winter, but I was thinking if we could use the elevation also in the math part, to have it as kind of an altering factor… what is your thought on it?

Yes! I’ve had that same thought on combining azimuth and elevation. So here’s what I’ve thought about but haven’t done the actual math. I thought of combining the min and max azimuth and the min and max elevation, then normalizing that on a 0-100 or some other arbitrary scale which can then be translated to a cover position. In my case in winter I want more light in the room earlier due to the lower elevation but higher azimuth, and in summer I want initially less light and solar gain due to lower azimuth regardless of solar elevation then as the sun progresses around and the azimuth increases, the shades can open. Imagine drawing an arc in the sky from sunrise to solar noon. At the summer and winter solstice, these arcs are at their extremes, winter would be a slow gradual arc from some point south of due east on the horizon to a point maybe 40 degrees above the horizon to the south at solar noon. But in summer this arc is more vertical originating at a point more north of due east along the horizon and traveling vertically to maybe 70-80 degrees elevation above the horizon at solar noon. Again, this is based on my location, but should be adaptable for any location (except flipped in the Southern Hemisphere where the sun still rises in the east and sets in the west but azimuth uses due north or 0 degrees as opposed to due south 180 degrees).