Tag,
ich habe an einer Minichartcard gebastelt.
Die erste Variante ist ein Mix aus HTML, SVG und Perl (Mehr Performance, schwieriger anzupassen) . Die zweite Variante ist ein Mix aus HTML, SVG und Echart (Weniger Performance, leichter anzupassen).
Zum Datensammeln nutze ich eine Perl-Sub in 99_myUtils.pm plus 2 at. Das eine schreibt kontinuierlich ein Array, das andere nullt um Mitternacht. Anstatt einem at
für das Array, kann auch ein notify verwendet werden. Dadurch ergeben sich dann eher Livedaten,
aber als Nachteil viel mehr Daten.
1. Daten sammeln (Array)
1.1. Error abfangen
Neues Reading in dem Device eurer Wahl anlegen
setreading <mydevice> chartArray 0
Damit wird eine Fehlermeldung verhindert.
1.2.1 Ringbuffer,in Perl-Sub in 99_myUtils.pm einfügen
Hiermit wird ein Ringbuffer der letzten 50 Werte erzeugt. Kommt einer dazu, wird der Älteste gekickt.
Dadurch entfällt Löschen um Mitternacht.
sub AppendToFixedArray {
my ($dev, $reading, $newVal, $maxSize) = @_;
$maxSize //= 50;
my $current = ReadingsVal($dev, $reading, '');
my @values = split(',', $current);
if (@values >= $maxSize) {
@values = @values[-($maxSize - 1) .. -1];
}
push @values, $newVal;
return join(',', @values);
}
1.2.2. Das passende at für Ringbuffer
defmod chartUpdate at +*00:05 {\
my $val = ReadingsVal("Smartmeter_2E1F50", "APOX_Power", 0);;\
my $new = AppendToFixedArray("Smartmeter_2E1F50", "chartArray", $val);;\
fhem("setreading Smartmeter_2E1F50 chartArray $new");;\
}
1.3.1. Kontinuierliches Array, in Perl-Sub in 99_myUtils.pm einfügen
sub AppendToArray {
my ($dev, $reading, $newVal) = @_;
my $current = ReadingsVal($dev, $reading, '');
my @values = split(',', $current);
push @values, $newVal;
return join(',', @values);
}
1.3.2. at für array
defmod chartUpdate at +*00:05 {\
my $val = ReadingsVal("Smartmeter_2E1F50", "APOX_Power", 0);;\
my $new = AppendToArray("Smartmeter_2E1F50", "chartArray", $val);;\
fhem("setreading Smartmeter_2E1F50 chartArray $new");;\
}
1.3.3. at zum nullen um Mitternacht
defmod chartReset at *00:00:00 {\
my $val = ReadingsVal("Smartmeter_2E1F50", "APOX_Power", 0);;\
fhem("setreading Smartmeter_2E1F50 chartArray $val");;\
}
2. Chartcard mit Perl. Mehr Performance, schwieriger zu modifizieren
2.1. Chartcard Line
im Anhang
2.2. Chartcard Bar
im Anhang
3. Chartcard mit Echarts. Weniger Performnace, einfacher zu modifizieren
3.1. echarts kopieren
echarts.min.js aus dem Anhang nach /fhem/www/codemirror/echarts.min.js. Eigentümer:fhem,Gruppe:dialout
3.2. Neustart
"shutdown restart"
3.3. stateformat
stateformat im Device anlegen
<style>
div#NamevonEuremDevice {
pointer-events: none;
}
</style>
<!-- Lade echarts direkt -->
<script src="/fhem/www/codemirror/echarts.min.js"></script>
<!-- Chart-Container -->
<div style="width:365px; padding:10px; border:1px solid #ddd; border-radius:6px; font-family:sans-serif; box-shadow:0 2px 4px rgba(0,0,0,0.1); box-sizing:border-box; height:90px; position:relative;">
<!-- Labels -->
<div style="position:absolute; top:10px; left:10px; width:90px; font-size:14px; text-align:left; line-height:26px;">
<div>Currently</div>
<div>Today in</div>
<div>Today out</div>
</div>
<!-- Werte -->
<div style="position:absolute; top:10px; left:80px; width:120px; font-size:14px; font-weight:bold; text-align:center; line-height:26px; white-space: normal; word-wrap: break-word; display: flex; flex-direction: column;">
<div>APOX_Power W</div>
<div>statAPOX_E_inDay kWh</div>
<div>statAPOX_E_outDay kWh</div>
</div>
<!-- Chart -->
<div style="position:absolute; top:10px; right:10px; width:160px; height:72px; overflow:hidden;">
<div id="minichart2" style="width:160px; height:72px;"></div>
</div>
</div>
<script>
var chart = echarts.init(document.getElementById('minichart2'));
var fullData = [chartArray];
var finalArray = fullData.slice(-30);
var option = {
grid: { top: 3, bottom: 0, left: 0, right: 0 },
xAxis: { type: 'category', show: false, data: [] },
yAxis: { type: 'value', show: false },
series: [{
data: finalArray,
type: 'line',
smooth: true,
symbol: 'none',
lineStyle: { width: 2, color: '#3b82f6' },
areaStyle: { color: 'rgba(59,130,246,0.2)' }
}],
animation: false,
tooltip: { show: false }
};
chart.setOption(option);
</script>
- In <div class="label" wird der Readingname gesetzt.
- In <div class="value" einfach ein Reading vom Device eintragen.
- Den Devicenamen in div#NamevonEuremDevice eintragen. Damit wird der Mousehover unterdrückt.
3.4. Beispiele mit dummys
3.4.1. Netzfequenz mit einem Reading
defmod Netzfrequenz dummy
attr Netzfrequenz room miniChart
attr Netzfrequenz stateFormat <style>\
div#Netzfrequenz {\
pointer-events: none;;\
} \
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:180px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:100px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Netzfrequenz</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>49.999 Hz</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:45px;; left:10px;; width:160px;; height:50px;; overflow:hidden;;">\
<div id="minichart" style="width:160px;; height:50px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('minichart'));;\
var fullData = [chartArray];;\
var finalArray = fullData.slice(-130);;\
var option = {\
grid: { top: 3, bottom: 3, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: [] },\
yAxis: { type: 'value',\
show: false,\
min: function(value) {\
return value.min;;\
},\
max: function(value) {\
return value.max;;\
}\
},\
series: [{\
data: finalArray,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: '#3b82f6' },\
areaStyle: { color: 'rgba(59,130,246,0.2)' }\
}],\
animation: false,\
tooltip: { show: false }\
};;\
chart.setOption(option);;\
</script>
setstate Netzfrequenz <style>\
div#Netzfrequenz {\
pointer-events: none;;\
} \
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:180px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:100px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Netzfrequenz</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>49.999 Hz</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:45px;; left:10px;; width:160px;; height:50px;; overflow:hidden;;">\
<div id="minichart" style="width:160px;; height:50px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('minichart'));;\
var fullData = [50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999];;\
var finalArray = fullData.slice(-130);;\
var option = {\
grid: { top: 3, bottom: 3, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: [] },\
yAxis: { type: 'value',\
show: false,\
min: function(value) {\
return value.min;;\
},\
max: function(value) {\
return value.max;;\
}\
},\
series: [{\
data: finalArray,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: '#3b82f6' },\
areaStyle: { color: 'rgba(59,130,246,0.2)' }\
}],\
animation: false,\
tooltip: { show: false }\
};;\
chart.setOption(option);;\
</script>
setstate Netzfrequenz 2025-06-11 18:46:49 chartArray 50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999
3.4.2. Netzfequenz mit 1 Reading und Icon oben rechts
defmod Netzfrequenz dummy
attr Netzfrequenz room miniChart
attr Netzfrequenz stateFormat <style>\
div#Netzfrequenz {\
pointer-events: none;;\
} \
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:100px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Netzfrequenz</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>49.999 Hz</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:45px;; left:10px;; width:350px;; height:50px;; overflow:hidden;;">\
<div id="minichart" style="width:350px;; height:50px;;"></div>\
</div>\
\
<!-- SVG-Logo oben rechts -->\
<img src="/fhem/www/images/default/icoBlitz.png" style="position:absolute;; top:10px;; right:10px;; width:24px;; height:24px;;" alt="Logo">\
\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('minichart'));;\
var fullData = [chartArray];;\
var finalArray = fullData.slice(-130);;\
var option = {\
grid: { top: 3, bottom: 3, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: [] },\
yAxis: { type: 'value',\
show: false,\
min: function(value) {\
return value.min;;\
},\
max: function(value) {\
return value.max;;\
}\
},\
series: [{\
data: finalArray,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: '#3b82f6' },\
areaStyle: { color: 'rgba(59,130,246,0.2)' }\
}],\
animation: false,\
tooltip: { show: false }\
};;\
chart.setOption(option);;\
</script>
setstate Netzfrequenz <style>\
div#Netzfrequenz {\
pointer-events: none;;\
} \
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:100px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Netzfrequenz</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>49.999 Hz</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:45px;; left:10px;; width:350px;; height:50px;; overflow:hidden;;">\
<div id="minichart" style="width:350px;; height:50px;;"></div>\
</div>\
\
<!-- SVG-Logo oben rechts -->\
<img src="/fhem/www/images/default/icoBlitz.png" style="position:absolute;; top:10px;; right:10px;; width:24px;; height:24px;;" alt="Logo">\
\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('minichart'));;\
var fullData = [50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999];;\
var finalArray = fullData.slice(-130);;\
var option = {\
grid: { top: 3, bottom: 3, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: [] },\
yAxis: { type: 'value',\
show: false,\
min: function(value) {\
return value.min;;\
},\
max: function(value) {\
return value.max;;\
}\
},\
series: [{\
data: finalArray,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: '#3b82f6' },\
areaStyle: { color: 'rgba(59,130,246,0.2)' }\
}],\
animation: false,\
tooltip: { show: false }\
};;\
chart.setOption(option);;\
</script>
setstate Netzfrequenz 2025-06-11 18:46:49 chartArray 50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999
3.4.3. Netzfequenz mit 3 Readings
defmod Netzfrequenz dummy
attr Netzfrequenz room miniChart
attr Netzfrequenz stateFormat <style>\
div#Netzfrequenz {\
pointer-events: none;;\
} \
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:90px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Aktuell</div>\
<div>Zeit</div>\
<div>Datum</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>49.999 Hz</div>\
<div>18:55</div>\
<div>11.06.25</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:10px;; right:10px;; width:160px;; height:72px;; overflow:hidden;;">\
<div id="minichart" style="width:160px;; height:72px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('minichart'));;\
var fullData = [chartArray];;\
var finalArray = fullData.slice(-130);;\
var option = {\
grid: { top: 3, bottom: 3, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: [] },\
yAxis: { type: 'value',\
show: false,\
min: function(value) {\
return value.min;;\
},\
max: function(value) {\
return value.max;;\
}\
},\
series: [{\
data: finalArray,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: '#3b82f6' },\
areaStyle: { color: 'rgba(59,130,246,0.2)' }\
}],\
animation: false,\
tooltip: { show: false }\
};;\
chart.setOption(option);;\
</script>
setstate Netzfrequenz <style>\
div#Netzfrequenz {\
pointer-events: none;;\
} \
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:90px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Aktuell</div>\
<div>Zeit</div>\
<div>Datum</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>49.999 Hz</div>\
<div>18:55</div>\
<div>11.06.25</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:10px;; right:10px;; width:160px;; height:72px;; overflow:hidden;;">\
<div id="minichart" style="width:160px;; height:72px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('minichart'));;\
var fullData = [50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999];;\
var finalArray = fullData.slice(-130);;\
var option = {\
grid: { top: 3, bottom: 3, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: [] },\
yAxis: { type: 'value',\
show: false,\
min: function(value) {\
return value.min;;\
},\
max: function(value) {\
return value.max;;\
}\
},\
series: [{\
data: finalArray,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: '#3b82f6' },\
areaStyle: { color: 'rgba(59,130,246,0.2)' }\
}],\
animation: false,\
tooltip: { show: false }\
};;\
chart.setOption(option);;\
</script>
setstate Netzfrequenz 2025-06-11 18:46:49 chartArray 50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999
3.4.4. Smartmeter Line positive rot/ negative grün
defmod miniSmartmeter dummy
attr miniSmartmeter room miniChart
attr miniSmartmeter stateFormat <style>\
div#miniSmartmeter {\
pointer-events: none;;\
}\
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:90px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Currently</div>\
<div>Today in</div>\
<div>Total out</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>currently_01 W</div>\
<div>todayIn_01 kWh</div>\
<div>todayOut_01 kWh</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:10px;; right:10px;; width:160px;; height:72px;; overflow:hidden;;">\
<div id="miniSmartmeterChart" style="width:160px;; height:72px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('miniSmartmeterChart'));;\
var rawData = [chartArray];;\
var finalArray = rawData.slice(-30);;\
var positiveData = [];;\
var negativeData = [];;\
\
for (var i = 0;; i < finalArray.length;; i++) {\
var v = finalArray[i];;\
if (v >= 0) {\
positiveData.push(v);;\
negativeData.push(i > 0 && finalArray[i - 1] < 0 ? 0 : null);;\
} else {\
negativeData.push(v);;\
positiveData.push(i > 0 && finalArray[i - 1] >= 0 ? 0 : null);;\
}\
}\
\
var option = {\
grid: { top: 3, bottom: 0, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: finalArray.map((_, i) => i) },\
yAxis: { type: 'value', show: false },\
series: [\
{\
data: positiveData,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: 'red' },\
areaStyle: { color: 'rgba(255,0,0,0.2)' },\
markLine: {\
silent: true,\
symbol: 'none',\
data: [{ yAxis: 0 }],\
lineStyle: { color: 'grey', width: 1, type: 'solid' }\
}\
},\
{\
data: negativeData,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: 'green' },\
areaStyle: { color: 'rgba(0,255,0,0.2)' }\
}\
],\
animation: false,\
tooltip: { show: false }\
};;\
\
chart.setOption(option);;\
</script>\
setstate miniSmartmeter <style>\
div#miniSmartmeter {\
pointer-events: none;;\
}\
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:90px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Currently</div>\
<div>Today in</div>\
<div>Total out</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>-800 W</div>\
<div>200 kWh</div>\
<div>3200 kWh</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:10px;; right:10px;; width:160px;; height:72px;; overflow:hidden;;">\
<div id="miniSmartmeterChart" style="width:160px;; height:72px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('miniSmartmeterChart'));;\
var rawData = [200,200,250,200,200,100,50,0,0,-50,-100,-150,-200,-200,-300,-350,-410,-455,-510,-630,-800];;\
var finalArray = rawData.slice(-30);;\
var positiveData = [];;\
var negativeData = [];;\
\
for (var i = 0;; i < finalArray.length;; i++) {\
var v = finalArray[i];;\
if (v >= 0) {\
positiveData.push(v);;\
negativeData.push(i > 0 && finalArray[i - 1] < 0 ? 0 : null);;\
} else {\
negativeData.push(v);;\
positiveData.push(i > 0 && finalArray[i - 1] >= 0 ? 0 : null);;\
}\
}\
\
var option = {\
grid: { top: 3, bottom: 0, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: finalArray.map((_, i) => i) },\
yAxis: { type: 'value', show: false },\
series: [\
{\
data: positiveData,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: 'red' },\
areaStyle: { color: 'rgba(255,0,0,0.2)' },\
markLine: {\
silent: true,\
symbol: 'none',\
data: [{ yAxis: 0 }],\
lineStyle: { color: 'grey', width: 1, type: 'solid' }\
}\
},\
{\
data: negativeData,\
type: 'line',\
smooth: true,\
symbol: 'none',\
lineStyle: { width: 2, color: 'green' },\
areaStyle: { color: 'rgba(0,255,0,0.2)' }\
}\
],\
animation: false,\
tooltip: { show: false }\
};;\
\
chart.setOption(option);;\
</script>\
setstate miniSmartmeter 2025-06-12 15:48:19 chartArray 200,200,250,200,200,100,50,0,0,-50,-100,-150,-200,-200,-300,-350,-410,-455,-510,-630,-800
setstate miniSmartmeter 2025-06-12 15:50:24 currently_01 -800
setstate miniSmartmeter 2025-06-12 13:11:19 todayIn_01 200
setstate miniSmartmeter 2025-06-12 13:11:37 todayOut_01 3200
3.4.5. Smartmeter Bar positive rot/ negative grün
defmod miniSmartmeter1 dummy
attr miniSmartmeter1 room miniChart
attr miniSmartmeter1 stateFormat <style>\
div#miniSmartmeter1 {\
pointer-events: none;;\
}\
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:90px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Currently</div>\
<div>Today in</div>\
<div>Total out</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>currently_01 W</div>\
<div>todayIn_01 kWh</div>\
<div>todayOut_01 kWh</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:10px;; right:10px;; width:160px;; height:72px;; overflow:hidden;;">\
<div id="miniSmartmeterChart1" style="width:160px;; height:72px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('miniSmartmeterChart1'));;\
var rawData = [chartArray];;\
var finalArray = rawData.slice(-30);;\
var positiveData = finalArray.map((v, i) => v >= 0 ? v : (i > 0 && finalArray[i - 1] >= 0 ? 0 : null));;\
var negativeData = finalArray.map((v, i) => v < 0 ? v : (i > 0 && finalArray[i - 1] < 0 ? 0 : null));;\
\
var option = {\
grid: { top: 3, bottom: 0, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: finalArray.map((_, i) => i) },\
yAxis: { type: 'value', show: false },\
series: [\
{\
data: positiveData,\
type: 'bar',\
symbol: 'none',\
smooth: true,\
itemStyle: { color: 'red' },\
markLine: {\
silent: true,\
symbol: 'none',\
data: [{ yAxis: 0 }],\
lineStyle: { color: 'grey', width: 1, type: 'solid' }\
}\
},\
{\
data: negativeData,\
type: 'bar',\
smooth: true,\
symbol: 'none',\
itemStyle: { color: 'green' }\
}\
],\
animation: false,\
tooltip: { show: false }\
};;\
\
chart.setOption(option);;\
</script>
setstate miniSmartmeter1 <style>\
div#miniSmartmeter1 {\
pointer-events: none;;\
}\
</style>\
\
<!-- Lade echarts direkt -->\
<script src="/fhem/www/codemirror/echarts.min.js"></script>\
\
<!-- Chart-Container -->\
<div style="width:365px;; padding:10px;; border:1px solid #ddd;; border-radius:6px;; font-family:sans-serif;; box-shadow:0 2px 4px rgba(0,0,0,0.1);; box-sizing:border-box;; height:90px;; position:relative;;">\
\
<!-- Labels -->\
<div style="position:absolute;; top:10px;; left:10px;; width:90px;; font-size:14px;; text-align:left;; line-height:26px;;">\
<div>Currently</div>\
<div>Today in</div>\
<div>Total out</div>\
</div>\
\
<!-- Werte -->\
<div style="position:absolute;; top:10px;; left:80px;; width:120px;; font-size:14px;; font-weight:bold;; text-align:center;; line-height:26px;; white-space: normal;; word-wrap: break-word;; display: flex;; flex-direction: column;;">\
<div>-800 W</div>\
<div>200 kWh</div>\
<div>3200 kWh</div>\
</div>\
\
<!-- Chart -->\
<div style="position:absolute;; top:10px;; right:10px;; width:160px;; height:72px;; overflow:hidden;;">\
<div id="miniSmartmeterChart1" style="width:160px;; height:72px;;"></div>\
</div>\
</div>\
\
<script>\
var chart = echarts.init(document.getElementById('miniSmartmeterChart1'));;\
var rawData = [200,200,250,200,200,100,50,0,0,-50,-100,-150,-200,-200,-300,-350,-410,-455,-510,-630,-800];;\
var finalArray = rawData.slice(-30);;\
var positiveData = finalArray.map((v, i) => v >= 0 ? v : (i > 0 && finalArray[i - 1] >= 0 ? 0 : null));;\
var negativeData = finalArray.map((v, i) => v < 0 ? v : (i > 0 && finalArray[i - 1] < 0 ? 0 : null));;\
\
var option = {\
grid: { top: 3, bottom: 0, left: 0, right: 0 },\
xAxis: { type: 'category', show: false, data: finalArray.map((_, i) => i) },\
yAxis: { type: 'value', show: false },\
series: [\
{\
data: positiveData,\
type: 'bar',\
symbol: 'none',\
smooth: true,\
itemStyle: { color: 'red' },\
markLine: {\
silent: true,\
symbol: 'none',\
data: [{ yAxis: 0 }],\
lineStyle: { color: 'grey', width: 1, type: 'solid' }\
}\
},\
{\
data: negativeData,\
type: 'bar',\
smooth: true,\
symbol: 'none',\
itemStyle: { color: 'green' }\
}\
],\
animation: false,\
tooltip: { show: false }\
};;\
\
chart.setOption(option);;\
</script>
setstate miniSmartmeter1 2025-06-12 15:48:19 chartArray 200,200,250,200,200,100,50,0,0,-50,-100,-150,-200,-200,-300,-350,-410,-455,-510,-630,-800
setstate miniSmartmeter1 2025-06-12 15:50:24 currently_01 -800
setstate miniSmartmeter1 2025-06-12 13:11:19 todayIn_01 200
setstate miniSmartmeter1 2025-06-12 13:11:37 todayOut_01 3200
Gruß schwatter
Hallo Schwatter,
Gleich mal ausprobiert, gefällt mir gut.
Problem gab es gleich mit den styles, die ich verwende.
Beim F18 sieht es so aus:
Bildschirmfoto 2025-06-10 um 10.48.44.png
Beim Flex leider so:
Bildschirmfoto 2025-06-10 um 10.49.01.png
Hab beim Flex leider öfter Probleme auch die doif charts funktionieren nicht so gut.
Erweiterungsvorschlag:
Eine 0 linie da power auch negativ wrden kann.
Ansonsten gute Arbeit.
Gruß
Hubert
Moin,
ja der flex wieder. Hatte gestern kurz geschaut und gleich die Augen verdreht :)
Mal sehen was das wieder ist.
Das mit der 0 Line ist nicht unbedingt nötig. Da dreht sich der blaue Schleier.
Aber ich schaue.
Danke für die Rückmeldung. Btw, einfach 2mal den Code so in einem Raum verwendet funktioniert nicht.
Da müssen ein paar Klassen und Co. geändert werden.
Gruß schwatter
Next try,
ausgedünnt + funktioniert bei mir in f18 und flex
<div style="width:365px; padding:10px; border:1px solid #ddd; border-radius:6px; font-family:sans-serif; box-shadow:0 2px 4px rgba(0,0,0,0.1); box-sizing:border-box; height:90px; position:relative;">
<!-- Labels -->
<div style="position:absolute; top:10px; left:10px; width:90px; font-size:14px; text-align:left; line-height:26px;">
<div>Currently</div>
<div>Today</div>
<div>Total out</div>
</div>
<!-- Werte -->
<div style="position:absolute; top:10px; left:80px; width:120px; font-size:14px; font-weight:bold; text-align:center; line-height:26px; white-space: normal; word-wrap: break-word; display: flex; flex-direction: column;">
<div>total.Power.v W</div>
<div>total.YieldDay.v Wh</div>
<div>total.YieldTotal.v kWh</div>
</div>
<!-- Chart -->
<div style="position:absolute; top:10px; right:10px; width:160px; height:72px; overflow:hidden;">
<div id="chart1" style="width:160px; height:72px;"></div>
</div>
</div>
<script>
if (typeof echarts === "undefined") {
var script = document.createElement("script");
script.src = "https://cdn.jsdelivr.net/npm/echarts@5";
script.onload = initChart;
document.head.appendChild(script);
} else {
initChart();
}
function initChart() {
var chart1 = echarts.init(document.getElementById('chart1'));
var option = {
grid: { top: 3, bottom: 0, left: 0, right: 0 },
xAxis: { type: 'category', show: false, data: [] },
yAxis: { type: 'value', show: false },
series: [{
data: [1, 2, 3, 2, 5, 3, 2, 4],
type: 'line',
smooth: true,
symbol: 'none',
lineStyle: { width: 2, color: '#3b82f6' },
areaStyle: { color: 'rgba(59,130,246,0.2)' }
}],
animation: false,
tooltip: { show: false }
};
chart1.setOption(option);
}
</script>
Gruß schwatter
Super sehr gut, bei mir auch.
Danke
Manchmal mag Fhem die letzte Anpassung nicht im stateformat. Eigentlich müsste es ausgelagert werden.
Mal sehen. Also nicht verwundert sein wenn es knallt, ich weiß Bescheid.
Gruß schwatter
Hallo,
gefällt mir. Ich habe zwei Punkte:
- wie kann ich die Skalierung ändern. Ich monitore die Netzfrequenz und die schwankt ja eher zwischen 49.x und 50.x
- es werden ja Daten von https://cdn.jsdelivr.net/npm/echarts geholt. Ich würde die lieber lokal halten.
Grüße Jörg
So ich denke ich hab es,
- Prüfung entfernt. Script wird direkt am Anfang geladen.
- @JoWiemann Script herunterladen. In einen Fhempfad legen, Neustart und Pfad im Script auf Lokal ändern. Müsste funktionieren.
- @JoWiemann Zu Netz Frequenz. Normalerweise passt sich die Höhe dem größten Wert an. Funktioniert nicht so wie gewünscht?
- Abgesehen davon habe ich jetzt fullData.slice(-30) hinzugefügt. Damit kann die Zeitspanne beeinflusst werden.
Bedeutet in Verbindung mit dem at 5min x 30 = 150min. Bzw die letzten 150min. Vorher waren es immer 24std. Bisschen viel.
- Damit die Readings funktionieren, weiterhin einfach den Readingnamen unter Werte eintragen.
- Sowie unter Labels den Namen vergeben.
- Damit der Minichart in einen anderen Device funktioniert, müssen nur noch 2 Stellen einzigartig sein:
<div id="minichartEinzigartig " style="width:160px; height:72px;"></div>
var chart = echarts.init(document.getElementById('minichartEinzigartig '));
<!-- Lade echarts direkt -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5"></script>
<!-- Chart-Container -->
<div style="width:365px; padding:10px; border:1px solid #ddd; border-radius:6px; font-family:sans-serif; box-shadow:0 2px 4px rgba(0,0,0,0.1); box-sizing:border-box; height:90px; position:relative;">
<!-- Labels -->
<div style="position:absolute; top:10px; left:10px; width:90px; font-size:14px; text-align:left; line-height:26px;">
<div>Currently</div>
<div>Today</div>
<div>Today out</div>
</div>
<!-- Werte -->
<div style="position:absolute; top:10px; left:80px; width:120px; font-size:14px; font-weight:bold; text-align:center; line-height:26px; white-space: normal; word-wrap: break-word; display: flex; flex-direction: column;">
<div>total.Power.v W</div>
<div>total.YieldDay.v Wh</div>
<div>total.YieldTotal.v kWh</div>
</div>
<!-- Chart -->
<div style="position:absolute; top:10px; right:10px; width:160px; height:72px; overflow:hidden;">
<div id="minichart" style="width:160px; height:72px;"></div>
</div>
</div>
<script>
var chart = echarts.init(document.getElementById('minichart'));
var fullData = [chartArray];
var finalArray = fullData.slice(-30);
var option = {
grid: { top: 3, bottom: 0, left: 0, right: 0 },
xAxis: { type: 'category', show: false, data: [] },
yAxis: { type: 'value', show: false },
series: [{
data: finalArray,
type: 'line',
smooth: true,
symbol: 'none',
lineStyle: { width: 2, color: '#3b82f6' },
areaStyle: { color: 'rgba(59,130,246,0.2)' }
}],
animation: false,
tooltip: { show: false }
};
chart.setOption(option);
</script>
Gruß schwatter
Hallo,
anbei das js in der Version 5.0
Bei einer Standardinstallation von fhem:
<script src="http://xxx.xxx.xxx.xxx:8083/fhem/www/echarts.min.js"></script>
Grüße Jörg
Hallo,
leider funktioniert die Skalierung nicht. Anbei mal der Inhalt eines Readings chartArray.
50.00,49.997,49.996,49.996,49.996,49.996,49.996,49.995,49.995,49.995,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.994,49.993,49.993,49.993,49.993,49.994,49.994,49.995,49.995,49.995,49.996,49.998,49.999,49.999,49.999,50.000,50.000,50.000,50.000,50.000,50.000,50.000,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999,49.999
Danke und Grüße
Jörg
PS: mit folgender Änderung funktioniert es jetzt:
yAxis: { type: 'value',
show: false,
min: function(value) {
return value.min;
},
max: function(value) {
return value.max;
}
},
Super,
haste schnell hinbekommen. Wenn man ein bisschen in der eCharts Doku schmökert findet man einiges.
Den Pfad ändere mal so
<script src="/fhem/www/codemirror/echarts.min.js"></script>
Bzw. ab /fhem reicht. Dann wohin du willst. Ich werde morgen den ersten Post überarbeiten und auch eChart lokal
mit einpflegen. Nehme dein Beispiel mit auf.
Gruß schwatter
Nabend,
erstes Post überarbeitet und auch ein paar Beispiele als dummy's hinzugefügt.
Gruß schwatter
@carlos
Hier 2 dummys zum testen. Beide für Smartmeter. Positive rot, negative grün und eine Linie für 0.
Code entfernt. Angepasst und hinzugefügt in #1. Das "if" im Code wurde ab und zu von Fhem beim erzeugen gelöscht.
Gruß schwatter
Cool, gefält mir. Das wird ja immer besser.
Eine nette Idee. Die hatte ich auch schon vor paar Jahren, deswegen hatte ich damals schon Perlfunktionen definiert, die das gleiche leisten und noch einiges mehr. Da kommt man dann mit wenigen Zeilen aus.
Aber es ist immer schön, wenn man selber was auf die Beine stellt.
Deine Ringe nutze ich auch gerne. Zum Beispiel im devStateIcon.
{ui_Table::temp_hum_ring(ReadingsVal("THsensorBk","temperature",0),ReadingsVal("THsensorBk","humidity",0))}
Aber ich wollte mal ausbrechen und schauen.
Gruß schwatter
Zitat von: schwatter am 12 Juni 2025, 19:48:06Deine Ringe nutze ich auch gerne. Zum Beispiel im devStateIcon.
{ui_Table::temp_hum_ring(ReadingsVal("THsensorBk","temperature",0),ReadingsVal("THsensorBk","humidity",0))}
Aber ich wollte mal ausbrechen und schauen.
Gruß schwatter
Ja, es ist immer gut selber was zu machen, oft entwickelt sich ein größeres Projekt mit der Zeit.
P.S. Man kann übrigens im deviStateIcon eines Devices auch die ui_Table::card-Funktion verwenden, die solche Verläufe visualisiert
Das habe ich aufm Schirm. Wollte es aber absichtlich spartanischer und visuell flexibel.
Funktional is deine Card natürlich besser.
Gruß schwatter
Nabend,
hier ein Beispiel für stateFormat ohne Echarts. Nur Html, SVG und Perl. Dadurch viel effizienter.
{
my @v = (split /,/, ReadingsVal('Smartmeter_2E1F50','chartArray',''))[-40..-1]; # letzte 40 Werte
my ($min, $max) = (sort {$a <=> $b} @v)[0,-1];
$max //= 0; $min //= 0;
my $range = $max - $min || 1;
# SVG-Zielgröße (angepasst!)
my $width = 160;
my $height = 70;
my $w = $width / (@v - 1 || 1);
# y-Position der Null-Linie
my $y0 = $height - ((0 - $min) / $range * $height);
# Punkte vorbereiten
my @points = map {
[ $_ * $w, $height - (($v[$_] - $min)/$range * $height), $v[$_] ]
} 0..$#v;
my $bar_width = $w * 0.6;
my $bars_svg = join "", map {
my ($x, $y, $val) = @{$points[$_]};
my $color = $val >= 0 ? 'red' : 'green';
if ($val >= 0) {
my $bar_height = $y0 - $y;
sprintf(
'<rect x="%.2f" y="%.2f" width="%.2f" height="%.2f" fill="%s" opacity="0.8" />',
$x - $bar_width/2, $y, $bar_width, $bar_height, $color
);
} else {
my $bar_height = $y - $y0;
sprintf(
'<rect x="%.2f" y="%.2f" width="%.2f" height="%.2f" fill="%s" opacity="0.8" />',
$x - $bar_width/2, $y0, $bar_width, $bar_height, $color
);
}
} 0..$#points;
my $current_power = ReadingsVal('Smartmeter_2E1F50','APOX_Power', '--');
my $todayIn = ReadingsVal('Smartmeter_2E1F50','statAPOX_E_inDay', '--');
my $todayOut = ReadingsVal('Smartmeter_2E1F50','statAPOX_E_outDay', '--');
return qq{
<style>
div#Smartmeter_2E1F50 { pointer-events:none; }
</style>
<div style="width:365px; padding:10px; border:1px solid #ddd; border-radius:6px; font-family:sans-serif; box-shadow:0 2px 4px rgba(0,0,0,0.1); box-sizing:border-box; height:90px; position:relative;">
<div style="position:absolute; top:10px; left:10px; width:90px; font-size:14px; text-align:left; line-height:26px;">
<div>Currently</div><div>Today in</div><div>Total out</div>
</div>
<div style="position:absolute; top:10px; left:80px; width:120px; font-size:14px; font-weight:bold; text-align:center; line-height:26px; display:flex; flex-direction:column; white-space:normal; word-wrap:break-word;">
<div>${current_power} W</div><div>${todayIn} Wh</div><div>${todayOut} kWh</div>
</div>
<div style="position:absolute; top:10px; right:10px; width:160px; height:70px; overflow:hidden;">
<svg style="width:160px!important; height:70px!important; display:block;" viewBox="0 0 160 70" preserveAspectRatio="none">
$bars_svg
</svg>
</div>
</div>
};
}
Gruß schwatter
Tag,
und hier noch als Line mit Html,SVG und Perl + Farbschleier. Das Post vorher habe ich auch nochmal angepasst. Die Viewbox war falsch skaliert.
{
my @v = (split /,/, ReadingsVal('OpenDTU','chartArray',''))[-40..-1]; # letzte 40 Werte
my ($min, $max) = (sort {$a <=> $b} @v)[0,-1];
$max //= 0; $min //= 0;
my $range = $max - $min || 1;
# Zielgröße der SVG
my $width = 155;
my $height = 65;
my $w = $width / (@v - 1 || 1); # Abstand zwischen Punkten
# Punkte berechnen
my @points = map {
my $x = $_ * $w;
my $y = $height - (($v[$_] - $min) / $range * $height);
[$x, $y]
} 0..$#v;
# Linie (Pfade) erzeugen
my $path_d = "M" . join(" L", map { sprintf("%.2f,%.2f", @$_) } @points);
# Fläche unter der Linie
my $area_path_d = $path_d . sprintf(" L%.2f,%.2f L0,%.2f Z", $width, $height, $height);
# Werte auslesen
my $current_power = ReadingsVal('OpenDTU','total.Power.v', '--');
my $todayIn = ReadingsVal('OpenDTU','total.Power.v', '--');
my $todayOut = ReadingsVal('OpenDTU','total.YieldTotal.v', '--');
return qq{
<style>
div#OpenDTU { pointer-events:none; }
</style>
<div style="width:365px; padding:10px; border:1px solid #ddd; border-radius:6px; font-family:sans-serif; box-shadow:0 2px 4px rgba(0,0,0,0.1); box-sizing:border-box; height:90px; position:relative;">
<!-- Labels -->
<div style="position:absolute; top:10px; left:10px; width:90px; font-size:14px; text-align:left; line-height:26px;">
<div>Currently</div><div>Today in</div><div>Total out</div>
</div>
<!-- Werte -->
<div style="position:absolute; top:10px; left:80px; width:120px; font-size:14px; font-weight:bold; text-align:center; line-height:26px; display:flex; flex-direction:column; white-space:normal; word-wrap:break-word;">
<div>${current_power} W</div><div>${todayIn} Wh</div><div>${todayOut} kWh</div>
</div>
<!-- SVG-Chart -->
<div style="position:absolute; top:10px; right:10px; width:160px; height:70px; overflow:hidden;">
<svg style="width:160px!important; height:70px!important; display:block;" viewBox="0 0 160 70" preserveAspectRatio="xMidYMid meet">
<path d="$area_path_d" fill="rgba(59,130,246,0.2)" />
<path d="$path_d" fill="none" stroke="#3b82f6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</div>
</div>
};
}
Gruß schwatter
Mahlzeit,
ich habe Post #1 überarbeitet. Es ist jetzt nach Perl und Echart gegliedert. Für Perl habe ich 2 Beispieldummys erstellt.
Das Board hat gemeckert beim Code einfügen, daher als Anhang.
Perlvariante.
- alle wichtigen Variablen am Anfang
- Bei chartCardLinePerl ist Moving Average enthalten. Wer das nicht braucht kann den Codeblock # Moving Average löschen.
- Bei chartCardLinePerl ist eine gepunktete Nulllinie enthalten. Wer das nicht braucht, einfach #<!-- Null-Linie --> löschen.
Gruß schwatter
Morgen,
erstes Post überarbeitet.
- Unter 1.2 Ringbuffer hinzugefügt.
- Dadurch werden die letzten 50 Werte gespeichert. Kommt ein Neuer dazu, fliegt der letzte Alte raus.
- Ein Überlauf wird dadurch verhindert.
- Das at um Mitternacht fällt weg.
- Dadurch besser für Livevalues.
Gruß schwatter