[Gelöst] MQTT für WLED, rgb reading mit # klappt nicht

Begonnen von stefanru, 22 März 2019, 21:16:26

Vorheriges Thema - Nächstes Thema

rudolfkoenig

ZitatBei "echtem LWT" ist es so, dass die "offline"-Meldung vom Server (!) erzeugt (genauer: dann ausgeliefert) wird, wenn sich der Client nicht rechtzeitig - wie angekündigt - meldet.
Noch etwas genauer :)
Das vom Client hinterlegte LWT wird vom Server publiziert (publish), wenn die Verbindung zum Client unterbrochen ist.
Die Verbindung kann auch vom Server beendet werden, wenn der Client sich nicht an seinem keepalive Versprechen haelt.

TomLee

#106
Sry, das mit dem LWT hatte ich mir nicht richtig angeschaut (eigentlich war ich auf dem Weg zur Dusche und dann schnell, schnell mal am Controller gespielt wegen der Frage).
Es erfolgt doch ein offline nach Zeit X, also erster Fehler war das ich länger hätte warten sollen und zweiter Denkfehler das ich FHEMWEB hätte im Browser aktualisieren müssen (weil ich eine Liste von Readings in eor angegeben habe ohne LWT siehe #101)  ::)

Zu der Frage :
Zitat
wie bringe ich den Status dazu mir den Online Status auch anzuzeigen? Wie bei den anderen MQTT2 auch?

Mit der farbigen Glühlampe könnte man es so lösen (ist nicht von mir, ist angepasst abgekupfert) und gefällt mir nicht, da bei Auswahl einer Farbe Code kurz angezeigt wird statt der Glühlampe (schließe aber nicht aus das mans auch anders/richtig/ohne dieses Verhalten lösen kann):

attr <DEVICENAME> devStateIcon {my $os = ReadingsVal($name,"LWT","offline") eq "online" ? "gruen" : "rot";;\
my $cd = Color::devStateIcon( $name, "rgb", "rgb", "brightness", "state" );;\
$cd =~ s/.*:([^:]+):.*/$1/;;\
'<div>'.FW_makeImage("10px-kreis-".$os)."<a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($cd)."</a></div>"}



Oder so, ganz simpel, ohne der farbigen Glühlampe dann halt:
attr <DEVICENAME> devStateIcon online:10px-kreis-gruen offline:10px-kreis-rot
attr <DEVICENAME> stateFormat LWT\
state


Zum ausprobieren den gezeigten Code wie er ist einfach in die Kommandozeile werfen, nur <DEVICENAME> ersetzen.

edit:

das Beispiel mit stateFormat kann man doch nicht einfach so über die Kommandozeile eingeben.
Das dann entweder über das + => Raw-Editor eingeben oder unten in irgendeinem Device über Raw definition den Raw-Editor aufrufen, den kompletten Code entfernen und den gezeigten Code einsetzen und mit execute commands bestätigen.

nochmal edit:

Bei dem Beispiel mit der farbigen Glühlampe kann man die div auch weglassen:

attr <DEVICENAME> devStateIcon {my $os = ReadingsVal($name,"LWT","offline") eq "online" ? "gruen" : "rot";;\
my $cd = Color::devStateIcon( $name, "rgb", "rgb", "brightness", "state" );;\
$cd =~ s/.*:([^:]+):.*/$1/;;\
FW_makeImage("10px-kreis-".$os)."<a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($cd)."</a>"}

australien

Hallo zusammen,

ich würde gerne mein Wled via MQTT2 oder html einen kompletten neuen Satz an Werten übergeben.

Und zwar brightness, effect, intensity, palette, rgb, speed und state also alles, um bestimmte Effekte einzuschalten.


Kann ich das mit einem set Befehl machen?
Wenn ja, wie?
Wenn nein, wie dann? myUtils?

danke
raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"

TomLee

Hallo,

an bspw. dem setList-Eintrag flash in #101 kannst dir ableiten wie man sowas in setList umsetzen könnte.

Gruß

Thomas

australien

das habe ich schon gesehen, aber kann es nicht lesen ;)

die setList ist ja im template schon vorhanden:


on:noArg wled/garage on
  off:noArg wled/garage off
  toggle:noArg wled/garage t
  rgb:colorpicker,RGB wled/garage/col #$EVTPART1
  brightness:colorpicker,BRI,0,1,255 wled/garage
  speed:colorpicker,BRI,0,1,255 wled/garage/api SX=$EVTPART1
  intensity:colorpicker,BRI,0,1,255 wled/garage/api IX=$EVTPART1
  palette:selectnumbers,0,1,46,0,lin wled/garage/api FP=$EVTPART1
  effect:selectnumbers,0,1,101,0,lin wled/garage/api FX=$EVTPART1
  loadPreset:selectnumbers,0,1,3,0,lin wled/garage/api PL=$EVTPART1
  dimup:noArg wled/garage/api A=~10
  dimdown:noArg wled/garage/api A=~-10


ich will jetzt folgendes schalten:
brightness 255
effect 11
intensity 125
palette 2
rgb FF0000
speed 240
state on


das ganze will ich auch noch mit 2 anderen Einstellungen machen, also insgesamt 3 voreinstellungen per set MQTT senden.

wie mach ich das?

raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"

TomLee

#110
So

deinsettername:noArg {fhem("set $NAME brightness 255;set $NAME effect 11;set $NAME intensity 125;set $NAME palette 2;set $NAME rgb FF0000;set $NAME speed 240;set $NAME on")}

?

australien

cool, genau so.

jetzt verstehe ich auch den Beitrag #101

Danke nochmal!
raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"

DeeSPe

#112
Dank der von Rudi gemachten Erweiterung in MQTT2_SERVER ist nun die IP Adresse des jeweiligen MQTT2_DEVICE Teil des Internals "<IODev>_CONN".

Rudi hat auch die SetExtensions so erweitert dass man nun den Inhalt von Widgets dynamisch erstellten kann.

Ich habe Beides gleich mal dafür verwendet um bei WLED die vorhandenen "effects" und "palettes" per Namen auswählbar zu machen.
Somit ist es nun möglich die vorhandenen Effekte anhand ihrer Nummer (Setter "effect") oder anhand ihres Namens (Setter "effectname") auszuwählen. Das Gleiche auch mit den vorhandenen Paletten. Beim Setzen anhand der Nummer wird auch das Reading für den Namen richtig gesetzt und umgekehrt.
Leider ist der Code dafür etwas komplexer geworden und erfordert zwei Funktionen in der "99_myUtils.pm".

Hier mal die nötigen Anpassungen:

1. Diese beiden Funktionen in die Datei "99_myUtils.pm" am Ende vor der schliessenden "1;" einfügen:
Code (99_myUtils.pm) Auswählen


2. Nun beim WLED MQTT2_DEVICE diese 4 Zeilen für die Setter (effect,effectname,palette,palettename) im Attribut "setList" ergänzen bzw. ändern:
Code (setList) Auswählen


3. Diese beiden Zeilen im Attribut "userReadings" hinzufügen:
Code (userReadings) Auswählen


Damit nun alles wie gewünscht funktioniert ist es nötig mindestens pro Palette und pro Effekt jeweils 1x eine Palette/Effekt mit ihrer Nummer aufzurufen. Also z.B.:
set <WLED> effect 1; set <WLED> palette 1

Nun können alle Effekte und Paletten mit ihren Namen (Setter "effectname" und "palettename") aufgerufen werden.
Etwas Schwierigkeiten gab es mit dem Effekt "Sparkle+" als Setter, weil das "+" am Ende natürlich in RegEx eine eigene Bedeutung hat. Deshalb habe ich das "+" kurzerhand durch "Plus" ersetzt.
Für die einfachere Bedienung in FHEMWEB kann man sich noch das Attribut "webCmd" setzen auf z.B.:
palettename:effectname:speed:intensity:rgb:brightness

Das Attribut "eventMap" kann man nun löschen.

Ich hoffe das kann noch jemand gebrauchen.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

australien

Zitat von: DeeSPe am 05 Dezember 2021, 22:22:20

1. Diese beiden Funktionen in die Datei "99_myUtils.pm" am Ende vor der schliessenden "1;" einfügen:
Code (99_myUtils.pm) Auswählen
sub WLED_getNames {
  my $dev = shift // return;
  my $na = shift // return;
  my $ip = (split("_",InternalVal($dev,"m2s_CONN",undef)))[1] // return;
  my $chash = $defs{$dev};
  my $nas = $na."s";
  HttpUtils_NonblockingGet( {
    url=>"http://$ip/json",
    callback=>sub($$$) {
      my ($hash,$err,$data) = @_;
      if ($data =~ /$nas..\[([^[]*?)]/) {
        my $s = $1;
        $s =~ s/["\n]//g;
        $s =~ s/[\s\&]/_/g;
        $s =~ s/\+/Plus/g;
        my @r = split(/,/,$s);
        readingsBeginUpdate($chash);
        readingsBulkUpdateIfChanged($chash,".".$nas."count",(scalar @r)-1);
        readingsBulkUpdateIfChanged($chash,".".$nas,$s);
        readingsEndUpdate($chash,0);
        readingsSingleUpdate($chash,$na."name",$r[ReadingsNum($dev,$na,0)],1);
      }
    }
  } )
}

sub WLED_setName($$$) {
  my $dev = shift // return;
  my $read = shift // return;
  my $val = shift // return;
  my $arr = ReadingsVal($dev,".".$read."s","") // return;
  my $wled = lc(InternalVal($dev,"CID",""));
  $wled =~ s/_/\//;
  my $top = $wled."/api F";
  $top .= $read eq "effect"?"X=":"P=";
  return $top.$val if ($val =~ /^\d\d?\d?$/);
  my $id;
  my $i = 0;
  for (split(",",$arr)) {
    if ($_ ne $val) {
      $i++;
      next;
    } else {
      $id = $i;
      last;
    }
  }
  return $top.$id;
}



Danke Dan!

kann es sein das in der Zeile
readingsSingleUpdate($chash,$na."name",$r[ReadingsNum($dev,$na,0)],1);

ein Fehler ist?
$r wurde nicht definiert bzw gehört da ein '.'?

raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"

DeeSPe

Zitat von: australien am 07 Dezember 2021, 10:22:14

Danke Dan!

kann es sein das in der Zeile
readingsSingleUpdate($chash,$na."name",$r[ReadingsNum($dev,$na,0)],1);

ein Fehler ist?
$r wurde nicht definiert bzw gehört da ein '.'?

Es funktioniert so wie es soll mit diesem Code.
Oder hast du ein konkretes Problem dass es nicht funktioniert?
Es wurde doch "@r" definiert. Auf Elemente in einem Array greift man dann mit "$r[X]" zu.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

australien

Komisch, jetzt schaut es besser aus.
Bei den Auswahlfeldern war nur verschiedener Code vorhanden, jetzt nicht mehr. Aber dafür  im ersten nur mehr Default und im zweiten Solid und Police.
Keine weiteren Effecte vorhanden.

raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"

DeeSPe

Zitat von: australien am 07 Dezember 2021, 10:45:55
Komisch, jetzt schaut es besser aus.
Bei den Auswahlfeldern war nur verschiedener Code vorhanden, jetzt nicht mehr. Aber dafür  im ersten nur mehr Default und im zweiten Solid und Police.
Keine weiteren Effecte vorhanden.

Ich zitiere mich mal selbst als Antwort darauf.
Zitat von: DeeSPe am 05 Dezember 2021, 22:22:20
Damit nun alles wie gewünscht funktioniert ist es nötig mindestens pro Palette und pro Effekt jeweils 1x eine Palette/Effekt mit ihrer Nummer aufzurufen. Also z.B.:
set <WLED> effect 1; set <WLED> palette 1

Gruß
Dan

P.S. Hattest Du auch Dein FHEM aktualisiert?
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

australien

Gerade ein update durchgeführt und auch der Erstbefehl aus geführt.

ein List meines Gerätes schaut so aus
Internals:
   CID        WLED_garage
   DEF        WLED_garage
   DEVICETOPIC MQTT2_WLED_garage
   FUUID      60ad397f-f33f-fbda-41e4-fb1449c4abcdd91d
   IODev      myMQTT2
   LASTInputDev myMQTT2
   MSGCNT     44
   NAME       MQTT2_WLED_garage
   NR         791
   STATE      off
   TYPE       MQTT2_DEVICE
   myMQTT2_CONN myMQTT2_10.68.0.165_11839
   myMQTT2_MSGCNT 44
   myMQTT2_TIME 2021-12-07 10:55:17
   READINGS:
     2021-12-07 10:23:02   IODev           myMQTT2
     2021-12-07 10:55:16   LWT             online
     2021-12-07 10:55:17   api             <?xml version="1.0" ?><vs><ac>0</ac><cl>255</cl><cl>0</cl><cl>0</cl><cs>0</cs><cs>0</cs><cs>0</cs><ns>0</ns><nr>1</nr><nl>0</nl><nf>1</nf><nd>60</nd><nt>0</nt><fx>11</fx><sx>216</sx><ix>125</ix><fp>2</fp><wv>0</wv><ws>0</ws><ps>0</ps><cy>0</cy><ds>WLED</ds><ss>0</ss></vs>
     2021-09-07 18:48:26   attrTemplateVersion 20200522 or prior
     2021-12-07 10:55:16   brightness      0
     2021-12-07 10:54:37   effect          11
     2021-12-07 10:44:05   effectname      set effect 48
     2021-12-07 10:54:37   intensity       125
     2021-12-07 10:54:37   palette         2
     2021-12-06 18:49:44   palettename     set "Default"))))}
     2021-12-07 10:55:16   rgb             FF0000
     2021-12-07 10:54:37   speed           216
     2021-09-10 16:11:22   spot            set
     2021-12-07 10:55:16   state           off
     2021-09-10 16:08:40   streifen_gruen  set
