Plot mal anders

Hallo zusammen

Hab heute mal wieder ein wenig rumgespielt und wollte die PV Anlage besser visualisieren.
Als Abfallprodukt ist eine nette Methode zur grafischen Darstellung von aktuellen Messwerten rausgekommen.

Alles nur natives PHP und CSS, kein JS, kein Highcharts, keine Googlechart kein gar nix,
Trotzdem recht ansehenlich wie ich finde.
Vorteil: Der Plot zeigt im WF immer Livedaten und braucht nahezu keine Resourcen.

Gebaut hab ich es nach der bekannten „Floorplan“ Methode.

Falls es jemand für eigene Kreationen anpassen möchte, hier der Code.


<?
$id_Floorplan = 23961 /*[Energie\PV\Visu\PV_Visu]*/;
$ImgBackground = '"user\PVMonitor\PVBackground.png"';

$AllHigh = 200;
$TopOffset = 56;
$LeftOffset = 80;
$ColWidth = 100;

// Lastverteilung
$LoadValues = array(
	array(getValue(35068 /*[Energie\Plugwise\Circles\Kühlschrank Keller\Leistung_log]*/) ,'Kühlschrank', 'rgba(220,210,0,0.4)'	) ,
	array(getValue(10978 /*[Energie\Plugwise\Circles\Gefrierschrank\Leistung_log]*/) , 'Gefrierschrank',	'rgba(80,140,230,0.7)') ,
	array(getValue(34012 /*[Energie\Plugwise\Circles\Aquarium\Leistung_log]*/) , 'Aquarium','rgba(90,200,70,0.7)'	) ,
	array(getValue(39185 /*[Energie\Plugwise\Circles\Heizraum\Leistung_log]*/) , 'Heizraum','rgba(240,60,230,0.7)'	) ,
	array(getValue(23343 /*[Energie\Plugwise\Circles\Luftbefeuchter\Leistung_log]*/) ,'Luftbef.','yellow'	) ,
	array(getValue(48100 /*[Energie\Plugwise\Circles\Server\Leistung_log]*/) ,	'Server/IT','rgba(240,240,10,0.7)'	) ,
	array(getValue(36554 /*[Energie\Plugwise\Circles\Computer\Leistung_log]*/) ,'Arbeitsplatz','rgba(250,20,40,0.7)') ,
);
$ScaleHigh = $AllHigh / 100;
$Sum = 0;
foreach($LoadValues as $Value) {
	$Sum = $Sum + $Value[0];
}

$Offset = $TopOffset;


// Batt Status
$BattChargeStatus = getValue(22402 /*[Energie\PV\PIP Daten\Batterie\Batterie Ladezustand]*/);
$BattColor = 'rgba(' . intval(255 / 100 * (100 - $BattChargeStatus)) . ',' . intval(255 / 100 * $BattChargeStatus) . ',0,1)';
$BattColor= 'background-image: -webkit-linear-gradient(rgba(60,240,70,0.9) 0%, yellow '.($BattChargeStatus-50).'% , rgba(250,20,40,0.8) 80%)';
$BattChargeStatus = $BattChargeStatus * $ScaleHigh;
$BattChargeStatusOffset = $TopOffset + $AllHigh - $BattChargeStatus;

// Inerterauslastung
$InvLoadStatus = getValue(17804 /*[Energie\PV\PIP Daten\Wechselrichter\Auslastung]*/);
$InvLoadStatus = $InvLoadStatus * $ScaleHigh;
$InvLoadStatusOffset = $TopOffset + $AllHigh - $InvLoadStatus;
$LoadColor='background-image: -webkit-linear-gradient(rgba(250,120,40,0.9) 0%, rgba(60,240,70,0.7)'.($InvLoadStatus-99).'% )';

// Generator
$PVWatt = getValue(12946 /*[Energie\PV\PIP Daten\PV Daten\PV Leistung]*/);
$PVWattPrz = (100 / getValue(25233 /*[Energie\PV\PIP Daten\Wechselrichter\Wirkleistung]*/)) * $PVWatt;
$BatWattPrz = 100 - $PVWattPrz;
$PVHigh = $PVWattPrz * $ScaleHigh;
$BatHigh = $BatWattPrz * $ScaleHigh;
$PVOffset = $TopOffset + $AllHigh - $PVHigh;
$BatOffset = $TopOffset + $AllHigh - $PVHigh - $BatHigh;


//  Now do the Plot

