Hi!
Bisher habe ich meine Perl-Probleme ganz gut selber hinbekommen.
Hier muss ich die Community mum Rat bitten.
definiert ist folgendes:
(myTL ist das Twillight-define)
Ich werte die berechnete Lichtstärke zur Steuerung der Rollläden
Rollladenpositionen sind Auf(on), 1%(=zu); im Log sind beide zustände eingetragen
define n_Rollladen notify myTL {\
my $L = ReadingsVal("myTL","light","5");;\
my $RF = Value("Rollladen_Flur");;\
if (($L >= 6) && (($RF ne "on"))){\
Log 1,"Rollladen auf...bei Lichtstärke: $L und Pos.Rollladen_Flur: $RF ";;\
fhem("set Rollladen_EG Auf;;set Rollladen_Flur Auf");;}\
elsif (($L <= 3) && (($RF ne "1 %")|| ($RF = "Set_1"))){\
Log 1, "Rollladen schliessen...bei Lichtstärke: $L und Pos.Rolll_Flur:$RF,";;\
fhem("set Rollladen_EG 1;;set Rollladen_Flur 1");;
}
trotzdem kommt ständig der Befehl zum senken der Rolläden (1%) bzw. set_1, obwohl die if-Abfrage nicht erfüllt wird:
2013.02.15 20:49:36 1: Rollladen schliessen...bei Lichtstärke: 0 und Pos.Rolll_Flur:set_1,
2013.02.15 20:49:36 2: CUL_HM set Rollladen_EG 1 rxt:1
2013.02.15 20:49:36 2: CUL_HM set Rollladen_Flur 1 rxt:1
2013.02.15 20:49:36 1: Rollladen schliessen...bei Lichtstärke: 0 und Pos.Rolll_Flur:set_1,
2013.02.15 20:49:36 2: CUL_HM set Rollladen_EG 1 rxt:1
2013.02.15 20:49:36 2: CUL_HM set Rollladen_Flur 1 rxt:1
2013.02.15 20:49:36 1: Rollladen schliessen...bei Lichtstärke: 0 und Pos.Rolll_Flur:set_1,
2013.02.15 20:49:36 2: CUL_HM set Rollladen_EG 1 rxt:1
2013.02.15 20:49:36 2: CUL_HM set Rollladen_Flur 1 rxt:1
Wo liegt hier der Fehler???
MfG, MisterEltako
Lichtstärke in Twillightwert ist keine richtige Lichtstärke, sondern ein Wert für den Horizont, den die Sonne erreicht hat:
0 - total night, sun is at least -18 degree below horizon
1 - astronomical twilight, sun is between -12 and -18 degree below horizon
2 - nautical twilight, sun is between -6 and -12 degree below horizon
3 - civil twilight, sun is between 0 and -6 degree below horizon
4 - indoor twilight, sun is between the indoor_horizon and 0 degree below horizon (not used if indoor_horizon=0)
5 - weather twilight, sun is between indoor_horizon and a virtual weather horizon (the weather horizon depends on weather conditions (optional)
6 - maximum daylight
Der Wert verändert sich im Laufe des Tages von 0(Sonne steht bei -18 Grad) über 1 2 3 4 5 6 5 4 3 2 1 0 und gibt immer den Sonnenstand an. Im Sommer werden in Norddeutschland manche Werte(-18 Grad) nicht erreicht.
Problematisch ist aus meiner Sicht "weather twilight". Der Wert wird aus dem Sonnenstand 0 Grad plus ein virtueller Wetterfaktor ermittelt. Dazu wird im Modul alle 900 Sekunden !!!!! das Wetter von yahoo geholt und eingerechnet. Ich bin der Meinung, dass so wie es umgesetzt ist, es nicht ganz richtig ist, so dass immer ein ganz merkwürdiger Wert herauskommt.
Deine Rolladen werden deshalb so oft "geschlossen", weil das Modul twilight viele Ereignisse feuert. Mit
define lichtwechsel notify Twilight {Log 3, "Nachricht von @: %" }
kannst du überprüfen welche Ereigisse es so liefert.
Du mußt Dir dann das von Dir benötigte Ereigniss heraussuchen.
Beispiel:
define lichtwechsel notify Twilight:(nextUpdate.*|light.*) {Log 3, "Nachricht von @: %" }
Hi!
Danke für die ausführliche Erklärung. So habe ich das mit dem Sonnenstand bisher nicht gesehen. Schade, das sowas nicht ausführlicher in der Doku erklärt ist (oder ich habe es nicht gefunden ;o))
Ich habe den Code nochmals etwas verändert:
define n_Rollladen notify myTL {\
my $Licht = ReadingsVal("myTL","light","5");;\
my $RollFl = Value("Rollladen_Flur");;\
my $Temp_erw = ReadingsVal("Local_Wetter","fc1_low_c","999");;\
if (($Licht >= 6) && (("$RollFl" ne "on")||("$RollFl" ne "set_Auf"))){\
Log 1,"Rollladen auf...bei Lichtstärke: $Licht und Pos.Rollladen_Flur: $RollFl ";;\
fhem("set Rollladen_EG Auf;;set Rollladen_Flur Auf");;}\
elsif (($Licht <= 3) && (($RollFl ne "1 %")||($RollFl ne "set_1"))){\
Log 1, "Rollladen schliessen...bei Lichtstärke: $Licht und Pos.Rolll_Flur:$RollFl bei $Temp_erw°C";;\
if (($Temp_erw > 0) && ($Licht<=3)){\
fhem("set Rollladen_EG 1;;set Rollladen_Flur 1");;}\
elsif (($Temp_erw < 1) && ($hour == 22) && ($RollFl ne "5 %")) {\
fhem("set Rollladen_EG 15;;set Rollladen_Flur 5");;}\
}\
}
Also liegt das Problem an:
if (($Licht >= 6) && (("$RollFl" ne "on")||("$RollFl" ne "set_Auf"))){\
2013.02.16 10:42:40 1: Rollladen auf...bei Lichtstärke: 6 und Pos.Rollladen_Flur: on
2013.02.16 10:42:40 2: CUL_HM set Rollladen_EG on rxt:1
2013.02.16 10:42:40 2: CUL_HM set Rollladen_Flur on rxt:1
2013.02.16 10:43:24 1: Rollladen auf...bei Lichtstärke: 6 und Pos.Rollladen_Flur: on
2013.02.16 10:43:24 2: CUL_HM set Rollladen_EG on rxt:1
2013.02.16 10:43:24 2: CUL_HM set Rollladen_Flur on rxt:1
D.h. ((6 >= 6) && (( on ne on) || (on ne "set_Auf"))){\
Bedingung1=Ergebnis:wahr und (Bedingung2=Ergebnis:nicht wahr oder Bedingung3=Ergebnis:wahr) ---> führt trotzdem zum Ausführen von {Rollladen schließen}
Meiner Meinung nach dürfte es doch nicht ausgeführt werden. Da muss irgendwie mein Fehler liegen....
MfG, MisterEltako
Hi!
Ich habe es jetzt mit "&&" statt "||" versucht, das scheint der Fehler gewesen zu sein. Mal sehen ob die Rollläden jetzt überhaupt schalten.... ;0)
D.h. ((6 >= 6) && (( on ne on) && (on ne "set_Auf"))){\
Bedingung1=Ergebnis:wahr und (Bedingung2=Ergebnis:nicht wahr und Bedingung3=Ergebnis:wahr) ---> jetzt kein Ausführen von {Rollladen schließen}
MfG, MisterEltako.
Ich denke $RollFl wird nicht richtig gefüllt sein. Man muss doch immer den ReadingsVal state und einen default wert oder so angeben.
Beim ersten ReadingsVal hast du jedenfalls light angegeben.
Ich wuerde beim notify regexp weiter einschränken.
Lass dir mal so über den Tag die events von Twilight ausgeben. Du wirst dich wundern wie oft es feuert.
Ich mag tw nicht.
Noch eine Ergänzung:
Sunrise_el ist besser.
Hi!
Heute Nachmittag blieben die Rollläden oben statt zu schließen...
@Dietmar63
Ich dachte Twillight ist genauer, aber Tendenz ist eigentlich zum Weather-Modul (wenn das noch die auf der Yahoo-Seite unter Details aufgeführten Sonnenaufgangs- und Sonnenuntergangszeitem anzeigen würde....)
So, nach endlos erscheinendem Ausprobieren habe ich mit meiner Version eine funktionierende Lösung gefunden. Ich traue der Sache noch nicht ganz, aber bin guter Hoffnung, dass das nun klappt.. ;o)
define n_Rollladen notify myTL.light.* {\
my $Licht = ReadingsVal("myTL","light","5");;\
my $RollFl = Value("Rollladen_Flur");;\
my $Temp_erw = ReadingsVal("Local_Wetter","fc1_low_c","999");;\
Log 1, "Lichtstärke: $Licht ,RollladenFlur: $RollFl, Temperatur: $Temp_erw°C";;\
if (($Licht >= 6) && ("$RollFl" eq "on")&&("$RollFl" ne "set_Auf")){\
Log 1,"Rollladen auf...";;\
fhem("set Rollladen_EG Auf;;set Rollladen_Flur Auf");;}\
elsif (($Licht <= 3) && ($RollFl != 1 %) && ("$RollFl" ne "set_1")){\
if (($hour != 22) && ($Temp_erw >= 1) && ($RollFl != 1 %) && ("$RollFl" ne "set_1")){\
Log 1, "Rollladen schliessen...";;\
fhem("set Rollladen_EG 1;;set Rollladen_Flur 1");;}\
elsif (($hour == 22) && ($Temp_erw < 1) && ($RollFl != 5 %) && ("$RollFl" ne "set_5")){\
Log 1, "Rollladen in Frostschutzstellung fahren...";;\
fhem("set Rollladen_EG 15;;set Rollladen_Flur 5");;}\
}\
}
Nach ersten Erkenntnissen lag es an ($RollFl ne "1 %"), da $RollFl auch "on" oder "set_1" oder "set_5" annehmen kann, dachte ich an einen Stringvergleich.
Richtig ist hier 2 Abfragen zu machen ($RollFl != "1 %") und z.B.("$RollFl" ne "set_1") --> da muss man erst Mal darauf kommen !!!!!
MfG, MisterEltako.
wenn du das hier: ### sunrise / sunset
if ($tag eq "yweather:astronomy" ) {
$value =~/sunrise="([0-9:.]*?) (..)" .*sunset="([0-9:.]*?) (..)".*/;
if ($1) { readingsBulkUpdate($hash, "sunrise", h2hms_fmt(hms2h($1))); }
if ($3) { readingsBulkUpdate($hash, "sunset", h2hms_fmt(hms2h($3)+12)); }
}
z.b. ab zeile 312 in 59_Weather.pm einbaust hast du deinen sonnen auf und untergang.
gruss
andre
@justme1968
Dazu kann ich nur sagen: genial!!!!!
Vielen Dank!
Wie kommt man nur an solche Info's? Ich hoffe ich bin irgendwann auch selbst in der Lage so etwas herauszufinden!
Das hilft mir sehr weiter. Jetzt fliegt erstmal Twillight raus und Weather wird ausgebaut....
MfG, MisterEltako.
Wenn es funktioniert sollten wir es einchecken, sonst ist es beim nächsten Update wieder futsch!
Wie wendet man bei TWILIGHT den indoor_horizon denn praktisch an? Gibt´s da gute Beispiele oder lässt man ihn am besten auf 0, wenn man im Flachland wohnt?
Ich meine die Angabe zum indoor_horizon wird im Modul so verwendt, dass er bei der Berechnung des jeweiligen SonnenAuf- bzw. Sonnenuntergangs auf den Horizont aufgeschlagen wird, so dass im Falle des Beispiels unten nicht mit 0° sondern jeweils mit 3° gerechnet wird. Dadurch wird dann der Zeitpunkt des Sonnenuntergangs etwas früher errechnet.
Die Idee, die dahintersteckt ist, dass tief in einem Häusermeer die Untergänge etwa früher sind.
define Twilight Twilight 52.44944 11.00512 3 12833399
define lichtwechsel notify Twilight:(nextUpdate.*|light.*) {Log 3, "Nachricht von @: %" }
hier ist übrigens eine Beschreibung wie Twilight ursprünglich auf einer CCU(HM) gedacht war:
http://www.homematic-wiki.info/mw/index.php/TCLScript:twilight (//%5Burl=www.homematic-wiki.info/mw/index.php/TCLScript:twilight)][/url]
Die Übertragung nach FHEM enthält leider noch einige kleine Fehler.
mit ist noch nicht ganz klar wie Twilight in Verbindung mit den WetterDaten funktioniert.
ZurZeit (13Uhr) ist es draußen total regnerisch und bewölkt -> keine Sonne. Wird auch auf YahooWetter angezeigt.
Trotzdem gibt Twilight den Faktor 6 aus, also volle Lichtintensität.
Schlussendlich benötige ich den Sonneneinfallswinkel um die Rolläden auf einen bestimmten Prozentsatz herunter/ oder wieder hochzufahren. Kann das Twilight auch? Bzw ist der Sonneneinfallswinkel intern schon ermittelt und muss nur über ein neues Reading herausgeführt werden?
Ob am Ende wirklich Sonne ist bekomme ich von einem Lichtsensor.
Ich habe mich mal mit Twilight intensiv beschäftigt und folgendes herausgefunden:
die "normalen" sunset/sunrise Zeiten(0°, -6°, -12°, -18°) werden fast identisch wie in sunset_el berechnet.
Das Verfahren ist etwas anders, deshalb sind die Zeiten nicht exakt gleich(Abweichung ca. 5 Minuten).
sr_weather bzw. ss_weather werden mit (0° + wetterfaktor) berechnet, der vom YahooWetter code abeleitet wird.
Bei starker Bewölkung sind das +6°, so dass die Ereignisse entsprechend später/früher (40 Minuten) eintreten. 1° entspricht etwa 7 Minuten.
Der Indoor_Horizon legt nocheinmal n° drauf, so dass man zusätzlich eine Häuerschlucht oder einen Schatten werfenden Baum simulieren kann.
Der light-Wert gibt einfach nur an in welchem Horizontbereich sich die Sonne im Moment befindet:
>(ss_weather) ==>6
<(ss_weather°) ==>5
<(indoor°) ==>4
<( 0°) ==>3,
<( -6°) ==>2,
<(-12°) ==>1,
<(-18°) ==>0
Wenn also der wetterfaktor 10° beträgt, dann ist ss_weather auf 10° berechnet also ca. 70 Minunten vor dem Sonnenuntergang 0°.
Bis 70 Minunten vor dem Sonnenuntergang 0° ist der light-Wert 6.
Es gibt irgendwo hier von Puschel74 eine Grafik, die das gut wiedergibt:
Link (http://forum.fhem.de/index.php?topic=11277.msg70615#msg70615)
wetterfaktor = (YahooWetter code)0 (tornado) wird mit 25° berechnet - recht hoch.
Weil mir die Korrekturwerte zu hoch waren, multipliziere ich sie mit einen Faktor kleiner 1, der mir vernünftigere Werte für ss_weather liefert.
wetterfaktor in Twilight:
310 my @a_current = (25,25,25,25,20,10,10,10,10,10,10, 7,
311 7, 7, 5,10,10, 6, 6, 6,10, 6 ,6, 6,
312 6, 6, 6, 5, 5, 3, 3, 0, 0, 0, 0, 7,
313 0,15,15,15, 9,15, 8, 5,12, 6, 8, 8);
Sonneneinfallswinkel werden nicht berechnet.
Vielleicht kann man die im Code versteckte Formel umstellen und den Einfallswinkel zum Zeitpunkt zu x berechnen.
Diese Beschreibung müßte man nur und Perl umsetzen: https://de.wikipedia.org/wiki/Sonnenstand (//de.wikipedia.org/wiki/Sonnenstand)
Mit dem enhaltenen Beispiel sollte das ein Kinderspiel sein.
yahoo-weather-condition-codes:
https://gist.github.com/bzerangue/805520 (//gist.github.com/bzerangue/805520)
puh, das ist schon heftig mit der Formel für den Sonnenstand.
Aber vielleicht hilft das hier ja weiter: http://ww3.cad.de/cgi-bin/ubb/postings.cgi?action=printpost&forum=Lisp&number=145&topic=000485.cgi&ReplyNum=000013&TopicSubject=sonnenstandsberechnung (//ww3.cad.de/cgi-bin/ubb/postings.cgi?action=printpost&forum=Lisp&number=145&topic=000485.cgi&ReplyNum=000013&TopicSubject=sonnenstandsberechnung)
Vielleicht kann man das ja benutzen um den Sonnenstand zu bestimmten Uhrzeiten zu bestimmen und danach die Rollläden zu steuern.
Gruß
Christian
Eine Lösung wäre vielleicht mit sunrise_abs(20) bzw sunset_abs die Zeiten zu errechnen, wann die Sonne die 20° am Himmel überschritten hat und dann regelmäßig bei Sonnenschein das Rollo schalten.
Das funktioniert mit existierenden Mitteln.
Ob 20° der richtige Wert ist, müßte man probieren.
ich habe mal soeben probiert:
{sunrise_abs ("HORIZON=45")} liefert 10:29:45.
{sunset_abs ("HORIZON=45")} liefert 16:04:07
Heute hätte die Sonne um 10:29:45 hier in Hannover die Sonne die 45° Marke überschritten.
Um 16:04:07 wäre sie wieder unter die 45° Marke gefallen.
Leider war es nicht sonnig!
Ich denke die Höhe der Sonne geht über Sunrise.
Ich dachte aber auch noch an den Azimuth zu bestimmten Zeiten zwecks Beschattung. Und das wird mit Sunrise nicht mehr gehen.
Gruß
Christian
man könnte als einfache Lösung zum Zeitpunkt
{sunrise_abs ("HORIZON=45")} also heute so gegen 10:29:45 ein at-Kommando starten, dass alle 5 oder 10 Minuten einen Lichtsensor auswertet. Wenn Sonne, dann beschatten, wenn keine Sonne dann Rollo zurückfahren.
define BeschattunsSteuerung at *{sunrise_abs ("HORIZON=45")} define prüfer at +*00:10:00 {prüfeSonnenschein()}
Das zweite at muss man jezt noch wieder los werden. Eventuell mit einem Zähler im zweiten at.
define BeschattunsSteuerung at *{sunrise_abs ("HORIZON=45")} define prüfer at +*{15}00:10:00 {prüfeSonnenschein()}
Zitat von: Dietmar63 schrieb am Mi, 22 Mai 2013 18:41Eine Lösung wäre vielleicht mit sunrise_abs(20) bzw sunset_abs die Zeiten zu errechnen, wann die Sonne die 20° am Himmel überschritten hat und dann regelmäßig bei Sonnenschein das Rollo schalten.
Das funktioniert mit existierenden Mitteln.
Ob 20° der richtige Wert ist, müßte man probieren.
ich habe mal soeben probiert:
{sunrise_abs ("HORIZON=45")} liefert 10:29:45.
{sunset_abs ("HORIZON=45")} liefert 16:04:07
Heute hätte die Sonne um 10:29:45 hier in Hannover die Sonne die 45° Marke überschritten.
Um 16:04:07 wäre sie wieder unter die 45° Marke gefallen.
Leider war es nicht sonnig!
ich meine es genau anders herum. Twilight aktualisiert seine Werte alle 10min. Also ist die Zeit fix und der Sonneneinfallswinkel durch die Zeit variabel. Damit soll am Ende gesteuert werden wie weit die Rollanden herunter fahren sollen. Ob sie überhaupt herunterfahren sollen bestimmt ein externer Licht-/Sonnensensor.
Twilight ermittelt übrigens hier in Norddeutschland im Moment keine Werte für sr-/ss_astro (-18°).
Die Sonne sinkt nicht mehr so tief unter den Horizont.
Der Wert für light erreicht somit auch nicht den Wert 0.
Im Süden ist das zur Zeit noch anders.
(siehe Anhang / see attachement)
PS: Ich verwende eine geänderte Version von TW, deshalb sieht man mehr Readings.
Ich habe mich jetzt mal selbst beigemacht und eine kleine Berechnugsprozedur geschrieben. IMHO sollte die nach 99_SUNRISE_EL integriert werden
use Math::Trig;
##########################################
# Prozedur berechnet den Stand der Sonne
# Parameter:
# keine
# Rückgabewert:
# Höhe der Sonne in °Grad
#
# Quelle: http://www.jgiesen.de/SME/tk/
##########################################
sub
sonnenstand() {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $K=pi/180;
############################
# If set in global, use longitude/latitude
# from global, otherwise set Berlin/Germany as
# default
my $long = AttrVal("global", "longitude", "13.41");
my $lat = AttrVal("global", "latitude", "52.51");
my $deklin = -23.45*cos($K*360*($yday+10)/365);
my $zeitgleichung = 60*(-0.171*sin(0.0337*$yday + 0.465) - 0.1299*sin(0.01787*$yday - 0.168));
my $stundenwinkel = 15*($hour + $min/60 - (15.0-$long)/15.0 - 12 + $zeitgleichung/60);
my $x = (sin($K*$lat)*sin($K*$deklin)) + (cos($K*$lat)*cos($K*$deklin)*cos($K*$stundenwinkel));
my $hoehe = asin($x)/$K;
my $y = -(sin($K*$lat)*sin($K*$hoehe) - sin($K*$deklin)) / (cos($K*$lat)*sin(acos(sin($K*$hoehe))));
my $azimut = acos($y)/$K;
$azimut = 360 - $azimut if($y<0);
#return "deklin: $deklin, zeitgleichung: $zeitgleichung, Stundenwinkel: $stundenwinkel, Höhe: $hoehe , Azimut: $azimut";
#return "Höhe: $hoehe , Azimut: $azimut";
return $hoehe;
}