Attributes:
   alias      MQTT2_WLED_garage
   comment    For questions about the use of different widgets for color selection see discussion at https://forum.fhem.de/index.php/topic,98880.msg995308.html
   devStateIcon {Color::devStateIcon( $name, "rgb", "rgb", "brightness", "state" )}
   eventMap   /effect 0:Solid/effect 2:Breathe/effect 63:Pride/effect 48:Police
   genericDeviceType light
   homebridgeMapping Brightness=brightness::brightness,maxValue=100,factor=0.39216,delay=true
   icon       hue_filled_iris
   model      wled_controller
   readingList wled/garage/status:.* LWT
  wled/garage/g:.* brightness
  wled/garage/g:.* { $EVENT ? {"state"=>"on"} : {"state"=>"off"} }
  wled/garage/c:.* { {"rgb"=>substr("$EVENT",1,6)} }
  wled/garage/v:.* api
  wled/garage/v:.* { $EVENT =~ m,(?<=<sx>)([\d]+)(?=<\/sx>), ? $1 eq ReadingsVal($NAME,"speed","unknown") ? return : {"speed"=>$1} : return; }
  wled/garage/v:.* {$EVENT =~ m,(?<=<ix>)([\d]+)(?=<\/ix>), ? $1 eq ReadingsVal($NAME,"intensity","unknown") ? return : {"intensity"=>$1} : return }
  wled/garage/v:.* {$EVENT =~ m,(?<=<fp>)([\d]+)(?=<\/fp>), ? $1 eq ReadingsVal($NAME,"palette","unknown") ? return : {"palette"=>$1} : return }
  wled/garage/v:.* {$EVENT =~ m,(?<=<fx>)([\d]+)(?=<\/fx>), ? $1 eq ReadingsVal($NAME,"effect","unknown") ? return :{"effect"=>"$1"} : return }
   room       0.2.Garage,MQTT2_DEVICE
   setList    on:noArg wled/garage on
  off:noArg wled/garage off
  toggle:noArg wled/garage t
  rgb:colorpicker,RGB wled/garage/col #$EVTPART1
  brightness:colorpicker,BRI,0,1,255 wled/garage
  speed:colorpicker,BRI,0,1,255 wled/garage/api SX=$EVTPART1
  intensity:colorpicker,BRI,0,1,255 wled/garage/api IX=$EVTPART1
  loadPreset:selectnumbers,0,1,3,0,lin wled/garage/api PL=$EVTPART1
  dimup:noArg wled/garage/api A=~10
  dimdown:noArg wled/garage/api A=~-10
 
