vorschlag: erweiterung devStateIcon um popup für widgets

Begonnen von justme1968, 13 Februar 2015, 22:56:34

Vorheriges Thema - Nächstes Thema

justme1968

zur zeit erlaubt devStateIcon nur die angabe von set kommandos ohne parameter (oder per eventMap mit jeweils einem festen parameter.

es gibt aber anwendungsfälle bei denen es wünschenswert ist beim klick auf das icon auch ein set kommando mit einem variablen parameter abzusetzen.

z.b. eine lampe die beim klick den slider für die helligkeit oder den colorpicker oder einen slider oder drop down für temperatur oder rolladen stand anzeigen soll. das ist z.b. im floorplan praktisch um nicht überall slider anzuzeigen wenn sie gerade nicht gebraucht werden.

mit den hier vorgestellten zwei kleinen änderungen lässt sich in der devStateIcon definition jetzt auch ein kommando verwenden das normalerweise (z.b. in den webCmd) ein fhem widget zum interaktiven einstellen des parameters verwenden würde.

ein möglicher patch besteht aus zwei teilen:
- FW_devState erweitern so das ein kommando das einen paramter erwartet erkannt wird und dann beim klick statt des normalen set kommandos ein popup erzeugt:
--- 01_FHEMWEB.pm       (revision 7956)
+++ 01_FHEMWEB.pm       (working copy)
@@ -2419,8 +2419,29 @@
     my ($icon, $isHtml);
     ($icon, $link, $isHtml) = FW_dev2image($d);
     $txt = ($isHtml ? $icon : FW_makeImage($icon, $state)) if($icon);
-    $link = "cmd.$d=set $d $link" if(defined($link));

+    my $cmd = FW_widgetOverride($d, $link);
+    my $htmlTxt;
+    my @c = split(' ', $cmd);   # @c==0 if $cmd==" ";
+    if(int(@c) && $allSets && $allSets =~ m/\b$c[0]:([^ ]*)/) {
+      my $values = $1;
+      foreach my $fn (sort keys %{$data{webCmdFn}}) {
+        no strict "refs";
+        $htmlTxt = &{$data{webCmdFn}{$fn}}($FW_wname,
+                                           $d, $FW_room, $cmd, $values);
+        use strict "refs";
+        last if(defined($htmlTxt));
+      }
+    }
+
+    if( $htmlTxt ) {
+      $link = undef;
+      $htmlTxt =~ s/'/\\"/g;
+      $txt = "<a onClick='FW_okDialog(\"$htmlTxt\")'\>$txt</a>";
+    } else {
+      $link = "cmd.$d=set $d $link" if(defined($link));
+    }
+
   }


- eine erweiterung von FW_okDialog um dort die fhemWidget zu ersetzen:
--- fhemweb.js (revision 7956)
+++ fhemweb.js (working copy)
@@ -230,6 +230,19 @@
       $(div).remove();
     }}]
   });
+
+  $("div.fhemWidget").each(function() {
+    var dev=$(this).attr("dev");
+    var cmd=$(this).attr("cmd");
+    var rd=$(this).attr("reading");
+    var params = cmd.split(" ");
+    FW_replaceWidget(this, dev, $(this).attr("arg").split(","),
+      $(this).attr("current"), rd, params[0], params.slice(1),
+      function(arg) {
+        FW_cmd(FW_root+"?cmd=set "+dev+(params[0]=="state" ? "":" "+params[0])+
+                        " "+arg+"&XHR=1");
+      });
+  });
}


in den angehängten screenshots und dem movie sieht man beispielhaft wie das ganze dann funktioniert. das beispiel in diesem fall ist natürlich etwas konstruiert je nach state zwischen zwei readings hin und her zu schalten würde man normalerweise vermutlich nicht tun. die webCmd sind nur da um zu zeigen das longpoll weiter funktioniert. normalerweise (z.b. auf einem floorplan) würde man nur das popup verwenden.

define d dummy       
attr d devStateIcon slider.*:on:dropDown dropDown.*:off:slider
attr d room popup   
attr d setList slider:slider,0,5,100 dropDown:0,1,2,3,4,5
attr d webCmd slider:dropDown


das ganze ist erst mal nur ein proof of concept und soll erst mal nur zeigen das der aufwand für eine solche erweiterung recht klein wäre.

