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

If anyone is interested, it’s possible to reduce this:

      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 %}

to this:

      position: >
        {% set a = state_attr('sun.sun', 'azimuth') | float(0) %}
        {% set values = { 80: 0,
                          170: 100, 
                          220: (((-2*a+440)/10)|int(0))*10,
                          251: 0,
                          301: (((2*a-500)/10)|int(0))*10 } %}
        {{ values.get(values.keys() | select('>', a) | first, 100) }}


EDIT

Correction. Added missing closing brace to final template.

It’s right if you want it to behave differently from the original version (because your version produces different results).

Copy-paste this into the Template Editor and experiment with it:

{% set a = 230 %} {{ a }}

The original version:
{% if a < 80 -%} 0 
{% elif a >= 80 and a < 170 -%} 100
{% elif a >= 170 and a < 220 -%} {{ (((-2*a+440)/10)|int)*10 }}
{% elif a >= 220 and a <= 250 -%} 0
{% elif a > 250 and a <= 300 -%} {{ (((2*a-500)/10)|int)*10 }}
{% else -%} 100
{% endif %}

Revised version:
{%- set values = { 80: 0,
                  170: 100, 
                  220: (((-2*a+440)/10)|int(0))*10,
                  251: 0,
                  301: (((2*a-500)/10)|int(0))*10 } %}
{{ values.get(values.keys() | select('>', a) | first, 100) }}

Your version:
{%- set values = { 0: 0,
                  79: 100,
                  170: (((-2*a+440)/10)|int(0))*10, 
                  220: 0,
                  250: (((2*a-500)/10)|int(0))*10,
                  301: 100 } %} 
{{ values.get(values.keys() | select('>', a) | first, 100) }}
2 Likes

You seam to know your coding stuff :slight_smile: I was wrong, deleted my post.

Would you help including some more variables into the code?

What do you want it to do?

Currently the shading is done by azimuth, on fixed values from the guy who started this.

But actually shading should be done by a lot more variable, especially calculating the position of the roller shutter. I work on the calculations and variables right now, but I am by no means able to transfer the calculation into code.

