I understand now,
you are my hero of the day
Yes, I got the thing about the position_template from the documentation
I understand now,
you are my hero of the day
Yes, I got the thing about the position_template from the documentation
That’s the configuration of a template cover, not the service call you need.
Sorry, I’m nosey sometimes Thanks for the exlplanation!
But I wanted to bring something different to the table, maybe this could help with or even replace your current solution.
There is a custom integration or blueprint (whatever fits your likings), that I could really recommend.
In this topic you’ll find the original (but still updated) blueprint, or you can go with the full blown integration. Maybe this fits your needs, you might want to give it at least a read, or even better a try!
Initially I as well tried to get my covers under control with some automations, but this integration does it far better!
If you want to take a look at the blueprint, you can find it here:
Ok… got it, is there a way to sort it out, or how to know that in my case I need service call?
Thanks for the tip, I already know both of them, I have already used them for some windows, unfortunately they do not achieve the desired result for shading the roof windows.
Worth a shot. I figured, it might not be a perfect solution, as I have the same problems “mit meinen Dachschrägenfenstern”, for all other windows the integration works like a charme.
Your automation was calling a service:
OK, I get it. To be honest, as a carpenter, I find this “let’s call it programming or scripting” thing difficult.
If you are interested, I can provide everything as soon as the roof windows are properly shaded
That would be nice, thanks!
I see, you’re more of a non-PC guy as a carpenter. Two good friends of mine are as well! Great job, and a lot of history involved. I remember one of them being on the “Walz” years (decades) ago… Funny times!
Anyway, what you posted above is the configuration of an integration, in your case a “template cover”. I’ll try to explain, please bare with me, if I simplify things for an easier understanding.
An integration in HA is something, that is like an interface, so HA can talk to devices.
HA ↔ integration ↔ device
As HA and the device need to find an understanding, what they want from each other, you have an integration. Not only, but something like a translator with some background knowledge.
Take a simple Zigbee bulb as an example. HA says “turn on” and sends this command to the integration. The integration “translates” this, if necessary, and sends the understandable command to the bulb. Ideally, the bulb now turns on.
To let the integration know, what you want, you send a service-call. Here you would use the service-call light.turn_on
and would send it to the bulp my_bulb
that is integrated via the bulb_integration
.
The opposite would be light.turn_off
or light.toggle
. These would be the service-calls.
But the service-calls only work, if an integration can work with it. That’s where you need the documentation you posted above - to configure the integration, to use its service-calls.
A question about this calculation: how do I know that the calculation is correct?
All values below 4500 result in 100 (cover open),
all values above 12600 result in 0 (cover closed).
At what point could I adjust the range? Probably the 900, but I don’t understand it right now.
I have to think about it while I sleep.
I noticed all of your breakpoints were multiples of 900.
x // 900
is integer division, so your smallest breakpoint, 4500, becomes 4, as do all numbers up to 5399.
5400 becomes 5 and so on up to 12600, which becomes 14.
Subtract 4 from each of those and you get a range from 0 to 10. Numbers less than 4500 will become negative; and those over 13499 will be over 10, but we will sort that out in the last step.
Next, multiply by 10 to get a useful range of 0 to 100. This range is the wrong way around, so we subtract that number from 100 to give a range of 100 to 0.
That gives us the middle bit of the formula:
100 - (((x // 900) - 4) * 10)
Then we do a clever step (credit to Taras) to restrict the output between 0 and 100:
((0, y, 100)|sort)[1]
chooses the middle value. Substitute the formula above in place of y
and you have the full template.
As per the template editor code and screenshot above, I tested that it behaved identically to your version.
There are many ways to implement what you want to do. Your template is fine, but a bit lengthy. Just by putting the sensor state into a variable (like my x
) and using that rather than repeating the sensor state lookup each time would have made it a lot shorter:
{% set x = states('sensor.bewegungsmelder_strase_ost_beleuchtungsstarke')|float(0) %}
{% if x >= 0 and x < 4500 %} 100
{% elif x >= 4500 and x < 5400 %} 90
{% elif x >= 5400 and x < 6300 %} 80
{% elif x >= 6300 and x < 7200 %} 70
{% elif x >= 7200 and x < 8100 %} 60
{% elif x >= 8100 and x < 9000 %} 50
{% elif x >= 9000 and x < 9900 %} 40
{% elif x >= 9900 and x < 10800 %} 30
{% elif x >= 10800 and x < 11700 %} 20
{% elif x >= 11700 and x < 12600 %} 10
{% elif x >= 12600 %} 0
{% endif %}
This syntax also works:
{% set x = states('sensor.bewegungsmelder_strase_ost_beleuchtungsstarke')|float(0) %}
{% if 0 <= x < 4500 %} 100
{% elif 4500 <= x < 5400 %} 90
{% elif 5400 <= x < 6300 %} 80
{% elif 6300 <= x < 7200 %} 70
{% elif 7200 <= x < 8100 %} 60
{% elif 8100 <= x < 9000 %} 50
{% elif 9000 <= x < 9900 %} 40
{% elif 9900 <= x < 10800 %} 30
{% elif 10800 <= x < 11700 %} 20
{% elif 11700 <= x < 12600 %} 10
{% elif x >= 12600 %} 0
{% endif %}
Or you can set up a lookup list that is nearly as short as the “maths” version but can have arbitrary breakpoints. This one finds the index of the first element in the list less than or equal to the sensor value, and multiplies by ten:
{% set m = [12600, 11700, 10800, 9900, 9000, 8100, 7200, 6300, 5400, 4500, 0] %}
{% set x = states('sensor.bewegungsmelder_strase_ost_beleuchtungsstarke')|float(0) %}
{{ m.index(m|select('<=',x)|first) * 10 }}
perfectly explained,
I understood it straight away,
EXCELLENT
the question comes from the fact that not every daylight sensor has the same dynamic,
I now have 4 Philipp hue SML004 motion sensors with daylight sensor,
all 4, even when I place them next to each other,
have a deviation of more than 5000 lux from each other. Therefore I have to adjust the steps for each one.
But with this explanation I am sure I can do it.
A big thank you to both of you for this excellent support.
@paddy0174
My used configuration…
Here is the macro configuration I used.
In the directory \xx.xx.xx.xxx\config\custom_templates\directional_azi.jinja
location of house instead of north, east, south,west
hof = means north
hofstrasse = means east
starsse = means south
scheune = means west
{% set y_day_azi = {
1:
{"hof": none,
"hofstrasse": none,
"strasse": [126,207],
"scheune": [202,232]},
13:
{"hof": none,
"hofstrasse": none,
"strasse": [123,207],
"scheune": [202,236]},
26:
{"hof": none,
"hofstrasse": none,
"strasse": [118,207],
"scheune": [202,241]},
39:
{"hof": none,
"hofstrasse": none,
"strasse": [114,207],
"scheune": [202,245]},
52:
{"hof": none,
"hofstrasse": [109,128],
"strasse": [109,207],
"scheune": [202,252]},
65:
{"hof": none,
"hofstrasse": [99,128],
"strasse": [99,207],
"scheune": [202,260]},
78:
{"hof": [94,106],
"hofstrasse": [91,128],
"strasse": [91,207],
"scheune": [202,269]},
91:
{"hof": [86,106],
"hofstrasse": [82,128],
"strasse": [82,207],
"scheune": [202,277]},
104:
{"hof": [78,106],
"hofstrasse": [74,128],
"strasse": [74,207],
"scheune": [202,285]},
117:
{"hof": [70,106],
"hofstrasse": [66,128],
"strasse": [66,207],
"scheune": [202,294]},
130:
{"hof": [67,106],
"hofstrasse": [63,128],
"strasse": [63,207],
"scheune": [202,297]},
143:
{"hof": [61,106],
"hofstrasse": [57,128],
"strasse": [57,207],
"scheune": [202,300]},
156:
{"hof": [57,106],
"hofstrasse": [53,128],
"strasse": [53,207],
"scheune": [202,306]},
169:
{"hof": [55,106],
"hofstrasse": [51,128],
"strasse": [51,207],
"scheune": [202,308]},
182:
{"hof": [55,106],
"hofstrasse": [51,128],
"strasse": [51,207],
"scheune": [202,308]},
195:
{"hof": [59,106],
"hofstrasse": [54,128],
"strasse": [54,207],
"scheune": [202,304]},
208:
{"hof": [63,106],
"hofstrasse": [59,128],
"strasse": [59,207],
"scheune": [202,299]},
221:
{"hof": [70,106],
"hofstrasse": [59,128],
"strasse": [59,207],
"scheune": [202,292]},
234:
{"hof": [78,106],
"hofstrasse": [74,128],
"strasse": [74,207],
"scheune": [202,286]},
247:
{"hof": [85,106],
"hofstrasse": [81,128],
"strasse": [81,207],
"scheune": [202,278]},
260:
{"hof": [93,106],
"hofstrasse": [89,128],
"strasse": [89,207],
"scheune": [202,270]},
273:
{"hof": [102,106],
"hofstrasse": [98,128],
"strasse": [98,207],
"scheune": [202,261]},
286:
{"hof": none,
"hofstrasse": [106,128],
"strasse": [106,207],
"scheune": [202,253]},
299:
{"hof": none,
"hofstrasse": [114,128],
"strasse": [114,207],
"scheune": [202,246]},
312:
{"hof": none,
"hofstrasse": [120,128],
"strasse": [124,207],
"scheune": [202,239]},
325:
{"hof": none,
"hofstrasse": [124,128],
"strasse": [124,207],
"scheune": [202,234]},
338:
{"hof": none,
"hofstrasse": none,
"strasse": [127,207],
"scheune": [202,232]},
351:
{"hof": none,
"hofstrasse": none,
"strasse": [126,207],
"scheune": [202,232]},
} %}
{% macro directional_azi(direction, current_azimuth) %}
{% set yd = now().timetuple().tm_yday %}
{% set keys = y_day_azi.keys() | list %}
{% set start_ind = ((keys + [yd])|sort).index(yd) - 1 %}
{% set dir_dict = y_day_azi.get(keys[start_ind]) %}
{% set dir_list = dir_dict.get(direction) %}
{{ false if dir_list is none else current_azimuth|int
in range(dir_list[0], dir_list[1]) }}
{% endmacro %}
My used template sensors, It should be binay not template, I put them into binary used UI helper
# Sonnenstand anhand der Himmelsrichtung und Tag im Jahr
- sensors:
azimuth_hof:
friendly_name: 'Azimuth Hof'
unique_id: 'azimuth_hof'
value_template: >-
{% from 'directional_azi.jinja' import directional_azi %}
{{ directional_azi('hof', states('sensor.sonne_solar_azimuth')) }}
azimuth_hofstrasse:
friendly_name: 'Azimuth Hof Starsse'
unique_id: 'azimuth_hofstrasse'
value_template: >-
{% from 'directional_azi.jinja' import directional_azi %}
{{ directional_azi('hofstrasse', states('sensor.sonne_solar_azimuth')) }}
azimuth_strasse:
friendly_name: 'Azimuth Starsse'
unique_id: 'azimuth_strasse'
value_template: >-
{% from 'directional_azi.jinja' import directional_azi %}
{{ directional_azi('strasse', states('sensor.sonne_solar_azimuth')) }}
azimuth_scheune:
friendly_name: 'Azimuth Scheune'
unique_id: 'azimuth_scheune'
value_template: >-
{% from 'directional_azi.jinja' import directional_azi %}
{{ directional_azi('scheune', states('sensor.sonne_solar_azimuth')) }}
this the automaion I used for two roof windows for now.
alias: Beschattung Dachfenster
description: Beschattung Dachfenster
trigger:
- platform: time_pattern
minutes: /15
id: 15 Minuten Raster
- platform: state
entity_id:
- binary_sensor.azimuth_strasse_binary
from: "on"
to: "off"
for:
hours: 0
minutes: 0
seconds: 30
id: Azimuth Straße Aus
- platform: state
entity_id:
- binary_sensor.azimuth_scheune_binary
from: "on"
to: "off"
for:
hours: 0
minutes: 0
seconds: 30
id: Azimuth Scheune Aus
condition:
- condition: and
conditions:
- condition: time
after: "06:00:00"
before: "22:30:00"
- condition: state
entity_id: input_boolean.beschattung_dachfenster_ein_aus
state: "on"
- condition: template
value_template: "{{ states('sensor.raumklima_gastezimmer_temperatur_2')|float >= 22 }}"
- condition: template
value_template: >-
{{
state_attr('automation.dachfesnster','last_triggered').day==now().day
}}
action:
- choose:
- conditions:
- condition: and
conditions:
- condition: trigger
id:
- 15 Minuten Raster
- condition: state
entity_id: binary_sensor.azimuth_strasse_binary
state: "on"
for:
hours: 0
minutes: 0
seconds: 30
sequence:
- service: cover.set_cover_position
metadata: {}
data:
position: >-
{% set x =
states('sensor.bewegungsmelder_strase_ost_beleuchtungsstarke')|float(0)
%} {{ ((0, 100 - (((x // 600) - 4) * 5), 100)|sort)[1] }}
target:
entity_id: cover.dachfenster_speicher_strasse
- conditions:
- condition: trigger
id:
- Azimuth Straße Aus
sequence:
- service: cover.open_cover
metadata: {}
data: {}
target:
entity_id: cover.dachfenster_speicher_strasse
- conditions:
- condition: and
conditions:
- condition: trigger
id:
- 15 Minuten Raster
- condition: state
entity_id: binary_sensor.azimuth_scheune_binary
state: "on"
for:
hours: 0
minutes: 0
seconds: 30
sequence:
- service: cover.set_cover_position
metadata: {}
data:
position: >-
{% set x =
states('sensor.bewegungsmelder_scheune_west_beleuchtungsstarke')|float(0)
%} {{ ((0, 100 - (((x // 1000) - 4) * 5), 100)|sort)[1] }}
target:
entity_id: cover.dachfenster_speicher_scheune
- conditions:
- condition: trigger
id:
- Azimuth Scheune Aus
sequence:
- service: cover.open_cover
metadata: {}
data: {}
target:
entity_id: cover.dachfenster_speicher_scheune
mode: parallel
max: 3