Rollo-Steuerung durch Helligkeitssensor: welches Modul?

Begonnen von DerITler, 04 Oktober 2025, 20:12:24

Vorheriges Thema - Nächstes Thema

DerITler

Hallo Zusammen,

wie in der Überschrift zu lesen, habe ich einen Helligkeitsensors, der jede Minute einen Wert sendet. Jetzt möchte ich, dass über diesen Wert meine Rollos gesteuert werden. Liegt der Helligkeitswert zum Beispiel zwischen 500 und 5000, sollen die Rollos nur zu 25% geöffnet sein. Aber nur, wenn der Wert den Bereich nicht in den nächsten 3 Minuten über- oder unterschreitet.

Über welches Helfermodul (notify, watchdog, etc.) würdet ihr das realisieren?

VG und danke für eure Antworten

betateilchen

Sowohl mit watchdog als auch mit notify ist sowas gut lösbar.

Aber die Aufgabe ist noch nicht ganz bis zum Ende formuliert.
  • Unter welcher Bedingung soll das Rollo wieder ganz aufgehen?
  • Wirkt sich das heruntergefahrene Rollo auf den Messwert des Sensors aus?

Etwas ähnliches wie Du hatte ich vor einiger Zeit auch mal probiert. Hat auch mit dem Runterfahren gut funktioniert. Aber bei wechselhaftem Wetter und zugehörigen Helligkeiten hatte ich plötzlich einen auf und ab "tanzenden" Rollladen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

DerITler

Ganz genau das ist mein Problem. Die Tanzenden Rollos. 😉

Um deine Frage zu beantworten: ich habe die Werte des Helligkeitsensors in feste Bereiche eingeteilt. Erreicht der Helligkeitswert einen Bereich, und bleibt in den nächsten 3 Minuten in diesem Bereich, stellen sich die Rollos dementsprechend ein. Ansonsten bleiben sie so, wie sie sind.
Und nein, die Stellung der Rollos haben keinen Einfluss auf die Werte des Helligkeitsensors.

frober

Zitat von: DerITler am 04 Oktober 2025, 20:33:02Ganz genau das ist mein Problem. Die Tanzenden Rollos. 😉

Vermeiden lässt sich das nicht ganz, aber man kann es entschärfen.
Meine Beschattung fährt erst nach 5 Min zu und nach 15 Min wieder auf, wenn die Voraussetzungen gegeben sind.

Des Weiteren benutze ich das Twilight-Modul um nach Sonnenstand und -höhe die einzelnen Rolladen zu steuern.
Ich benutze auch keinen Helligkeitssensor, sondern die Temperaturdifferenz in Anlehnung an
https://www.stall.biz/project/robuster-sonnensensor-ganz-einfach/

Das Ganze wird mit einem notify getriggert und in MyUtils verarbeitet.

Alternativ gibt es noch das ASC-Modul.
Raspi 3b mit Raspbian Bullseye und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

DerITler

Zitat von: frober am 05 Oktober 2025, 10:23:13
Zitat von: DerITler am 04 Oktober 2025, 20:33:02Ganz genau das ist mein Problem. Die Tanzenden Rollos. 😉

Das Ganze wird mit einem notify getriggert und in MyUtils verarbeitet.

Könntest du mir das zur Verfügung stellen?

frober

Zitat von: DerITler am 05 Oktober 2025, 17:17:29
Zitat von: frober am 05 Oktober 2025, 10:23:13Das Ganze wird mit einem notify getriggert und in MyUtils verarbeitet.

Könntest du mir das zur Verfügung stellen?

Kommt drauf an wie fit du in Fhem und Perl bist.

Das Ganze ist auf meine Fhem-Konfiguration zugeschnitten mit einigen Sonderlocken...
D.h. es kann nicht einfach verwendet werden und dient nur als Inspiration.
Ich werde es natürlich vorher um die Sonderlocken bereinigen.
Raspi 3b mit Raspbian Bullseye und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

DerITler


frober

Das notify ist simpel:
defmod n_Beschattung notify Sonnenstand:azimuth:.* {beschattung()}Sonnenstand ist mein Twilight-Device, beschattung() die Sub die in MyUtils aufgerufen wird.

