Anzeige von "devicestate" und "reading" (Stil 0 + Stil 3)

Begonnen von nine42, 24 Februar 2016, 22:21:20

Vorheriges Thema - Nächstes Thema

nine42

Ich verwende den Floorplan nun schon seit langer Zeit auf einem Tablet (nicht zuletzt wegen des hohen WAFs ;-).

Neben der Einzel-Darstellung von States (als Icons) und Readings würde ich gerne beides anzeigen lassen.
Beispiel wäre der Zustand eines Kontaktsensors - zusammen mit der letzten Kontaktzeit, die in einem userReading des Kontakt-Devices abgelegt wird.
Ich könnte zur Darstellung zwar "state" und das "userReading" mit "stateFormat" zusammensammeln, fände es aber wesentlich eleganter, mit FHEM-Bordmitteln zu arbeiten.

Gibt es dafür in Floorplan einen Weg?

(... ich hab' in 95_FLOORPLAN.pm etwas geschmökert - wäre, meiner Meinung nach, in FP_show() recht einfach umzusetzen - z.B. als "Stil 9" ... o.k. das Ganze müsste dann auch noch dokumentiert werden ...)


Eine ähnliche Frage ist in http://forum.fhem.de/index.php/topic,48743.0.html beschrieben.
Bislang hab' ich genau die Lösung umgesetzt, die dort (auch) vorgeschlagen wird. Das ist aber unschön, weil man ein neues Dummy-Device erzeugt, die Information zur Zeit aber eigentlich zum Device gehört und nicht in ein anderes...

UliM

Hi,
ich würde hier ein readingsproxy device empfehlen.
Gruß Uli
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

nine42

Hallo,

Readingsproxy: "Makes (a subset of) a reading from one device available as a new device.
This can be used to map channels ... to independend devices that can have state, icons and webCmd different from the parent device and can be used in a floorplan."
... eigentlich mach´ich das gerade schon mit einem Dummy - dort speichere ich die Schaltzeit im state ab. Beim Dummy muss ich allerdings noch über ein "notify" gehen, um den Wert zu übertragen. Das wird der Readingsproxy wohl selbständig machen. Also schon mal eine Verbesserung - Danke.

ABER:
Als Informatiker möchte ich die Daten da lassen, wo sie hingehören - und die Zeit der letzten Zustandsänderung eines Devices gehört als Attribut (im OO-Sinne) in meinen Augen zu dem Device selbst (als userreading). Diese Zeit muss auch nicht geschaltet werden (was ein Vorteil der Readingsproxy-Lösung wäre)
.... jetzt müsste man das nur noch zusammen mit dem Zustand darstellen können ...

Ich schau' mir ´mal den Code in 95_FLOORPLAN.pm an und schlage dann ggf. einen patch vor (für einen Style "9").
... Den Style "8" schau' ich mir dann auch an wg. einer dynamischen Darstellung von Commandos à la tabletUI-widget
(in jquery bin ich allerdings nicht sehr erfahren. Ich bleib' dran, hab' aber z.Z. wenig Zeit -> http://forum.fhem.de/index.php?topic=49883.new;topicseen#new)
Zudem: Ich hab' in FHEM zwar schon vieles konfiguriert und auch einiges in myUtils programmiert, hab' aber etwas Bedenken bei "offizielleren" Sachen wg. der Seiteneffekte in FHEM, die ich nicht wirklich kenne ...
... aber Übung macht den Meister.

Ist das o.k. für Dich?

Peter

UliM

Hi,
klar, gern.
Ich hab mal in Angriff genommen, einen style zu bauen, bei dem man über ein Attribut angeben kann, welche Bestandteile angezeigt wrden sollen, welche in derselben Zeile oder untereinander. Ist aber auf Grund der bestehenden Programmstruktur leider nicht so einfach, und die Abwärtskompatibilität muss ja gewährleistet bleiben.
Vielleicht nehm ich da noch mal nen Anlauf, hab aber aktuell auch leider keine Zeit...
Gruß, Uli
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

nine42

Hallo,

Die Idee mit den "disjunkten" Attributen ist super!
... bin auch gerade am Sichten von FP_show: "zig" Spezialfälle teilweise mit ODER, teilweise mit UND verknüpft.
Wird nicht einfach, da Ordnung reinzubekommen ;-)

... viel Spaß;-)

Grüße, Peter

nine42

Hallo Uli,