Its more like,

  • you know the direction the window is facing, so you know from when to when azimuth shading is required (like -30+50°)
  • you know the height of the window, the depth of the wall with window sill (and acceptable sun strake behind the window sill, and you could calculate from what elevation no shading is required anymore since the wall would shade it itself.
  • you know from what current elevation the user wants shading so when to start the daily shading work
  • and from what max day elevation shading is generally required, so it wont run in winter and spring
  • you may want to consider a cat door as a minimum opening, no matter what the shading calculation gives as shading position.
  • you know the % value when window is fully shaded by the shutter
  • you know the % value when the roller shutter starts covering the window

With all that the calculation of the shading position of the roller shutter is just math.

and from that, one could code a code that just needs the values of the window to run shading all by its self with out big fiddeling. and does the shading in a way the acceptable sun streake inside is never exceeded, but the shutter is maximal open at the same time. who wants to live behind shutters is the idea here.

Those calculations (algebra) and the flow chart i could do, but i cant do the coding.

and beyond that, one may wants to prefer a awning thats mounted over the window if its not raining or windy or the awning wont cover enough of the window.

or has a roof window at an angle

or has shading by other objects and only requires shading in other azimuth degres.

and my want that it closes/open on dusk and dawn, probably on two steps, like pre open, open and pre close and close, depending on lux

and as well, one may want to asses the cloud level and the forecast temp and indoor temp or if an AC is running etc. pp

it would get quite complicated.

Here are all the variables I think would be likely needed.

User input mainly, but also some sensor values.

First we need these global variables:

  • forecast out door temperature for the day
  • global indoor temp limit with no AC
  • global indoor temp limit with AC of room
  • global indoor temp limit with global AC status
  • global flat/house indoor temp for if no room temp entity available
  • cloud level status in %
  • cloud level to activate shading
  • sun elevation
  • sun azimut
  • wind speed sensor
  • rain event sensor
  • LUX sensor
  • global switch shading: on / off for for time x / off permanent
  • global switch nightly shutters: on / off for time x / off permanent

now we need window facts for each window.

  • window number
    • friendly name
    • roller shutter entity
    • window related switch shading: on / off for for time x / off permanent
    • window related switch nightly shutters: on / off for time x / off permanent
    • room temp entity (if not available, use globale indoor temp)
    • sensor for room AC-Status (if not available use global if not available assume AC off)
    • room temp limit without AC
    • A/C status (always shade when on “cooling”)
    • direction the window is facing in decimal ° compass direction
    • deviation from vertical if e.g. roof window
    • height of window in mm
    • width of wall including inside window sill in mm
    • acceptable width of sun streaks (AWS) in mm
    • depth of the shutter from outside wall
    • azimut deviation from window direction to start shading (would be mostly negative)
    • azimut deviation from window direction to stop shading (would be mostly positive)
    • minimum elevation that is required for shading (max elevation will be calculated for each window by wall thickness (width of window) and AWS) out side of those two limits shutter will be at 100%
    • start shading in % of roller shutter
    • fully shaded in % of roller shutter
    • max shading position (e.g. to prevent lock out from terrace doors or animals from their doors)
    • two step opening in morning? (y/n)
      • offset for non working days (y/n)
      • offset time
      • step one opening on lux > xx
      • step one opening lux duration
      • step one opening fallback elevation
      • step one opening in %
      • step two opening on lux > xx
      • step two opening lux duration
      • step two opening fallback elevation
      • step two opening in % (100% usually)
    • two step closing in evening y/n
      • step one closing on lux < xx
      • step one closing lux duration
      • step one closing fallback elevation
      • step one closing in %
      • step one closing ignore max shading position to prevent lockout of animals y/n
        • time offset after step one to close to 0%
      • step one closing ignore
      • step two closing on lux < xx
      • step two closing lux duration
      • step two closing fallback elevation
      • step two closing in % (0% usually)
      • step two closing ignore max shading position to prevent lockout of animals y/n
        • time offset after step two to close to 0%
    • awning over window (y/n)
      • prefer awning over shutter for shading (y/n)
      • fall back to shutter on wind speeds over
      • fall back to shutter on rain (y/n)
      • entity of awning
      • start shading with awing %
      • 100% of awning shades 100% (including AWS) on sun elevation °
      • fall back if awning cant shade 100% (y/n)
      • % when to fall back if awning cant shade 100%

First we need some code that puts that all into perspective.

Then we need an automation, that runs every time the azimuth changes 1 full degree and considers all these values to come to a conclusion for the roller shutter or awing of each window and sets their cover.set_cover_position and then move on to the next one. Rinse and repeat.

The algebra part is pretty straight forward:

Wall thickness + indoor window sill + acceptable sun stake - position of roller shutter in the wall = one part of the triangle (a)

The other one (b) we get with

tan(alpha) * a = b

where alpha is the elevation

b is the position inside the full window height for the roller shutter to archive good shading by the owners specification.

so we could easily calculate a percentage from that.

100 / windows height * b = % to be closed (x)

Now we need to calculate the roller shutter position, we got a no shading value (c), probably 98%, and a full shading value (d), probably at about 15% so we have

c - d = e (100% distance from no to full shading)

e * x + c = roller shutter position in %

Now we need to calculate from what elevation on the roller shutter could be fully open. but this could also be entered by the user, since there could be a balcony or a roof eaves that shades the window in a different way than just the wall and its thickness.

What do you say @123 doable?

of course we need a variable block for global and each window and some automation that would consider the rest of the global variables like the temps and clouds and so on.

I think I got the algebra for the opening position inside this string

edit says: forget about this, the formula is all wrong, im working on it in the thread linkt with the 4 in 1 automation to posts further down. The solution will be there when I am finished with the roller shutter stuff.


set a = #deviation from vertical if e.g. roof window
set b = #height of window in mm
set c = #width of wall including inside window sill in mm
set d = #acceptable width of sun streaks (AWS) in mm
set e = #depth of the shutter from outside wall
set f = #start shading in % of roller shutter
set g = #fully shaded in % of roller shutter

set shutter_shading_pos = ((tan('sun.azimuth' + a) * 0,01 * (c + d) * b * (f - g)) + g)

I say you should start a new topic because this one was solved a long time ago and your requirements are substantially different. By starting a new topic, it’s more likely to attract fresh eyes to it.

yes, sir

Not to mention that it was a decent amount of work to get the original automations to work with just the azimuth vs shutter positions for 4 groups of shades.

by my count you’ve added about 60 different variables into the mix. I doubt anyone is going to want to tackle that.

If you get all the math worked out then I’m sure someone can convert it into a working template.

Good luck.

I have my elevation2shutter pos calculation in combination with parts of your azimuth code running on one test device (I have a baby diaper changing table that moves up and down to be stored away thats working with a roller shutter motor and is therefore able to resemble a roller shutter) right now, iits all totally messed up, but I’ll get it to work. Probably just did some silly stuff integrating all the calculations into one formula. I just start with an elevation follow today, and then build from there.

what really would help would be a code that simulates a days sun movement so I have sensors for azimuth and elevation to bind the code to that simulat 24h of elevation and azimuth inside 10 minutes. so I could see if my code does what i want it to do, but dont have to wait the whole day.

got some recommendation how to make that happen?

not automatically.

you could paste the template into the dev tools template editor and create variables for the elevation and azimuth and use those variables in the template instead of the real sun attributes.

then you can just manually change the variable values and see the result of the template change.

that’s what I did in coming up with the original templates above to test things.

Im struggling to get a for each loop working. I am not a coder…

for azimuth thats pretty simple in theory, but not for me cooding noop would like to have it change in half degree increments (0,5) every second, so a day would take 12 mins.

for elevation, this is much more complicated as is oscillates between -20 and +40 at azimuth 0 and 180 at my location. I dont need the compound curves the sun really does. linear function is totally acceptable.

I think it should work like: you enter the elevation level you want to test and the corresponding lower elevation level is set to upper elevation -80°

also the increment should be variable. to adjust for speed and detail.

Now one could just use simple math to get the corresponding elevation to the azimuth and simple set these from a table.

I may be able to utilise @123 shorted code from here

I just put that into excel to get the calculations right. I cant upload the excel file, so here is the formulas (csv export

set required increment		0,5
Set elevation max ange to 		67
zero azimuth elevation then is	(formula: =C3-80)
change per azimuth			(formula: =80/180*C2)

First row Azimuth is 0
second row Azimuth is {formula: =WENN(A9<360;A9+C$2;"") } #you my need to replace "wenn" with "if" and pull down to 1000 rows.

First row Elevation (same row as 0 Azimuth) {formula: =WENN(A9="";"";WENN(A9<=180;(A9*C$5/C$2)+C$4;((A9-(2*(A9-180)))*C$5/C$2)+C$4))} # you may need to replace "wenn" with "if" and pull down to 1000 rows.

Now you got the Table for Azimuth to elevation calculation thats almost the real sun movement for your location when you enter the desired highes elevation of the day you want to test for.

But how to get that into a code in here, I have honestly not a clue how to do that.

And here is the result for a summer day in my area

required increment;;0,5;;;
Set elevation max ange to ;;67;;;
zero azimuth elevation then is;;-13;;;
change per azimuth;;0,22222;;;
;;;;;
;;;;;
Azimuth;;Elevation;;;
0;;-13,0000;;;
0,5;;-12,7778;;;
1;;-12,5556;;;
1,5;;-12,3333;;;
2;;-12,1111;;;
2,5;;-11,8889;;;
3;;-11,6667;;;
3,5;;-11,4444;;;
4;;-11,2222;;;
4,5;;-11,0000;;;
5;;-10,7778;;;
5,5;;-10,5556;;;
6;;-10,3333;;;
6,5;;-10,1111;;;
7;;-9,8889;;;
7,5;;-9,6667;;;
8;;-9,4444;;;
8,5;;-9,2222;;;
9;;-9,0000;;;
9,5;;-8,7778;;;
10;;-8,5556;;;
10,5;;-8,3333;;;
11;;-8,1111;;;
11,5;;-7,8889;;;
12;;-7,6667;;;
12,5;;-7,4444;;;
13;;-7,2222;;;
13,5;;-7,0000;;;
14;;-6,7778;;;
14,5;;-6,5556;;;
15;;-6,3333;;;
15,5;;-6,1111;;;
16;;-5,8889;;;
16,5;;-5,6667;;;
17;;-5,4444;;;
17,5;;-5,2222;;;
18;;-5,0000;;;
18,5;;-4,7778;;;
19;;-4,5556;;;
19,5;;-4,3333;;;
20;;-4,1111
20,5;;-3,8889
21;;-3,6667
21,5;;-3,4444
22;;-3,2222
22,5;;-3,0000
23;;-2,7778
23,5;;-2,5556
24;;-2,3333
24,5;;-2,1111
25;;-1,8889
25,5;;-1,6667
26;;-1,4444
26,5;;-1,2222
27;;-1,0000
27,5;;-0,7778
28;;-0,5556
28,5;;-0,3333
29;;-0,1111
29,5;;0,1111
30;;0,3333
30,5;;0,5556
31;;0,7778
31,5;;1,0000
32;;1,2222
32,5;;1,4444
33;;1,6667
33,5;;1,8889
34;;2,1111
34,5;;2,3333
35;;2,5556
35,5;;2,7778
36;;3,0000
36,5;;3,2222
37;;3,4444
37,5;;3,6667
38;;3,8889
38,5;;4,1111
39;;4,3333
39,5;;4,5556
40;;4,7778
40,5;;5,0000
41;;5,2222
41,5;;5,4444
42;;5,6667
42,5;;5,8889
43;;6,1111
43,5;;6,3333
44;;6,5556
44,5;;6,7778
45;;7,0000
45,5;;7,2222
46;;7,4444
46,5;;7,6667
47;;7,8889
47,5;;8,1111
48;;8,3333
48,5;;8,5556
49;;8,7778
49,5;;9,0000
50;;9,2222
50,5;;9,4444
51;;9,6667
51,5;;9,8889
52;;10,1111
52,5;;10,3333
53;;10,5556
53,5;;10,7778
54;;11,0000
54,5;;11,2222
55;;11,4444
55,5;;11,6667
56;;11,8889
56,5;;12,1111
57;;12,3333
57,5;;12,5556
58;;12,7778
58,5;;13,0000
59;;13,2222
59,5;;13,4444
60;;13,6667
60,5;;13,8889
61;;14,1111
61,5;;14,3333
62;;14,5556
62,5;;14,7778
63;;15,0000
63,5;;15,2222
64;;15,4444
64,5;;15,6667
65;;15,8889
65,5;;16,1111
66;;16,3333
66,5;;16,5556
67;;16,7778
67,5;;17,0000
68;;17,2222
68,5;;17,4444
69;;17,6667
69,5;;17,8889
70;;18,1111
70,5;;18,3333
71;;18,5556
71,5;;18,7778
72;;19,0000
72,5;;19,2222
73;;19,4444
73,5;;19,6667
74;;19,8889
74,5;;20,1111
75;;20,3333
75,5;;20,5556
76;;20,7778
76,5;;21,0000
77;;21,2222
77,5;;21,4444
78;;21,6667
78,5;;21,8889
79;;22,1111
79,5;;22,3333
80;;22,5556
80,5;;22,7778
81;;23,0000
81,5;;23,2222
82;;23,4444
82,5;;23,6667
83;;23,8889
83,5;;24,1111
84;;24,3333
84,5;;24,5556
85;;24,7778
85,5;;25,0000
86;;25,2222
86,5;;25,4444
87;;25,6667
87,5;;25,8889
88;;26,1111
88,5;;26,3333
89;;26,5556
89,5;;26,7778
90;;27,0000
90,5;;27,2222
91;;27,4444
91,5;;27,6667
92;;27,8889
92,5;;28,1111
93;;28,3333
93,5;;28,5556
94;;28,7778
94,5;;29,0000
95;;29,2222
95,5;;29,4444
96;;29,6667
96,5;;29,8889
97;;30,1111
97,5;;30,3333
98;;30,5556
98,5;;30,7778
99;;31,0000
99,5;;31,2222
100;;31,4444
100,5;;31,6667
101;;31,8889
101,5;;32,1111
102;;32,3333
102,5;;32,5556
103;;32,7778
103,5;;33,0000
104;;33,2222
104,5;;33,4444
105;;33,6667
105,5;;33,8889
106;;34,1111
106,5;;34,3333
107;;34,5556
107,5;;34,7778
108;;35,0000
108,5;;35,2222
109;;35,4444
109,5;;35,6667
110;;35,8889
110,5;;36,1111
111;;36,3333
111,5;;36,5556
112;;36,7778
112,5;;37,0000
113;;37,2222
113,5;;37,4444
114;;37,6667
114,5;;37,8889
115;;38,1111
115,5;;38,3333
116;;38,5556
116,5;;38,7778
117;;39,0000
117,5;;39,2222
118;;39,4444
118,5;;39,6667
119;;39,8889
119,5;;40,1111
120;;40,3333
120,5;;40,5556
121;;40,7778
121,5;;41,0000
122;;41,2222
122,5;;41,4444
123;;41,6667
123,5;;41,8889
124;;42,1111
124,5;;42,3333
125;;42,5556
125,5;;42,7778
126;;43,0000
126,5;;43,2222
127;;43,4444
127,5;;43,6667
128;;43,8889
128,5;;44,1111
129;;44,3333
129,5;;44,5556
130;;44,7778
130,5;;45,0000
131;;45,2222
131,5;;45,4444
132;;45,6667
132,5;;45,8889
133;;46,1111
133,5;;46,3333
134;;46,5556
134,5;;46,7778
135;;47,0000
135,5;;47,2222
136;;47,4444
136,5;;47,6667
137;;47,8889
137,5;;48,1111
138;;48,3333
138,5;;48,5556
139;;48,7778
139,5;;49,0000
140;;49,2222
140,5;;49,4444
141;;49,6667
141,5;;49,8889
142;;50,1111
142,5;;50,3333
143;;50,5556
143,5;;50,7778
144;;51,0000
144,5;;51,2222
145;;51,4444
145,5;;51,6667
146;;51,8889
146,5;;52,1111
147;;52,3333
147,5;;52,5556
148;;52,7778
148,5;;53,0000
149;;53,2222
149,5;;53,4444
150;;53,6667
150,5;;53,8889
151;;54,1111
151,5;;54,3333
152;;54,5556
152,5;;54,7778
153;;55,0000
153,5;;55,2222
154;;55,4444
154,5;;55,6667
155;;55,8889
155,5;;56,1111
156;;56,3333
156,5;;56,5556
157;;56,7778
157,5;;57,0000
158;;57,2222
158,5;;57,4444
159;;57,6667
159,5;;57,8889
160;;58,1111
160,5;;58,3333
161;;58,5556
161,5;;58,7778
162;;59,0000
162,5;;59,2222
163;;59,4444
163,5;;59,6667
164;;59,8889
164,5;;60,1111
165;;60,3333
165,5;;60,5556
166;;60,7778
166,5;;61,0000
167;;61,2222
167,5;;61,4444
168;;61,6667
168,5;;61,8889
169;;62,1111
169,5;;62,3333
170;;62,5556
170,5;;62,7778
171;;63,0000
171,5;;63,2222
172;;63,4444
172,5;;63,6667
173;;63,8889
173,5;;64,1111
174;;64,3333
174,5;;64,5556
175;;64,7778
175,5;;65,0000
176;;65,2222
176,5;;65,4444
177;;65,6667
177,5;;65,8889
178;;66,1111
178,5;;66,3333
179;;66,5556
179,5;;66,7778
180;;67,0000
180,5;;66,7778
181;;66,5556
181,5;;66,3333
182;;66,1111
182,5;;65,8889
183;;65,6667
183,5;;65,4444
184;;65,2222
184,5;;65,0000
185;;64,7778
185,5;;64,5556
186;;64,3333
186,5;;64,1111
187;;63,8889
187,5;;63,6667
188;;63,4444
188,5;;63,2222
189;;63,0000
189,5;;62,7778
190;;62,5556
190,5;;62,3333
191;;62,1111
191,5;;61,8889
192;;61,6667
192,5;;61,4444
193;;61,2222
193,5;;61,0000
194;;60,7778
194,5;;60,5556
195;;60,3333
195,5;;60,1111
196;;59,8889
196,5;;59,6667
197;;59,4444
197,5;;59,2222
198;;59,0000
198,5;;58,7778
199;;58,5556
199,5;;58,3333
200;;58,1111
200,5;;57,8889
201;;57,6667
201,5;;57,4444
202;;57,2222
202,5;;57,0000
203;;56,7778
203,5;;56,5556
204;;56,3333
204,5;;56,1111
205;;55,8889
205,5;;55,6667
206;;55,4444
206,5;;55,2222
207;;55,0000
207,5;;54,7778
208;;54,5556
208,5;;54,3333
209;;54,1111
209,5;;53,8889
210;;53,6667
210,5;;53,4444
211;;53,2222
211,5;;53,0000
212;;52,7778
212,5;;52,5556
213;;52,3333
213,5;;52,1111
214;;51,8889
214,5;;51,6667
215;;51,4444
215,5;;51,2222
216;;51,0000
216,5;;50,7778
217;;50,5556
217,5;;50,3333
218;;50,1111
218,5;;49,8889
219;;49,6667
219,5;;49,4444
220;;49,2222
220,5;;49,0000
221;;48,7778
221,5;;48,5556
222;;48,3333
222,5;;48,1111
223;;47,8889
223,5;;47,6667
224;;47,4444
224,5;;47,2222
225;;47,0000
225,5;;46,7778
226;;46,5556
226,5;;46,3333
227;;46,1111
227,5;;45,8889
228;;45,6667
228,5;;45,4444
229;;45,2222
229,5;;45,0000
230;;44,7778
230,5;;44,5556
231;;44,3333
231,5;;44,1111
232;;43,8889
232,5;;43,6667
233;;43,4444
233,5;;43,2222
234;;43,0000
234,5;;42,7778
235;;42,5556
235,5;;42,3333
236;;42,1111
236,5;;41,8889
237;;41,6667
237,5;;41,4444
238;;41,2222
238,5;;41,0000
239;;40,7778
239,5;;40,5556
240;;40,3333
240,5;;40,1111
241;;39,8889
241,5;;39,6667
242;;39,4444
242,5;;39,2222
243;;39,0000
243,5;;38,7778
244;;38,5556
244,5;;38,3333
245;;38,1111
245,5;;37,8889
246;;37,6667
246,5;;37,4444
247;;37,2222
247,5;;37,0000
248;;36,7778
248,5;;36,5556
249;;36,3333
249,5;;36,1111
250;;35,8889
250,5;;35,6667
251;;35,4444
251,5;;35,2222
252;;35,0000
252,5;;34,7778
253;;34,5556
253,5;;34,3333
254;;34,1111
254,5;;33,8889
255;;33,6667
255,5;;33,4444
256;;33,2222
256,5;;33,0000
257;;32,7778
257,5;;32,5556
258;;32,3333
258,5;;32,1111
259;;31,8889
259,5;;31,6667
260;;31,4444
260,5;;31,2222
261;;31,0000
261,5;;30,7778
262;;30,5556
262,5;;30,3333
263;;30,1111
263,5;;29,8889
264;;29,6667
264,5;;29,4444
265;;29,2222
265,5;;29,0000
266;;28,7778
266,5;;28,5556
267;;28,3333
267,5;;28,1111
268;;27,8889
268,5;;27,6667
269;;27,4444
269,5;;27,2222
270;;27,0000
270,5;;26,7778
271;;26,5556
271,5;;26,3333
272;;26,1111
272,5;;25,8889
273;;25,6667
273,5;;25,4444
274;;25,2222
274,5;;25,0000
275;;24,7778
275,5;;24,5556
276;;24,3333
276,5;;24,1111
277;;23,8889
277,5;;23,6667
278;;23,4444
278,5;;23,2222
279;;23,0000
279,5;;22,7778
280;;22,5556
280,5;;22,3333
281;;22,1111
281,5;;21,8889
282;;21,6667
282,5;;21,4444
283;;21,2222
283,5;;21,0000
284;;20,7778
284,5;;20,5556
285;;20,3333
285,5;;20,1111
286;;19,8889
286,5;;19,6667
287;;19,4444
287,5;;19,2222
288;;19,0000
288,5;;18,7778
289;;18,5556
289,5;;18,3333
290;;18,1111
290,5;;17,8889
291;;17,6667
291,5;;17,4444
292;;17,2222
292,5;;17,0000
293;;16,7778
293,5;;16,5556
294;;16,3333
294,5;;16,1111
295;;15,8889
295,5;;15,6667
296;;15,4444
296,5;;15,2222
297;;15,0000
297,5;;14,7778
298;;14,5556
298,5;;14,3333
299;;14,1111
299,5;;13,8889
300;;13,6667
300,5;;13,4444
301;;13,2222
301,5;;13,0000
302;;12,7778
302,5;;12,5556
303;;12,3333
303,5;;12,1111
304;;11,8889
304,5;;11,6667
305;;11,4444
305,5;;11,2222
306;;11,0000
306,5;;10,7778
307;;10,5556
307,5;;10,3333
308;;10,1111
308,5;;9,8889
309;;9,6667
309,5;;9,4444
310;;9,2222
310,5;;9,0000
311;;8,7778
311,5;;8,5556
312;;8,3333
312,5;;8,1111
313;;7,8889
313,5;;7,6667
314;;7,4444
314,5;;7,2222
315;;7,0000
315,5;;6,7778
316;;6,5556
316,5;;6,3333
317;;6,1111
317,5;;5,8889
318;;5,6667
318,5;;5,4444
319;;5,2222
319,5;;5,0000
320;;4,7778
320,5;;4,5556
321;;4,3333
321,5;;4,1111
322;;3,8889
322,5;;3,6667
323;;3,4444
323,5;;3,2222
324;;3,0000
324,5;;2,7778
325;;2,5556
325,5;;2,3333
326;;2,1111
326,5;;1,8889
327;;1,6667
327,5;;1,4444
328;;1,2222
328,5;;1,0000
329;;0,7778
329,5;;0,5556
330;;0,3333
330,5;;0,1111
331;;-0,1111
331,5;;-0,3333
332;;-0,5556
332,5;;-0,7778
333;;-1,0000
333,5;;-1,2222
334;;-1,4444
334,5;;-1,6667
335;;-1,8889
335,5;;-2,1111
336;;-2,3333
336,5;;-2,5556
337;;-2,7778
337,5;;-3,0000
338;;-3,2222
338,5;;-3,4444
339;;-3,6667
339,5;;-3,8889
340;;-4,1111
340,5;;-4,3333
341;;-4,5556
341,5;;-4,7778
342;;-5,0000
342,5;;-5,2222
343;;-5,4444
343,5;;-5,6667
344;;-5,8889
344,5;;-6,1111
345;;-6,3333
345,5;;-6,5556
346;;-6,7778
346,5;;-7,0000
347;;-7,2222
347,5;;-7,4444
348;;-7,6667
348,5;;-7,8889
349;;-8,1111
349,5;;-8,3333
350;;-8,5556
350,5;;-8,7778
351;;-9,0000
351,5;;-9,2222
352;;-9,4444
352,5;;-9,6667
353;;-9,8889
353,5;;-10,1111
354;;-10,3333
354,5;;-10,5556
355;;-10,7778
355,5;;-11,0000
356;;-11,2222
356,5;;-11,4444
357;;-11,6667
357,5;;-11,8889
358;;-12,1111
358,5;;-12,3333
359;;-12,5556
359,5;;-12,7778
360;;-13,0000

Sorry for the delay, here’s my fully working automatic shutter control automation, with some comments to make it a little bit more comprehensible. In case of any question, just let me know!

# SOUTH COVER 1:
alias: Shutter auto control in summer - SOUTH1
description: ''
trigger:
  - platform: state
    entity_id: sun.sun
condition:
  - condition: state
    entity_id: alarm_control_panel.area_1
    state: disarmed
  - condition: numeric_state
    entity_id: sun.sun
    attribute: elevation
    above: '35'
action:
  - service: cover.set_cover_position
    target:
      entity_id:
        - cover.dolgozo_redny_medence_fele
    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 < 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 %}
mode: single

# SOUTH COVER 2:
alias: Shutter auto control in summer - SOUTH2
description: ''
trigger:
  - platform: state
    entity_id: sun.sun
condition:
  - condition: state
    entity_id: alarm_control_panel.area_1
    state: disarmed
  - condition: template
    value_template: '{{ 5 <= now().month <= 9 }}'
  - condition: state
    entity_id: sun.sun
    state: above_horizon
# these two condition below is only to make sure that we are awake, and went downstairs, other better condition could be used for this pupose
  - condition: numeric_state
    entity_id: sensor.zsolt_s_iphone_steps_2
    above: '30'
  - condition: numeric_state
    entity_id: sensor.linda_sajat_steps
    above: '30'
action:
  - service: cover.set_cover_position
    target:
      entity_id:
        - cover.emelet_folyoso_redny
    data:
      position: >
        {% if state_attr('sun.sun', 'azimuth') | float < 80 %}
          0
        {% elif state_attr('sun.sun', 'azimuth') | float >= 90 and
        state_attr('sun.sun', 'azimuth') | float < 130 %}
          {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 250) / 10) | int) * 10 }}
        {% elif state_attr('sun.sun', 'azimuth') | float >= 130 and
        state_attr('sun.sun', 'azimuth') | float < 180 %}
          0
        {% elif state_attr('sun.sun', 'azimuth') | float >= 180 and
        state_attr('sun.sun', 'azimuth') | float <= 220 %}
          {{ ((( 2 * (state_attr('sun.sun', 'azimuth') | float )  - 340) / 10) | int) * 10 }}
        {% else %}
          100
        {% endif %}