effect:{"selectnumbers,0,1,".ReadingsNum($name,".effectscount",5).",0,lin"} {WLED_setName($NAME,"effect",$EVTPART1)}
effectname:{"select,".join(",",sort(split(",",ReadingsVal($name,".effects","Solid,Police"))))} {WLED_setName($NAME,"effect",$EVTPART1)}
palette:{"selectnumbers,0,1,".ReadingsNum($name,".palettescount",5).",0,lin"} {WLED_setName($NAME,"palette",$EVTPART1)}
palettename:{"select,".join(",",sort(split(",",ReadingsVal($name,".palettes","Default"))))}  {WLED_setName($NAME,"palette",$EVTPART1)}

 
  kitt:noArg {fhem("set $NAME brightness 255;set $NAME intensity 125;set $NAME palette 2;set $NAME rgb FF0000;set $NAME speed 216;set $NAME effect 11")}
  streifen_gruen:noArg {fhem("set $NAME brightness 255;set $NAME effect 0;set $NAME intensity 78;set $NAME palette 2;set $NAME rgb 05FF2F;set $NAME speed 225")}
  spot:noArg {fhem("set $NAME brightness 255;set $NAME intensity 30;set $NAME palette 2;set $NAME rgb FFFFFF;set $NAME speed 86;set $NAME effect 85")}
   setStateList on off toggle
   userReadings effectname:effect.* {WLED_getNames($name,"effect")},
palettename:palette.* {WLED_getNames($name,"palette")}
   webCmd     palettename:effectname:speed:intensity:rgb:brightness
raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"

TomLee

#118
Hab den Vorschlag auch noch nicht zum laufen gebracht.

Was mir bis jetzt aufgefallen ist :

my $ip = (split("_",InternalVal($dev,"m2s_CONN",undef)))[1] // return;

Sollte doch so lauten:

my $ip = (split("_",InternalVal($dev,"MQTT2_Server_CONN",undef)))[1] // return;

Das Internal m2s_CONN heiß bei mir MQTT2_Server_CONN.

Dann klappts aber immer noch nicht.

@Australien

Ich mein in der setList dürfen keine Leerzeilen vorkommen, die musst du definitiv rausnehmen.

edit:

Ach, eben verstehe ich das mit dem Internal, das heißt immer so wie man den MQTT2_SERVER benannt hat.

australien

mit der Umbenennung des m2s_CONN in den eigenen MQTT2 Server gehen jetzt die Paletten, aber die Effecte sind immer nur noch bei Police und Solid.
raspberry pi3
signalduino, Shelly1, Shelly2, Sonos, Unifi
Amazon Fire Tablet 7 | Noname Android Tablet 10"