hab' etwas Zeit gefunden und einen "Stil 9: (Icon + Device-Reading)" eingebaut.
Damit kann ich nun ein userreading zusätzlich zum state-icon und (optional) den Namen darstellen.
Ich hab' das soweit getestet - bei mir tut es gut. Es war auch nicht wirklich schwierig, so dass ich die begründete Hoffnung habe, dass es grundsätzlich tut, ohne etwas zu zerschiessen.
Ich verwende das, um einen Zeitstempel (hier: das letzte Öffnen eines Kontaktes) der im Device selbst abgespeichert ist anzuzeigen, teilweise mit Namen, teilweise ohne (->Angehängtes Bild)
Wär' super, wenn Du Dir das anschauen und ggf. übernehmen könntest.

Hier die Beschreibung, was ich wo gemacht habe:

in floorplanstyle: neuen Style eintragen
  - z.B. nach .devicename
    .devicereadingval {font-size: 11px; text-align:center; }
 
in 95_FLOORPLAN.pm: neuen Code und Dokumentation eintragen
  - Zeile 158: Erweiterung des Arrays um neuen Stil
  my @styles = ("0 (Icon only)","1 (Name+Icon)","2 (Name+Icon+Commands)","3 (Device-Reading)","4 (S300TH-specific)","5 (Icon+Commands)",
              "6 (Reading+Timestamp)","7 (Commands only)","8 (Icon+Commands popup)","9 (Icon + Device-Reading)");

  - Zeile 614: Code zur Behandlung des neuen Stils
    ########################
    # Device-readingvalue per device
        if ($style == 9) {
            FW_pO "<tr class=\"devicereadingval fp_$FP_name\" id=\"$d"."-$text-val\">";        # For css: class=devicereadingval, id=<devicename>-<reading>-val
            my $devName = ReadingsVal($d, $text, "Undefined Reading $d-<b>$text</b>");         # Style 9 = reading-value
            FW_pO "<td colspan=\"$cols\">";
            FW_pO "$devName" ;
            FW_pO "</td></tr>";
        }

   - neue Zeile 1062 (ca.) Englische Dokumentation des neuen Stils
               <li>9  icon, device-reading</li>

   - neue Zeile 1233 (ca.) Deutsche Dokumentation des neuen Stils
               <li>9  icon, Geräte-reading</li>


Grüße, Peter

nine42

Hallo Uli,

... longpolling ... verflixt ... hätte mir denken können, dass es da Probleme gibt.

Die userReadings werden zwar dargestellt, aber Änderungen bei einem userreading werden (anders als bei states) nicht nach Floorplan per Ajax übertragen.
D.h. der patch tut "im Prinzip" (Namensänderungen werden ja auch in Floorplan nicht sofort übertragen) aber für meinen Anwendungsfall muss ich nochmals ran ...

Grüße, Peter

nine42

... ok: nächster Versuch:
Ich hatte die HTML-Generierung aus der Generierung des Device-name übernommen - das war blauäugig.
Jetzt stammt die Code-Vorlage aus der Generierung des Device-states (und der "Stil 3" hatte schließlich funktioniert).
Darin ist auch der Fall für "FHT-temperature" vorgesehen - was ich nicht testen konnte.
  Jetzt funktioniert das longpolling auch für das userReading.  :D
Ich schätze, das longpolling hat etwas mit "informID" zu tun (ohne das überprüft zu haben).


Das wäre dann der Code zum Überprüfen:

in floorplanstyle: neuen Style eintragen
  - z.B. nach .devicename
    .devicereadingval {font-size: 11px; text-align:center; }
 
in 95_FLOORPLAN.pm: neuen Code und Dokumentation eintragen
  - Zeile 158: Erweiterung des Arrays um neuen Stil
  my @styles = ("0 (Icon only)","1 (Name+Icon)","2 (Name+Icon+Commands)","3 (Device-Reading)","4 (S300TH-specific)","5 (Icon+Commands)",
              "6 (Reading+Timestamp)","7 (Commands only)","8 (Icon+Commands popup)","9 (Icon + Device-Reading)");

  - Zeile 614: Code zur Behandlung des neuen Stils
    ########################
    # Device-readingvalue per device
        if ($style == 9) {
          FW_pO "<tr class=\"devicereadingval fp_$FP_name\" id=\"$d"."-$text\">";               # For css: class=devicereadingval, id=<devicename>-<reading>
          my $readingValue = "";                                                                # initialize variable that stores reading-value
          $readingValue = ReadingsVal($d, $text, "Undefined Reading $d-<b>$text</b>");          # get reading from device
          $readingValue =~ s/measured-temp: ([\.\d]*) \(Celsius\)/$1/;                          # format FHT-temperature ???
          FW_pO "<td><div informId=\"$d-$text\">$readingValue</div>";                           # set up html with reading-value -> use informId for longpolling
          FW_pO "</td></tr>";
        }

   - neue Zeile 1062 (ca.) Englische Dokumentation des neuen Stils
               <li>9  icon, device-reading</li>

   - neue Zeile 1233 (ca.) Deutsche Dokumentation des neuen Stils
               <li>9  icon, Geräte-reading</li>



