Automatic blind control OH/NodeRed

Hi everyone,

i am currently planning to implement a automatic shutter blind control
Just wanted to ask the community what is the experience so far?
Is it better/more comfortabel to go with NodeRed and use any of the blindcontroller “binding” or create rules within OH directly and play with different items states like lux, altitude…

Please share your suggestions.
Thank you in advance.

Personally I try to limit the number of systems being involved, therefore try to do most within openhab.

One general thing:
Be cautious with any blind automation that’s related to a door, that you will not lock out yourself


Hi @openhab_knx,

I am controlling my blinds on two sides of the house (east and west) by openhab.
This is completely based on rules (currently Rules DSL but I am planning to migrate it to JS or Python rules) and I am using the following values:

  • current outdoor temperature (combined temperature values of some sensors)
  • sun elevation (astro binding)
  • sun azimuth (astro binding)
  • current cloud coverage (local weather forecast by openweathermap)

The blind automation is configurable with some parameters to adapt it to the seasonal needs:

I can post more details if you like.



wow looks great, i am very interested in the details.
My plan is to additionally use the illuminance sensor outdoor instead of the cloud coverage by openweathermap.

Are you also able to “lock” single shutters? For example if you watch TV and would like to exclude the shutter in the living room(rest of the shutters should continue with the shading) until you activate the automatic again.

What is your “sync” time? In which time frame you are reacting changes (temp, cloud coverage azimut and elevation?). I am planning to use about 30min to avoid a “shutter loop” if there are many changes outside. (cloud and windy which affects the illuminance etc.)

Thank you in advance.

This is also my plan for the future - in the meantime I use the cloud coverage. But to be honest: most of the time I simply let the blinds down as soon as the sun comes around the house corner - no matter how bright the sun ist :slight_smile:

I have thought about that but haven’t implemented it yet.

The scripts runs as soon as my item for the sun azimuth changes. And these items will be updated every 15 minute by the astro binding.
And yes, I have switches and settings for the opening of the blinds but in most cases I use just the closing automatism.

This basic code is based on some other community member’s code which I adapted for my needs. I also had some thoughts of refactoring the code to make it more readable and reusable, but I simply had no time for this until now.

RolloAbWest rule:

configuration: {}
  - id: "1"
      itemName: LokaleSonnendaten_Azimut
    type: core.ItemStateChangeTrigger
conditions: []
  - inputs: {}
    id: "6"
      type: application/vnd.openhab.dsl.rule
      script: >-
        val String logPrefix = 'Rolloautomatik - RollosWestseiteRunterfahren - '

        if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Regel wurde gestartet')

        var String timeLast = 'xxxx-xx-xx'

        if (RolloAutomatik_WestRunterLastRun.state == NULL) {
            if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
        } else {
            timeLast = RolloAutomatik_WestRunterLastRun.state.toString().substring(0,10)

        var String timeNow = now.toString().substring(0,10)

        if (RolloAutomatikEin.state == ON && RolloAutomatik_WestRunterfahren.state == ON) {
            if (timeNow != timeLast) {
                if ((LokaleSonnendaten_Azimut.state as QuantityType<Number>).intValue > (RolloAutomatik_WestAzimuthRunter.state as DecimalType).intValue) {
                    if (((TemperatursensorAussenHutte_ActualTemperature.state as QuantityType<Number>).intValue > (RolloAutomatik_WestTempMin.state as DecimalType).intValue) || RolloAutomatik_SperreTemperatur.state == ON) {
                        if (LokalesWetterVorhersage_Bewolkung.state <= (RolloAutomatik_WestWolkenMax.state as DecimalType).intValue || RolloAutomatik_SperreWolken.state == ON) { 
                            if ((LokaleSonnendaten_Position_Elevation.state as QuantityType<Number>).intValue > (RolloAutomatik_WestElevationHoch.state as DecimalType).intValue) {
                              // Rollos runterfahren
                              if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Rollos werden runtergefahren')
                                  if (i.state <= (RolloAutomatik_WestZielwert.state as DecimalType).intValue) {
                                      if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Fahre Rolladen auf ' + RolloAutomatik_WestZielwert.state.toString() + '%: ' +
                                      i.sendCommand((RolloAutomatik_WestZielwert.state as DecimalType).intValue)
                                  } else {
                                      if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Rolladen ist bereits weiter geschlossen (' + i.state.toString() + '%) als er geschlossen werden sollte und wird daher ignoriert')
                              // Letzte Ausführung mit entsprechendem Zeitstempel belegen
                              RolloAutomatik_WestRunterLastRun.postUpdate(new DateTimeType(now))
                            } else {
                                if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Aktuelle Sonnenhöhe (' + (LokaleSonnendaten_Position_Elevation.state as QuantityType<Number>).intValue.toString() + ') ist kleiner als minimale Sonnenhöhe (' + (RolloAutomatik_WestElevationHoch.state as DecimalType).intValue.toString() + ')')
                        } else {
                            if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Maximalbewölkung (' + (RolloAutomatik_WestWolkenMax.state as DecimalType).intValue.toString() + ') wurde ueberschritten (' + LokalesWetterVorhersage_Bewolkung.state.toString() + ')')
                    } else {
                        if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Mindest-Temperatur (' + (RolloAutomatik_WestTempMin.state as DecimalType).intValue.toString() + ') wurde nicht erreicht durch aktuelle Temperatur (' + TemperatursensorAussenHutte_ActualTemperature.state.toString() + ')')
                } else {
                    if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Sonnenrichtung (' + (LokaleSonnendaten_Azimut.state as QuantityType<Number>).intValue.toString() + ') hat noch nicht Schwellwert (' + (RolloAutomatik_WestAzimuthRunter.state as DecimalType).intValue.toString() + ') erreicht')
            } else {
                if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Automatik heute bereits einmal gelaufen, wird daher ignoriert')
        } else {
             if (EnableLog_RolladenRules.state == ON) logInfo('rolladen.rules', logPrefix + 'Beende, da Automatik nicht aktiv')
    type: script.ScriptAction


Hi Jonathan,

Thank you, so we are on the same way…
Have modified the same code as mentioned in this topic :slight_smile:

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.