mode: single

# WEST COVER UPSTAIRS BEDROOM:
alias: Shutter auto control in summer - WEST upstairs bedroom
description: ''
trigger:
  - platform: state
    entity_id: sun.sun
condition:
  - condition: template
    value_template: |
      {{ 5 <= now().month <= 9 }}
  - condition: state
    entity_id: alarm_control_panel.area_1
    state: disarmed
# these two condition below is only to make sure that we are awake, and went downstairs, other better condition could be used for this pupose
  - condition: numeric_state
    entity_id: sensor.zsolt_s_iphone_steps_2
    above: '30'
  - condition: numeric_state
    entity_id: sensor.linda_sajat_steps
    above: '30'
  - condition: sun
    before: sunset
    after: sunrise
action:
  - service: cover.set_cover_position
    target:
      entity_id:
        - cover.szul_halo_redny
        - cover.szul_furd_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 < 160 %}
         100
        {% elif state_attr('sun.sun', 'azimuth') | float >= 160 and
        state_attr('sun.sun', 'azimuth') | float < 200 %}
          {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 410) / 10) | int) * 10 }}
        {% elif state_attr('sun.sun', 'azimuth') | float >= 200 and
        state_attr('sun.sun', 'azimuth') | float <= 290 %}
          0
        {% elif state_attr('sun.sun', 'azimuth') | float > 290 and
        state_attr('sun.sun', 'azimuth') | float <= 300 %}
          {{ ((( 2 * (state_attr('sun.sun', 'azimuth') | float )  - 560) / 10) | int) * 10 }}
        {% else %}
          100
        {% endif %}
