HTMLBox Status Wärmepumpe (Beta)

NEUSTE VERSION HIER

Hallo zusammen,
ich bastle gerade an einer Kachel für den Status meiner Wärmepumpe und würde gerne mal eure Meinung einholen bzw. gerne auch Vorschläge von hier berücksichtigen. Hab ich was vergessen? Was ist euch an Informationen wichtig etc.

Das Bild ist animiert (Lüfter dreht sich in eingeschaltetem Zustand)
Es gibt die Zustände An/Heizen, An/Warmwasser und aus

Status: Heizbetrieb, Warmwasser, Defrost, aus
Modus: Normal, Eco, Silent

Viele Grüße
Stephan

2 „Gefällt mir“

Schick!
Bekommst Du auch Daten ob im Speicher der Heizstab aktiv ist und was der ggf. gerade braucht?

Cheers Seppm

Kann ich einbauen, auch wenn für mich nicht relevant. WW macht schön die WP außer bei arktischen Außentemperaturen wo die WP am Limit läuft…

Ich hab noch folgende Werte geplant:
Temperatur: Vorlauf, Rücklauf, Außen, WW Speicher
Statusanzeige: Heizstab WP, Heizstab Speicher

Cool!
Bissl OT:
Bis zu welcher Außentemperatur geht das ohne Heizstab?
Und welche Vorlauf Temp schafft man damit für Warmwasser und FBH?
Man hört da diverse Stories über die Fähigkeiten der WP, da hat sich scheinbar viel getan die letzten Jahre.
Merci Seppm

Extrem cool…
Sobald du was zum testen hast bin ich sehr gerne bereit :blush:

Ich würde mir noch drei Buttons (mit Statusrückmeldung) zur Steuerung wünschen:
Aktiviere/Deaktiviere Heizung
Aktiviere/Deaktiviere Kühlung
Aktiviere/Deaktiviere Warmwasseraufbereitung

Mega, freue mich auf das Ergebnis. :heart_eyes:

Das kommt auf den eingestellten Bivalenzpunkt der wärmepumpe an. Oder bei nicht erreichen der Vorlauf Soll Temperatur

Für alle die testen wollen hier mal ein erste Beta.

Hinweis:
Getestet habe ich es bisher nur in der neuen Tile Visu! Im Browser und der iOS App.
Code muss noch etwas entschlackt werden, zum testen sollte es aber reichen :wink:
Thema Schriftgrößen und Skalierung bei unterschiedlichen Kachelgrößen müssen wir mal beobachten, bitte hier Feedback geben.

Neu:

  • Kompressorfrequenz als Balkenanzeige hinzugefügt
  • Status für Heizstäbe hinzugefügt
  • Temperaturen für WW, Außen, Vor- und Rücklauf
  • Balkenoptik optimiert.

Damit die Balken korrekt funktionieren müsst ihr jeweils euren individuellen Maximalwert angeben. Also z.B. bei der Durchflussmenge den Wert hier anpassen: $durchflussmenge_max = 1500; //Liter

Bilder:
Wärmepumpe.zip (112,8 KB)
Bilder unter diesem Pfad ablegen: /user/img/wp/ Oder unten im Quelltext entsprechend anpassen.

Script:

<?php

// Statusvariablen 
$status = GetValueFormatted(35831);
$status_raw = GetValue(38983);
$status_ww_raw = GetValue(20743);
$status_defrost_raw = GetValue(25475);
$status_silent = GetValue(53628);
$status_eco = GetValue(31136);

//Temperaturen
$temp_aussen = GetValueFormatted(41468);
$temp_ww = GetValueFormatted(22043);
$temp_vl = GetValueFormatted(37910);
$temp_rl = GetValueFormatted(27204);

//Heizstäbe
$hs_backup = GetValue(58032);
$hs_ww_1 = GetValue(21501);
$hs_ww_2 = GetValue(56712);
$hs_ww_3 = GetValue(39438);

//Icon für Anzeige Status Heizstäbe
$hs_backup_icon = ($hs_backup == true) ? "🟢" : "⚪";
$hs_ww_1_icon = ($hs_ww_1 == true) ? "🟢" : "⚪";
$hs_ww_2_icon = ($hs_ww_2 == true) ? "🟢" : "⚪";
$hs_ww_3_icon = ($hs_ww_3 == true) ? "🟢" : "⚪";


//Wärmemengenzähler Heizbetrieb kW
$erzeugung_heizbetrieb_aktuell = GetValue(16429);

//Wärmemengenzähler Warmwasserbetrieb kW
$erzeugung_ww_aktuell = GetValue(14805);

//Aktueller Stromverbrauch in Watt
$watt = GetValueFormatted(25434);

//Verbrauch Heute kWh
$kwh_heute = GetValueFormatted(17601);

//Verbrauch gesamt kWh
$kwh_gesamt = GetValueFormatted(20013);

// Maximale Heizleistung in kW
$leistung_max = 7;

//Durchflussmenge
$durchflussmenge = GetValue(52976);
$durchlussmenge_liter = $durchflussmenge * 1000; //Liter
$durchlussmenge_max = 1500; //Liter
$durchflussmenge_prozent = $durchlussmenge_liter / $durchlussmenge_max * 100;
$durchflussmenge_prozent_round = round($durchflussmenge_prozent, 0);


//Lüfterdrehzahl
$luefterdrehzahl = GetValue(33890);
$luefterdrehzahl_max = 600; //Umdrehungen/Minute
$luefterdrehzahl_prozent = $luefterdrehzahl / $luefterdrehzahl_max * 100;
$luefterdrehzahl_prozent_round = round($luefterdrehzahl_prozent, 0);

//Kompressor
$kompressor = GetValue(19570);
$kompressor_max = 70; //Herz
$kompressor_prozent = $kompressor / $kompressor_max * 100;
$kompressor_prozent_round = round($kompressor_prozent, 0);
$kompressor_aktuell_round =round($kompressor, 0);


//Energieeffizientz
$cop_heizen = round(GetValue(21001),2);
$cop_ww = round(GetValue(12736),2);
$jaz_gesamt = round(GetValue(33510),2);
$jaz_heizen = round(GetValue(59006),2);
$jaz_ww = round(GetValue(16842),2);


if ($status_raw == true && $status_ww_raw == false) {
$leistung_prozent = $erzeugung_heizbetrieb_aktuell / $leistung_max * 100;
//Momentane Heizleistung in kW gerundet
$erzeugung_aktuell_round = round($erzeugung_heizbetrieb_aktuell, 2);
}
elseif ($status_raw == true && $status_ww_raw == true) {
$leistung_prozent = $erzeugung_ww_aktuell / $leistung_max * 100;
//Momentane Heizleistung in kW gerundet
$erzeugung_aktuell_round = round($erzeugung_ww_aktuell, 2);
}
else {
$leistung_prozent = 0;
//Momentane Heizleistung in kW
$erzeugung_aktuell = 0;
$erzeugung_aktuell_round = 0;
}
// Akteulle Leistung in % gerundet (wird für den Diagrammbalken verwendet)
$leistung_prozent_round = round($leistung_prozent, 0);


// Diagramm-Balkenbreite rechter Blaken berechnen
$balken_rechts_leistung_breite_prozent = 100 - $leistung_prozent_round;
$balken_rechts_durchfluss_breite_prozent = 100 - $durchflussmenge_prozent_round;
$balken_rechts_luefterdrehzahl_breite_prozent = 100 - $luefterdrehzahl_prozent_round;
$balken_rechts_kompressor_breite_prozent = 100 - $kompressor_prozent_round;

if ($status_silent == true) {
$modus_text ='Silent';
}
elseif ($status_eco == true){
$modus_text ='Eco';
}
else {
$status_css = 'status-fertig';
$modus_text ='Normal';
}


if ($status_raw == true && $status_defrost_raw == false && $status_ww_raw == false) {
    $wp_image = 'wp_an_heizen.gif';
    $status_css = 'status-heat';
    $status_text = 'Heizbetrieb';
    $cop = $cop_heizen;
}
elseif ($status_raw == true && $status_defrost_raw == true) {
    $wp_image = 'wp_an_heizen.gif';
    $status_css = 'status-defrost';
    $status_text = 'Abtauen';
    $cop = 0;
}
elseif ($status_raw == true && $status_ww_raw == true) {
    $wp_image = 'wp_an_ww.gif';
    $status_css = 'status-ww';
    $status_text = 'Warmwasser';
    $cop = $cop_ww;
}
else {
    $wp_image = 'wp_aus.png';
    $status_css = 'status-off';
    $status_text = 'Aus';
    $cop = 0;
}




