FHEM mit bunten Bildern

Begonnen von Prof. Dr. Peter Henning, 22 März 2015, 15:49:50

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Hallo Liste,

nachdem ich das gestern auf dem Usertreffen angekündigt habe, hier die erste Implementation.

1. In die Datei 99_myUtils.pm einfügen


# This block is only needed when SVG is loaded bevore FHEMWEB
sub FW_pO(@);
use vars qw($FW_RET);     # Returned data (html)
use vars qw($FW_RETTYPE); # image/png or the like
use vars qw($FW_plotmode);# Global plot mode (WEB attribute), used by SVG
use vars qw($FW_plotsize);# Global plot size (WEB attribute), used by SVG
use vars qw(%FW_webArgs); # all arguments specified in the GET

sub myUtils_Initialize($$)
{
  my ($hash) = @_;
  $data{FWEXT}{"/SVGX_widget"}{FUNC} = "SVGX_widget";
  $data{FWEXT}{"/SVGX_widget"}{FORKABLE} = 1;
}


2.
In der Datei 99_myutils.pm eine Subroutine einfügen:

sub SVGX_widget($)
{
  my ($arg) = @_;
  my $type = $FW_webArgs{type};
  my $subtype = $FW_webArgs{subtype};
 
  my @size=split('x',($FW_webArgs{size} ? $FW_webArgs{size} : 320x240));
  #Log 1,"++++++++++++++++++++++++++++++++++++++++++++";
  #Log 1,"SVGX_widget type $type (subtype $subtype) called with $arg";
  #Log 1,"SVG Plotmode is ".AttrVal($FW_wname, "plotmode", "SVG");
  #Log 1,"SVGX_widget has size ".$size[0]."x".$size[1];
  #Log 1,"++++++++++++++++++++++++++++++++++++++++++++";
 
  $FW_RETTYPE = "image/svg+xml";
  $FW_RET="";
  FW_pO '<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 0 320 200" width="'.$size[0].'px" height="'.$size[1].'px">';

  if( $type eq 'bar' ){
    #
    # Horizontal color bar
    #
    #  ---------------
    # | |    | |    | |
    #  ---------------
    #
    # 16           264
    # three parameters w. scale
    # p1 = interior display value - either as "reading" name or as number
    #      if it is given as "reading" name, a dev parameter must be given
    # s1 = scale, consisting of max. value and unit e.g.: 35.0 kWh
    # p2 = exterior display value - either as "reading" name or as number
    # s2 = scale, consisting of (ignored) number and unit, e.g.: 1 kW
    # p3 = lower bottom label

    my $p1 = $FW_webArgs{p1};
    my $raw1;
    if( $p1 =~ /\d*\.\d*/ ){
      $raw1 = $p1;
    } else {
      $raw1 = ReadingsVal($FW_webArgs{dev},$p1,0);
    }
    my @s1 = split(' ',$FW_webArgs{s1});

    my $p2 = $FW_webArgs{p2};
    my $raw2;
    if( $p2 =~ /\d*\.\d*/ ){
      $raw2 = $p2;
    } else {
      $raw2 = ReadingsVal($FW_webArgs{dev},$p2,0);
    }
    my @s2 = split(' ',$FW_webArgs{s2});

    #-- scaling
    my $val1 = int($raw1/$s1[0]*248+16);
 
    FW_pO '<defs>';
    #-- white - snow4
    FW_pO '<linearGradient id="grad0" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:white;stop-opacity:1"/><stop offset="100%" style="stop-color:rgb(139, 137, 137);stop-opacity:1"/></linearGradient>';
    if( $subtype eq 'red'){
      #-- lightsalmon/red and lightsalmon/lightsalmon3
      FW_pO '<linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:rgb( 255, 192, 188);stop-opacity:1"/><stop offset="100%" style="stop-color:red;stop-opacity:1"/></linearGradient>';
      FW_pO '<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:rgb( 255, 192, 188);stop-opacity:1"/><stop offset="100%" style="stop-color:rgb( 255, 140, 105);stop-opacity:1"/></linearGradient>';
   }elsif( $subtype eq 'green'){
      #-- chartreuse/green and chartreuse/chartreuse3
      FW_pO '<linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:rgb( 127,255, 0);stop-opacity:1"/><stop offset="100%" style="stop-color:green;stop-opacity:1"/></linearGradient>';
      FW_pO '<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:rgb( 127,255, 0);stop-opacity:1"/><stop offset="100%" style="stop-color:rgb( 102, 205, 0);stop-opacity:1"/></linearGradient>';
    }elsif( $subtype eq 'blue'){
      #-- cyan/blue and cyan/cyan3
      FW_pO '<linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:cyan;stop-opacity:1"/><stop offset="100%" style="stop-color:blue;stop-opacity:1"/></linearGradient>';
      FW_pO '<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:cyan;stop-opacity:1"/><stop offset="100%" style="stop-color:rgb( 0, 205, 205);stop-opacity:1"/></linearGradient>';
    }
    #-- colored shadow 1 / 2 pixel
    FW_pO '<filter id="cshadow1" x="0" y="0" width="200%" height="200%"><feOffset result="offOut" in="SourceGraphic" dx="1" dy="1" /><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0.9 0.9 0.9 0.4 0" /><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="1" /><feBlend in="SourceGraphic" in2="blurOut" mode="normal" /></filter>';
    FW_pO '<filter id="cshadow2" x="0" y="0" width="200%" height="200%"><feOffset result="offOut" in="SourceGraphic" dx="2" dy="2" /><feColorMatrix result="matrixOut" in="offOut" type="saturate" values="0.2" /><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="1" /><feBlend in="SourceGraphic" in2="blurOut" mode="normal" /></filter>';
    FW_pO '</defs>';
   
    FW_pO '<g><g transform="translate(0,45)">';
    FW_pO '<rect x="16" y="5" width="40" height="80" rx="20" ry="40" fill="url(#grad0)"/>';
    FW_pO '<rect x="264" y="5" width="40" height="80" rx="20" ry="40" fill="rgb(255,250,250)"/>';
    FW_pO sprintf('<rect x="16" y="5" width="%d" height="80" rx="20" ry="40" fill="url(#grad1)"/>',$val1+20);
    FW_pO sprintf('<rect x="%d" y="5" width="40" height="80" rx="20" ry="40" fill="url(#grad2)"/>',$val1);
    FW_pO '<rect x="264" y="5" width="40" height="80" rx="20" ry="40" fill="none" stroke="rgb(139, 137, 137)" stroke-width="2"/>';
    FW_pO '<rect x="16" y="5" width="288" height="80" rx="20" ry="40" fill="none" stroke="rgb(139, 137, 137)" stroke-width="2"/>';
    #-- label
    FW_pO sprintf('<text x="150" y="52" fill="rgb(75, 75, 75)" style="filter:url(#cshadow1);font-size:24px;font-weight:bold">%5.2f %s</text>',
       $raw1,$s1[1]);
    FW_pO '</g>';
    FW_pO sprintf('<text x="30" y="40" fill="blue" style="filter:url(#cshadow2);font-family:Helvetica;font-size:32px;font-weight:bold">%5.2f %s</text>',
       $raw2,$s2[1]);
    FW_pO sprintf('<text x="16" y="160" fill="rgb(75, 75, 75)" style="filter:url(#cshadow1);font-family:Helvetica;font-size:24px;font-weight:bold">%s</text>',
       $FW_webArgs{p3});
    FW_pO '</g>';
  }elsif($type eq 'thermometer'){
    #
    # Vertical thermometer symbol
    #
    #    ||
    #    || 
    #    ||
    #   |__|
    #
    # one parameters w. scale
    # p1 = display value - either as "reading" name or as number
    #      if it is given as "reading" name, a dev parameter must be given
    # s1 = scale, consisting of max. value and unit e.g.: 35.0 kWh
    #

    my $p1 = $FW_webArgs{p1};
    my $raw1;
    if( $p1 =~ /\d*\.\d*/ ){
      $raw1 = $p1;
    } else {
      $raw1 = ReadingsVal($FW_webArgs{dev},$p1,0);
    }
    my @s1 = split(' ',$FW_webArgs{s1});
  }
  FW_pO '</svg>';
  return ($FW_RETTYPE, $FW_RET);
}


3. Wenn man nun als normalen "STATE" eines Devices ein Bild anzeigen lassen möchte, (sagen wir, die readings Wd und Pac des devices nt5000), so muss dessen Stateformat gesetzt werden auf


<embed src='fhem/SVGX_widget?type=bar&subtype=green&dev=nt5000&size=200x100&p1=Wd&s1=35.0 kWh&p2=Pac&s2=1 kW&p3=PV'/>


4. Selbstverständlich kann man das auch in Webseiten einbinden - einfach per <img href="<serveradresse>/fhem ...."/>

Resultate siehe anliegende Bilddatei.

Bisher ist nur der horizontale Balken realisiert - mehr solcher Widgets werde ich noch zur Verügung stellen. Außerdem muss noch die automatische Aktualisierung eingebaut werden.

Die leichte (und beabsichtigte) Verunschärfung beruht auf dem SVG-Filter, wem das nicht gefällt sollte die entsprechenden Parameter aus dem Code herauslassen.

LG

pah

kvo1

Hallo pah,

hab das eben mal versucht nachzustellen... mit meinem Gaszählerstand... irgendwas mach ich aber falsch (Achtung "Anfänger"  ;) )

Du schreibst einmal "99_myUtils.pm" und dann "99_myutils.pm"    meinst Du die gleiche Datei ?

Wo muss diese Datei(en) liegen .? , doch im Pfad .../fhem/FHEM   ? oder

Firefox bemängelt (bei mir ) ein fehlendes Plugin ????

Danke für ein paar Tipp´s

kvo1





RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Prof. Dr. Peter Henning

Ja, gleiche Datei mit U.

Welches fehlende Plugin ? Firefox kann SVG ganz gut verarbeiten.

LG

pah

anfichtn

Moin!

Ich hab das gleiche Problem....

fehlendes Plugin.

direktaufruf der funktion ist auch nicht möglich.

Grüße

anfichtn
FHEM 5.6 + Pilight + Pimatic auf BananaPro mit Bananian 15.04 r01
FB7270 v2 & FB7412
LDA382A mit WifiLight
MAX-Cube (aculfw), 6 Fensterkonstakte, 5 HK-Thermostate, 3 WandThermostate
[...]

Prof. Dr. Peter Henning

Hm. Mal ein Test: Was sagt diese seltsame Firefox-Version, wenn man mit ihr die anhängende Datei aufmacht ?

LG

pah

kvo1

RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Prof. Dr. Peter Henning

OK, das ist geklärt. Nächster Testschritt:

1. In der 99_myUtils.pm die Zeilen

  #Log 1,"++++++++++++++++++++++++++++++++++++++++++++";
  #Log 1,"SVGX_widget type $type (subtype $subtype) called with $arg";
  #Log 1,"SVG Plotmode is ".AttrVal($FW_wname, "plotmode", "SVG");
  #Log 1,"SVGX_widget has size ".$size[0]."x".$size[1];
  #Log 1,"++++++++++++++++++++++++++++++++++++++++++++";

von Kommentarzeichen befreien.

2. reload von 99_:myUtils.pm

3. Im Browser aufrufen


http://<server-adresse>/fhem/SVGX_widget?type=bar&subtype=green&p1=3.45&s1=10 kWh&p2=2.0&s2=1 kW&p3=Keine Ahnung


und mitteilen, was passiert.

LG

pah

kvo1

http://<server-adresse>/fhem/SVGX_widget?type=bar&subtype=green&p1=3.45&s1=10 kWh&p2=2.0&s2=1 kW&p3=Keine Ahnung

Hier kommt nichts raus !

http://<server-adresse/fhem/SVGX_widget?type=bar&subtype=green&dev=HCN2_Gas&size=200x100&p1=countsPerDay&s1=35.0 kWh&p2=verbrTagkWh&s2=1 kW&p3=PV

Kommt siehe "link.jpg"

im Fhem aber "CNG-reading2.jpg"

die Readings sind aber vorhanden   "CNG-reading.jpg"

Ich habe wohl noch ein Verständnisproblem was p1 / S1 / p2 / s2 ... angeht  ?

Anbei mal meine DEF

###########################
define HCN2_Gas HourCounter AZ3fachSchalter_Sw_01.closed.* AZ3fachSchalter_Sw_01.open.*
attr HCN2_Gas group Gaszähler
attr HCN2_Gas room UG_Gesamt
attr HCN2_Gas userReadings verbrTagkWh {sprintf("%.2f",ReadingsVal("HCN2_Gas","countsPerDay",0)*0.1*0.9655*11.178) . " kWh";;;;}
attr HCN2_Gas verbose 1
attr HCN2_Gas stateFormat <embed src='fhem/SVGX_widget?type=bar&subtype=green&dev=HCN2_Gas&size=200x100&p1=countsPerDay&s1=35.0 kWh&p2=verbrTagkWh&s2=1 kW&p3=PV'/>