mode: single

# EAST COVER UPSTAIRS BEDROOM:
alias: Shutter auto control in summer - EAST upstairs bedroom
description: ''
trigger:
  - platform: state
    entity_id: sun.sun
condition:
  - condition: state
    entity_id: alarm_control_panel.area_1
    state: disarmed
  - condition: template
    value_template: '{{ 5 <= now().month <= 9 }}'
  - condition: state
    entity_id: sun.sun
    state: above_horizon
# these two condition below is only to make sure that someone in the room is awake, and already pulled up partially or fully the window cover
  - condition: device
    device_id: be6ad1c3bfd5a6651fe3e4639bb6e930
    domain: cover
    entity_id: cover.emma_redny
    type: is_position
    above: 1
  - condition: device
    device_id: 20e00b553784c55815e722b9ab476099
    domain: cover
    entity_id: cover.sari_redny
    type: is_position
    above: 1
action:
  - service: cover.set_cover_position
    target:
      entity_id:
        - cover.emma_redny
        - cover.sari_redny
    data:
      position: |
        {% if state_attr('sun.sun', 'azimuth') | float < 100 %}
          0
        {% elif state_attr('sun.sun', 'azimuth') | float >= 130 %}
          100
        {% else %}
          {{ (((state_attr('sun.sun', 'azimuth') | float - 70 ) / 10) | int) * 10 }}
        {% endif %}