... ALLERDINGS habe ich ein neues Problem:
Wenn ich das Reading des Devices (hier: CON_Westfenster) über folgendes Notify verändere, funktioniert das longpolling nicht - auch nicht das von "Stil 3".

define CON_Westfenster CUL_HM 2ECD66
attr CON_Westfenster userReadings
define ContactTime notify CON_.*:open.* { \
   my $time = strftime('%H:%M', localtime) ;;\
   fhem( "setreading ".$NAME." time ".$time);; \
}

Ich habe daher das Notify ersetzt durch einen Perl-Code nach dem userReading, der statt des Notifies die Schaltzeit des Kontakts berechnet:

define CON_Westfenster CUL_HM 2ECD66
attr CON_Westfenster userReadings time { strftime('%H:%M', localtime);; }

.. das funktioniert sehr gut: Die Zeit wird gesetzt, sobald der Kontakt geöffnet wird und der FLOORPLAN zeigt das über longpolling auch sofort an

... ALLERDINGS kann ich jetzt das userReading nicht mehr mit einem Timer zurücksetzen:

define Remove_Timestamps at *00:00:00 { \
   fhem ("setreading CON_.* time ---") ;; \
}

denn sobald ich es tue wird wohl ein event generiert (?), welches den Perl-Code des userReadings sofort wieder ausführt, so dass wieder die Zeit drinnen steht.
Zudem erzeugen jetzt auch andere events ein Aktualisieren des userReadings - ohne dass sich der state verändert hätte.
(z.B. Neustart von FHEM).

.. ich hab' nun einiges mit Triggern und event-on-change-reading bzw. event-on-update-reading ausprobiert.
Es ist zum Haarausreißen. Entweder kommt das "setreading" nicht an, oder das longgpolling tut nicht mehr (da wohl kein Event generiert wird)
... ich komme nicht weiter ...

nine42

o.k. ... dann doch mit viel Ausprobieren:
Die Idee war, nur bei einem "open"-Event die Zeit zu setzen, aber irgendwie kann ich mit $EVENT den Event nicht abfragen.
... also frage ich den STATE (mit "Value") ab.
Wenn der STATE "open" ist, wurde der Kontakt geöffnet und die Zeit wird eingetragen.
Wenn der STATE "closed" ist, kam offenbar irgendein anderes Event an und das Zeitattribut wird mit dem alten Zeitstempel überschrieben.

define CON_Westfenster CUL_HM 2ECD66
attr CON_Westfenster userReadings time { Value("CON_Westfenster") eq "open"? strftime('%H:%M', localtime) : ReadingsVal("CON_Westfenster","time","???");;}

... jetzt tut auch "setreading CON_.* time ---"

... was jetzt noch passieren kann ist, dass der Kontakt lange offen ist und in der Zwischenzeit irgendein anderes Event "zuschlägt" - dann würde die Zeit des neuen Events eingetragen. Mal sehen, wie ich das noch abfange (hat da jemand eine Idee?)

UliM

Hi,
mir ist im Moment nicht klar, ob Du da noch tätig bist oder der patch fertig ist.
Wie sieht's denn aus?
Gruß, Uli
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

nine42

#10
Hallo Uli,

nachdem mein erster Patchversuch am longpolling gescheitert war, bin ich etwas vorsichtig geworden und wollte das Ganze im alltäglichen Betrieb etwas intensiver testen.
Der Patch (der vom 27.2. 23:17) funktioniert - Du kannst Ihn übernehmen - das wär super !
Ich habe die neue Version von 95_FLOORPLAN.pm auch nochmals beigefügt.
Die Revisionsbeschreibung müsstest Du dann noch im Kopf von 95_FLOORPLAN.pm vornehmen.
Die Erweiterung des floorplanstyle auch.

Grüße, Peter