Die Temperaturdifferenz wird über userReadings direkt im Device (bei mir ein Dummy) berechnet.

Für den Vergleich der Uhrzeit benutze ich eine separate Sub:
sub CalculateTime()
{
  return strftime("%H%M", localtime()); # 1528 -> ohne Doppelpunkt, zum Vergleichen
}

und hier die eigentliche Sub:
sub beschattung {

  # debug
  my $logging = 0;

  # definition von azimuth pro Himmelsrichtung (Ausgerichten an Ost = Schlafzimmer, Sued = Küche, West = Esszi, Nord = Wohnzi)
  my $RolloOstZu =  10; #  -6° ??
  my $RolloOstAuf = 127; # 127°
  my $RolloSuedZu =  82; #  82°
  my $RolloSuedAuf = 220; # 214°
  my $RolloWestZu = 162; # 162°
  my $RolloWestAuf = 286; # 318°
  my $RolloNordZu = 251; # 251°
  my $RolloNordAuf = 286; # 360° ??
 
  # Definition der Grenzwerte
  my $pctDiff =  8; # Differenz, wann die Rollos an die Sonnenhöhe angepasst werden
  my $BeschGrenze = 20; # Tempdiff, Grenze für Beschattung
  my $maxRolloClose = 15; # maximale Beschattung (Rillen offen)
  my $SonnenHoeheMin=  5; # minimale Sonnenhöhe, wo die Berechnungern ausgeführt werden
     
  # Zustand der Rolladen (auf/zu)
  my $RolloOst = ReadingsVal('MQTT2_Rollo_WC','state',100);
  my $RolloSued = ReadingsVal('MQTT2_Rollo_Kueche_Sued','state',100);
  my $RolloWestU = ReadingsVal('RolloWestUnten','state',100);
  my $RolloWestO = ReadingsVal('RolloWestOben','state',100);
  my $RolloNord = ReadingsVal('MQTT2_Rollo_Wohnzimmer','state',100);
  my $RolloSchlafzi = ReadingsVal('MQTT2_Rollo_Schlafzimmer','state',100);  # Schlafzimmer ganztags zu bei Sonne
 
  my $Sonnenstand = ReadingsNum('Sonnenstand','azimuth','err',1); # azimuth (0 = Nord, 180 = Süd)
  return debug('Sonnenstand konnte nicht gelesen werden') if ($Sonnenstand eq "err");
  my $Sonnenhoehe = ReadingsNum('Sonnenstand','elevation',0,1); # elevation (starten bei 20°, max. 60°)
  my $Beschattung = ReadingsNum('Sonnenstand','beschatten',1); # 1 = beschatten, 0 = nicht beschatten, ermitteln über Bewölkung, reading setzen und timestamp auswerten
  my $Tempdiff = ReadingsNum('SonnenTemp','TempDiff',0,1); # Differenz "Sonnentemp" - Lufttemp (Test bei 10°)
  my $Aussentemp = ReadingsNum('KS300','temperature',0,1); # Fahren ab 20°C Außentemeratur
  my $TuerWohn = 'zu'; # Fahren verhindern bei auf
  my $TuerEss = 'zu'; # Fahren verhindern bei auf
  my $Wohntemp = ReadingsNum('BME280','temperature',22); # Wohnraumtemperatur
  my $WohnT = 0; # Unter 21°C im Wohnraum nicht beschatten
  my $Badtemp = ReadingsNum('Bad','temperature',22); # Badtemperatur
  my $BadT = 0; # Unter 21°C im Bad RolloObenWest nicht beschatten
  my $cTime = CalculateTime();
  my $SonnenUnterg  = 0;
 
 
  if ($cTime >= 1900)
  {
    debug('Beschattung wurde aufgerufen', 'Test1.log') if $logging;
  }
 
 
  return if($Sonnenhoehe < $SonnenHoeheMin && $cTime < 900); # verhindert, dass Rollos zu früh am Morgen auf gehen
  # Bewölkung ermitteln
  if ($Sonnenhoehe >= $SonnenHoeheMin)
  {
  if ($Aussentemp >= 27) # bei hohen Aussentemperaturen wird die Tempdiff kleiner, daher wird die Grenze herabgesetzt (alt Temp = 27, Diff = 16/13)
{
  $BeschGrenze = 13;
  }
  if ($Aussentemp <= 19) # bei niedrigen Aussentemperaturen (alt = 20°) wird die Tempdiff größer, daher wird die Grenze hoch gesetzt
{
  $BeschGrenze = 25;
  }
if ($cTime < 940)         # vor 09:40 Uhr Tempdiff auf 15 setzen, damit die Verschattung im Schlafzimmer rechtzeitig funktioniert
{
  $BeschGrenze = 11;
  }
if ($Sonnenhoehe <= 16 && $cTime > 1930)
{
    $SonnenUnterg = 1;
debug("Sonnenuntergang aktiv") if $logging;
}
if ($Aussentemp > 30 && $Tempdiff >= $BeschGrenze && $Beschattung != 2 && $SonnenUnterg != 1)
{
$Beschattung = 2;       # alle Fenster beschatten (Wärmestrahlung)
fhem('setreading Sonnenstand beschatten 2');
debug("Beschattung aktiviert (Tempdiff)") if $logging;
}
  elsif ($Aussentemp <= 30 && $Tempdiff >= $BeschGrenze && $Beschattung != 1 && $SonnenUnterg != 1)
{
$Beschattung = 1;       # nur Fester mit direkter Sonneneinstrahlung beschatten
fhem('setreading Sonnenstand beschatten 1');
debug("Beschattung aktiviert (Tempdiff)") if $logging;
}
elsif ($Tempdiff < $BeschGrenze && $Beschattung != 0 || $SonnenUnterg == 1)
{
$Beschattung = 0;
fhem('setreading Sonnenstand beschatten 0');
debug("Beschattung deaktiviert (Tempdiff)") if $logging;
}
  }
  my $EinstrahlZeit = ReadingsAge('Sonnenstand','beschatten',0); # bewölkt seit in sek.
 
 
  # Bei Sonnenschein länger als xxx und Sonnenstand öffnen, bzw. schließen
  if ($Sonnenhoehe >= $SonnenHoeheMin && $Beschattung == 1 && $EinstrahlZeit > 120) {
   
my $pct = int(0.5 + $Sonnenhoehe - 25); # anpassung des Beschattungswinkels (bei 60° Sonnenhöhe -> Rolladen 50% geschlossen)
if ($pct < $maxRolloClose) {$pct = $maxRolloClose}; # Rolladen nicht ganz zu fahren (Rillen noch offen)
my $pct1 = $pct - 15; # Beschattungswert für Rolladen oben (höhere Fenster)
if ($pct1 < 15) {$pct1 = 15}; # RolladenOben nicht ganz zu fahren (Rillen noch offen)

if ($Wohntemp >= 21) {$WohnT = 1;} # nur fahren wenn Wohntemperatur größer 21°C ist -> vereinfachte Schreibweise (if $WohnT)
if ($Badtemp  >= 21) {$BadT  = 1;} # nur fahren wenn Badtemperatur größer 21°C ist  -> vereinfachte Schreibweise (if $BadT)
   
if ($Sonnenstand > $RolloOstZu && $Sonnenstand < $RolloOstAuf)
{
if ($pct > $RolloOst + $pctDiff || $pct < $RolloOst - $pctDiff)
{
fhem("set MQTT2_Rollo_WC pct $pct");
debug("Rolladen WC wird auf $pct% _ZU_ gefahren") if $logging;
$selectlog = 1;
}
}
elsif ($Sonnenstand > $RolloOstAuf)
{
if ($RolloOst != 100)
{
fhem('set MQTT2_Rollo_WC pct 100');
debug('Rolladen WC wird _AUF_ gefahren') if $logging;
}
}
if ($Sonnenstand > $RolloOstZu && $Sonnenstand < $RolloWestAuf)  # Rollo Schlafzimmer ganztags zu, wenn Sonne scheint
{
my $Urlaub = 0;
if (IsWe() && $cTime <= 800) {$Urlaub = 1;}
if ($RolloSchlafzi != 15 && $Urlaub == 0)
{
fhem('set MQTT2_Rollo_Schlafzimmer pct 15');
debug('Rolladen Schlafzimmer wird auf 15% _ZU_ gefahren') if $logging;
$selectlog = 1;
}
}
elsif ($Sonnenstand > $RolloWestAuf)
{
if ($RolloSchlafzi != 100)
{
fhem('set MQTT2_Rollo_Schlafzimmer pct 100');
debug('Rolladen Schlafzimmer wird _AUF_ gefahren') if $logging;
}
}
if ($Sonnenstand > $RolloSuedZu && $Sonnenstand < $RolloSuedAuf)
{
if ($pct > $RolloSued + $pctDiff || $pct < $RolloSued - $pctDiff)
{
fhem("set MQTT2_Rollo_Kueche_Sued pct $pct") if $WohnT; # nur schließen, wenn es im Wohnraum mehr als 21°C sind
debug("Rolladen Sued wird auf $pct% _ZU_ gefahren") if $logging && $WohnT;
$selectlog = 1 if $WohnT;
}
}
elsif ($Sonnenstand > $RolloSuedAuf)
{
if ($RolloSued != 100)
{
fhem('set MQTT2_Rollo_Kueche_Sued pct 100');
debug('Rolladen Sued wird _AUF_ gefahren') if $logging;
}
}
if ($Sonnenstand > $RolloWestZu && $Sonnenstand < $RolloWestAuf)
{
if ($pct > $RolloWestU + $pctDiff || $pct < $RolloWestU - $pctDiff)
{
fhem("set RolloWestUnten pct $pct") if $WohnT; # nur schließen, wenn es im Wohnraum mehr als 21°C sind
debug("Rolladen West unten wird auf $pct% _ZU_ gefahren") if $logging && $WohnT;
$selectlog = 1 if $WohnT;
}
if ($pct1 > $RolloWestO + $pctDiff || $pct1 < $RolloWestO - $pctDiff)
{
fhem("set RolloWestOben pct $pct1") if $BadT; # nur schließen, wenn es im Bad mehr als 21°C sind
debug("Rolladen West oben wird auf $pct1% _ZU_ gefahren") if $logging && $BadT;
$selectlog = 1 if $BadT;
}
}
elsif ($Sonnenstand > $RolloWestAuf)
{
if ($RolloWestU != 100)
{
fhem('set RolloWestOben pct 100');
debug('Rolladen West wird _AUF_ gefahren') if $logging;
}
}
if ($Sonnenstand > $RolloNordZu && $Sonnenstand < $RolloNordAuf)
{
if ($pct > $RolloNord + $pctDiff || $pct < $RolloNord - $pctDiff && $WohnT == 1) # nur schließen, wenn es im Wohnraum mehr als 21°C sind 
{
if ($TuerEss ne 'offen') {fhem("set MQTT2_Rollo_Esszi_Nord pct $pct")};   # nicht fahren bei geöffneter Terrassentür ->Im Shelly shedule ausschalten!
if ($TuerWohn ne 'offen') {fhem("set MQTT2_Rollo_Wohnzimmer pct $pct")};  # nicht fahren bei geöffneter Terrassentür ->Im Shelly shedule ausschalten!
debug("Rolladen Nord wird auf $pct% _ZU_ gefahren") if $logging;
$selectlog = 1;
}
}
elsif ($Sonnenstand > $RolloNordAuf)
{
if ($RolloNord != 100)
{
fhem('set RolloNord pct 100');
debug('Rolladen Nord wird _AUF_ gefahren') if $logging;
}
}
debug("Azimuth = $Sonnenstand, Sonnenhoehe = $Sonnenhoehe, Temp = $Aussentemp, Ost = $RolloOst, Sued = $RolloSued, West = $RolloWestU, Nord = $RolloNord, Beschgr = $BeschGrenze, Tempdiff = $Tempdiff, Sonne scheint $Beschattung seit $EinstrahlZeit s") if $logging;
debug("PCT = $pct%, PCT1 = $pct1%, Wohntemp = $Wohntemp, WohnT = $WohnT, Badtemp = $Badtemp, BadT = $BadT") if $logging;
return;
  }
 
  # Bei Aussentemperatur von > 30°C alle Fenster beschatten (Wärmestrahlung)
  if ($Sonnenhoehe >= $SonnenHoeheMin && $Beschattung == 2 && $EinstrahlZeit > 120) {
   
my $pct = $maxRolloClose;    # RolladenOben nicht ganz zu fahren (Rillen noch offen)

if ($Sonnenstand > $RolloOstZu && $Sonnenstand < $RolloNordAuf)
{
fhem("set RolloAlle pct $pct");
debug("Alle Rolladen werden auf $pct% _ZU_ gefahren") if $logging;
$selectlog = 1;
}

debug("Azimuth = $Sonnenstand, Sonnenhoehe = $Sonnenhoehe, Temp = $Aussentemp, Ost = $RolloOst, Sued = $RolloSued, West = $RolloWestU, Nord = $RolloNord, Beschgr = $BeschGrenze, Tempdiff = $Tempdiff, Sonne scheint $Beschattung seit $EinstrahlZeit s") if $logging;
debug("PCT = $pct%, Wohntemp = $Wohntemp, WohnT = $WohnT, Badtemp = $Badtemp, BadT = $BadT") if $logging;
return;
  }
 
  return if ($RolloOst == 100 && $RolloSued == 100 && $RolloWestU == 100 && $RolloNord == 100);
 
  # bei Bewölkung länger als x * 5 Min wieder öffen oder nach 19:00 wenn Sonne tiefer als 6° steht
  if ($Sonnenhoehe > $SonnenHoeheMin && $Beschattung == 0 && $EinstrahlZeit > 800 || $Sonnenhoehe <= $SonnenHoeheMin && $Sonnenhoehe > 0 && $cTime > 1900) {
   
  debug("Uhrzeit = $cTime, Sonnenhoehe = $Sonnenhoehe, Azimut = $Sonnenstand, Temp = $Aussentemp, Beschgr = $BeschGrenze, Tempdiff = $Tempdiff, Sonne scheint $Beschattung seit $EinstrahlZeit s") if ($logging);

if ($RolloOst != 100)
{
fhem('set MQTT2_Rollo_WC pct 100');
debug('Rolladen WC wird _AUF_ gefahren') if $logging;
}
if ($RolloSchlafzi != 100)
{
fhem('set MQTT2_Rollo_Schlafzimmer pct 100');
debug('Rolladen Schlafzimmer wird _AUF_ gefahren') if $logging;
}
if ($RolloSued != 100)
{
fhem('set MQTT2_Rollo_Kueche_Sued pct 100');
debug('Rolladen Sued wird _AUF_ gefahren') if $logging;
}
if ($RolloWestU != 100)
{
fhem('set RolloWestOben pct 100');
debug('Rolladen West wird _AUF_ gefahren') if $logging;
}
if ($RolloNord != 100)
{
fhem('set RolloNord pct 100');
debug('Rolladen Nord wird _AUF_ gefahren') if $logging;
}
return;
  }
return; 
}
leider verschiebt sich teilweise die Einrückung beim posten...


Einige Sonderlocken habe ich drin gelassen...
Wenn $logging auf 1 gesetzt ist, werden die debug-Meldungen ins Fhem-Log geschrieben.
Die Sub dient nur zur Beschattung, morgens und abends fahren die Rollladen autark.
Es wird auch nur beschattet, wenn die Heizung aus (habe ich eigentlich im notify) und eine gewisse Raumtemperatur erreicht ist.
Die Rollladen sind zum Teil in einer structure zusammengefasst, werden aber auch teilweise einzeln angesteuert.
Die Beschattungshöhe wird je nach Fensterhöhe angepasst, so dass überall der "gleiche" Spalt offen ist, bzw. keine Sonne rein scheint.
Die Rollladen werden nur bei einer Mindestveränderung verfahren. Somit wird das "Tanzen" vermindert. 

Viel Spaß damit  ;)

Da ich es hier veröffentliche, nochmal der Hinweis:
Der Code dient rein als Inspiration und ist so nicht verwendbar, da er auf mein Haus/meine Fhem-Konfiguration maßgeschneidert ist!!!
Raspi 3b mit Raspbian Bullseye und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...