Plotly interactive Graph Card

Ok, for anybody looking for an answer, it was resolved here:

Hi,

I’m trying to get a enegy dashboard like card, showing the hours my heating system is active per day.

This is my code nowadays:

type: custom:plotly-graph
hours_to_show: 168
defaults:
  yaxes:
    fixedrange: true
layout:
  xaxis:
    rangeselector:
      'y': 1.25
      buttons:
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year
entities:
  - entity: sensor.salon_heating_equivalente_left
    statistic: sum
    period: day
    name: Horas calefaccion equivalentes
    unit_of_measurement: h
    type: bar
    filters:
      - derivate: d
refresh_interval: 10

The problem is that the period and derivate filter are fixed. I would like them to change to month when I press the buttom year, similar to what happens in th energy dashboard.

Any idea on how to do it? I have been trying with getFromConfig parameter but I don’t know how and where use it.

Hi Susan!
yeah, I’m back from vacation :slight_smile:
Would you make a post with your question in a Q&A github discussion?
It’s easier for me to follow up there when involves some back and forth.

Try using a $ex and something like:

{
   const [start, end] = get('visible_range');
   const dist = +end-start;
   const day = 1000*60*60*24;
   const month = day*30;
   if (dist < day) return 'h';
   if (dist < month) return 'd';
   return 'M';
}

I tried that code and it works for change the derivate filter, but some strange error appears. This is the code configured in the card:

type: custom:plotly-graph
hours_to_show: 168
defaults:
  yaxes:
    fixedrange: true
layout:
  xaxis:
    rangeselector:
      'y': 1.25
      buttons:
        - count: 1
          step: day
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year
entities:
  - entity: sensor.salon_heating_equivalente_left
    statistic: sum
    period: 
      0s: hour
      24h: hour
      7d: day
      6M: month
      1y: month
    name: Horas calefaccion equivalentes
    unit_of_measurement: h
    type: bar
    filters:
      - derivate: |       
          $ex {
             const [start, end] = get('visible_range');
             const dist = +end-start;
             const day = 1000*60*60*24;
             const month = day*30;
             if (dist < day) return 'h';
             if (dist <= month) return 'd';
             return 'M';
          }
refresh_interval: 10

So the filter is changing when I press the buttons, but the bars shown are not correct. THis is the variable history that I want to represent in the graph bar:

However the first representation of the graph is showing an strange first value on Feb. 20:

image

If I scroll to the left a little that strange value disapper:

image

I I change to 1d the values ar not correct either, if the total day is 3h (and the total var value is 18.5 h) , one hour the same day cannot be 63 hours.

image

The same is happening when changing to 1m:
image

ok, I have tried different options and neither seem to work. Even more, with the simplier original code , the wrong values also appears in the graph:

Original code:

type: custom:plotly-graph
hours_to_show: 168
defaults:
  yaxes:
    fixedrange: true
layout:
  xaxis:
    rangeselector:
      'y': 1.25
      buttons:
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year
entities:
  - entity: sensor.salon_heating_equivalente_left
    statistic: sum
    period: day
    name: Horas calefaccion equivalentes
    unit_of_measurement: h
    type: bar
    filters:
      - derivate: d
refresh_interval: 10

First representation:

image

after scrolling to the left, the value the 20th changes to 4.86h

image

Scrolling a little more I can get the correct value, 2.34h but the 19th is not represented and the variable has value for that day (values from 18th )

image

When you derivate or integrate, you should discard the first datapoint. This is because Home Assistant sends a “fake” datapoint at the exact beginning of the requested range (i.e the leftmost date in the visible range), with the value before it.

When derivating or integrating, the math takes into account the time difference between points, which will be therefore wrong for the first element.

Use

filters:
  - filter: i>0

Ok, now this solved the first wrong value when accesing the card:

type: custom:plotly-graph
hours_to_show: 168
defaults:
  yaxes:
    fixedrange: true
layout:
  xaxis:
    rangeselector:
      'y': 1.25
      buttons:
        - count: 1
          step: day
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year
entities:
  - entity: sensor.salon_heating_equivalente_today
    statistic: sum
    period:
      0s: hour
      24h: hour
      7d: day
      1M: day
      6M: month
      1y: month
    name: Horas calefaccion equivalentes
    unit_of_measurement: h
    type: bar
    filters:
      - filter: i>0
      - derivate: |
          $ex {
             const [start, end] = get('visible_range');
             const dist = +end-start;
             const day = 1000*60*60*24;
             const month = day*30;
             if (dist <= day) return 'd';
             if (dist <= month) return 'd';
             return 'M';
          }