... und zwischenzeitlich hab' ich auch rausbekommen, wie ich damit einen Zeitstempel für meine Kontakte realisiere - der auch die unterschiedlichen Events berücksichtigt.
Damit werden die Kontaktzeiten eines Tages als Uhrzeit dargestellt - ab einem Tag ohne Kontakte wird das Datum - etwas dunkler - dargestellt.


Die Definition der Kontakte:

### CONTACT - Westfenster ######################################################
define CON_Westfenster CUL_HM 2ECD66
...
attr CON_Westfenster fp_Erdgeschoss 254,25,9,timedate
...
attr CON_Westfenster userReadings timedate { getContactTime($name) }, date { getContactDate($name) }


und der Code dafür in myUtils:

################################################################################
# Dealing with readings of CON_.*
################################################################################

#--- getContactTime ------------------------------------------------------------
sub getContactTime($) {
  my $device = $_[0];
  my $timedate = "";
  my $state = ReadingsVal($device,"state","???");    # get value of "state"
  my $STATE = Value($device);                        # get value of "STATE"

  #--- contact has only been opened, if current state is open, previous state (STATE) is closed
  if ( ($state eq "open") && ($STATE eq "closed") ) { # contact has been opened
    $timedate =  strftime('%H:%M', localtime); # set display value
  } else {                                     # contact has not been opened
    my $olddate = ReadingsVal($device,"date","???");
    my $newdate = strftime('%d.%m', localtime);
    if ( $newdate eq $olddate ) {            # same day: leave value
      $timedate = ReadingsVal($device,"timedate","???");
    } else {                                 # new date: substitute time by date
      $timedate =  "<div class=\"devicedate\">".$olddate."</div>";
    }
  }
  return $timedate;
}

#--- getContactDate ------------------------------------------------------------
sub getContactDate($) {
  my $device = $_[0];
  my $date   = "";
  my $state  = ReadingsVal($device,"state","???");   # get value of "state"
  my $STATE  = Value($device);                       # get value of "STATE"
  #--- current state is open, previous state (STATE) was closed -> contact has been opened
  if ( ($state eq "open") && ($STATE eq "closed") ) {
    $date = strftime('%d.%m', localtime);        # contact opened -> store new date
  } else {
    $date = ReadingsVal($device,"date","???"); # contact still closed -> just copy value
  }
  return $date;
}


.. und der Timer, der jede Nacht die Zeiten löscht und durch das Datum ersetzt:

#--- Remove Timestamps always at midnight --------------------------------------
define Remove_Timestamps at *00:00:01 { \
   fhem ("setreading CON_.* time ---") ;; \
}


... das Ganze sieht dann so wie im Anhang dargestellt aus.

UliM

Hi,
ok, kommt mit in die nächste Version.
Es hatte vor Langem schon mal jemand nen neuen Stil gebaut für LCARS-layout (Icon und commands nebeneinander statt untereinander), mal sehen ob cih das noch finde, muss auch noch mit rein.
=8-)
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

nine42

Hallo Uli,

Super!

Wg. Stil: Icon & Commando.
Das würde ja Stil 5 entsprechen.
Die Formatierung sollte wohl besser nicht im Code, sondern im Style gemacht werden (?)
(Ich habe bei mir z.B. die Kommandos mit "position/left/top" neben das icon gebracht und über "display" als einspaltige Tabelle)
... oder habe ich das falsch verstanden ...

Grüße, Peter

UliM

Hi,
bei dem LCARS-Stil stehen pro device links das icon und rechts daneben (nicht darunter) die kommandos. Floorplan legt je device einen html-Tabelle an, und Name, icon, Kommandos sind jeweils eine Zeile, erscheinen also jeweils untereinander. Daher kriegt man mit css zwar hin, dass alle Kommandos innerhalb einer Tabellenzelle untereinander stehen, das Erscheinen der Kommandos NEBEN dem icon aber m.W. nicht. Wenn's dafür doch ne Möglichkeit gibt, würde ich mich freuen, die kennenzulernen.
=8-)
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

nine42

Hallo

... meinst Du so -> siehe Anhang?


Für die Positionierung neben den Icons:
#JAL_Wohnzimmer_L-devicecommands { position:absolute; top:-14px;  left:35px; }
#JAL_Wohnzimmer_R-devicecommands { position:absolute; top:-14px;  left:-25px; }

Für die vertikale Anordnung
.devicecommands td        { display:block; padding:0px; }


Grüße, Peter