für eine endgültige version wäre es zumindest im floorplan schön wenn man beim klick auf das icon nicht nur ein sonder mehrere kommandos im popup haben kann. z.b. um helligkeit und farbe einer lampe einzustellen. z.b. durch mehrere mit ; getrennte kommandos.

die js erweiterung sollte natürlich nicht den replace code kopieren sondern das sollte aus FW_jqueryReadyFn ausgelagert und von beiden stellen aufgerufen werden.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

#1
anbei eine version die auch mehrere widgets im popup unterstützt. damit kann man dann z.b für eine lampe farbe und helligkeit im gleichen popup haben:attr d devStateIcon .*:on:hue:ct:dim
attr d setList hue:colorpicker,HUE,0,100,65000 ct:colorpicker,CT,2500,6000 dim:slider,0,5,100


--- 01_FHEMWEB.pm (revision 7956)
+++ 01_FHEMWEB.pm (working copy)
@@ -2392,7 +2392,7 @@
   my ($hasOnOff, $link);

   my $cmdList = AttrVal($d, "webCmd", "");
-  my $allSets = getAllSets($d);
+  my $allSets = FW_widgetOverride($d, getAllSets($d));
   my $state = $defs{$d}{STATE};
   $state = "" if(!defined($state));

@@ -2419,8 +2419,36 @@
     my ($icon, $isHtml);
     ($icon, $link, $isHtml) = FW_dev2image($d);
     $txt = ($isHtml ? $icon : FW_makeImage($icon, $state)) if($icon);
-    $link = "cmd.$d=set $d $link" if(defined($link));

+    my $cmdlist = $link;
+    my $h = "";
+    foreach my $cmd (split(":", $cmdlist)) {
+      my $htmlTxt;
+      my @c = split(' ', $cmd);   # @c==0 if $cmd==" ";
+      if(int(@c) && $allSets && $allSets =~ m/\b$c[0]:([^ ]*)/) {
+        my $values = $1;
+        foreach my $fn (sort keys %{$data{webCmdFn}}) {
+          no strict "refs";
+          $htmlTxt = &{$data{webCmdFn}{$fn}}($FW_wname,
+                                           $d, $FW_room, $cmd, $values);
+          use strict "refs";
+          last if(defined($htmlTxt));
+        }
+      }
+
+      if( $htmlTxt ) {
+        $h .= "<p>$htmlTxt</p>";
+      }
+    }
+
+    if( $h ) {
+      $link = undef;
+      $h =~ s/'/\\"/g;
+      $txt = "<a onClick='FW_okDialog(\"$h\")'\>$txt</a>";
+    } else {
+      $link = "cmd.$d=set $d $link" if(defined($link));
+    }
+
   }


statt des ok dialogs würde ich einen neuen dialog ohne ok button und nur dem x zum schliessen verwenden wollen und ihn direkt neben dem device icon erscheinen lassen.

für den floorplan würde ich einen neuen typ 7 vorschlagen der nur das icon anzeigt und beim klick alle webCmd im popup anzeigt.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Ich habe nichts gegen die Moeglichkeit, Werte in einem Dialog aendern zu koennen.

Mich stoert es aber, das im devStateIcon unterzubringen. Insb. wenn diese unterschiedliche Bilder anzeigen soll, ist die Spezifikation etwas muehsam. Waere es nicht intuitiver, sowas in webCmd unterzubringen? Idee: wir fuehren mit einem neuen Attribut eine weitere Ebene ein, um solche Befehle spezifizieren zu koennen, davon koennten beide profitieren.

Sag Bescheid, wenn du meinst, dass ich es uebermehmen soll, deine Kommentare klingen so, als ob du es noch als unfertig betrachten wuerdest.

justme1968

ich möchte auf jeden fall den dialog und die positionierung noch überarbeiten bevor es übernommen wird.

an ein eigenes attribut hatte ich anfangs auch gedacht.

das würde dann aber bedeuten das es zwei attribute gibt die das aussehen und verhalten des icons bestimmen. da sehe ich mögliche konflikte und unklarheiten. vermutlich wird es auch schwierig den vorrang eindeutig zu definieren ohne am ende funktionalität und code zu verdoppeln.