refresh_interval: 10

But when pressing any of the buttons that modified the period , the values are still wrong:

1d button: More then 18h in 1h period seems impossible to me

image

1M button:

image

! year button is not charguing anything, I guess because the 1 year period : 1 month is not completed yet??

I have a graph with my current power consumption and the production of power of my small solar panels.
I’d like to have a seperate graph with my EV charging and have this substracted from my total power consumption graph, as the 11kw show as huge spikes. Is it possible? There is no substract filter and i’m not very clear how to solve this. Thanks!

image

Hi @mateine , more on this graph.

I compared my graph bar with the actual variable I want to represent and detected more strange behavior.

For example, the variable is recording values since february 17th but the bar graph is only showing values since february 20th:

Do you think this is a wrong configuration of the statistics graph or it’s a bug?

I paste the code again as I did some minor changes to test them:

type: custom:plotly-graph
hours_to_show: 168
defaults:
  yaxes:
    fixedrange: true
layout:
  xaxis:
    rangeselector:
      'y': 1.25
      buttons:
        - count: 1
          step: day
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year
entities:
  - entity: sensor.salon_heating_equivalente_today
    statistic: sum
    period:
      0s: hour
      24h: hour
      7d: day
      1M: day
      6M: month
      1y: month
    name: Horas calefaccion equivalentes
    unit_of_measurement: h
    type: bar
    filters:
      - filter: i>0
      - derivate: |
          $ex {
             const [start, end] = get('visible_range');
             const dist = +end-start;
             const day = 1000*60*60*24;
             const month = day*30;
             if (dist <= day) return 'd';
             if (dist <= month) return 'd';
             return 'M';
          }
refresh_interval: 10

Looking for advice - so I have few sensors. Some are statistic sensors such as:

state_class: total_increasing
source: sensor.meter_electric_consumption_kwh
status: collecting
last_period: 12.9
last_valid_state: 13819.8
meter_period: daily
cron pattern: 0 0 * * *
last_reset: 2024-02-26T23:00:00.009322+00:00
unit_of_measurement: kWh
device_class: energy
friendly_name: daily_energy

While others just have certain value:

unit_of_measurement: kWh
friendly_name: Daily self consumed energy

I currently use graph using apex chart card that displays both correctly. However using plotly, second one is not displayed.
Example card is:

type: custom:plotly-graph
entities:
  - entity: sensor.daily_self_consumed_energy
    name: |
      $fn ({ ys,meta }) =>
        "Self" + "(" +ys[ys.length ]+" kWh)"
    type: bar
    statistic: max
    period: day
    texttemplate: '%{y}'
    marker:
      color: green
  - entity: sensor.daily_energy
    name: |
      $fn ({ ys,meta }) =>
        "From Grid" + "(" +ys[ys.length - 1]+" kWh)"
    type: bar
    statistic: state
    period: day
    texttemplate: '%{y}'
    marker:
      color: red
hours_to_show: 5d
layout:
  xaxis:
    rangeselector:
      'y': 1.2
      buttons:
        - count: 7
          step: day
        - count: 14
          step: day
        - count: 30
          step: day
  yaxis:
    fixedrange: true

It displays sensor.daily_energy sensor just fine, however other is not, regardless if I use max, mean or min. How can I do that?
I get this instead:
image

With Apex, I get something like this:
image

Appreciate the help

Can check against the standard statistics card in home assistant?
Statistics with period beyond 5minutes should be stored forever

Try removing the “statistic” key for sensors without statistics. Also i suggest you remove the first datapoint when using bar charts with a filter like this: filter: i>0

Ok changed it tk this, but it still does not show. + When I scroll through the graph, bars chage their thickness.

type: custom:plotly-graph
entities:
  - entity: sensor.daily_self_consumed_energy
    name: |
      $fn ({ ys,meta }) =>
        "Self" + "(" +ys[ys.length ]+"kWh)"
    type: bar
    period: day
    texttemplate: '%{y}'
    filter: i>0
    marker:
      color: green
  - entity: sensor.daily_energy
    name: |
      $fn ({ ys,meta }) =>
        "From Grid" + "(" +ys[ys.length - 1]+"kWh)"
    type: bar
    statistic: state
    period: day
    texttemplate: '%{y}'
    filter: i>0
    marker:
      color: red