IF (($_IPS['SENDER'] == 'Variable') or ($_IPS['SENDER'] == 'Execute')) {

	// Your Script to get Actuator icon

	$ausgabe = '<p> Photovoltaik Übersicht </p>';
	$ausgabe.= '<p> </p>';
	$ausgabe.= '<div id="floorplan" position:absolute; left:0px; top:0px; z-index:-10';
	$ausgabe.= '<p> <img src=' . $ImgBackground . '; border="0"></p> </div>';

	// Generator (Entweder 100% Netz oder Akku/PV anteilig)

	$Offset = $TopOffset;
	if (getValue(29240 /*[Energie\PV\PIP Daten\Status\Betriebmodus]*/) <> 2) {
		$ausgabe.= '<div style="width:' . $ColWidth . 'px; height:' . $PVHigh . 'px; position:absolute; left:' . ($LeftOffset) . 'px; top:' . $PVOffset . 'px; z-index:0;
				  background-color: rgba(60,240,70,0.7); border: 1px solid gray;";>
              <p style="font-family: Verdana; font-size:10px" > PV </p>
					</div>';
		$ausgabe.= '<div style="width:' . $ColWidth . 'px; height:' . $BatHigh . 'px; position:absolute; left:' . ($LeftOffset) . 'px; top:' . $BatOffset . 'px; z-index:0;
				  background-color: rgba(80,140,230,0.7); border: 1px solid gray;";>
              <p style="font-family: Verdana; font-size:10px" > Akku </p>
					</div>';
	}
	else {
		$ausgabe.= '<div style="width:' . $ColWidth . 'px; height:' . $AllHigh . 'px; position:absolute; left:' . ($LeftOffset) . 'px; top:' . $TopOffset . 'px; z-index:0;
 		  background-color: orange; border: 1px solid gray;";>
               <p style="font-family: Verdana; font-size:10px" > Netz </p>
					</div>';
	}

	$ausgabe.= '<div style="font-size:10px; font-family: Verdana; color: #777777; position:absolute; left:' . ($LeftOffset + 10) . 'px; top:260px; z-index:1";
            <p> Energiequelle </p>  </div>';


// Lastverteilung

	foreach($LoadValues as $Value) {
		$Value[0] = (($Value[0] * 100) / $Sum) * $ScaleHigh;
		if ($Value[0] > 1) {
			$ausgabe.= '<div style="width:' . $ColWidth . 'px; height:' . $Value[0] . 'px; position:absolute; left:' . ($LeftOffset + 150) . 'px; top:' . $Offset . 'px; z-index:0;
				  background-color: ' . $Value[2] . '; border: 1px solid gray;";>
              <p style="font-family: Verdana; font-size:10px" > ' . $Value[1] . '</p>
					</div>';
			$Offset = $Offset + $Value[0];
		}

		$ausgabe.= '<div style="font-size:10px; font-family: Verdana; color: #777777; position:absolute; left:' . ($LeftOffset + 10 + 150) . 'px; top:260px; z-index:1";
            <p> Lastverteilung </p>  </div>';
	}

	// Batt Ladestatus Status
	$ausgabe.= '<div style="width:100px; height:' . $BattChargeStatus . 'px; position:absolute; left:' . ($LeftOffset + 300) . 'px; top:' . $BattChargeStatusOffset . 'px; z-index:0;
				  '.$BattColor.'; border: 1px solid gray;";>
              <p></p>
					</div>';
	$ausgabe.= '<div style="font-size:10px; font-family: Verdana; color: #777777; position:absolute; left:' . ($LeftOffset + 10 + 300) . 'px; top:260px; z-index:1";
            <p> Akkuladezustand </p>  </div>';

	// Inverter Load Status
	$ausgabe.= '<div style="width:100px; height:' . $InvLoadStatus . 'px; position:absolute; left:' . ($LeftOffset + 450) . 'px; top:' . $InvLoadStatusOffset . 'px; z-index:0;
				  '.$LoadColor.'; border: 1px solid gray;";>
              <p></p>
					</div>';
	$ausgabe.= '<div style="font-size:10px; font-family: Verdana; color: #777777; position:absolute; left:' . ($LeftOffset + 10 + 450) . 'px; top:260px; z-index:1";
            <p> Inverterauslastung </p>  </div>';
            

   $ausgabe.= '<div style="font-size:25px; font-family: Verdana; color: #777777; position:absolute; left:' . ($LeftOffset-50) . 'px; top:330px; z-index:1";
            <p> Ersparnis Heute: '.round(getvalue(21834 /*[Energie\PV\PIP Daten\Ertrag\Euro_Ertrag Heute]*/),2).'€ </p>  </div>';

	$ausgabe.= '<div style="font-size:25px; font-family: Verdana; color: #777777; position:absolute; left:' . ($LeftOffset-50) . 'px; top:300px; z-index:1";
            <p> Ersparnis Gestern: '.round(getvalue(42506 /*[Energie\PV\PIP Daten\Ertrag\Euro_Tagesertrag]*/),2).'€ </p>  </div>';


// ___________________________________________________________

	SetValue($id_Floorplan, $ausgabe);
}

