Lichtsteuerung Sonnenaufgang Sonnenuntergang

Begonnen von Ingooooo, 24 November 2018, 02:48:42

Vorheriges Thema - Nächstes Thema

Ingooooo

Hallo,

bei mir geht es und eine Lichsteuerung.
Fhem läuft bei mir auf dem Pi. Daran ist ein PCA9685 inkl. Endstufen angeschlossen(16 PWM Kanäle).

Mein Vorhaben ist, dass zum Morgen das Licht langsam hochgefahren wird und zum Abend langsam runtergefahren wird.
Die Werte zum Berechnen werden vom Modul Twilight genommen.

Ich benutze den prozentualen Wert "twilight".
Zur Berechnung benutze ich folgenden Befehl:
+*00:01:00 set PWM Port00 {(ReadingsVal("myTwilight2","twilight",0) * 4000 / 100 )}

Leider funktioniert bei mir das Runden nicht, deswegen benutze ich den Wert "4000" anstatt "4095".
Somit entsteht keine Kommazahl, damit kann der PCA angesteuert werden.

Vielleicht kann mir jemand einen eleganteren Weg zeigen.



Der zweite Punkt ist, ich möchte den Sonnenaufgang und -untergang mit einem RGB LED Band simulieren.
Dieses hängt auch am PCA.
Es soll das Morgenrot beim Sonnenaufgang  und am Abend das Abendrot enthalten.


Wie ich das machen soll, habe ich noch keine Idee.



Ich Hoffe, ihr könnt mir dabei helfen.


Gruß Ingo

CoolTux

#1

+*00:01:00 set PWM Port00 { int(ReadingsVal('myTwilight2','twilight',0) * 4095 / 100 ) }
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Ingooooo

Bekomme diese Meldung

2018.11.24 11:06:55 3: PWM_berechnen_Licht_1: Unknown argument Port00 { int(ReadingsVal('myTwilight2','twilight',0) * 4095 / 100 ) }, choose one of Port00:slider,0,1,4095 Port01:slider,0,1,4095 Port02:slider,0,1,4095 Port03:slider,0,1,4095 Port04:slider,0,1,4095 Port05:slider,0,1,4095 Port06:slider,0,1,4095 Port07:slider,0,1,4095 Port08:slider,0,1,4095 Port09:slider,0,1,4095 Port10:slider,0,1,4095 Port11:slider,0,1,4095 Port12:slider,0,1,4095 Port13:slider,0,1,4095 Port14:slider,0,1,4095 Port15:slider,0,1,4095 all:slider,0,1,4095

CoolTux


+*00:01:00 { fhem('set PWM Port00 ' . int(ReadingsVal('myTwilight2','twilight',0) * 4095 / 100)) }


Dann komplett in Perl.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Ingooooo

Vielen Dank dir, klappt jetzt.


Jetzt noch zum RGB, wie ich das machen kann.

Am besten wäre, wenn der Sonnenaufgang eine halbe Stunde vor "sr_naut" beginnen würde.