mode: single

2 Likes

awesome, thanks a lot, it will help me with the code in my full solution that moves the shutters according to elevation during the shading.

thanks

1 Like

Hi, came across this thread because I’d like to do the same thing.

I’m just looking at your code @Guesswho620 , and I believe is solely based on azimuth of the sun based on the season, and not if its actually sunny or cloudy outside? I could be mistaken on this.

I would like to setup something similar based on a few things:

  • only for sunset
  • based on azimuth
  • based on presence (being home)—I have set this up for another automation and use the state for that
  • based on my weather station sensor that has a lux sensor (already reporting to HA via an integration)

The last condition is for example, I don’t want the blinds adjusting if its not sunny AND it does not have to depend on that actual value except if its above a certain value (its sunny or not sunny). For example, on day like today in March with sunny skies, a lux under 95w/m2 is comfortable on the eyes but I’ll have to figure out how azimuth corresponds to lux on a clear during the late sping/summer/winter/fall seasons on , sunny day, and maybe even a cloudy day, but basically this automation would be running between the times of after 3pm to about 9 pm…but that would depend on the season also. Heres a sunny day example in march (2 days ago), and how it changes as the sun moves.

image

Perhaps this would allow me to intrduce a condition that if the lux is greater than X w/m2 for more than 30 seconds in the time of 4 to 9 pm, adjust the blinds/covers accordingly.

