[gelöst] Switch: Icon und Text OHNE Befehl im "state"

Begonnen von GaiusMarius, 21 Oktober 2022, 17:46:49

Vorheriges Thema - Nächstes Thema

GaiusMarius

Ich hätte gerne mehr Informationen auf einen Blick an den Devices als sie standardmäßig anzeigen. Das ist mir auch ganz gut gelungen (siehe anhängende Screenshots)! 8)
Der Erste ist ein Fenster-Öffnungssensor; im "State" wird der Zustand (offen, geschlossen, gekippt), RSSI und diverse andere (für mich wichtige) Informationen angezeigt.
Der Zweite ist eine Schaltsteckdose mit ähnlichen Anzeigen.

Allerdings ist bei Schaltern der "State" im FHEMWEB als Kommando/Befehl ausgeführt. Daher ist auch im zweiten Screenshot der Text orange. Im dritten Screenshot sieht man das Mouse-Over mit Kommando/Befehl.

Nun die Frage: Kann ich das implizite Kommando/Befehl unterdrücken/entfernen? In dem Beispiel habe ich ja extra die Befehle "anschalten" und "ausschalten" eingebaut.

Zitat von: justme1968 am 27 Januar 2015, 13:12:29die {..} version von devStateIcon kann neben STATE:icon:cmd auch direkt html code zurück geben. dam könntest du dir dann z.b. mit etwas wie readingsGroup_makeLink() den html code für ein icon und jede beliebiges fhem kommando zurück geben lassen und als device icon verwenden.
Ich habe etwas herumexperimentiert und meine, dass - selbst mit Perl {...} - nur die zwei Formen "STATE:icon:cmd" oder "HTML-Code ohne Beeinflussung des cmd" möglich sind.

BTW: Wo ist eigentlich "verdrahtet", dass zwischen on und off hin- und hergeschaltet werden muss?