Die Farbwerte habe ich im Internet gefunden.(https://www.computerhilfen.de/info/sonnenaufgang-mit-alexa-fhem-und-philips-hue.html)
Die Werte sind aber in Hexadezimal, diese müssten dann in einen dezimalen Wert mit 12 Bit umgerechnet werden.

Ist sowas möglich?

Gruß Ingo

CoolTux

Zitat von: Ingooooo am 24 November 2018, 12:07:45
Vielen Dank dir, klappt jetzt.


Jetzt noch zum RGB, wie ich das machen kann.

Am besten wäre, wenn der Sonnenaufgang eine halbe Stunde vor "sr_naut" beginnen würde.

Die Farbwerte habe ich im Internet gefunden.(https://www.computerhilfen.de/info/sonnenaufgang-mit-alexa-fhem-und-philips-hue.html)
Die Werte sind aber in Hexadezimal, diese müssten dann in einen dezimalen Wert mit 12 Bit umgerechnet werden.

Ist sowas möglich?

Gruß Ingo

Möglich ist alles. Allerdings würde ich jetzt auch nur im Internet suchen wie das geht.
Also Perl Hex in dezimal 12 Bit.
Wobei ich die 12 Bit nicht verstehe. Kenne mich da aber auch nicht so aus.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

nanostrukturtechniker

Hallo,

das ist mein Sonnenaufgangsskript (der Link von vorhin ein bisschen abgeändert,). Durch die Gruppe kann man das Ganze auch bequem stoppen: Die Gruppe löschen und dann stoppt es...

Von 16 in 12 Bit umrechnen heißt einfach nur, die Nullen, die die Werte zwischen drin auffüllen rauszuschneiden:

https://www.oreilly.com/library/view/mastering-perl/9780596527242/ch16.html

Als alter C-ler kann ich da nur einen Link zu Perl schicken.


Das Ganze sieht so aus:

16 Bit - die ersten zwei Zahlen sind immer 0:

00123456 00123456

12 Bit:

123456 123456 - Die Nullen werden rausgeschnitten. Das geht mit den Shift Operatoren, die die Zahlen an die entsprechenden stellen schieben. Danach können sie ge-andet werden.

Wie gesagt - nur eine kurze Übersicht.

Viele Grüße

Jörg


Der Sonnenaufgan in 99_MyUtils.pm, Aufruf mit: Sonnenaufgang("LED_Schlafzimmer", ""); Im zweiten Parameter kann man noch einen Befehl angeben (z.B. set Rollladen on), dann geht im Anschluss noch der Rollladen auf


##########################################################
# Sonnenaufgang
# simuliert einen Sonnenaufgang mit RGB
# https://www.computerhilfen.de/info/sonnenaufgang-mit-alexa-fhem-und-philips-hue.html
sub Sonnenaufgang($$)
{
    my ($device, $finished) = @_;
    fhem("set ".$device." RGB 030100;");
    my @sonne = ('0B0300','190601','230902','2F0D03','370F03','401204','481405','521806','591007','622108','6E2508','772809','7F2A09','882D0A','90300A','96320A','9D330A','A6360A','B0390A','B0450A','B9480B','C1580B','CB610B','D3650C','D6740C','DC770B','DC810B','E5860B','ED8E12','F2A113','F2B013','F5B51A','F9BA22','FBBD29','FEC232','FFC742','FECC55','FED166','FDD473','FDD880','FEDD8C','FDDF97','FDE4A7','FDEABC','FDEEC8','FDF0D1','FDF3DA','FCF4E2');
    my $speed=15;
    my $i = 0;
    for($i = 0; $i < @sonne; $i++)
    {
        #Old call with sleep - will block FHEM!
        #fhem("sleep ".($i*$speed)."; set ".$device." RGB ".$sonne[$i]." ".$speed.";");
       
        #new call with At - no idea why we have to go over extra string?
        my $name="_AWLSZ" . $i;
        my $command="define ". $name. " at +" .  SecInTimespec($i*$speed). " set ".$device." RGB ".$sonne[$i]." ".$speed.";";
        fhem($command);
        $command="attr ". $name. " group _AWLSZ";
        fhem($command);
        $command="attr ". $name. " room Schlafzimmer";
        fhem($command);
    }
    Log 1, $i;
    if ($finished ne "") {
        #fhem("sleep ".(($i+1)*$speed).";".$finished.";")
        my $name="_AWLSZ_Final";
        my $command="define ". $name. " at +" .  SecInTimespec($i*$speed). " " . $finished .";";
        fhem($command);
        $command="attr ". $name. " group _AWLSZ";
        fhem($command);
        $command="attr ". $name. " room Schlafzimmer";
        fhem($command);   
    };
}

crusader

#7
Die Werte im @sonne-Array bestehen aus 3 Byte, jeweils eines für Rot, Grün und Blau.

Die musst Du für Deine drei PWM-Kanäle separieren und von 8bit auf 12bit umrechnen.

Rot:
my $PWM_R = (hex($sonne[$i]) >> 16 & 0xff) << 4

Rest erklärt sich für alte C-ler ja von allein  :D

Ingooooo

Guten Abend, habe garnicht mitbekommen, dass hier weiterhin geantwortet wurde.

Mit dem RGB stelle ich erstmal zurück.

Das Licht läuft soweit akzeptabel, aber noch nicht zufriedenstellend.
Es gibt sicherlich elegantere Wege.

Am besten wäre es, wenn man eine bestimmte Zeit eingeben kann, zu der das Dimmen anfangen bzw. enden soll und dann noch die Dimm Dauer.

Mein Ansatz momentan ist, dass ich zwei Werte habe.
"Ist_Licht" und "Soll_Licht"

Mit dem "Ist_Licht" sollen dann die PWM Kanäle angesteuert werden.

"Soll_Licht" ist der Sollwert, auf dem er aufgedimmt bzw. abgedimmt wird.


Das "Soll_Licht" soll dann über den Befehl at zur bestimmten Zeit gesetzt werden.


Nach meiner Vorstellung soll es wie folgt aussehen:
Ist_Licht>Soll_Licht dann Ist_Licht -1
Ist_Licht<Soll_Licht dann Ist_Licht +1
Ist_Licht=Soll_Licht dann soll nichts passieren

Habe damit ein wenig rumprobiert, aber komme da nicht voran.

+*00:00:01 {
if (ReadingsVal("Ist_Licht","state",0)>ReadingsVal("Soll_Licht","state",0)) {
  set Ist_Licht {(ReadingsVal("Ist_Licht","state",0) - 1)};
}
elsif (ReadingsVal("Ist_Licht","state",0)<ReadingsVal("Soll_Licht","state",0)) {
  set Ist_Licht {(ReadingsVal("Ist_Licht","state",0) + 1)};
}
else {
   };
}


Das war mein Ansatz, funktioniert aber leider nicht.



Vielleicht hat ja einer einige Ideen wie man es lösen kann.


Danke im Voraus

Gruß

Ingooooo

Hallo, habe es soweit hinbekommen.

Der Code sieht momentan so aus:
+*00:00:01 {
if (ReadingsVal("Ist_Licht","state",0)>ReadingsVal("Soll_Licht","state",0))
  { fhem('set Ist_Licht ' . (ReadingsVal('Ist_Licht','state',0) * 0.997)) }

elsif (ReadingsVal("Ist_Licht","state",0)<ReadingsVal("Soll_Licht","state",0))
{ fhem('set Ist_Licht ' . (ReadingsVal('Ist_Licht','state',0) * 1.003)) }
else {
   };
};

{
if (ReadingsVal("Ist_Licht","state",0)>4095)
  {  fhem('set Ist_Licht ' . 4095) }

elsif (ReadingsVal("Ist_Licht","state",0)<6)
{  fhem('set Ist_Licht ' . 6) }
else {
   };
};


{ fhem('set PWM Port00 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port14 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port03 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port09 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port05 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port06 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port11 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port01 ' . int(ReadingsVal('Ist_Licht','state',0))) };
{ fhem('set PWM Port10 ' . int(ReadingsVal('Ist_Licht','state',0) * 0.8 )) };
{ fhem('set PWM Port15 ' . int(ReadingsVal('Ist_Licht','state',0) * 0.8 )) };
{ fhem('set PWM Port13 ' . int(ReadingsVal('Ist_Licht','state',0) * 0.8 )) };
{ fhem('set PWM Port07 ' . int(ReadingsVal('Ist_Licht','state',0))) }



Gruß
Ingo

Prof. Dr. Peter Henning

Bitte etwas mehr mit den Perl-Grundlagen beschäftigen. Und

ReadingsVal("Soll_Licht","state",0) => Value("Soll_Licht")

ersetzen.

LG

pah

Ingooooo

Danke dir, aber was ist der Unterschied daran?

Soll_Licht und Ist_Licht sind Dummys um die Werte zwischenzuspeichern.



Gruß

Ingo

CoolTux

Hallo Peter hallo Ingo,

ReadingsVal list das Reading state aus wobei Value das Internal STATE aus list.
Persönlich würde ich wenn es um das Reading geht auch ReadingsVal nehmen. Das Internal STATE nimmt im normal Fall zwar den Wert vom Reading state an kann aber manipuliert werden.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Prof. Dr. Peter Henning

Und es ist nicht notwendig, Dummy-Devices mit Zwischenwerten anzulegen...

LG

pah

CoolTux

Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net