ESP RGBWW Wifi Led Controller - Hinweise zu Sammelbestellung 2.5

Begonnen von mrpj, 07 Februar 2016, 17:53:42

Vorheriges Thema - Nächstes Thema

funclass

#705
@pjakobs

Hab die Doku mal soweit erstellt. Könntest diese ja vor dem nächsten Push mal ins Modul übernehmen.

@alle

natürlich auch mal kritisch drüber schauen ob ich irgendwo Murks geschrieben habe. Die Ausführliche Erläuterung zum HSV-Farbraum etc. habe ich mir erspart, diese gibts ja schon im WiFiLight Modul.

Bei den Umlauten in der deutschen Beschreibung bin ich mir nicht ganz sicher. In meiner testweisen Übernahme ins Modul wurden diese sauber im FHEMWEB dargestellt.

herrmannj

Zitat von: pjakobs am 26 Juni 2016, 08:17:57
im Moment mag mein Array noch nicht ganz so wie ich mir das vorstelle.
pj
May i help ?

vg
joerg

vbs

#707
Hm, mMn besteht da momentan ein Problem beim Setzen von Werten mit Ramp-Angabe. Habe gerade mehrfach den Fall, dass ein set nicht ausgeführt wird. zB:
set ledNeu2 hsv 140,89,100 960

Führt zu keinem Effekt, wird jedoch in FHEM angezeigt. Ein set ohne Ramp klappt dann. Auch kürzere Ramps werden manchmal nicht ausgeführt. Ich kann das leider nicht zuverlässig reproduzieren.
Modul-Version von gestern abend.

funclass

Zitat von: vbs am 26 Juni 2016, 12:46:07
Hm, mMn besteht da momentan ein Problem beim Setzen von Werten mit Ramp-Angabe. Habe gerade mehrfach den Fall, dass ein set nicht ausgeführt wird. zB:
set ledNeu2 hsv 140,89,100 100 960

Führt zu keinem Effekt, wird jedoch in FHEM angezeigt. Ein set ohne Ramp klappt dann. Auch kürzere Ramps werden manchmal nicht ausgeführt. Ich kann das leider nicht zuverlässig reproduzieren.
Modul-Version von gestern abend.

Was soll die 960 am Ende des Befehls bedeuten? In deinem Fall wäre ramp 100sek und die 960 steht an der Stelle wo die Flags q/l folgen würden.

vbs


pjakobs

Zitat von: mrpj am 26 Juni 2016, 11:28:18
Steht doch in der Doku  ;)

Wie kann man das umschreiben, so dass es einfacher verständlich ist?

nee, is schon ok, ich hatte den PoC code von Jörg genommen und garnicht weiter drüber nachgedacht, das ist so absolut sinnvoll und verständlich - mann muss nur hinsehen :o
Zitat von: mrpj am 26 Juni 2016, 11:28:18

Hinweise zu solid: die Zeitangabe bedeutet "mindestens" - wenn danach kein neues Kommando in der Q ist, bleibt der Controller in dem Zustand. (da er sonst keinen anderen definierten Zustand hätte).

Ich denke mit den beiden Kommandos "fade" & "solid" kann man einiges an Lichtspielerei erstellen  ;)

Um dies Sinnvoll umzusetzen müsste man mehr als 2 Koordinaten nutzen, denn auch zwischen den beiden Koordinaten ist die Kennlinie von LEDs nicht linear.  Von meiner Seite aus wird da in den nächsten Monaten keine Implementierung kommen.

Ich freue mich aber immer um Menschen die sich engagieren und Code zu dem Projekt beitragen   :)

Ich muss mal sehen, in einem anderen Projekt, in dem ich involviert war, wurde ganz viel zum Thema (Helligkeits) Kalibrierung gemacht.

Zitat von: herrmannj am 26 Juni 2016, 12:32:04
May i help ?

vg
joerg

Da wäre ich dankbar. Ich stehe manchmal mit den perl datatypes auf Kriegsfuß und hier auf dem Schlauch.
Es gibt einen Branch dev-pj-queue,
darin habe ich die LedController_Set() funktion wie folgt definiert:

sub
LedController_Set(@){
my @command=@_;
my ($ledDevice, $name, $cmd, @args) = @command;
   return "Unknown argument $cmd, choose one of hsv rgb state update hue sat val dim on off rotate" if ($cmd eq '?');
Log3 ($ledDevice, 5, "$ledDevice->{NAME} (set) called with $cmd, busy flag is $ledDevice->{helper}->{isBusy}"); 
if($ledDevice->{helper}->{isBusy} eq 1){
push (@{$ledDevice->{helper}->{cmdQueue}}, [@command]);

Log3 ($ledDevice, 4,"$ledDevice->{NAME} (queue) pushed ".Dumper(($ledDevice, $name, $cmd, @args))." to queue");
Log3 ($ledDevice, 5,"$ledDevice->{NAME} (queue) queue is now".Dumper(@{$ledDevice->{helper}->{cmdQueue}}));
} else {
LedController_doSet(@command);
}
}


