Blind automation - written in appdaemon, made for homeassistant

Hi there,

I decided to open source the code that controls my blinds. You can find it here: GitHub - wogri/hass-blinds: Homessistant Blind library

It’s not trivial to configure, but I believe it’s rather advanced. Here’s the strategy that it implements:

Hass-blinds tries to optimize on either heating or cooling a building depending on the outside temperature. It also makes sure the maximum amount of light floods the house, so it defaults to “blinds are up”.

A Blind will go down if the sun angle (also known as azimuth) positions itself in a way where we know the sun goes through the window, a certain temperature threshold inside the room has been reached, the sun is intense enough and no human has overridden the blind position previously. If a window is underneath a ledge, one can configure the height of the window and the length of the ledge. The code will then do the geometric algebra to only close the blinds when the sun actually reaches the room. If the ledge still throws shadow into the window, the blinds will not go down.

If it gets dark one can configure if the blinds go down automatically or not. The same thing is configureable when the sun rises - blinds can go up at a lux threshold or stay down.

It is also sensitive to what’s happening inside of rooms. If lights are turned on inside a room it is possible to change the lux thresholds so that blinds go down earlier if it dawns.

The angle of the fins will be auto-adjusted according to the height of the sun to again allow maximum light into the room. However to not make adjustments all the time this is done in ~10% steps.

The mornings are tricky, because when the sun is intense in the morning it can already be disturbing, but the actual lux values might be low. Here we again apply a linear function of a threshold when the sun should go down in the morning depending on its height. So if the sun is still low the lux threshold is lower than if the sun reaches a higher point.

If you have binary sensors that know about the state of a window door (open or closed) the blinds will not go down if the door is open to avoid locking someone out.

The best (and most complicated) part about hass-blinds is that they tend to be friendly to humans. If a human overrides the position of a blind because “they know better than the code” then hass-blinds backs off for a configurable amount of time. This method is called the kill switch. Whenever the code believes that a human overrode a blind position it will enable the kill switch. You can release the kill switch by reloading the appdaemon code - e. g. touch blinds.py . The kill switch time can be configured per blind and really depends on the ignorance of the people that live with you :slight_smile:

I haven’t tried my own instructions that I documented, there’s a good chance you need to do more than I wrote down in the README.md on GitHub. So I recommend that you know how appdaemon works if you want to try it out. Pull requests welcome!

4 Likes

Hi wogri,

are you still maintaining this git? The idea is very nice but I have difficulties to make it work.
It is probably written in an older version of AppDaemon with different function definition.

For example, I found that all functions self.listen_state are not correctly defined anymore and made the code crash/behave strangely. In fact, the code defined for example:

self.listen_state(self.temperature_update, entity=self.args["outside_temp_sensor"])

while function should be written as:

self.listen_state(self.temperature_update, entity_id=self.args["outside_temp_sensor"])

This made the callback point to random sensors and ultimately crashed. They are probably other function that needs to be rewritten because of the latest python version and/or AppDaemon.

Happy to help to restore the code to the latest python version :slight_smile: and push changes to git when finished.

Hey,
thanks for reaching out. I had to lock my homeassistant installation to an older version because of modbus issues in my setup with newer implementations. I’d be very happy if you patched my code, I will review your PRs.
I still actively use this code every day and it still makes me my life significantly easier!

Hey Wogri,

I am about to release a new version with major changes:

  • simplified configuration (get ride of all repicatied configuration like max_temp and wind_speed)
  • better response to windy situtation
  • windows type is getting automatically to door if contact is not empty
  • inside_temperature is now working also for entites that are not thermostat, so I removed inside_temperature_is_no_thermostat
  • finished the min temp (it was useless AS IS)
  • added support for z-wave roller shutter
  • adddd support for weather station displaying sun light in W/m^2
  • Corrected a bug for windows where entry azimuth > exit azimuth
  • Added the possibility to set a fixed time for the manual_day_control parameters
  • code refractoring
  • simplified readme
  • support for latest AppDaemon version

However, I still had two questions on your code, would be nice if you could help me out before I do the push.