hours_to_show: 5d
layout:
  xaxis:
    rangeselector:
      'y': 1.2
      buttons:
        - count: 7
          step: day
        - count: 14
          step: day
        - count: 30
          step: day
  yaxis:
    fixedrange: true

filters:
  - filter: i>0

See this section GitHub - dbuezas/lovelace-plotly-graph-card: Highly customisable Lovelace card to plot interactive graphs. Brings scrolling, zooming, and much more!

There is a gap in the 19th and also the value the 20th is different in the HA-card. The 18th doesn’t appear in plotly

Changing to 1 day graphs and period to hour, it can be see the bars are similar but the valors are completely illogical in plotly whereas in HA native card the have a logical value each hour

Changing to 1 month does’t change the native statistics card, as there is only dates since the 17th, but the values seem again to be logical, whereas in plotly the bars seems to be proportionally correct but the values aren’t.

Thank you. So I changed my template sensor to:

state_class: total_increasing
unit_of_measurement: kWh
device_class: energy
friendly_name: Daily Self Consumed Energy

But it still shows “undefined” for the value in the name, and there is no graph displayed. I also tried to remove “statistic” as you recommended, but that did not change anything. Is there anything else that I am not getting?

it will take some time for the sensor statistics to be collected and stored. Give it a couple of days

Hello,
i would like to open a subview. Thought i’d do that by double clicking.

on_dblclick: |-
  $fn ({ hass }) => () => {
    hass.callService('light', 'turn_on', {
      entity_id: 'light.portique_lumiere'
    })
  }

But the doubelclick does not support navigation actions or does it? the default tap_action is not supported either right?

  tap_action:
    action: navigate
    navigation_path: /lovelace/living_room

i found this thread where someone found a workaround.

but i cannot get the

window.history.pushState(null,"","/lovelace-main/0");       
window.dispatchEvent(new CustomEvent("location-changed"));

to work.

Any ideas on this topic?

Thanks. It took some time but statistics started to work after.

I am trying to display daily consumption. This is what it looks like:
image

Is there a way how can I move “total” line graph to the back, so that bars are in the front?

And this is the code:

type: custom:plotly-graph
entities:

  - entity: sensor.hourly_energy
    name: |
      $fn ({ ys,meta }) =>
        "Grid" + "(" +ys[ys.length - 1].toFixed(2)+"kWh)"
    type: bar
    filters:
      - filter: i>0
    statistic: state
    period: hour
    texttemplate: '%{y}'
    marker:
      color: red
  - entity: sensor.hourly_self_consumed_energy
    name: |
      $fn ({ ys,meta }) =>
        "Self" + "(" +ys[ys.length - 1].toFixed(2)+"kWh)"
    type: bar
    filters:
      - filter: i>0
    statistic: state
    period: hour
    texttemplate: '%{y}'
    marker:
      color: rgb(0, 204, 0)
  - entity: sensor.hourly_electricity_exported_to_grid_huawei
    name: |
      $fn ({ ys,meta }) =>
        "Export" + "(" +ys[ys.length - 1].toFixed(2)+"kWh)"
    type: bar
    filters:
      - filter: i>0
    statistic: state
    period: hour
    texttemplate: '%{y}'
    marker:
      color: rgb(230, 230, 0)
  - entity: sensor.hourly_house_total_consumed_energy
    name: |
      $fn ({ ys,meta }) =>
        "Total" + "(" +ys[ys.length - 1].toFixed(2)+"kWh)"
    type: line
    line:
      shape: spline
      color: rgb(255, 214, 204)
    fill: tozeroy
    statistic: state
    period: hour
    texttemplate: '%{y}'
    marker:
      color: rgb(255, 214, 204)
hours_to_show: current_day
layout:
  barmode: stack
  xaxis:
    rangeselector:
      'y': 1.2
  yaxis:
    fixedrange: true

One another question. For similar with my water usage, I have values in cubic meters. I display that on the bar, so I get values like “0.323”. How can I multiply it by 1000 to get “323” value instead? I am using texttemplate: '%{y}'