mein Verständnis ist, dass
push @array1, [@array2]
eben das ganze array @array2 als ein Elememt in @array1 pusht. Der dump sagt aber was anderes.
Ich habe in Wifilight gesehen, dass da das Array vor dem push aus Komponenten aufgebaut wird - das wollte ich vermeiden, ich hab stattdessen versucht die ganze "Kommandozeile" durch

LedController_Set(@){
my @command=@_;
zu übernehmen, in der Hoffnung, mir dann ansonsten nirgendwo Gedanken machen zu müssen.

bevor ich den http-Request absetze, setze ich in LedController_SetHSVColor(@) mit

$ledDevice->{helper}->{isBusy}=1;
ein globales Flag, dass ich dann in LedController_ParseSetHSVColor(@) mit

$ledDevice->{helper}->{isBusy}=0;
wieder lösche.

bevor ich dann da wieder rausspringe hole ich mir, wenn vorhanden, das nächste Kommando vom Stack und führe es aus:

if(my @command = shift $ledDevice->{helper}->{cmdQueue}){
Log3 ($ledDevice, 4,"$ledDevice->{NAME} (queue) shifted ".Dumper(@command)." off the queue");
LedController_doSet(@command);


Eins ist klar: irgendwas is faul daran, denn es funktioniert nicht.

Das Flag wird a) korrekt gesetzt, b) erkannt und c) auch wieder gelöscht. Das Problem ist m.E. entweder die Art, wie ich das Array behandle, oder ich bekommen vielleicht ganz am Anfang schon die Parameter nicht korrekt in das @command array - wobei - der erste Aufruf von doSet funktioniert ja problemlos, also muss es das queueing / dequeueing sein.

Zitat von: funclass am 26 Juni 2016, 12:22:26
@pjakobs

Hab die Doku mal soweit erstellt. Könntest diese ja vor dem nächsten Push mal ins Modul übernehmen.
Danke! Ich nehm's in den nächsten dev-pj commit rein.

Zitat von: vbs am 26 Juni 2016, 12:46:07
Hm, mMn besteht da momentan ein Problem beim Setzen von Werten mit Ramp-Angabe. Habe gerade mehrfach den Fall, dass ein set nicht ausgeführt wird. zB:
set ledNeu2 hsv 140,89,100 960

Führt zu keinem Effekt, wird jedoch in FHEM angezeigt. Ein set ohne Ramp klappt dann. Auch kürzere Ramps werden manchmal nicht ausgeführt. Ich kann das leider nicht zuverlässig reproduzieren.
Modul-Version von gestern abend.

hmm... klappt bei mir, führt zu ner Art Mintgrün.

lässt sich das reproduzieren? Kannst Du mir mal den Log output posten?
Grüße

pj

herrmannj

Zitatnee, is schon ok, ich hatte den PoC code von Jörg genommen und garnicht weiter drüber nachgedacht, das ist so absolut sinnvoll und verständlich - mann muss nur hinsehen :o
Topic war solid.

Die Notwendigkeit hatte sich mir in der API aber auch nicht komplett erschlossen.

Beispiel: Ich möchte von 0% Rot auf 100% in 10 Sek, dann 20 Sek so bleiben (hier solid?), dann auf 100% Grün  in 30 Sek.

Wäre:
set LED HSV 0,100,0; set LED HSV 100,100,100 10 q; set LED HSV 100,100,100 20 q; set LED HSV 120,100,100 30 q

Wie passt "solid" gedanklich da rein ? Die API calls würden das doch alle genauso per fade abbilden können. Gibt es da ein pro und contra ?

vg
joerg

herrmannj

@pjakobs

wg Q:

ich schau gerade. Ich schlage eine alternative Herangehensweise vor (und nehme mir gleich mal den code vor)

Im "_set" so wie gehabt verarbeiten, api call bilden. Das JSON + meta in die Queue schreiben. Grund, a: (imho) stringenter, b: wenn (!) wir später pollen dann müssen wir eine Konkurrenz mit den set verhindern. Ist ja beides ein API call. Die könnten dann einfach mit in die Q rein. Der Q ist es ja egal was drin ist, die muss nur wissen wohin (endpoint) und was (body + query).

vg
joerg

pjakobs

Zitat von: herrmannj am 26 Juni 2016, 23:46:11
Topic war solid.

Die Notwendigkeit hatte sich mir in der API aber auch nicht komplett erschlossen.

Beispiel: Ich möchte von 0% Rot auf 100% in 10 Sek, dann 20 Sek so bleiben (hier solid?), dann auf 100% Grün  in 30 Sek.

Wäre:
set LED HSV 0,100,0; set LED HSV 100,100,100 10 q; set LED HSV 100,100,100 20 q; set LED HSV 120,100,100 30 q

Wie passt "solid" gedanklich da rein ? Die API calls würden das doch alle genauso per fade abbilden können. Gibt es da ein pro und contra ?

vg
joerg

hmm.. ich kann das schon nachvollziehen, auf der API Ebene heißt das dann ja

h:0, s:100, v:0, t:0, cmd:solid
h:100, s:100, v:100, t:10, cmd:fade
h:100, s:100, v:100, t:20, cmd:solid
h:120, s:100, v:100, t:30, cmd:fade