?>

Kein JS, Highcharts, Googlechart, nix!? Das sieht man… man sieht nix!
Screenshot vergessen!? :slight_smile:

kein gar nix,

Das beantwortet das doch :smiley:

Gut pariert, ja, sorry, war zu schnell am Abzug.

Dafür sieht es um so besser aus…

Hallo zusammen,
ich habe die nette Idee von bbernhard mal aufgegriffen und ein kleines Script erstellt, mit dem man horizontale Farbskalen darstellen kann. Vorgehensweise:

(1) Neue Varable vom Typ String/HTML-Box erstellen (Beispielname: „Gesamtleistung“). Unterhalb dieser Variablen drei Float-Variablen mit den Namen „greenLimit“, „yellowLimit“ und „maxValue“ anlegen (auf genaue Schreibweise achten).

(2) Unterhalb der zu überwachenden Variable (die vielleicht ja schon vorhanden ist), eine neue Integervariable „ScaleID“ anlegen. Dieser Variablen gebt Ihr dann als Wert die ID der zuvor erstellten HTML-Box.

(3) Als nächstes legt Ihr ein Script mit dem folgenden Inhalt an. Im Skript muss nichts konfiguriert werden.

(4) Für dieses Skript legt Ihr ein Ereignis an, das auf eine Wertänderung der zu überwachenden Variablen reagiert.

Das sollte es dann gewesen sein.

<?
// siehe allgemeine Doku: http://www.mediaevent.de/css/gradient.html
$fade=10; // Überlappungsbereich zwischen zwei Farben in Prozent

$currentValueID = $_IPS['VARIABLE'];  // ID der ausloesenden Variablen
$ScaleID = GetValue(IPS_GetObjectIDByName("ScaleID", $currentValueID));

$greenLimit = GetValue(IPS_GetObjectIDByName("greenLimit", $ScaleID));
$yellowLimit = GetValue(IPS_GetObjectIDByName("yellowLimit", $ScaleID));
$maxValue = GetValue(IPS_GetObjectIDByName("maxValue", $ScaleID));

$green_stop = $greenLimit/$maxValue*100;
$yellow_stop = $yellowLimit/$maxValue*100;

$currentValue = GetValue($currentValueID);

$relValue = $currentValue/$maxValue*100;

if($relValue <= $green_stop)
{
	$color = 'background-image: linear-gradient(90deg,
		green '.k2p($relValue).'%,
		black '.k2p($relValue).'%
	);';
}
else if($relValue <= $yellow_stop)
{
	if($green_stop + $fade > $relValue)  // das Band darf nicht weiter nach rechts gehen als der relValue, 
	   $yellow_left = $relValue;         // sonst ist der schwarze Balken zu kurz und der Messwert zu hoch.
	else
      $yellow_left = $green_stop + $fade;
	
	$color = 'background-image: linear-gradient(90deg,
		green '.k2p($green_stop).'%,
		yellow '.k2p($yellow_left).'%,
		yellow '.k2p($relValue).'%,
		black '.k2p($relValue).'%
	);';

}
else
{
	if($yellow_stop + $fade > $relValue)  // das Band darf nicht weiter nach rechts gehen als der relValue,
	   $red_left = $relValue;         // sonst ist der schwarze Balken zu kurz und der Messwert zu hoch.
	else
      $red_left = $yellow_stop + $fade;

	$color = 'background-image: linear-gradient(90deg,
		green '.k2p($green_stop).'%,
		yellow '.k2p(($green_stop + $fade)).'%,
		yellow '.k2p($yellow_stop).'%,
		red '.k2p($red_left).'%,
		red '.k2p($relValue).'%,
		black '.k2p($relValue).'%
	);';

}

if (($_IPS['SENDER'] == 'Variable') or ($_IPS['SENDER'] == 'Execute')) {

    $ausgabe = '<div style="width:80%; height: 30px;'.$color.'"></div>
	             <div style="width:80%; position: relative; left:'.($relValue*0.8+0.5).'%; top:-25px;">'.GetValueFormatted($currentValueID).'</div>';

    SetValue($ScaleID, $ausgabe);
}
function k2p($str)
{
    return str_replace(",", ".", $str);
}
?>