der einfachste und vermutlich häufigste fall ist ja das bei einem klick genau ein kommando ausgeführt wird. die einzige änderung wäre hier das man auch set kommandos verwenden kann die einen variablen parameter erwarten. also dim oder pct statt on und off. die definition von devStateIcon wird also nicht komplizierter als sie jetzt auch ist.

das die definition etwas mühsam wird wenn es unterschiedliche bilder gibt hat ja nichts mit dem popup zu tun sondern ist jetzt auch schon so. z.b. bei einem rollladen mit 10 icons für unterschiedliche zustände.

eine vereinfachung könnte sein das man ein mal zustand und icon in ein attribut steckt und zum anderen zustand und kommando.

das ist aber alles nicht rückwärts kompatibel zu machen.

---

was ich mir prinzipiell noch vorstelle könnte (auch für andere multivalue attribute, also solche die über irgend ein trennzeichen einstellungen für mehrere zustände treffen) ist das man sie tatsächlich intern als hash abbildet und über eine liste aus key und value darstellt und editiert. das würde auch probleme mit den unterschiedlichen trennzeichen und verbotenen zeichen vermeiden.

aussehen könnte das z.b. so:devStateIcon { 'on' => { icon => 'on', onClick => 'off' },
               'off' => { icon => 'off', onClick => 'on' } }


das ist zwar länger als die aktuelle version und schwieriger auf der kommando zeile zu tippen, es ist aber strukturiert und
der vorteil wäre dann eine einheitliche interne darstellung ohne immer neu zu splitten und zu parsen sowie die möglichkeit ein einheitliches ähnlich strukturiertes gui zum editieren bereit zu stellen.

das würde aber von evetMap über die event-... attribute und devStateIcon bis hin zu plotFunction sehr viel attribute betreffen und wäre ein größerer umbau und eine andere baustelle.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

#4
anbei eine version die von meiner seite aus funktioniert. ich denke es ist erst mal am sinnvollsten es über devStateIcon umzusetzen.

auf fhemweb seite:
- ein kommando bei devStateIcon kann jetzt auch eines sein das einen parameter erwartet
- bei kommandos ohne parameter ist alles wie bisher
- bei kommandos mit parametern erscheint ein popup mit dem entsprechenden widget
- widgetOverride wird ausgewertet

auf js seite:
- das ersetzen der fhemwidgets ist ein eine eigene funktion FW_replaceWidgets ausgelagert
- in FW_okDialog werden im übergebenen text die widgets ersetzt
- FW_okDialog hat einen optionalen zweiten parameter um ein parent element zur positionierung des dialogs anzugeben
- der saveCheck dialog wird direkt am fragezeichen positioniert

zur positionierung des dialogs: die im patch eingebaute variante positioniert den dialog immer vom anker element hin zur fenster mitte. das liefert im floorplan meiner meinung nach bessere ergebnisse als die auskommentierte zeile die alles jquerui überlässt.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Du schiebst das okDialog zum aufrufenden Widget vom Mitte des Bildschirms. Bin noch nicht sicher, ob mir das gefaellt, und ob die Menge an notwendigen Code das rechtfertigt. Und ich kann es nicht nachvollziehen, warum du die Positionierung selbst machst, "bessere ergebnisse" ist mir zu schwammig.

Ich kriege eine Warnung, weiss nicht genau warum:
2015.02.15 14:33:44.982 1: PERL WARNING: Use of uninitialized value $cmdlist in split at ./FHEM/01_FHEMWEB.pm line 2437.

justme1968

der dialog wird nur verschoben wenn ein ankerpunkt mit übergeben wird. für die popups die einen wert einzustellen ist das meiner menung nach auf jeden fall sinnvoll um zu sehen zu welchem icon/device der dialog gehört und so gut es geht zu vermeiden das der dialog genau über dem icon liegt. das ist sonst auf dem floorpan sehr oft der fall

wenn du das für den saveCheck dialog nicht magst kannst du den paramter einfach weg lassen. ich finde es aber auch da praktisch weil man die maus nicht so weit bewegen muss.

besser heisst es ist konsistent immer zur mitte hin. die jquery regeln (die auskommentierte zeile) verschieben den dialog nur wenn er nicht mehr auf den bildschirm passt. das schaut beim floorplan mit icons nahe am rechten rand manchmal seltsam aus.


die warnung kommt vermutlich von einem icon bei dem überhaup kein kommando definiert ist. das schaue ich mir noch mal an.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Zitatdas schaut beim floorplan mit icons nahe am rechten rand manchmal seltsam aus.

Ich haette gerne dafuer einen Beipiel (am besten nachvollziehbar), da es mir zu viele Zeilen sind, die ich mir in einem Jahr nicht mehr erklaeren kann.

rudolfkoenig

Hab eingecheckt, aber erstmal mit der jQuery eigenen Positionierung.
Seit welcher Version unterstuetzt perl den // Operator? Die Suchmaschine ignoriert // in der Anfrage.

rudolfkoenig

Habs doch gefunden: perl 5.10.0
Schauen wir mal, ob jemand noch mit einem aelteren Version unterwegs ist.

justme1968

danke fürs einchecken.

würdest du im FW_okDialog vor dem FW_replaceWidgets auch noch ein FW_replaceLink einbauen?

dann muss das nicht umständlich im floorplan passieren (http://forum.fhem.de/index.php/topic,33935.msg262778.html#msg262778).

ich würde vorschlagen das genau so wie beim FW_replaceWidgets auszulagern und dann aus FW_jqueryReadyFn und FW_okDialog aufzurufen.

ich würde den patch dazu fertig machen...
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Habs eingebaut, weiss aber nicht, wie ich testen soll.
Haste ein Beispiel?

justme1968

das reicht noch nicht ganz.

es muss etwas in der art sein:$(div).find("a[href]").each(function() { FW_replaceLink(this) });

ich baue dir einen test.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

es muss auf jeden fall diese zeile sein:$(div).find("a[href]").each(function() { FW_replaceLink(this); }); die variante die du eingecheckt hattest bricht mit einem fehler ab.

zum testen kannst du folgendes machen. ein dummy mit webCmd anlegen:define dddd dummy
attr dddd devStateIcon on:on:off off:off:on
attr dddd fp_fp 392,1014,8,,
attr dddd room popup
attr dddd setList on off pct:slider,0,5,100
attr dddd webCmd on:off:pct:pct 50


das hier:sub
popupTest
{
  my($d) = @_;

  my $cmdList = AttrVal($d, "webCmd", "");
  my $allSets = FW_widgetOverride($d, getAllSets($d));
  my $state = $defs{$d}{STATE};

  my $txt = $state;

  my ($icon, $isHtml);
  $txt = FW_makeImage($state);
     
  my $cmdlist = $cmdList;
  my $h = "";
  foreach my $cmd (split(":", $cmdlist)) {
    my $htmlTxt;
    my @c = split(' ', $cmd);   # @c==0 if $cmd==" ";
    if(int(@c) && $allSets && $allSets =~ m/\b$c[0]:([^ ]*)/) {
      my $values = $1;
      foreach my $fn (sort keys %{$data{webCmdFn}}) {
       no strict "refs";
        $htmlTxt = &{$data{webCmdFn}{$fn}}($FW_wname,
                                         $d, $FW_room, $cmd, $values);
        use strict "refs";
        last if(defined($htmlTxt));
      }   
    }   
   
    if( $htmlTxt ) {
      $h .= "<p>$htmlTxt</p>";
    } else {
      my $link = "cmd.$d=set $d $cmd";
      $h .= "<p><a href='$FW_ME$FW_subdir?$link$FW_CSRF'>$cmd</a></p>";
    }   
  }
   
  if( $h ) {
    $h =~ s/'/\\"/g;
    $txt = "<a onClick='FW_okDialog(\"$h\",this)'\>$txt</a>";
  }

  $txt = "<div id=\"$d\" class=\"col2\">$txt</div>";

  return $txt;
}
als devStateIconVerwenden:attr dddd devStateIcon {popupTest($name)}

beim klick auf das icon bekommst du dann ein popup mit allen in webCmd definierten kommandos. ohne das FW_replaceLink erfolgt für die drei kommandos ein neu aufbau der seite weil das XHR fehlt. mit dem FW_replaceLink bleibt das popup offen und das schalten geht im hintergrund.

in der normalen raum übersicht ist natürlich nur beschränkt sinnvoll aber mit dem patch von hier: http://forum.fhem.de/index.php/topic,33935.msg262778.html#msg262778 ist es für den floorplan.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968