Nun kann man natürlich sagen, was ja mein erster Gedanke war, ein fade von 100,100,100 nach 100,100,100 in 20s ist gut genug, aber ich verstehe auch die Idee hinter solid.

pj

pjakobs

Zitat von: herrmannj am 26 Juni 2016, 23:57:45
@pjakobs

wg Q:

ich schau gerade. Ich schlage eine alternative Herangehensweise vor (und nehme mir gleich mal den code vor)

Im "_set" so wie gehabt verarbeiten, api call bilden. Das JSON + meta in die Queue schreiben. Grund, a: (imho) stringenter, b: wenn (!) wir später pollen dann müssen wir eine Konkurrenz mit den set verhindern. Ist ja beides ein API call. Die könnten dann einfach mit in die Q rein. Der Q ist es ja egal was drin ist, die muss nur wissen wohin (endpoint) und was (body + query).

vg
joerg

ok, dann sollten wir aber gleich noch einen Schritt weiter gehen, und das eigentliche Senden des API Calls in eine eigene Funktion stecken, die von allen anderen genutzt wird (im Moment steckt das ja in _SetHSV, GetHSV etc).
Wenn wir ein _sendRequest(@) bauen, dann können wir dort a) checken ob ein anderer Request in flight ist, und b) den neuesten Request in die Queue stecken. Gleiches für die Callback Funktion. Damit wäre dann, für alles andere auf der Ebene des Moduls, das API zwingend serialisiert.

Grüße

pj


herrmannj


mrpj

Zitat von: herrmannj am 26 Juni 2016, 23:46:11
Topic war solid.

Die Notwendigkeit hatte sich mir in der API aber auch nicht komplett erschlossen.

Beispiel: Ich möchte von 0% Rot auf 100% in 10 Sek, dann 20 Sek so bleiben (hier solid?), dann auf 100% Grün  in 30 Sek.

Für mich war die Aufsplittung von Animationsbefehlen (fade/solid) expliziter. Dadurch wird die Verantwortung an den Nutzer der API übergeben und der Controller muss nicht Anhand von Bedingungen erahnen, ob der Nutzer z.B. nun 30Sekunden lang eine Farbe zeigen möchte, oder aber mir dem Selben Befehl der Farbkreis einmal durchlaufen werden soll.

Bei konkreten Veränderungsvorschlägen kann ja nochmal besprochen werden, ob und wie eine Anpassung umgesetzt werden kann

herrmannj

Zitat von: mrpj am 27 Juni 2016, 01:16:23
Für mich war die Aufsplittung von Animationsbefehlen (fade/solid) expliziter. Dadurch wird die Verantwortung an den Nutzer der API übergeben und der Controller muss nicht Anhand von Bedingungen erahnen, ob der Nutzer z.B. nun 30Sekunden lang eine Farbe zeigen möchte, oder aber mir dem Selben Befehl der Farbkreis einmal durchlaufen werden soll.

Bei konkreten Veränderungsvorschlägen kann ja nochmal besprochen werden, ob und wie eine Anpassung umgesetzt werden kann
Alles gut. das kann ja im fhem modul gemacht werden.

Danke, vg
joerg

herrmannj

Zitat von: pjakobs am 27 Juni 2016, 00:12:57
ok, dann sollten wir aber gleich noch einen Schritt weiter gehen, und das eigentliche Senden des API Calls in eine eigene Funktion stecken, die von allen anderen genutzt wird (im Moment steckt das ja in _SetHSV, GetHSV etc).
Wenn wir ein _sendRequest(@) bauen, dann können wir dort a) checken ob ein anderer Request in flight ist, und b) den neuesten Request in die Queue stecken. Gleiches für die Callback Funktion. Damit wäre dann, für alles andere auf der Ebene des Moduls, das API zwingend serialisiert.

Grüße

pj

Hello,

im Anhang. Ich habe jetzt keine allzu tiefen Test gemacht. Im Kern sieht jut aus. Sorry, ich habe jetzt keine diff gezogen, denke aber zum testen auch so ok. Kannst aber generell auf der Version weiterarbeiten, ist auch refactoring drin.

vg
joerg

herrmannj

oh sorry. die doc:

in der $param die an NonBlocking get ging ändert sich:

der key "parser" kommt dazu. Da ist die ref auf die routine welche den api call auswerten soll.
der key "callback" zeigt immer auf "LedController_callback". Dort muss error handling ergänzt werden und von da aus wird "parser" aufgerufen.

LedController_addCall(@) {
  my ($ledDevice, $param) = @_;

Hier wird der call in die queue geschrieben. $param ist der hash vom NonBlocking get inkl der mods oben.

sub
LedController_doCall(@) {
  my ($ledDevice) = @_;

setzt busy, holt ein element aus der queue und führt aus

sub
LedController_callback(@) {
  my ($param, $err, $data) = @_;

wird von NonBlocking get als callback aufgerufen.
busy löschen, den handler der das result des api calls bedient aufrufen, schauen ob weitere calls in der queue liegen (und ausführen)

vg
joerg