Vielleicht noch einige Erläuterungen:
Ich habe die Variable „ScaleID“ eingeführt, um im Script erkennen zu können, welche HTML-Box zu verwenden ist. Ich hätte die HTML-Box sicherlich auch unterhalb der zu überwachenden Variablen anordnen können, hätte dann aber eine starre hierarchische Struktur im FrontEnd bekommen. Mit der Variable ScaleID kann ich die HTML-Box dagegen irgendwo hinlegen. Und diese Vorgehensweise ermöglicht es außerdem, dass Script generisch zu halten, so dass es auch für mehrere Skalen verwendet werden kann.
Wenn Ihr eine bessere Möglichkeit kennt, wäre ich sehr daran interessiert (bin halt noch in den Anfängen ;-).

Im Skript selbst habe ich kleine Skalenbereiche eingeführt, in der die farbliche Überlappung erscheint. Die Breite wird mit dem Parameter „$fade“ festgelegt. Für jede HTML-Box werden individuelle Werte für Maximalwert und Limits für grün und gelb definiert. HIntergrund: Bei meinen Anwendungsfall möchte ich die drei el. Phasen des Hauses darstellen. Grün bedeuten dabei „Grundlast“, und die drei Phasen haben unterschiedliche Grundlasten und müssen somit unterschiedliche Schwellen für den Übergang von grün nach gelb (und auch von gelb nach rot) haben.

Wenn ich Ahnung von CSS hätte, könnte man sicherlich die Skalen noch aufpeppen, z.B. mit Skaleneinteilungen und deren Werten usw.

EDIT: Ich habe festgestellt, dass mit den neueren IPS-Versionen die Farbskala nicht mehr angezeigt wird. Das liegt daran, dass als Dezimaltrennzeichnen nun ein Komma ausgegeben wird und nicht mehr der Punkt.
Lösung (vielleicht nicht die Beste):
Ich verwende oben im Script nun eine Function k2p(), die vor der CSS-Formatierung das Dezimaltrennzeichnen von Komma in Punkt ändert.

Viele Grüße
Peter

@Peter: Sehr schön, so macht Community Spass.
bb

@ Peter, sehr schönes Script.
Bei einem zweirichtungs Zähler hat man ja auch negative Werte. Ich hab im Moment leider keine Idee, wie man das Umsetzt.

Vielleicht kann ja jemand helfen.

Michael

@Peter

Danke, feine Sache - habe es mal in meine HTML Seite reingenommen - den Max Wert halte ich dynamisch - da aus Zählersicht ja eventuell mal ein paar KW zusammenkommen könnten - dann wäre der tolle Balken nicht mehr so schön wenn man immer auf den „Max“ Wert gehen würde. Zumindest bei meiner Darstellung :slight_smile:

Danke und Grüsse,
MaLu

Power.png

Hallo MaLu,

wie hast du es denn hinbekommen die Plots so nebeneinander im WebFront anzuzeigen?

Gruß, Michael

Hallo Michael,

das ist eine HTML Box im normalen WF habe ich es gar nicht probiert.

Grüsse,
MaLu

…mmmhhh … Neuland, hab noch tatsächlich noch nie eine HTML Box genutzt. Danke für die Info!
Kannst du mir da ev. auf die Sprünge helfen wie ich da mehrere Werte darstelle?
…sonst muss ich mir wohl mal die Doku reinziehen und das selbst ergründen.

Gruß, Michael

Hallo Michael,

wenn Du den „normalen“ Plot schon „am laufen“ hast - dann arbeiteste ja schon mit HTML Box :D.

Bezüglich HTML Box und dem nebeneinander darstellen von Werten - siehe folgender Link

Mehrere Variablen nebeneinander darstellen oder Werte Formatiert nebeneinander anzeig

Hoffe das hilft Dir erstmal weiter.

Grüsse,
MaLu

super, sehe ich mir mal an - Danke!

Gruß, Michael

Okay MaLu, ich fange ja ganz langsam an zu verstehen … nur nebeneinander will es noch nicht.
Kannst du mir vielleicht mal deinen HTML String als Beispiel posten ? Wie gesagt, mit HTML Tags stehe ich noch ganz am Anfang.

Gruß, Michael

Hallo zusammen,
bei mir wurden nach irgendeinem Upgrade der IPS-Version (Raspberry) die Farbskalen nicht mehr dargestellt. Ich vermute, dass dies mit der UTF-8 Umstellung zu tun hat, denn nun wird als Dezimaltrennzeichen nicht mehr der Punkt, sondern das Komma verwendet, was scheinbar in den <div style> Angaben zu Problemen führt.

EDIT: nachdem nun mit der neuesten IPS-Version vom 26.11.2015 setlocale aus Sicherheitsgründen nicht mehr unterstützt wird, verwende ich nun im Script die Funktion k2p(), die vor der CSS-Formatierung die Dezimaltrennzeichen von Komma auf Punkt umstellt.

Gruß
Peter