one thing to mention is with having the lux sensor, this eliminates the seasons coding part.

hi @finity

just wanted to follow up here on the code you provided:

data:
      position: >
        {% if state_attr('sun.sun', 'azimuth') | float < 80 %}
          20  
        {% elif state_attr('sun.sun', 'azimuth') | float >= 80 and
        state_attr('sun.sun', 'azimuth') | float < 170 %}
          90
        {% 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 %}
          20
        {% 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 %}
          80
        {% endif %}

are the position values modifiable, like above? I tried to use my positions, but it doesn’t seem to like it on that parts where the azimuith falls on formula parts:

  {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 440) / 10) | int) * 10 }}

 {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 440) / 10) | int) * 10 }}

also, for me, I have a west facing window, thus if I change the azimuth settings i.e from 80, 170, 220, 251, 301 to something else, how would I have to modify the above formula parts?

also, does this overide the current position of the shade (whatever position its on) on every command?

thanks

What do you mean here?

what are you seeing to say “it doesn’t like it”?

it really depends on what the values are for the sun position vs the positions for the blinds.

without knowing the desired relationship between the two variables it’s hard to know what the formula values will be.

it doesn’t override the current actual position. It just commands the blind to move to a new actual position. Which will then be reflected in the position displayed after the move.

@finity thanks for replying, sorry I should more clear.