Hier mein Device:defmod HS_EG_KU_Absaugung CUL_HM 1BEB45
attr HS_EG_KU_Absaugung .mId 00A1
attr HS_EG_KU_Absaugung DbLogInclude state,uR_Activity,uR_RssiDevAtFhemValue,uR_RssiDevAtFhemDevn,uR_RssiFhemAtDevValue,uR_RssiFhemAtDevDevn
attr HS_EG_KU_Absaugung IODev HMLAN
attr HS_EG_KU_Absaugung IOgrp VCCU:HMLAN
attr HS_EG_KU_Absaugung actCycle 000:29
attr HS_EG_KU_Absaugung actStatus alive
attr HS_EG_KU_Absaugung alias Absaugung, Küche
attr HS_EG_KU_Absaugung autoReadReg 4_reqStatus
attr HS_EG_KU_Absaugung devStateIcon {\
  my $An_Text  = 'an';;\
  my $Aus_Text = 'aus';;\
\
  my $Mein_Geraet_Text = 'Dunstabzugshaube';;\
\
  my %Farbschema_AnIstGut      = ($An_Text => 'lime', $Aus_Text => 'red');;\
  my %Farbschema_AnIstSchlecht = ($An_Text => 'red',  $Aus_Text => 'lime');;\
  my $Mein_Farbschema  = \%Farbschema_AnIstGut;;\
\
  my $Schaltzustand = ReadingsVal($name, 'state', '?');;\
  my $Mein_Schaltzustand_Text = 'unbekannt';;\
  if    ($Schaltzustand eq 'on')  {$Mein_Schaltzustand_Text = $An_Text;;}\
  elsif ($Schaltzustand eq 'off') {$Mein_Schaltzustand_Text = $Aus_Text;;}\
\
  my $Schaltzustand_Icon = 'TR_'.$Mein_Geraet_Text.'_Zustand_'.$Mein_Schaltzustand_Text;;\
  my $Schaltzustand_icon_html = FW_makeImage($Schaltzustand_Icon.'@'.%$Mein_Farbschema{$Mein_Schaltzustand_Text}, $Mein_Schaltzustand_Text);;\
\
\
  (my $rssi    = sprintf('%1.1f', ReadingsVal($name, 'uR_RssiDevAtFhemValue', undef))) =~ tr/./,/;;\
\
  my $commState = ReadingsVal($name, 'commState', undef);;\
  my $activity  = ReadingsVal($name, 'uR_Activity', undef);;\
\
  my $commState_unknown_text = 'Kommandozustand unbekannt';;\
  my $commState_unknown_icon = 'TR_Gerätebefehle_Zustand_unbekannt';;\
  my $commState_text = $commState_unknown_text;;\
  my $commState_icon = $commState_unknown_icon;;\
  if ($commState eq 'CMDs_done') {\
    $commState_text = 'Kommandos ausgeführt';;\
    $commState_icon = 'TR_Gerätebefehle_Zustand_ausgeführt';;}\
  elsif ($commState eq 'CMDs_processing...') {\
    $commState_text = 'Kommandos in Ausführung';;\
    $commState_icon = 'TR_Gerätebefehle_Zustand_ausführend';;}\
  elsif ($commState eq 'CMDs_pending') {\
    $commState_text = 'wartende Kommandos';;\
    $commState_icon = 'TR_Gerätebefehle_Zustand_wartend';;}\
  my $commState_icon_html = FW_makeImage($commState_icon, $commState_text);;\
\
  my $activity_unknown_text = 'Aktivität unbekannt';;\
  my $activity_unknown_icon = 'TR_Geräteaktivität_Zustand_unbekannt';;\
  my $activity_text = $activity_unknown_text;;\
  my $activity_icon = $activity_unknown_icon;;\
  if ($activity eq '+') {\
    $activity_text = 'Gerät aktiv';;\
    $activity_icon = 'TR_Geräteaktivität_Zustand_gut';;}\
  elsif ($activity eq '-') {\
    $activity_text = 'Gerät inaktiv';;\
    $activity_icon = 'TR_Geräteaktivität_Zustand_fehlerhaft';;}\
  elsif ($activity eq '?') {\
    $activity_text = $activity_unknown_text;;\
    $activity_icon = $activity_unknown_icon;;}\
  my $activity_icon_html = FW_makeImage($activity_icon, $activity_text);;\
\
  '<div>'.$Schaltzustand_icon_html.';; <b>'.$rssi.'</b> dB<br>Befehle: '.$commState_icon_html.';; Aktivität: '.$activity_icon_html.'</div>'\
}
attr HS_EG_KU_Absaugung eventMap /on:anschalten/\
/off:ausschalten/
attr HS_EG_KU_Absaugung expert none
attr HS_EG_KU_Absaugung group Küche
attr HS_EG_KU_Absaugung icon TR_Dunstabzugshaube_Symbol
attr HS_EG_KU_Absaugung model HM-LC-SW1-PL2
attr HS_EG_KU_Absaugung peerIDs 00000000,
attr HS_EG_KU_Absaugung room Technik
attr HS_EG_KU_Absaugung subType switch
attr HS_EG_KU_Absaugung userReadings uR_Activity {\
  my $Activity = ReadingsVal($NAME, 'Activity', 'unknown');;\
  if    ($Activity eq 'alive') {'+'}\
  elsif ($Activity eq 'dead' ) {'-'}\
  else                         {'?'}\
},\
\
uR_RssiDevAtFhemValue {\
  my $RssiValueMax = '';;\
  my $Rssi_At_Text = 'rssi_at_';;\
  foreach my $InternalName (keys(%$hash)) {\
    if ($InternalName =~ m/^$Rssi_At_Text/) {\
      (my $RssiValue = $hash->{$InternalName}) =~ s/^.*:([^:]+$)/$1/;;\
      if ($RssiValue ne '') {\
        if ($RssiValueMax eq '')           {$RssiValueMax = $RssiValue;;}\
        elsif ($RssiValueMax < $RssiValue) {$RssiValueMax = $RssiValue;;}\
      }\
    }\
  }\
  sprintf("%01.1f", $RssiValueMax) if ($RssiValueMax ne '');;\
},\
\
uR_RssiDevAtFhemDevn {\
  my $RssiValueMax = '';;\
  my $RssiMaxDev   = '';;\
  my $Rssi_At_Text = 'rssi_at_';;\
  foreach my $InternalName (keys(%$hash)) {\
    if ($InternalName =~ m/^$Rssi_At_Text/) {\
      (my $RssiValue = $hash->{$InternalName}) =~ s/^.*:([^:]+$)/$1/;;\
      if ($RssiValue ne '') {\
        if (($RssiValueMax eq '') || ($RssiMaxDev eq '')) {$RssiValueMax = $RssiValue;;;;($RssiMaxDev = $InternalName) =~ s/^$Rssi_At_Text//;;}\
        elsif ($RssiValueMax < $RssiValue)                {$RssiValueMax = $RssiValue;;;;($RssiMaxDev = $InternalName) =~ s/^$Rssi_At_Text//;;}\
      }\
    }\
  }\
  $RssiMaxDev if ($RssiValueMax ne '');;\
},\
\
uR_RssiFhemAtDevValue {\
  my $RssiValueMax = '';;\
  my $Rssi_Text    = 'rssi_';;\
  my $Rssi_At_Text = 'rssi_at_';;\
  foreach my $InternalName (keys(%$hash)) {\
    if ($InternalName =~ m/^$Rssi_Text/) {\
      if (!($InternalName =~ m/^$Rssi_At_Text/)) {\
        (my $RssiValue = $hash->{$InternalName}) =~ s/^.*:([^:]+$)/$1/;;\
        if ($RssiValue ne '') {\
          if ($RssiValueMax eq '')           {$RssiValueMax = $RssiValue;;}\
          elsif ($RssiValueMax < $RssiValue) {$RssiValueMax = $RssiValue;;}\
        }\
      }\
    }\
  }\
  sprintf("%01.1f", $RssiValueMax) if ($RssiValueMax ne '');;\
},\
\
uR_RssiFhemAtDevDevn {\
  my $RssiValueMax = '';;\
  my $RssiMaxDev   = '';;\
  my $Rssi_Text    = 'rssi_';;\
  my $Rssi_At_Text = 'rssi_at_';;\
  foreach my $InternalName (keys(%$hash)) {\
    if ($InternalName =~ m/^$Rssi_Text/) {\
      if (!($InternalName =~ m/^$Rssi_At_Text/)) {\
        (my $RssiValue = $hash->{$InternalName}) =~ s/^.*:([^:]+$)/$1/;;\
        if ($RssiValue ne '') {\
          if (($RssiValueMax eq '') || ($RssiMaxDev eq '')) {$RssiValueMax = $RssiValue;;;;($RssiMaxDev = $InternalName) =~ s/^$Rssi_Text//;;}\
          elsif ($RssiValueMax < $RssiValue)                {$RssiValueMax = $RssiValue;;;;($RssiMaxDev = $InternalName) =~ s/^$Rssi_Text//;;}\
        }\
      }\
    }\
  }\
  $RssiMaxDev if ($RssiValueMax ne '');;\
},
attr HS_EG_KU_Absaugung webCmd anschalten:ausschalten

rudolfkoenig

ZitatIch habe etwas herumexperimentiert und meine, dass - selbst mit Perl {...} - nur die zwei Formen "STATE:icon:cmd" oder "HTML-Code ohne Beeinflussung des cmd" möglich sind.

Das ist so allgemein nicht richtig, wie man das mit folgender Definition nachstellen kann:
define d dummy
attr d devStateIcon off:general_aus on:general_an
attr d devStateIcon { "off:general_aus on:general_an" }
set d on

Hier erzeugen beide Varianten das Gleiche, jeweils ein Icon ohne Auswirkung, wenn man draufklickt.

Mit einem zusaetzlichen "attr d setList on off" wird ein Befehl ausgefuehrt, jeweils das im Vergleich zu state das Andere.
Das wiederum kann man mit "attr d cmdList :" abstellen.

ZitatBTW: Wo ist eigentlich "verdrahtet", dass zwischen on und off hin- und hergeschaltet werden muss?
In FHEMWEB.pm, FW_devState()

ZitatHier mein Device:
Hilft wenig: der Code ist zu gross, um es in vertretbarer Zeit verstehen zu koennen, und erzeugt Fehler, wenn man es einfach testen will.
Aus Erfahrung: es hilft beiden Parteien, wenn man den Code auf das Minimum vereinfacht.

GaiusMarius

#2
Zitat von: rudolfkoenig am 22 Oktober 2022, 12:31:24Das ist so allgemein nicht richtig, wie man das mit folgender Definition nachstellen kann:
Ups, der Meister persönlich! :o
Jein ;) So wie ich es verstanden habe ist es egal, ob das "regexp:icon-name:cmd - Dreierpärchen" direkt eingetippt ist oder von einem Perl-Statement zurückgeliefert wird. Es wird dabei immer gleich behandelt.
Anders, wenn Perl ein undef oder ein in <> eingeschlossenen Text liefert. Dann wird entweder das Standardicon oder der Text (anscheinend inklusive der <>) als HTML gezeigt/interpretiert/eingebaut.

Ich habe also beim Attribut devStateIcon drei Möglichkeiten:

  • regexp:icon-name:cmd - Dreierpärchen (egal ob handgetippt oder durch Perl generiert
  • undef, durch Perl generiert
  • HTML, durch Perl generiert

Da ich Icon und Text mischen möchte1), habe ich mich für 3. "HTML durch Perl" entschieden2). Und in dem HTML kann ich nicht explizit angeben, dass ich kein3 cmd haben möchte...
Das cmd wird ja auch nicht von mir in irgendeiner Form einprogrammiert, sondern scheint automatisch zu existieren, weil der (Sub-)Typ des Devices ein switch ist.

Hier noch einmal das Device, soweit abgestrippt, dass man bitte nicht mehr nach dem Sinn des Gerätes fragen darf:defmod switch CUL_HM 1BEB45
attr switch devStateIcon {
  my $state = ReadingsVal($name, 'state', undef);
  my $icon = 'Next';
  if ($state eq 'on')  {$icon = 'Prev'}
  my $icon_html = FW_makeImage($icon, '');

  '<div>'.$icon_html.' '.$state.'</div>'
}
attr switch eventMap /on:an/ /off:aus/
attr switch model HM-LC-SW1-PL2
attr switch subType switch
attr switch webCmd an:aus


Im Screenshot sieht man, dass "mein" Icon-Text-Gemisch weiterhin mit einem cmd belegt ist.


1 = vielleicht geht das gar nicht
2 = vielleicht war das falsch
3 = Achtung: doppelte Verneinung!

rudolfkoenig

ZitatUnd in dem HTML kann ich nicht explizit angeben, dass ich kein3 cmd haben möchte...
Doch.
Im {} liefert man zwei Werte zurueck, Bild (als HTML) und Befehl.
Wenn dieser Befehl noFhemwebLink heisst, dann wird kein Befehl dazuerfunden.
Das ist hier "dokumentiert": https://forum.fhem.de/index.php/topic,39546.msg337514.html#msg337514 :)

Die vorletzte Zeile des Beispiels muss so abgewandelt werden:
  ('<div>'.$icon_html.' '.$state.'</div>', 'noFhemwebLink')

GaiusMarius

 
Zitat von: rudolfkoenig am 24 Oktober 2022, 16:28:25Die vorletzte Zeile des Beispiels muss so abgewandelt werden
:-*

Meinen allerherzlichsten Dank! Funktioniert bestens!