Plot data in frontend

It would be great if a component could provide an array of data that is plotted as a graph in the frontend.
I can see several use cases for this:

  • Weather forecast. A backend component could provide an array with expected future temperature (rain, wind or something else), and this should be shown as a graph in the frontend.

  • Electricity price. In the Tibber sensor (https://github.com/home-assistant/home-assistant/pull/9661 ) the electricity price is available for the next days, so the backend component could provide an array with this data.

@andrey : Is this something you could be interesting to do? I know you have done a lot of great work with the frontend. I have not done much development of frontend, but could help with the backend code.

In some cases, isn’t this already in place, but not in the default display. The history component populates a graph that can be viewed by clicking on a component. Can this just be pulled into the default view or are you looking for something else?

No, what you’re referring is plotting available only to the recorder component. What daniel means is a “framework”, so that other modules from the backend can expose data, that is graphed in the frontend. However, this data is in no way related to recorded events and values, it could very well be about future values (e.g. weather forecast).

I think this can be useful indeed!

A similar graph as the history component would be fine. But the history component only reads the data from the database. And I want a graph that the component could update dynamically without adding it to the database. (The weather forecast will change, and than could the component just update an array.)
But I think the graph should be part of the more-info card as the history plot.

edit: @kirichkov: explained it correctly

FYI, the weather platform already has this functionality, OpenWeatherMaps certainly (I added it myself), not sure about the others.
it looks like this:
image

I can be enabled using the weather platform (https://home-assistant.io/components/weather.openweathermap/)

1 Like

Plotting graphs is added in 0.55 with the History Graph component.

https://home-assistant.io/components/history_graph/

I understood from this thread that I can plot future data on graph using history graph, like weather forecast or electricity price.
But I could not achieve this.
OpenWeatherMap shows only recorded data, and not forecast on graph (forecast is shown below using lots of rows).
Is there any component which shows future data on graph in Home Assistant ?

The weather components do that, but should be refactored

Hej @Danielhiversen

Just wanted to share that I am currently doing a hack where I have a html in my www folder which I view using an iframe-card. it works well on my wall tablet, but it’s not very elegant elsewhere, and it seems like it affect load time on older devices.

I have it displayed on my kitchen tablet, and I haven’t opened the tibber app since basically. I have a full screen view version as well, but it’s a bit redundant actually.

Ideally I would want to make this into a lovelace card, but ultimately lacking the knowhow. Would love some help if there are any takers.


(A second dark line appears once the price for the upcoming day is avaiable).

Below is the html shown in the iframe card.

<script src="jquery-3.3.1.js"></script>
<script src="Chart.bundle.js"></script>

<canvas id="canvas" width="350" height="180"></canvas>
<script>

    var labels;
    var data;

    $.ajax({
    url: "https://api.tibber.com/v1-beta/gql",
    beforeSend: function(xhr) {
      xhr.setRequestHeader("Authorization", "Bearer d1007ead2dc84a2b82f0de19451c5fb22112f7ae11d19bf2bedb224a003ff74a");
    },
    type: 'POST',
    dataType: 'json',
    contentType: 'application/json',
    processData: false,
    data: '{ "query": "{viewer {homes {currentSubscription {priceInfo {today {total} tomorrow {total}}}}}}"}',
    success: function (data) {
      doWork(data);
    },
    error: function(){
    alert("Cannot get data");
    }
  });

  function doWork(data)
  {
      var idag  = data.data.viewer.homes[0].currentSubscription.priceInfo.today;
      var imorgon  = data.data.viewer.homes[0].currentSubscription.priceInfo.tomorrow;

      dataIdag = idag.map(function(e) {
         return e.total;
      });

      dataImorgon = imorgon.map(function(e) {
         return e.total;
      });

      var ctx = canvas.getContext('2d');

      var gradientStroke = ctx.createLinearGradient(0, 50, 0, 130);

      gradientStroke.addColorStop(1, "rgba(0,255,0,0.5)");
      gradientStroke.addColorStop(0.5, "rgba(255,255,0,0.5)")
      gradientStroke.addColorStop(0, "rgba(255,0,0,0.5)");

      var pointStroke = ctx.createLinearGradient(0, 50, 0, 200);

      pointStroke.addColorStop(1, "rgba(0,255,0,0.1)");
      pointStroke.addColorStop(0.5, "rgba(255,255,0,0.1)")
      pointStroke.addColorStop(0, "rgba(255,0,0,0.1)");

      var config = {
         type: 'line',
         options: {
          responsive: false,
          legend: {
            display: false
          },
          animation: {
        duration: 0
    },
          tooltips: {
      callbacks: {
         label: function(tooltipItem) {
                return tooltipItem.yLabel;
         }
      },
      displayColors: false,
       mode: 'nearest'
  },
          maintainAspectRatio: false,
             scales: {
                 yAxes: [{
                     ticks: {
                         beginAtZero:true,
               min: 0.4,
               max: 1.1,
               stepSize: 0.1,
                     }
                 }]
             }},
         data: {
            labels: [00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
            datasets: [
      {
         label: 'Imorgon',
         data: dataImorgon,
         backgroundColor: gradientStroke,
         borderColor: "rgba(200,100,200,0.4)",
         pointRadius: 0.1,
         pointHoverRadius: 0,
         fill: false
       },
       {
          label: 'Idag',
          data: dataIdag,
          backgroundColor: gradientStroke,
          pointBackgroundColor: pointStroke,
          borderColor: gradientStroke,
          fill: true,
          pointRadius: 10,
          pointHoverRadius: 15,
 }],
         }
};
if (config &&
  config.data &&
  config.data.datasets) {
  // Loop through all the datasets
    for (var j = 1; j< dataIdag.length; j++){
      var thecolor;
    if (dataIdag[j-1] > 0.7)
     thecolor = "rgb(255,0,0)"
     else {
       thecolor = "rgb(0,255,0)"
     }
  }
}
      var chart = new Chart(ctx, config);
  }
</script>

So essentially it’s a JSON query to the API using a Bearer token (I pasted one of their demo tokens above so hide my own).

I posted here as well, in case it was possible to integrate with the lovelave mini graph card.

2 Likes

Hey, @wrenchse.

Sorry for probably very stupid questions, but I am learning as I am going here.
Have you found any more info regarding this solution? I’m quite inexperienced with most of this, but I tried to include your code to my Home Assistant. Where should
I put the referenced js files to get the chart working?

I tried to reference them to the online repositories and also local download in the same folder as the html file, but no result. I did see the chart grid in the iFrame card though. I have not enabled SSL on my HA, so could this maybe be a reason. I cannot see any iFrame content when logged in externally either.

By the way, the Tibber sensor is working OK, so the token is working.

You say you could see the grid, which kinda indicates that it might be working? if you open that web page directly you should be able to get some debug information in the developer console if something is wrong. But to be honest, perhaps you were just trying on a day where electricity was really cheap? :slight_smile: I set the minimum to 0.4 SEK per kW/h so anything below that would not show up.

I just have the html directly in the www folder, and the js dependencies as well.

Hi, yes the price is mostly below 0.2 NOK right now, so that might be the issue. Thanks for the info.

Change the html code to say min 0.1 maybe instead of 0.4 and you should probably see the graph. Congratulations on the cheap electricity! :slight_smile:

Thanks. It’s working perfectly now. We’re enjoying the cheap electricity as long as it lasts. :slight_smile:
While testing, it seems that the html is buffered somewhere so that I have to rename the html file for each change, but I’m probably satisfied with the layout soon.
Thanks for great work, and I like the addition of the day-ahead line.

Hi @wrenchse

Really nice to be able to implement the future price in a graph! Do you know if it is possible to get a sensor for the future price? Even if it is just a value for for example two hours ahead. My thought is to be able to start some floor heating before the price rises in a certain time intervall. It is easy to compare with the price at the moment but then it is already to late to start warming if the price increases.

I don’t think the sensor itself has access to that data, but what I’ve done before is using node-red send a http-get request with the same api structure to get the data. (Initially before doing this web page that was my approach). So you could pass values from that into a sensor if you’d like.

I had the exact same use case as you described, but eventually realised that the electricity is always the most expensive at the same hours every day so I for instance heat up bathroom floor between 5-7AM then off until 15-17 (gets expensive at 18 when most people cook). Etc.