### Alles loggen ==> define FileLog_HCN2_Gas FileLog ./log/HCN2_Gas-%Y.log HCN2_Gas
### nicht alle Daten in das Logfile schreiben
define FileLog_HCN2_Gas FileLog ./log/HCN2_Gas-%Y-%m.log HCN2_Gas:countsOverall:.*|HCN2_Gas:countsPerDay:.*|HCN2_Gas:state:.*
attr FileLog_HCN2_Gas group Gaszähler
attr FileLog_HCN2_Gas logtype text
attr FileLog_HCN2_Gas room hidden
# dummy fuer Zaehlerstand im Floorplan
define Zaehlerstand dummy
attr Zaehlerstand group Gaszähler
attr Zaehlerstand room UG_Gesamt
define myNotify notify HCN2_Gas:countsOverall.* { fhem("set Zaehlerstand ". $EVTPART1 / 10 ) }
# dummy fuer Tagesverbrauch im Floorplan
define Tagesverbrauch dummy
attr Tagesverbrauch alias Tagesverbrauch (m³)
attr Tagesverbrauch group Gaszähler
attr Tagesverbrauch room UG_Gesamt
define TVNotify notify HCN2_Gas:countsPerDay.* { fhem("set Tagesverbrauch ". $EVTPART1 / 10 ) }
####################################################################
### Umrechung/Darstellung der Leistung in KWh
####################################################################
### neues UserReading fuer Energieverbrauch in KWh
# dummy fuer TagesLeistung im Floorplan
define TagesLeistung dummy
attr TagesLeistung alias Tagesenergie
attr TagesLeistung group Gaszähler
attr TagesLeistung room UG_Gesamt
define KWNotify notify HCN2_Gas:verbrTagkWh.* set TagesLeistung %EVTPART1 KWh

kvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

UweH

#8
Interessanter Effekt. Firefox 36.0.4 auf Linux Mint 17.1
Im Dashboard mault Firefox über ein fehlendes Plugin, im Raum OWX ist alles ok...

Edit: Hab's gerade mal unter Win 8.1 versucht, gleicher Effekt mit Firefox 36.0.4. Unter Ubuntu Mate mit 36.0.1 ebenso.
Ganz verrückt ist der IE11 unter Win 8.1. Statt des SVG lädt er die FHEM-Webseite...

kvo1

#9
Hallo pah,
Ich würde das Thema gern weiter verfolgen.
Könntest Du die Parameter bitte nochmal beschrieben , bzw mir eine Denkanstoß geben, was da in
meinem Fall falsch ist.

Danke vorab.

Kvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Prof. Dr. Peter Henning

Mach ich.

type=bar (einzige Möglichkeit bisher)
subtype=green,red oder blue
size=200x100  (Größe)
dev=HCN2_Gas  (Devicename)
p1=countsPerDay (Entweder ein Zahlenwert, oder der Name eines Readings, bestimmt Zylinderfüllung)
s1=35.0 kWh (Maximaler Wert (d.h. farbige Säule füllt den Zylinder) und Skalenparameter (kWh hier))
p2=verbrTagkWh (Entweder ein Zahlenwert, oder der Name eines Readings, wird oben drüber geschrieben)
s2=1 kW (Zahl wird ignoriert, Skalenparameter (kW hier))
p3=PV (Label, wird unten drunter geschrieben)

LG

pah

kvo1

Hallo pah,
danke für die Erklärung , aber irgendwas mache ich vermutlich immer noch falsch.
Habe jetzt mal versucht den Inhalt eines Brunnens darzustellen , mit folgenden Readings

content      1746.5
Level          66
rawValue    266
state          1746.5     

Maximale Menge sind 2100 Liter !

attr Brunnen stateFormat <embed src='fhem/SVGX_widget?type=bar&subtype=green&dev=Brunnen&size=200x100&p1=content&s1=2100.0 Liter&p2=rawValue&s2=1 Liter&p3=Wassermenge'/>

p2 (rawValue)  soll oben drüber geschrieben werden, das tut´s aber nicht , stattdessen 0.00 Liter !

Was mache ich hier noch falsch ?

Danke für Deine Geduld.

PS:
Eins ist mir auch noch aufgefallen, die Darstellung im Floorplan scheint nicht zu funktionieren  :-[

kvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Prof. Dr. Peter Henning

#12
Hm, kann evtl. am Integer-Wert des raw liegen. Bitte mal probieren, den Parameterwert für p2 durch die Zahl 266.0 zu ersetzen.

Betreffend Floorplan: Habe ich derzeit noch nicht auf der Agenda, kann ich nichts dazu sagen. Erst einmal die Widgets im FHEMWEB, dann kommen andere Frontends dran.

LG

pah

kvo1

Zitat von: Prof. Dr. Peter Henning am 05 April 2015, 05:44:37
Hm, kann evtl. am Integer-Wert des raw liegen. Bitte mal probieren, den Parameterwert für p2 durch die Zahl 266.0 zu ersetzen.

Betreffend Floorplan: Habe ich derzeit noch nicht auf der Agenda, kann ich nichts dazu sagen. Erst einmal die Widgets im FHEMWEB, dann kommen andere Frontends dran.

LG

pah
266.0 geht !

LgKvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Prof. Dr. Peter Henning

OK, Fehler gefunden.

In dem oben angebenen Code bitte

/\d*\.\d*/

durch

/\d*\.+\d*/

ersetzen.

LG

pah