$html = '
<style>

        body {margin: 0px;}
    ::-webkit-scrollbar { width: 8px; }
    ::-webkit-scrollbar-track { background: transparent; }
    ::-webkit-scrollbar-thumb { background: transparent; border-radius: 20px; }
    ::-webkit-scrollbar-thumb:hover { background: #555; }
    
    .main_container {
        width: 100%;
        display: flex;
        flex-wrap: nowrap;
        position: relative;
        font-size: 0.9em;
        box-sizing: border-box;
    }



    .div1 {
        width: 30%;
        max-width: 250px;
        min-width: 10px;
        box-sizing: border-box;
    }

    .div1 img {
        width: 100%;
        
        box-sizing: border-box;
    }

    .div2 {
        width: 70%;
        padding: 5px 5px 5px 2.5%;
        margin: 0px 0px 0px 2.5%;
        box-sizing: border-box;
        border-radius:0px 0px 0px 0px;
        //background: linear-gradient(to right, rgba(135,135,135,0.1), white);
       // background: rgba(135,135,135,0.07);
        border-left: 1px dotted #28cdab;

        
    } 
    
    
    .balkendiagramm {
        width: 100%;
        display: flex;
        position: relative;
        margin-bottom: 2%;
        box-sizing: border-box;
    }

.balken_links_leistung, .balken_links_durchfluss, .balken_links_luefterdrehzahl, .balken_links_kompressor, .balken_rechts_leistung, .balken_rechts_durchfluss, .balken_rechts_luefterdrehzahl, .balken_rechts_kompressor  {
        height: var(--div-height);
        padding: 0.5% 0px 0.5% 0px;
        border-radius: calc(var(--div-height) / 4) 0px 0px calc(var(--div-height) / 4);
        font-size: 0.9em;

}

.balken_links_leistung {
width: '.$leistung_prozent_round.'%;
 background: repeating-linear-gradient(to right, red 0%, orange 50%, red 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}

.balken_links_durchfluss {
        width: '.$durchflussmenge_prozent_round.'%;
  background: repeating-linear-gradient(to right, #0054ff 0%, #44a4f5 50%, #0054ff 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}

.balken_links_luefterdrehzahl {
        width: '.$luefterdrehzahl_prozent_round.'%;
  background: repeating-linear-gradient(to right, #d9f3ff 0%, #44a4f5 50%, #d9f3ff 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}

.balken_links_kompressor {
        width: '.$kompressor_prozent_round.'%;
  background: repeating-linear-gradient(to right, #990303 0%, #ff0000 50%, #990303 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}



    .balken_links_leistung_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }
    .balken_links_durchfluss_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }

        .balken_links_luefterdrehzahl_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }
        .balken_links_kompressor_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }


    .balken_rechts_leistung {
        width: ' .$balken_rechts_leistung_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;        
    }

        .balken_rechts_durchfluss {
        width: ' .$balken_rechts_durchfluss_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;          
    }

        .balken_rechts_luefterdrehzahl {
        width: ' .$balken_rechts_luefterdrehzahl_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;          
    }

        .balken_rechts_kompressor {
        width: ' .$balken_rechts_kompressor_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;         
    }



/*
    .status-heat, .status-defrost, .status-ww {
        animation: blink 1.5s infinite;
        animation-fill-mode: both;
    }
*/
.
    .status_off {
        color: #000;
    }

    .status-fertig {
        color: #0eb025;
    }

    .status-heat, .status-ww {
        color: #ff9100;
    }
    
    .status-defrost {
        color: #006bfd;
    }

    @keyframes blink {
        0% {
            opacity: 0
        }

        50% {
            opacity: 1
        }

        100% {
            opacity: 0
        }
    }


</style>
</head>
<body>



<div class="main_container">
    <div class="div1">
        <img src="/user/img/wp/' . $wp_image . '"/>
    </div>
    <div class="div2">
        <b>Status: </b><span class="' . $status_css . '">' . $status_text . '<br></span>
        <b>Modus:</b> ' . $modus_text . '</br>
        
        <div class="balkendiagramm">
            <div class="balken_links_leistung"><span class="balken_links_leistung_text"><b>Leistung: </b>' . $erzeugung_aktuell_round . ' KW</span></div>
            <div class="balken_rechts_leistung"></div>
        </div>
        
        <div class="balkendiagramm">
            <div class="balken_links_kompressor"><span class="balken_links_kompressor_text"><b>Kompressor: </b>' . $kompressor_aktuell_round . ' Hz</span></div>
            <div class="balken_rechts_kompressor"></div>
        </div>

        <div class="balkendiagramm">
            <div class="balken_links_durchfluss"><span class="balken_links_durchfluss_text"><b>Durchfluss: </b>' . $durchlussmenge_liter . ' l/h</span></div>
            <div class="balken_rechts_durchfluss"></div>
        </div>
        
        <div class="balkendiagramm">
            <div class="balken_links_luefterdrehzahl"><span class="balken_links_luefterdrehzahl_text"><b>Lüfterdrehzahl: </b>' . $luefterdrehzahl . ' rpm</span></div>
            <div class="balken_rechts_luefterdrehzahl"></div>
        </div>
        
        JAZ: 🏠' . $jaz_gesamt . ' 🔥' . $jaz_heizen . ' 💧' . $jaz_ww . '</br>
        COP: ' . $cop . '</br>
        Verbrauch: ⚡️' . $watt . ', ⚡️ Heute: ' . $kwh_heute . '</br>
        Temp.: 🌳 ' . $temp_aussen . ' 💧 ' . $temp_ww. ' ⬇️ ' . $temp_vl . ' ⬆️ ' . $temp_rl . '</br>
        Heizstäbe:&nbsp;WP:&nbsp;'.$hs_backup_icon.'&nbsp;&nbsp;&nbsp;WW-Speicher:&nbsp;'.$hs_ww_1_icon.'&nbsp;&nbsp;'.$hs_ww_2_icon.'&nbsp;&nbsp;'.$hs_ww_2_icon.'
    </div>
            
</div>

<script>
//Diagrammbalken-Höhe automatisch an die Schriftgröße anpassen
    var spanElement = document.querySelector(\'.balken_links_leistung_text\');
    var divElement = document.querySelectorAll(\'.balken_links_leistung, .balken_links_durchfluss, .balken_links_luefterdrehzahl, .balken_rechts_leistung, .balken_rechts_durchfluss, .balken_rechts_luefterdrehzahl\');
    var root = document.documentElement; // HTML-Dokument

    // Ermittle die Höhe des span-Elements
    var spanHeight = spanElement.clientHeight;

    // Setze eine CSS-Variable mit der Höhe des span-Elements
    root.style.setProperty(\'--div-height\', spanHeight + \'px\');
</script>
';
//HTML Code in Stringvariable schreiben 
Setvalue(26743, $html);

@paresy
Eine Bitte an die IT Profis hier:
Könnte man die HTML Kacheln mit AJAX und der RPC API dynamisch updaten? Falls hier jemand eine Idee hat bitte immer her damit. Davon hab ich leider null Plan…

Viel Spaß beim testen.
Stephan

2 „Gefällt mir“

Habe das Script auf meine Bedürfnisse angepasst, dh unter anderem einige Werte (JAZ und Heizstäbe) entfernt, die Schrift etwas vergrössert und den Code etwas geändert, da ich Variablen habe, welche den Status und den Modus bereits liefern.

Ich würde mir noch wünschen, dass die Grafik der Wärmepumpe beim vergrössern und verkleinern der Kachel in jede Richtung skaliert (bis jetzt nur horizontal)

Und eine Möglichkeit, die Kühlfunktion darzustellen wäre auch ganz nett.

Auf dem Handy sieht es schon sehr gut aus, auf dem Monitor dürfte es noch etwas grösser dargestellt werden.

Bei mir sieht es auf dem Monitor so aus:
image

Auf dem Handy sieht es so aus:

So sieht das angepasste Script aus:

<?php

// Statusvariablen 
$status = GetValue(18590);
$modus_text = GetValue(43979);


/* Deaktiviert da Statusvariable direkt den Wert liefert
$status_raw = GetValue(12345);
$status_ww_raw = GetValue(20743);
$status_defrost_raw = GetValue(25475);
$status_silent = GetValue(53628);
$status_eco = GetValue(31136);
*/

//Temperaturen
$temp_aussen = GetValueFormatted(44814);
$temp_ww = GetValueFormatted(53122);
$temp_vl = GetValueFormatted(38011);
$temp_rl = GetValueFormatted(23722);

/* Keine Heizstäbe angesteuert
//Heizstäbe
$hs_backup = GetValue(58032);
$hs_ww_1 = GetValue(21501);
$hs_ww_2 = GetValue(56712);
$hs_ww_3 = GetValue(39438);

//Icon für Anzeige Status Heizstäbe
$hs_backup_icon = ($hs_backup == true) ? "🟢" : "⚪";
$hs_ww_1_icon = ($hs_ww_1 == true) ? "🟢" : "⚪";
$hs_ww_2_icon = ($hs_ww_2 == true) ? "🟢" : "⚪";
$hs_ww_3_icon = ($hs_ww_3 == true) ? "🟢" : "⚪";
*/

//Wärmemengenzähler Heizbetrieb kW
$erzeugung_heizbetrieb_aktuell = GetValue(13040);

//Wärmemengenzähler Warmwasserbetrieb kW
$erzeugung_ww_aktuell = GetValue(13040);

//Aktueller Stromverbrauch in Watt
$watt = GetValueFormatted(57766);

//Verbrauch Heute kWh
$kwh_heute = GetValueFormatted(33799);

//Verbrauch gesamt kWh
$kwh_gesamt = (GetValue(21352)+GetValue(16354));

// Maximale Heizleistung in kW
$leistung_max = 7;

//Durchflussmenge
$durchflussmenge = GetValue(58837);
//$durchlussmenge_liter = $durchflussmenge * 1000; //Liter
$durchlussmenge_liter = $durchflussmenge; //Liter
$durchlussmenge_max = 1100; //Liter
$durchflussmenge_prozent = $durchlussmenge_liter / $durchlussmenge_max * 100;
$durchflussmenge_prozent_round = round($durchflussmenge_prozent, 0);


//Lüfterdrehzahl
$luefterdrehzahl = GetValue(45953);
$luefterdrehzahl_max = 600; //Umdrehungen/Minute
$luefterdrehzahl_prozent = $luefterdrehzahl / $luefterdrehzahl_max * 100;
$luefterdrehzahl_prozent_round = round($luefterdrehzahl_prozent, 0);


//Kompressor
$kompressor = GetValue(54272);
$kompressor_max = 3100; //Umdrehungen/Minute
$kompressor_prozent = $kompressor / $kompressor_max * 100;
$kompressor_prozent_round = round($kompressor_prozent, 0);
$kompressor_aktuell_round =round($kompressor, 0);


//Energieeffizientz
$cop_heizen = round(GetValue(57924),2);
$cop_ww = round(GetValue(57924),2);
/*
$jaz_gesamt = round(GetValue(33510),2);
$jaz_heizen = round(GetValue(59006),2);
$jaz_ww = round(GetValue(16842),2);
*/

//if ($status_raw == true && $status_ww_raw == false) {
if ($status == 'Heizen' || 'Kühlbetrieb') { //geändert
$leistung_prozent = $erzeugung_heizbetrieb_aktuell / $leistung_max * 100;
//Momentane Heizleistung in kW gerundet
$erzeugung_aktuell_round = round($erzeugung_heizbetrieb_aktuell, 2);
}
//elseif ($status_raw == true && $status_ww_raw == true) {
elseif ($status == 'Warmwasser') { //geändert
$leistung_prozent = $erzeugung_ww_aktuell / $leistung_max * 100;
//Momentane Warmwasserleistung in kW gerundet
$erzeugung_aktuell_round = round($erzeugung_ww_aktuell, 2);
}
else {
$leistung_prozent = 0;
//Momentane Heizleistung in kW
$erzeugung_aktuell = 0;
$erzeugung_aktuell_round = 0;
}
// Aktuelle Leistung in % gerundet (wird für den Diagrammbalken verwendet)
$leistung_prozent_round = round($leistung_prozent, 0);


// Diagramm-Balkenbreite rechter Blaken berechnen
$balken_rechts_leistung_breite_prozent = 100 - $leistung_prozent_round;
$balken_rechts_durchfluss_breite_prozent = 100 - $durchflussmenge_prozent_round;
$balken_rechts_luefterdrehzahl_breite_prozent = 100 - $luefterdrehzahl_prozent_round;
$balken_rechts_kompressor_breite_prozent = 100 - $kompressor_prozent_round;

/* Deaktiviert da Variable bereits ausgewertet
if ($modus == true) {
$modus_text ='Silent';
}
elseif ($status_eco == true){
$modus_text ='Eco';
}
else {
$status_css = 'status-fertig';
$modus_text ='Normal';
}
*/

//if ($status_raw == true && $status_defrost_raw == false && $status_ww_raw == false) {
if ($status == 'Heizen') {  //geändert
    $wp_image = 'wp_an_heizen.gif';
    $status_css = 'status-heat';
    $status_text = 'Heizbetrieb';
    $cop = $cop_heizen;
}
elseif ($status == 'Kühlbetrieb') {  //hinzugefügt
    $wp_image = 'wp_an_heizen.gif';
    $status_css = 'status-defrost';
    $status_text = 'Kühlbetrieb';
    $cop = $cop_heizen;
}    
//elseif ($status_raw == true && $status_defrost_raw == true) {
elseif ($status == 'Abtauen') { //geändert
    $wp_image = 'wp_an_heizen.gif';
    $status_css = 'status-defrost';
    $status_text = 'Abtauen';
    $cop = 0;
}
//elseif ($status_raw == true && $status_ww_raw == true) {
elseif ($status == 'Warmwasser') {//geändert
    $wp_image = 'wp_an_ww.gif';
    $status_css = 'status-ww';
    $status_text = 'Warmwasser';
    $cop = $cop_ww;
}
else {
    $wp_image = 'wp_aus.png';
    $status_css = 'status-off';
    $status_text = 'Keine Anforderung';
    $cop = 0;
}




$html = '
<style>

        body {margin: 0px;}
    ::-webkit-scrollbar { width: 8px; }
    ::-webkit-scrollbar-track { background: transparent; }
    ::-webkit-scrollbar-thumb { background: transparent; border-radius: 20px; }
    ::-webkit-scrollbar-thumb:hover { background: #555; }
    
    .main_container {
        width: 100%;
        display: flex;
        flex-wrap: nowrap;
        position: relative;
        font-size: 1.0em;
        box-sizing: border-box;
    }



    .div1 {
        width: 30%;
        max-width: 250px;
        min-width: 10px;
        box-sizing: border-box;
    }

    .div1 img {
        width: 100%;
        
        box-sizing: border-box;
    }

    .div2 {
        width: 70%;
        padding: 5px 5px 5px 2.5%;
        margin: 0px 0px 0px 2.5%;
        box-sizing: border-box;
        border-radius:0px 0px 0px 0px;
        //background: linear-gradient(to right, rgba(135,135,135,0.1), white);
       // background: rgba(135,135,135,0.07);
        border-left: 1px dotted #28cdab;

        
    } 
    
    
    .balkendiagramm {
        width: 100%;
        display: flex;
        position: relative;
        margin-bottom: 2%;
        box-sizing: border-box;
    }

.balken_links_leistung, .balken_links_durchfluss, .balken_links_luefterdrehzahl, .balken_links_kompressor, .balken_rechts_leistung, .balken_rechts_durchfluss, .balken_rechts_luefterdrehzahl, .balken_rechts_kompressor  {
        height: var(--div-height);
        padding: 0.5% 0px 0.5% 0px;
        border-radius: calc(var(--div-height) / 4) 0px 0px calc(var(--div-height) / 4);
        font-size: 0.9em;

}

.balken_links_leistung {
width: '.$leistung_prozent_round.'%;
 background: repeating-linear-gradient(to right, red 0%, orange 50%, red 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}

.balken_links_durchfluss {
        width: '.$durchflussmenge_prozent_round.'%;
  background: repeating-linear-gradient(to right, #0054ff 0%, #44a4f5 50%, #0054ff 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}

.balken_links_luefterdrehzahl {
        width: '.$luefterdrehzahl_prozent_round.'%;
  background: repeating-linear-gradient(to right, #d9f3ff 0%, #44a4f5 50%, #d9f3ff 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}

.balken_links_kompressor {
        width: '.$kompressor_prozent_round.'%;
  background: repeating-linear-gradient(to right, #990303 0%, #ff0000 50%, #990303 100%);
  background-size: 200% auto;
  background-position: 0 100%;
  animation: gradient 5s infinite;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes gradient { 
  0%   { background-position: 0 0; }
  100% { background-position: -200% 0; }
}



    .balken_links_leistung_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }
    .balken_links_durchfluss_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }

        .balken_links_luefterdrehzahl_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }
        .balken_links_kompressor_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }


    .balken_rechts_leistung {
        width: ' .$balken_rechts_leistung_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;        
    }

        .balken_rechts_durchfluss {
        width: ' .$balken_rechts_durchfluss_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;          
    }

        .balken_rechts_luefterdrehzahl {
        width: ' .$balken_rechts_luefterdrehzahl_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;          
    }

        .balken_rechts_kompressor {
        width: ' .$balken_rechts_kompressor_breite_prozent.'%;
        background: rgba(135,135,135,0.2);
        border-radius: 0px calc(var(--div-height) / 4) calc(var(--div-height) / 4) 0px;         
    }



/*
    .status-heat, .status-defrost, .status-ww {
        animation: blink 1.5s infinite;
        animation-fill-mode: both;
    }
*/
.
    .status_off {
        color: #000;
    }

    .status-fertig {
        color: #0eb025;
    }

    .status-heat, .status-ww {
        color: #ff9100;
    }
    
    .status-defrost {
        color: #006bfd;
    }

    @keyframes blink {
        0% {
            opacity: 0
        }

        50% {
            opacity: 1
        }

        100% {
            opacity: 0
        }
    }


</style>
</head>
<body>



<div class="main_container">
    <div class="div1">
        <img src="/user/img/wp/' . $wp_image . '"/>
    </div>
    <div class="div2">
        <b>Modus:</b> ' . $modus_text . '</br></span>
        <b>Status: </b><span class="' . $status_css . '">' . $status_text . '<br>
        
        <div class="balkendiagramm">
            <div class="balken_links_leistung"><span class="balken_links_leistung_text"><b>Leistung: </b>' . $erzeugung_aktuell_round . ' KW</span></div>
            <div class="balken_rechts_leistung"></div>
        </div>
        
        <div class="balkendiagramm">
            <div class="balken_links_kompressor"><span class="balken_links_kompressor_text"><b>Kompressor: </b>' . $kompressor_aktuell_round . ' rpm</span></div>
            <div class="balken_rechts_kompressor"></div>
        </div>

        <div class="balkendiagramm">
            <div class="balken_links_durchfluss"><span class="balken_links_durchfluss_text"><b>Durchfluss: </b>' . $durchlussmenge_liter . ' l/h</span></div>
            <div class="balken_rechts_durchfluss"></div>
        </div>
        
        <div class="balkendiagramm">
            <div class="balken_links_luefterdrehzahl"><span class="balken_links_luefterdrehzahl_text"><b>Lüfterdrehzahl: </b>' . $luefterdrehzahl . ' rpm</span></div>
            <div class="balken_rechts_luefterdrehzahl"></div>
        </div>
        
        
        COP: ' . $cop . '</br>
        Verbrauch: ⚡️' . $watt . ', ⚡️ Heute: ' . $kwh_heute . '</br>
        Temp.: 🌳 ' . $temp_aussen . ' 💧 ' . $temp_ww. ' ⬇️ ' . $temp_vl . ' ⬆️ ' . $temp_rl . '</br>
            
</div>

<script>
//Diagrammbalken-Höhe automatisch an die Schriftgröße anpassen
    var spanElement = document.querySelector(\'.balken_links_leistung_text\');
    var divElement = document.querySelectorAll(\'.balken_links_leistung, .balken_links_durchfluss, .balken_links_luefterdrehzahl, .balken_rechts_leistung, .balken_rechts_durchfluss, .balken_rechts_luefterdrehzahl\');
    var root = document.documentElement; // HTML-Dokument

    // Ermittle die Höhe des span-Elements
    var spanHeight = spanElement.clientHeight;

    // Setze eine CSS-Variable mit der Höhe des span-Elements
    root.style.setProperty(\'--div-height\', spanHeight + \'px\');
</script>
';
//HTML Code in Stringvariable schreiben 
Setvalue(28466, $html);

Gebt uns dazu noch ein wenig Zeit. Nach dem Release machen wir mit der 7.1 weiter und dort soll es für die neue Visu auch eine Art SDK geben, womit dann genau solche Dinge möglich gemacht werden sollen in irgendeiner Art und Weise. Ich würde dann bestimmt auch mal so eine (oder andere Kachel) mir vornehmen und eine Demo bauen, mit der ihr dann weiter machen könnt :slight_smile:

Besonders wichtig sind uns aber 3 Dinge:

  • Es sollte sicher sein (d.h. bereits über die normale RPC API laufen, welche für die normalen Anfragen genutzt wird), sodass ihr euch nicht um das Thema kümmern müsst (und auch nicht aus versehen Löcher ins Sicherheitskonzept reißen könnt)
  • Die Variablenänderungen sollten über den Rückkanal, den die Visu bereits hat, kommen und an die HTMLBox weitergeleitet werden
  • D.h. spezielle WebHooks und Webanfragen zum „periodischen“ Aktualisieren soll es definitiv nicht geben (ist auch viel zu aufwendig). Es soll einfacher sein.

Nur mal so als kleinen konzeptionellen Ausblick.

paresy

1 „Gefällt mir“

Moin,
das hört sich super an :slight_smile:

Da das Thema mich schon sehr interessiert und ich was dazu lernen möchte hab ich mal ein bisschen was getestet. Auch wenn ich Javascript in der Vergangenheit gemieden habe wie der Teufel das Weihwasser…

Was hab ich bis jetzt:
Websocket zur Webfront API läuft.
Ich reagiere auf Variablenänderungen und schreibe die neuen Werte in css Variablen und in den html Code.

Hat zufällig jemand ein Beispiel wie ich bei der ersten Scriptausführung aktiv die Werte abrufen kann?
Da habe ich gerade überhaupt keinen Plan. Jetzt werden die Werte halt erst aktualisiert bzw. angezeigt wenn sich ein Wert ändert. Das kann dann halt bei Werten wie der JAZ schon mal ein paar Tage dauern :wink:

Websocket ist auf jeden Fall der Gamechanger bei den HTML Boxen!

Viele Grüße
Stephan

1 „Gefällt mir“

Kleines Projektupdate:

Das Experiment mit dem websocket und der API konnte soweit erfolgreich abgeschlossen werden. Alle Werte werden bei Änderung dynamisch in der html Box aktualisiert. Die Balken bewegen sich bei Änderungen schön smooth an die neue Position. Beim ersten Laden der html Box werden initial alle Werte aktiv über die rpc API abgerufen und gesetzt. Jetzt geht’s ans Code aufräumen und das ganze Teil möglichst einfach konfigurierbar machen…

Feinjustierung in optischen Sachen…

Viele Grüße
Stephan

Ps. @paresy
Ihr verwendet ja die Font Awesome Sachen. Kann man das in eine html Box einbinden? Oder muss ich das selbst implementieren?

4 „Gefällt mir“

Toll was du da machst mit den html-Boxen.
Gäbe schon bald ein Modul, ‚da8ters html-boxen‘.
Danke dass du dir die Zeit nimmst dafür :+1:

2 „Gefällt mir“

Aktuellste Version hier:
https://community.symcon.de/t/htmlbox-status-waermepumpe-beta/134954/25?u=da8ter

Hallo zusammen,

nachfolgend meine experimentelle Version die komplett über den Websocket und die API läuft. Also kein ständiges neu Laden der HTML Box nötig.

wp_kachel

Bitte beachtet alle Hinweise oben in dem Skript zur Konfiguration!

Credits gehen an mich, Tante Google und ChatGPT für zahlreiche Tipps, Anregungen und Verbesserungsvorschläge. :wink:

Viel Spaß beim Testen
Stephan

<?php
/*
Anleitung:

Vorbereitung:
- Die WP Bilder müssen im entsprechenden Pfad abgelegt werden.
- Es muss ein Fernzugriffs-Passwort gesetzt sein
- Es muss ein Webfront-Passwort gesetzt sein
- Alle hier verwendeten Variablen müssen irgendwo im Webfront verwendet werden, sonst hat der Webfront Websocket keinen Zugriff auf diese Variablen. Am einfachsten ist es, im Webfront eine Kategorie anzulegen. In diese Kategorie erstellt ihr Links zu allen Variablen oder Instanzen, die die Variablen enthalten. Die Kategorie kann über "Objekt bearbeiten" auf Unsichtbar und deaktiviert gestellt werden. (gibt es hier für eine elegantere Lösung? Bitte im Forum posten.)
- Im nächsten Schritt müssen alle Variablen-IDs im $config Array eingetragen werden.
- Für den Status und Modus werden Integer erwartet: 0-9
    Wärmepumpenstatus: 0=AUS, 3=Heizen, 4=Abtauen, 5=Warmwasser. Das kann aber angepasst werden. Es können bis zu 10 eigenen Stati definiert werden (Text, Textfarbe und WP Bild)
    Wärmepumpen Modus: 0=Normal, 1=Silent, 2=Eco. Es können bis zu 10 eigenen Modi definiert werden (Text)

Icon:
Für die Icon verwende ich Font Awesome. Bitte auf der Webseite kostenlos Anmelden und unter https://fontawesome.com/start sich den "Kit embed code" schicken lassen. 
Der sollte wie folgt aussehen:
<script src="https://kit.fontawesome.com/xxxxxxxxxxxx.js" crossorigin="anonymous"></script>
Die URL bitte hier eintragen:
*/
$fontawesomeurl = "https://kit.fontawesome.com/xxxxxxxxxxxx.js";


// Variablen IDs konfigurieren

// Hier die entsprechende Variablen-ID eintragen.
// Hinweis zu den Heizstäben: Wird ein Heizstab NICHT benötigt, bitte 0 eintragen

$config = array(
    'wp_status' => 14983, // Statusanzeige WP (Integer: 0=AUS, 3=Heizen, 4=Abtauen, 5=Warmwasser)
    'wp_modus' => 41747, // Modus WP (Integer: 0=Normal, 1=Silent, 2=Eco)
    'wp_temp_aussen' => 41468, // Außentemperatur
    'wp_temp_ww' => 22043, // Temperatur Trinkwasserspeicher
    'wp_temp_vl' => 37910, // Temperatur WP Vorlauf
    'wp_temp_rl' => 27204, // Temperatur WP Rücklauf
    'wp_hz_backup' => 58032, // Status Heizstab Backupheater (true=an, false=aus)
    'wp_hz_ww_1' => 21501, // Status Heizstab Trinkwasserspeicher Phase 1 (true=an, false=aus)
    'wp_hz_ww_2' => 56712, // Status Heizstab Trinkwasserspeicher Phase 2 (true=an, false=aus)
    'wp_hz_ww_3' => 39438, // Status Heizstab Trinkwasserspeicher Phase 3 (true=an, false=aus)
    'wp_durchlauf' => 23549, // Durchfluss in Litern/h
    'wp_luefter' => 33890, // Drehzahl Lüfter in rpm
    'wp_kompressor' => 19570, // Kompressorleistung in Hz
    'wp_cop_heizen' => 21001, // COP Heizung
    'wp_cop_ww' => 12736, // COP Trinkwasser
    'wp_jaz' => 33510, // JAZ
    'wp_jaz_heizung' => 59006, // JAZ Heizung
    'wp_jaz_ww' => 16842, // JAZ Trinkwasser
    'wp_leistung' => 20303, // Aktuelle Heizleistung in kW
    'wp_verbrauch' => 25434, // Aktueller Verbrauch in Watt
    'wp_verbrauch_heute' => 17601 // Verbrauch aktueller Tag in kWh
);

// Zugangsdaten für den Webfront Websocket und die JSON RPC API
$username = "max.musterman@mail.com"; // E-Mailadresse
$wf_password = "password"; // Webfront Passwort
$fern_password = "password"; // Fernzugriff Passwort
$serverAddress = "192.168.0.134"; // IP-Adresse vom Symcon-Rechner
$port = "3777";
$webfront_id = "11891"; // ID der Webfront Instanz

// Heizstabanzeige: Hier kann die Anzahl der Heizstäbe konfiguriert werden. Möglich sind 1-3 "Heizstäbe" true = wird angezeigt, false = wird ausgeblendet
$hz_1 = true; // Heizstab 1
$hz_2 = true; // Heizstab 2
$hz_3 = true; // Heizstab 3

// Status und Modus definieren
// WP Status
$wp_status_text0 = "Aus"; // Integer 0
$wp_status_0_color = "#000000"; // Integer 0 Farbe
$wp_status_image_0 = "wp_aus.png"; // Integer 0 Bild

$wp_status_text1 = "Statustext"; // Integer 1
$wp_status_1_color = "#000000"; // Integer 1 Farbe
$wp_status_image_1 = "wp_aus.png"; // Integer 1 Bild

$wp_status_text2 = "Statustext"; // Integer 2
$wp_status_2_color = "#000000"; // Integer 2 Farbe
$wp_status_image_2 = "wp_aus.png"; // Integer 2 Bild

$wp_status_text3 = "Heizen"; // Integer 3
$wp_status_3_color = "#fc9003"; // Integer 3 Farbe
$wp_status_image_3 = "wp_an_heizen.gif"; // Integer 3 Bild

$wp_status_text4 = "Abtauen"; // Integer 4
$wp_status_4_color = "#03a1fc"; // Integer 4 Farbe
$wp_status_image_4 = "wp_an_heizen.gif"; // Integer 4 Bild

$wp_status_text5 = "Warmwasser"; // Integer 5
$wp_status_5_color = "#fc9003"; // Integer 5 Farbe
$wp_status_image_5 = "wp_an_ww.gif"; // Integer 5 Bild

$wp_status_text6 = "Statustext"; // Integer 6
$wp_status_6_color = "#000000"; // Integer 6 Farbe
$wp_status_image_6 = "wp_aus.png"; // Integer 6 Bild

$wp_status_text7 = "Statustext"; // Integer 7
$wp_status_7_color = "#000000"; // Integer 7 Farbe
$wp_status_image_7 = "wp_aus.png"; // Integer 7 Bild

$wp_status_text8 = "Statustext"; // Integer 8
$wp_status_8_color = "#000000"; // Integer 8 Farbe
$wp_status_image_8 = "wp_aus.png"; // Integer 8 Bild

$wp_status_text9 = "Statustext"; // Integer 9
$wp_status_9_color = "#000000"; // Integer 9 Farbe
$wp_status_image_9 = "wp_aus.png"; // Integer 9 Bild

// WP Modus
$wp_modus_text0 = "Normal"; // Integer 0
$wp_modus_text1 = "Silent"; // Integer 1
$wp_modus_text2 = "Eco"; // Integer 2
$wp_modus_text3 = "Modustext"; // Integer 3
$wp_modus_text4 = "Modustext"; // Integer 4
$wp_modus_text5 = "Modustext"; // Integer 5
$wp_modus_text6 = "Modustext"; // Integer 6
$wp_modus_text7 = "Modustext"; // Integer 7
$wp_modus_text8 = "Modustext"; // Integer 8
$wp_modus_text9 = "Modustext"; // Integer 9


//Maximalwerte der Wärmepumpe
$wp_leistung_max = "7"; // in KW
$wp_kompressor_max = "75"; // in Hz
$wp_durchfluss_max = "1700"; // in l/h
$wp_luefter_max = "650"; // rpm


// Ab hier nichts mehr ändern! AUSSER DIE ID IN DER HTML-BOX VARIABLE IN DER LETZTEN ZEILE!
//__________________________________________________________________________________________________________________





// Alle Variablen IDs kommmasepariert ausgeben.
$alle_ids = implode(', ', $config);

$hz_1_css = $hz_1 ? 'inline' : 'none';
$hz_2_css = $hz_2 ? 'inline' : 'none';
$hz_3_css = $hz_3 ? 'inline' : 'none';

$html = '
<script src="'. $fontawesomeurl .'" crossorigin="anonymous"></script>
<style>
    :root {
        --' . $config['wp_leistung'] . ';
        /* Aktuelle Leistung */
        --max_heizleistung: '. $wp_leistung_max .'; /* Maximale Heizleistung */
        --heizleistung_prozent_round: calc(var(--' . $config['wp_leistung'] . ') / var(--max_heizleistung) * 100%); /* Aktuelle Leistung in Prozent zur maximalen Heizleistung */
        --' . $config['wp_kompressor'] . ';
        /* Kompressor */
        --max_kompressor: '. $wp_kompressor_max .'; /* Maximale Kompressorleistung */
        --kompressor_prozent_round: calc(var(--' . $config['wp_kompressor'] . ') / var(--max_kompressor) * 100%); /* Aktuelle Leistung in Prozent zur maximalen Heizleistung */
        /* Lüfter */
        --' . $config['wp_luefter'] . ';
        --max_luefter: '. $wp_luefter_max .'; /* Maximale Lüfterdrehzahl */
        --luefter_prozent_round: calc(var(--' . $config['wp_luefter'] . ') / var(--max_luefter) * 100%); /* Aktuelle Lüfterdrehzahl in Prozent zur maximalen Drehzahl */
        /* Durchfluss */
        --' . $config['wp_durchlauf'] . ';
        --max_durchfluss: '. $wp_durchfluss_max .'; /* Maximaler Durchfluss */
        --durchfluss_prozent_round: calc(var(--' . $config['wp_durchlauf'] . ') / var(--max_durchfluss) * 100%); /* Aktueller Durchfluss in Prozent zur maximalen Durchflussmenge */
    }

    body {
        margin: 0px;
    }

    ::-webkit-scrollbar {
        width: 8px;
    }

    ::-webkit-scrollbar-track {
        background: transparent;
    }

    ::-webkit-scrollbar-thumb {
        background: transparent;
        border-radius: 20px;
    }

    ::-webkit-scrollbar-thumb:hover {
        background: #555;
    }

    .main_container {
        width: 100%;
        display: flex;
        flex-wrap: nowrap;
        position: relative;
        font-size: 0.9em;
        box-sizing: border-box;
    }

    .div1 {
        width: 20%;
        box-sizing: border-box;
    }

    .div1 img {
        width: 100%;
        box-sizing: border-box;
    }

    .div2 {
        width: 80%;
        padding: 5px 5px 5px 2.5%;
        margin: 0px 0px 0px 2.5%;
        box-sizing: border-box;
        border-radius: 0px;
        border-left: 1px dotted #28cdab;
    }

    .balkendiagramm {
        width: 100%;
        display: flex;
        position: relative;
        margin-bottom: 2%;
        box-sizing: border-box;
    }

    .balken_links_leistung,
    .balken_links_durchfluss,
    .balken_links_luefterdrehzahl,
    .balken_links_kompressor,
    .balken_rechts_leistung,
    .balken_rechts_durchfluss,
    .balken_rechts_luefterdrehzahl,
    .balken_rechts_kompressor {
        height: var(--div-height);
        border-radius: calc(var(--div-height) / 4) 0px 0px calc(var(--div-height) / 4);
        font-size: 0.9em;
        transition: width 2s;
        transition-timing-function: ease;
    }

    @keyframes gradient_leistung {
        0% {
            background-position: 0 0;
        }
        100% {
            background-position: -200% 0;
        }
    }

    @keyframes gradient_durchfluss {
        0% {
            background-position: 0 0;
        }
        100% {
            background-position: -200% 0;
        }
    }

    @keyframes gradient_luefterdrehzahl {
        0% {
            background-position: 0 0;
        }
        100% {
            background-position: -200% 0;
        }
    }

    @keyframes gradient_kompressor {
        0% {
            background-position: 0 0;
        }
        100% {
            background-position: -200% 0;
        }
    }

    .balken_links_leistung {
        width: var(--heizleistung_prozent_round);
        background: repeating-linear-gradient(to right, red 0%, orange 50%, red 100%);
        background-size: 200% auto;
        background-position: 0 100%;
        animation: gradient_leistung 10s infinite;
        animation-fill-mode: forwards;
        animation-timing-function: linear;
    }

    .balken_links_durchfluss {
        width: var(--durchfluss_prozent_round);
        background: repeating-linear-gradient(to right, #0054ff 0%, #44a4f5 50%, #0054ff 100%);
        background-size: 200% auto;
        background-position: 0 100%;
        animation: gradient_durchfluss 5s infinite;
        animation-fill-mode: forwards;
        animation-timing-function: linear;
    }

    .balken_links_luefterdrehzahl {
        width: var(--luefter_prozent_round);
        background: repeating-linear-gradient(to right, #13b7f2 0%, #99e4ff 50%, #13b7f2 100%);
        background-size: 200% auto;
        background-position: 0 100%;
        animation: gradient_luefterdrehzahl 5s infinite;
        animation-fill-mode: forwards;
        animation-timing-function: linear;
    }

    .balken_links_kompressor {
        width: var(--kompressor_prozent_round);
        background: repeating-linear-gradient(to right, #990303 0%, #ff0000 50%, #990303 100%);
        background-size: 200% auto;
        background-position: 0 100%;
        animation: gradient_kompressor 5s infinite;
        animation-fill-mode: forwards;
        animation-timing-function: linear;
    }

    .balken_links_text {
        position: absolute;
        top: 50%;
        left: 2%;
        transform: translate(-0%, -50%);
        color: white;
        z-index: 2;
        padding: 3px;
    }

    .hz_1 {
        display: ' . $hz_1_css . ';
    }
    .hz_2 {
        display: ' . $hz_2_css . ';
    }
    .hz_3 {
        display: ' . $hz_3_css . ';
    }
    .balken_rechts {
        width: 100%;
        border-radius: calc(var(--div-height) / 4) calc(var(--div-height) / 4);
        background: linear-gradient(to right, rgba(135, 135, 135, 0.6) 0%, rgba(135, 135, 135, 0.2) 100%);
    }

    .status_0 {
        color: ' . $wp_status_0_color . ';
    }
    .status_1 {
        color: ' . $wp_status_1_color . ';
    }
    .status_2, {
        color: ' . $wp_status_2_color . ';
    }
    .status_3 {
        color: ' . $wp_status_3_color . ';
    }
    .status_4 {
        color: ' . $wp_status_4_color . ';
    }
    .status_5 {
        color: ' . $wp_status_5_color . ';
    }
    .status_6 {
        color: ' . $wp_status_6_color . ';
    }
    .status_7 {
        color: ' . $wp_status_7_color . ';
    }
    .status_8 {
        color: ' . $wp_status_8_color . ';
    }
    .status_9 {
        color: ' . $wp_status_9_color . ';
    }

    @keyframes blink {
        0% {
            opacity: 0
        }
        50% {
            opacity: 1
        }
        100% {
            opacity: 0
        }
    }

    .container_daten {
        display: flex;
        flex-wrap: nowrap;
        width: 100%;
    }

    .daten_links {
        margin-right: 20px;
        border: 0px solid #000;
    }

    .daten_rechts {
        border: 0px solid #000;
    }


</style>
</head>
<body>



<div class="main_container">
    <div id="div1" class="div1">
           </div>
    <div class="div2">
        <b>Status: </b><span id="' . $config['wp_status'] . '"></span></br>
        <b>Modus: </b><span id="' . $config['wp_modus'] . '"></span></br>
        
        <div class="balkendiagramm">
        <div class="balken_rechts">
        <div class="balken_links_leistung">
        <span class="balken_links_text"><b>Leistung: </b> <span id="' . $config['wp_leistung'] . '">0</span> KW</span>
        </div>
        </div>
        </div>
        
        <div class="balkendiagramm">
        <div class="balken_rechts">
        <div class="balken_links_kompressor">
        <span class="balken_links_text"><b>Kompressor: </b><span id="' . $config['wp_kompressor'] . '">0</span> Hz</span>
        </div>
        </div>
        </div>

        <div class="balkendiagramm">
        <div class="balken_rechts">
        <div class="balken_links_durchfluss">
        <span class="balken_links_text"><b>Durchfluss: </b><span id="' . $config['wp_durchlauf'] . '">0</span> l/h</span>
        </div>
        </div>
        </div>
        
        <div class="balkendiagramm">
        <div class="balken_rechts">
        <div class="balken_links_luefterdrehzahl">
        <span class="balken_links_text"><b>Lüfterdrehzahl: </b><span id="' . $config['wp_luefter'] . '">0</span> rpm</span>
        </div>
        </div>
        </div>

        <div class="container_daten">
        <div class="daten_links">
        JAZ:</br>
        COP:</br>
        Verbrauch:</br>
        Temp.:</br>
        Heizstäbe:</div>
        <div class="daten_rechts">
        <i class="fa-solid fa-house fa-sm" style="color: #26d4b9;"></i> <span id="' . $config['wp_jaz'] . '"></span>  <i class="fa-solid fa-fire-flame-curved fa-sm" style="color: #26d4b9;"></i> <span id="' . $config['wp_jaz_heizung'] . '"></span> <i class="fa-solid fa-droplet fa-sm" style="color: #26d4b9;"></i> <span id="' . $config['wp_jaz_ww'] . '"></span></br>
        Heizen: <span id="' . $config['wp_cop_heizen'] . '">0</span>, WW: <span id="cop_ww">0</span> </br>
        <span id="' . $config['wp_verbrauch'] . '"></span> Watt,  Heute: <span id="' . $config['wp_verbrauch_heute'] . '"></span> kWh</br>
        <i class="fa-solid fa-tree fa-sm" style="color: #26d4b9;"></i>  <span id="' . $config['wp_temp_aussen'] . '">0</span>°C      <i class="fa-solid fa-droplet fa-sm" style="color: #26d4b9;"></i>  <span id="' . $config['wp_temp_ww'] . '">0</span>°C      <i class="fa-solid fa-circle-down fa-sm" style="color: #26d4b9;"></i>  <span id="' . $config['wp_temp_vl'] . '">0</span>°C <i class="fa-solid fa-circle-up fa-sm" style="color: #26d4b9"></i> <span id="' . $config['wp_temp_rl'] . '">0</span>°C</br>
        WP:&nbsp;<span id="' . $config['wp_hz_backup'] . '"></span>&nbsp;&nbsp;&nbsp;WW-Speicher:&nbsp;<span class="hz_1" id="' . $config['wp_hz_ww_1'] . '"></span>&nbsp;<span class="hz_2" id="' . $config['wp_hz_ww_2'] . '"></span>&nbsp;<span class="hz_3" id="' . $config['wp_hz_ww_3'] . '"></span>
        </div></div>

   </div>
            
</div>

<script type="text/javascript" charset="UTF-8">
//Diagrammbalken-Höhe automatisch an die Schriftgröße anpassen
    var spanElement = document.querySelector(\'.balken_links_text\');
    var divElement = document.querySelectorAll(\'.balken_links_leistung, .balken_links_durchfluss, .balken_links_luefterdrehzahl, .balken_rechts_leistung, .balken_rechts_durchfluss, .balken_rechts_luefterdrehzahl\');
    var root = document.documentElement; // HTML-Dokument

    // Ermittle die Höhe des span-Elements
    var spanHeight = spanElement.clientHeight;

    // Setze eine CSS-Variable mit der Höhe des span-Elements
    root.style.setProperty(\'--div-height\', spanHeight + \'px\');
</script>


  <script type="text/javascript" charset="UTF-8">
        var username = \'' . $username . '\';
        var password = \'' . $fern_password . '\';
        var serverAddress = \'' . $serverAddress . '\';
        var serverPort = \'' . $port . '\';
        var variableIDs = [' . $alle_ids . '];

        // Create basic authentication string
        var credentials = btoa(username + \':\' + password);

        // Construct the URL for the JSON-RPC request
        var rpcURL = \'http://\' + serverAddress + \':\' + serverPort + \'/api/\';

        // Create JSON-RPC requests for each variable
        var jsonRPCRequests = variableIDs.map(function(id, index) {
            return {
                jsonrpc: \'2.0\',
                method: \'GetValue\',
                params: [id],
                id: index + 1
            };
        });


        jsonRPCRequests.forEach(function(request, index) {
            fetch(rpcURL, {
                method: \'POST\',
                headers: {
                    \'Authorization\': \'Basic \' + credentials,
                    \'Content-Type\': \'application/json\'
                },
                body: JSON.stringify(request)
            })
            .then(response => response.json())
            .then(data => {
                if (data.error) {
                    console.error(\'Fehler bei Anfrage \' + (index + 1) + \': \' + data.error.message);
                } else {
                    var value = data.result;
                    var variableID = variableIDs[index];
                    var divElement = document.getElementById(variableID.toString());
                    if (divElement) {
if (variableID === ' . $config['wp_status'] . ') {
    var statusMapping = {
        0: { text: \'' . $wp_status_text0 . '\', image: \'/user/img/wp/' . $wp_status_image_0 . '\' },
        1: { text: \'' . $wp_status_text1 . '\', image: \'/user/img/wp/' . $wp_status_image_1 . '\' },
        2: { text: \'' . $wp_status_text2 . '\', image: \'/user/img/wp/' . $wp_status_image_2 . '\' },
        3: { text: \'' . $wp_status_text3 . '\', image: \'/user/img/wp/' . $wp_status_image_3 . '\' },
        4: { text: \'' . $wp_status_text4 . '\', image: \'/user/img/wp/' . $wp_status_image_4 . '\' },
        5: { text: \'' . $wp_status_text5 . '\', image: \'/user/img/wp/' . $wp_status_image_5 . '\' },
        6: { text: \'' . $wp_status_text6 . '\', image: \'/user/img/wp/' . $wp_status_image_6 . '\' },
        7: { text: \'' . $wp_status_text7 . '\', image: \'/user/img/wp/' . $wp_status_image_7 . '\' },
        8: { text: \'' . $wp_status_text8 . '\', image: \'/user/img/wp/' . $wp_status_image_8 . '\' },
        9: { text: \'' . $wp_status_text9 . '\', image: \'/user/img/wp/' . $wp_status_image_9 . '\' },
    };

    if (statusMapping[value]) {
        divElement.innerHTML = \'<span class="status_\' + value + \'">\' + statusMapping[value].text + \'</span>\';
        var divElement = document.getElementById(\'div1\');
        divElement.innerHTML = \'<img src="\' + statusMapping[value].image + \'"/>\';
    }
}
                               
                         else if (variableID === ' . $config['wp_modus'] . ') {
                            if (value === 0) {
                                value = \'' . $wp_modus_text0 . '\';
                            } else if (value === 1) {
                                value = \'' . $wp_modus_text1 . '\';
                            } else if (value === 2) {
                                value = \'' . $wp_modus_text2 . '\';
                            } else if (value === 3) {
                                value = \'' . $wp_modus_text3 . '\';
                            } else if (value === 4) {
                                value = \'' . $wp_modus_text4 . '\';
                            } else if (value === 5) {
                                value = \'' . $wp_modus_text5 . '\';
                            } else if (value === 6) {
                                value = \'' . $wp_modus_text6 . '\';
                            } else if (value === 7) {
                                value = \'' . $wp_modus_text7 . '\';
                            } else if (value === 8) {
                                value = \'' . $wp_modus_text8 . '\';
                            } else if (value === 9) {
                                value = \'' . $wp_modus_text9 . '\';
                            }
                            divElement.innerHTML = value; 
                        }
                        //Status Heizstab WP
                         else if (variableID === ' . $config['wp_hz_backup'] . ') { 
                        var value = value ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                            divElement.innerHTML = value;
                        } 
                        // Status Heizstab WW 1
                        else if (variableID === ' . $config['wp_hz_ww_1'] . ') {
                        var value = value ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                        divElement.innerHTML = value;
}

                        //Status Heizstab WW 2
                         else if (variableID === ' . $config['wp_hz_ww_2'] . ') { 
                        var value = value ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                            divElement.innerHTML = value;
                        } 
                         //Status Heizstab WW 3
                         else if (variableID === ' . $config['wp_hz_ww_3'] . ') { 
                        var value = value ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                            divElement.innerHTML = value;
                        }                        
                        
                        
                        else {
                            // Check for decimal places
                            if (value.toString().includes(\'.\')) {
                                // Round the value to two decimal places
                                value = parseFloat(value).toFixed(2);
                            }

                            
                            divElement.textContent = value;

                            // Update the CSS variables
                            var cssVariableName = \'--\' + variableID;
                            var root = document.documentElement;
                            root.style.setProperty(cssVariableName, value);
                        }
                    }
                }
            })
            .catch(error => {
                console.error(\'Fehler bei der Anfrage \' + (index + 1) + \': \' + error);
            });
        });
    </script>





    <script type="text/javascript" charset="UTF-8">
    // Erstellen Sie eine WebSocket-Verbindung
        var username = \'' . $username . '\';
        var password = \'' . $wf_password . '\';
        var serverAddress = \'' . $serverAddress . '\';
        var serverPort = \'' . $port . '\';
        var wfid= \'' . $webfront_id . '\';
        var connection = new WebSocket(\'ws://\' + serverAddress + \':\' + serverPort + \'/wfc/\' + wfid + \'/api/\', [encodeURIComponent(btoa(\'webfront:\' + password))]); 

    // Wenn die Verbindung geöffnet ist
    connection.onopen = function(event) {
        console.log(\'WebSocket-Verbindung geöffnet.\');
    };




    // Wenn eine Nachricht empfangen wird
    connection.onmessage = function(event) {
        var data = JSON.parse(event.data);

        // Überprüfen Sie, ob die CSS-Variable vorhanden ist
        var senderID = data.SenderID;
        var cssVariableName = \'--\' + senderID;
        var root = document.documentElement;

        // Den numerischen Wert aus dem "Data"-Array extrahieren
        var numericValue = data.Data[0];

        if (getComputedStyle(root).getPropertyValue(cssVariableName)) {
            // Setzen Sie den Wert in die CSS-Variable
            root.style.setProperty(cssVariableName, numericValue);
        }

               // Heizleistung Text im Balken aktualisieren
                if (senderID === ' . $config['wp_leistung'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_leistung'] . '\');
                    resultDiv.innerHTML = parseFloat(numericValue.toFixed(2));
                }
                // Kompressor Text im Balken aktualisieren
                else if (senderID === ' . $config['wp_kompressor'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_kompressor'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Lüfterdrehzahl Text im Balken aktualisieren
                else if (senderID === ' . $config['wp_luefter'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_luefter'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Durchflussmenge Text im Balken aktualisieren
                else if (senderID === ' . $config['wp_durchlauf'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_durchlauf'] . '\');
                    numericValue = numericValue;
                    resultDiv.innerHTML = numericValue;
                }
                // JAZ gesamt Text Aktualisieren
                else if (senderID === ' . $config['wp_jaz'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_jaz'] . '\');
                    resultDiv.innerHTML = parseFloat(numericValue.toFixed(2));
                }
                // JAZ Heizen Text Aktualisieren
                else if (senderID === ' . $config['wp_jaz_heizung'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_jaz_heizung'] . '\');
                    resultDiv.innerHTML = parseFloat(numericValue.toFixed(2));
                }
                // JAZ WW Text Aktualisieren
                else if (senderID === ' . $config['wp_jaz_ww'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_jaz_ww'] . '\');
                    resultDiv.innerHTML = parseFloat(numericValue.toFixed(2));
                }
                // COP Heizen Text Aktualisieren
                else if (senderID === ' . $config['wp_cop_heizen'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_cop_heizen'] . '\');
                    resultDiv.innerHTML = parseFloat(numericValue.toFixed(2));
                }
                // COP WW Text Aktualisieren
                else if (senderID === ' . $config['wp_cop_ww'] . ') {
                    var resultDiv = document.getElementById(\'cop_ww\');
                    resultDiv.innerHTML = parseFloat(numericValue.toFixed(2));
                }
                // Temperatur Außen Text Aktualisieren
                else if (senderID === ' . $config['wp_temp_aussen'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_temp_aussen'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Temperatur WW Text Aktualisieren
                else if (senderID === ' . $config['wp_temp_ww'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_temp_ww'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Temperatur Vorlauf Text Aktualisieren
                else if (senderID === ' . $config['wp_temp_vl'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_temp_vl'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Temperatur Rücklauf Text Aktualisieren
                else if (senderID === ' . $config['wp_temp_rl'] . ') {
                    var resultDiv = document.getElementById(\'' . $config['wp_temp_rl'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Heizstab Backup
                else if (senderID === ' . $config['wp_hz_backup'] . ') {
                    var numericValue = numericValue ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                    var resultDiv = document.getElementById(\'' . $config['wp_hz_backup'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Heizstab 1 WW
                else if (senderID === ' . $config['wp_hz_ww_1'] . ') {
                    var numericValue = numericValue ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                    var resultDiv = document.getElementById(\'' . $config['wp_hz_ww_1'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Heizstab 2 WW
                else if (senderID === ' . $config['wp_hz_ww_2'] . ') {
                    var numericValue = numericValue ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                    var resultDiv = document.getElementById(\'' . $config['wp_hz_ww_2'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
                // Heizstab 3 WW
                else if (senderID === ' . $config['wp_hz_ww_3'] . ') {
                    var numericValue = numericValue ? \'<i class="fa-solid fa-circle fa-sm" style="color: #26d4b9;"></i>\' : \'<i class="fa-regular fa-circle fa-sm" style="color: #26d4b9;"></i>\';
                    var resultDiv = document.getElementById(\'' . $config['wp_hz_ww_3'] . '\');
                    resultDiv.innerHTML = numericValue;
                }
// Status WP (Heizen, Warmwasser, Aus, Defrost)

else if (senderID === ' . $config['wp_status'] . ') {
    var divElement = document.getElementById(\'' . $config['wp_status'] . '\');
    var statusMapping = {
        0: { text: \'' . $wp_status_text0 . '\', image: \'/user/img/wp/' . $wp_status_image_0 . '\' },
        1: { text: \'' . $wp_status_text1 . '\', image: \'/user/img/wp/' . $wp_status_image_1 . '\' },
        2: { text: \'' . $wp_status_text2 . '\', image: \'/user/img/wp/' . $wp_status_image_2 . '\' },
        3: { text: \'' . $wp_status_text3 . '\', image: \'/user/img/wp/' . $wp_status_image_3 . '\' },
        4: { text: \'' . $wp_status_text4 . '\', image: \'/user/img/wp/' . $wp_status_image_4 . '\' },
        5: { text: \'' . $wp_status_text5 . '\', image: \'/user/img/wp/' . $wp_status_image_5 . '\' },
        6: { text: \'' . $wp_status_text6 . '\', image: \'/user/img/wp/' . $wp_status_image_6 . '\' },
        7: { text: \'' . $wp_status_text7 . '\', image: \'/user/img/wp/' . $wp_status_image_7 . '\' },
        8: { text: \'' . $wp_status_text8 . '\', image: \'/user/img/wp/' . $wp_status_image_8 . '\' },
        9: { text: \'' . $wp_status_text9 . '\', image: \'/user/img/wp/' . $wp_status_image_9 . '\' },
    };

    if (statusMapping[numericValue]) {
        divElement.innerHTML = \'<span class="status_\' + numericValue + \'">\' + statusMapping[numericValue].text + \'</span>\';
        var divElement = document.getElementById(\'div1\');
        divElement.innerHTML = \'<img src="\' + statusMapping[numericValue].image + \'"/>\';
    }
}
    };

    // Wenn ein Fehler auftritt
    connection.onerror = function(event) {
        console.error(\'WebSocket-Fehler: \' + event);
    };

    // Wenn die Verbindung geschlossen wird
    connection.onclose = function(event) {
        console.log(\'WebSocket-Verbindung geschlossen.\');
    };
</script>


';
//HTML Code in Stringvariable schreiben 
Setvalue(26743, $html);
3 „Gefällt mir“

Wow, da haste mal wieder vorgelegt :wink:

:+1:
Heiko

1 „Gefällt mir“

hier noch eine kleinere Version der Bilder (Breite 200px) die großen Bilder sind doch sehr rechenintensiv gewesen. Da fing das iPhone irgend wann an zu glühen…

Wärmepumpe_klein.zip (114,0 KB)

Gruß Stephan

1 „Gefällt mir“

Hallo Stephan,

Danke für die Top Arbeit. So richtig funzt das neue Script noch nicht bei mir.
Was auffällt, der Aufbau ist sehr langsam. Die Werte kommen langsam zur Ansicht, ist das normal? Bis alles, inkl. dem Bild, Dargestellt wird dauert es eine Weile.

Was nicht funktioniert sind die Verbrauchswerte, die werden mir einfach nicht angezeigt. Die Variablen dafür habe ich eingetragen.

Und die farbigen Balken sind bei mir komplett Gefüllt, obwohl teilweise die aktuellen Werte bei 0 sind.

Die Heizstäbe habe ich alle auf „0“ gesetzt, die zeigt er mir allerdings trotzdem an.

Wenn die Werte nur langsam kommen dann funktioniert die Abfrage über die API nicht. Die werden ja beim ersten Anzeigen der Box über die api geladen. Über den websocket kommen dann die Änderungen rein… Fernzugriff ist mit Passwort eingerichtet?

Heizstäbe auch hier auf false gesetzt?
$hz_1 = true; // Heizstab 1
$hz_2 = true; // Heizstab 2
$hz_3 = true; // Heizstab 3

Bei dir wird auch nicht die korrekte Schriftart angezeigt… das Problem ist aber bei den ips Jungs bekannt.

So Fernzugriff gerade noch mal Kontrolliert, der funzt und Passwort wird auch benötigt.

Heizstäbe habe ich auf false gesetzt

Scheinbar gibt es noch ein Problem mit den Sicherheitseinstellungen des Webservers. Dies verhindert momentan eine API Verbindung über eine HTMLBox. Temporäre Lösung: bei den Spezialschaltern die ServerSecurity deaktivieren. Danach werden übrigens auch die Schriften korrekt geladen.