1/ Why is this parameter blind_runtime different from 0 and why waiting before changing the tilt ? I put it to 0 and it seems to work fine so far, since AppDaemon run multirheading without issue and my controler as well. Is this because of your controler that get mixed up if you specify position and tilt simultaneously ?

2/ In the blind_lib you defined window_height=240 and this cannot be changed from the configuration. Is there a reason why or should it be added to the apps.yml ?

I was also thinking to add the code to HACS https://hacs.xyz/. What do you think ?

Thank you :slight_smile:

1 Like

This is great, thank you!

  • Corrected a bug for windows where entry azimuth > exit azimuth

I’ve used this as a hack in the past for windows that should have never gone down regardless of the position of the sun. Used to be useful for windows that face north.

  • simplified readme

Please add yourself as a contributor!

  • Added the possibility to set a fixed time for the manual_day_control parameters

That’s cool, I’m sure that’s useful for folks out there with less sophisticated sensors, thank you!

  • support for latest AppDaemon version

yay!

1/ Why is this parameter blind_runtime different from 0 and why waiting before changing the tilt ? I put it to 0 and it seems to work fine so far, since AppDaemon run multirheading without issue and my controler as well. Is this because of your controler that get mixed up if you specify position and tilt simultaneously ?

correct. my controller only understands a position or an angle, but not both at the same time. when the blinds go down the shutters are completely closed in my setup. with the runtime I’m able to shorten the time where it’s completely dark in the room by a bit.

2/ In the blind_lib you defined window_height=240 and this cannot be changed from the configuration. Is there a reason why or should it be added to the apps.yml ?

Yes, I must have forgotten about this. The window_height is used to calculate when to close the blinds that are under a ledge: hass-blinds/lib/blinds_lib.py at c4ff2182f56ba2d71541ba032446eb4bbfe3448b · wogri/hass-blinds · GitHub
So it would make sense to make this a configurable parameter in apps.yml for folks with a different room height.

Do the tests pass after your refactor?

Thanks for the quick reply :slight_smile: ,

so still a bit of work to be done. I have tested almost everything except for the new workflow of the wind sensor.

For the blind-runtime it seems like that putting it to 0 caused some trouble. probably because of the master_lock being called in the tiltt and position function simultanouessly. I will have to look more deepy into i. Ultimately I would like to have a multi-threading option for the covers that support it.

I will keep you posted (I will not push the changes before a few days anyway)

Hello, I published the Cover Control Automation (CCA) blueprint some time ago and am trying to make dynamic controls possible. Unfortunately, the HA blueprints quickly reach their technical limits.
I already use AppDaemon myself for ControllerX. But I would prefer to do without all levels of abstraction.

How about getting together with a few developers and creating a custom component? Do you think that would make sense?

1 Like

would definitely make sense, but I currently don’t have time to spare for this unfortunately.

We should publlish it to HACS. So it woudl be available as an integratin from the HACS store. Personnally, I do not have a lot of time to spent but I would be happy to see it on the HACS store :upside_down_face:

I would already push my changes and then we will see on how to integrate to HACS once done.

thanks folks, you’re awesome. As I said before, I can spend my time on code reviews.

I finally found time to push the changes.
@Herr.Vorragend if you want to make some work on it you can use the newest version once the pulll is accepted

1 Like

Just noticed this project and have already seen your blueprints. I’ve build already an Adaptive Cover integration for HACS that dynamically adjusts the cover position based on the solar position. Or based on climate inputs based on some scientific research.

It is still in a beta phase since I am still learning and adding new features before it really can be stable. Happy to help and/or implement some features that are not covered.

1 Like

I had a quick look at how to build my own integration. And I used your integration as a sample. I think your approach is really great.

To be honest, I’m not sure whether I want to go down that route. I have a lot of programming experience in different languages. But I’m quite happy with the blueprint. Unfortunately, the blueprint is not very elegantly programmed. Lots of repetitions. No functions. No abstraction levels. Simply top-down YAML code.

Maybe I’ll look deeper into the subject at some point. Summer is approaching for me. I have better things to do and don’t want to spend my time in front of the computer.

1 Like