Here’s what would work for my situation. I only want the shade to block on the sun when its beaming through the west side window (not control it 24/7), basiclly, the position of the shade should change from 80% to 20% (when sun is approaching, 220 to 270) and 20% to 80% when the sun is going the other way (270 up to 320). Something like this below:

data:
      position: >
        {% if state_attr('sun.sun', 'azimuth') | float = 220 %}
          80  
        {% elif state_attr('sun.sun', 'azimuth') | float >= 220 and
        state_attr('sun.sun', 'azimuth') | float < 270 %}
          {{ (((-2 * (state_attr('sun.sun', 'azimuth') | float )  + 560) / 10) | int) * 10 }}
        {% elif state_attr('sun.sun', 'azimuth') | float >= 220 and
        state_attr('sun.sun', 'azimuth') | float = 270 %}
          20
        {% elif state_attr('sun.sun', 'azimuth') | float > 270 and
        state_attr('sun.sun', 'azimuth') | float <= 320 %}
          {{ ((( 2 * (state_attr('sun.sun', 'azimuth') | float )  - 520) / 10) | int) * 10 }}
        {% if state_attr('sun.sun', 'azimuth') | float = 320 %}
          80  
        {% endif %}

I haven’t tried this code, but I know its not going to work because if you place an azimuth of 319, it will return a position of 117% (when it should be close to 80%)

It really is high school math. I’ll need a graphic calculator to figure out the equation of the line within the azimuth and position ranges…lol

looks like this works for me

y= -1.20x + 344.00