[Mini-Chart-Card] Schätzeisen bzw. grobe Visualisierung von Daten

Begonnen von schwatter, 09 Juni 2025, 23:37:53

Vorheriges Thema - Nächstes Thema

schwatter

Nabend,

ich habe an einer Minichartcard gebastelt.

Es ist ein kunterbunter Mix aus stateformat mit etwas HTML und JS, einer 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. echarts kopieren

echarts.min.js aus dem Anhang nach /fhem/www/codemirror/echarts.min.js. Eigentümer:fhem,Gruppe:dialout

2.Neustart

"shutdown restart"

3.Error abfangen

Neues Reading in dem Device eurer Wahl anlegen

setreading <mydevice> chartArray 0
Damit wird eine Fehlermeldung verhindert.

4. 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.


5. Perl-Sub in 99_myUtils.pm

sub AppendToArray {
  my ($dev, $reading, $newVal) = @_;
  my $current = ReadingsVal($dev, $reading, '');
  my @values = split(',', $current);
  push @values, $newVal;
  return join(',', @values);
}

6. 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");;\
}

7. 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");;\
}

8. Beispiele mit dummys

8.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



8.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

8.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



Gruß schwatter

carlos

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:
Du darfst diesen Dateianhang nicht ansehen.

Beim Flex leider so:
Du darfst diesen Dateianhang nicht ansehen.

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
FHEM svn auf Intel NUC mit proxmox, 3 Raspberry Pi, signalduino, nanoCUL,  toom Baumarkt Funksteckdosen, einige sonoffs, hue, shelly

schwatter

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

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

carlos

FHEM svn auf Intel NUC mit proxmox, 3 Raspberry Pi, signalduino, nanoCUL,  toom Baumarkt Funksteckdosen, einige sonoffs, hue, shelly

schwatter

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

JoWiemann

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
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

schwatter

#7
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

JoWiemann

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
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

JoWiemann

#9
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;
             }
          },
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

schwatter

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

schwatter

Nabend,

erstes Post überarbeitet und auch ein paar Beispiele als dummy's hinzugefügt.


Gruß schwatter

schwatter

#12
@carlos

Hier 2 dummys zum testen. Beide für Smartmeter. Positive rot, negative grün und eine Linie für 0.

Line

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


Bar

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 = [];;\
  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: 'bar',\
        itemStyle: { color: 'red' },\
        markLine: {\
          silent: true,\
          symbol: 'none',\
          data: [{ yAxis: 0 }],\
          lineStyle: { color: 'grey', width: 1, type: 'solid' }\
        }\
      },\
      {\
        data: negativeData,\
        type: 'bar',\
        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 = [];;\
  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: 'bar',\
        itemStyle: { color: 'red' },\
        markLine: {\
          silent: true,\
          symbol: 'none',\
          data: [{ yAxis: 0 }],\
          lineStyle: { color: 'grey', width: 1, type: 'solid' }\
        }\
      },\
      {\
        data: negativeData,\
        type: 'bar',\
        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

carlos

FHEM svn auf Intel NUC mit proxmox, 3 Raspberry Pi, signalduino, nanoCUL,  toom Baumarkt Funksteckdosen, einige sonoffs, hue, shelly

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF