This totally worked! thanks.
Thank you for your help. I placed āscrollZoom: falseā under a config: section as suggested, but this did not fix my problem. Let me describe the behavior more specifically (in case this helps):
-
If my mouse is not over the plot area (above or below the card) and I put my two fingers on the trackpad and scroll (up, down or back and fourth) the behavior is as expected (no zooming). I can scroll past the Plotly card up and down with no problems as long as I donāt take my two fingers off the trackpad and as long as they are initially placed on the trackpad when my mouse is NOT over the plot.
-
If the mouse is IN the plot area (so the mouse curser is a āplusā) and then I put my two fingers on the trackpad to scroll up or down, the plot will zoom in or out. The display also scrolls up or down even to the point where the mouse will no longer be over the plot. As long as I keep my two fingers on the trackpad, the plot will also zoom while Iām scrolling, even if my mouse has moved completely off of the graph.
Not sure if thereās any way to fix this, but here is my code:
type: custom:plotly-graph
disable_pinch_to_zoom: true
layout:
config:
scrollZoom: false
margin:
r: 75
dragmode: false
legend:
orientation: h
xanchor: center
x: 0.5
entities:
- entity: sensor.deye_sunsynk_sol_ark_pv_power
name: Solar
fill: tozeroy
line:
color: gold
filters:- sliding_window_moving_average:
window_size: 10
extended: false
- sliding_window_moving_average:
- entity: sensor.deye_sunsynk_sol_ark_load_power
name: Load
fill: tozeroy
line:
color: blue
filters:- sliding_window_moving_average:
window_size: 10
extended: false
- sliding_window_moving_average:
- entity: sensor.deye_sunsynk_sol_ark_grid_power
name: Grid
fill: tozeroy
line:
color: red
filters:- sliding_window_moving_average:
window_size: 10
extended: false
- sliding_window_moving_average:
- entity: sensor.deye_sunsynk_sol_ark_battery_state_of_charge
name: Battery SOC
line:
color: black
hours_to_show: 24
refresh_interval: 10
title: Energy Overview
type: custom:plotly-graph
disable_pinch_to_zoom: true
layout:
config:
scrollZoom: false
margin:
r: 75
dragmode: false
legend:
orientation: h
xanchor: center
x: 0.5
entities:
- entity: sensor.deye_sunsynk_sol_ark_pv_power
name: Solar
fill: tozeroy
line:
color: gold
filters:
- sliding_window_moving_average:
window_size: 10
extended: false
- entity: sensor.deye_sunsynk_sol_ark_load_power
name: Load
fill: tozeroy
line:
color: blue
filters:
- sliding_window_moving_average:
window_size: 10
extended: false
- entity: sensor.deye_sunsynk_sol_ark_grid_power
name: Grid
fill: tozeroy
line:
color: red
filters:
- sliding_window_moving_average:
window_size: 10
extended: false
- entity: sensor.deye_sunsynk_sol_ark_battery_state_of_charge
name: Battery SOC
line:
color: black
hours_to_show: 24
refresh_interval: 10
title: Energy Overview
AhĆ”, the config doesnāt go inside layout. it goes on the root level
I am using an expression to calculate a range for a y-axis, because I need to exclude a trace. I use getFromConfig(entities
) to get the traces, then find min and max for the desired traces.
Can I somehow detect which traces are shown? (Enabled or disabled in the legend)
I want to make a chart with a overview of the energy used and produced in a year. So 2 plots for a month, 24 a year.
Is that possible ? And how do I make it happen ?
Can I somehow detect which traces are shown?
Thatās unfortunately not supported at the moment. Feel free to open a feature request issue in the repo and Iāll look into it for the next release
yes, thatās possible, look into:
And while you are at it, you may want to read the whole readme and look around in the discussions page.
Hi, discovered this great Plotly extension, and created this power-energy history-graph using some example-code from some examples.
I added a function to add the the āliveā state info of the entity to this graph. As you can see when using this, the last column is continuously growing. (No energy-export here, due to sun-set )
type: custom:plotly-graph
title: Plotly
hours_to_show: current_week
time_offset: 8h
stack: false
defaults:
entity:
unit_of_measurement: kWh
texttemplate: '%{y}'
type: bar
statistic: state
period:
0s: 5minute
2h: hour
6d: day
360d: month
entities:
- entity: sensor.p1_meter_totale_energie_import
filters:
- delta
- fn: |
({xs,ys,hass,statistics}) => {
let statLast = statistics.length-1;
let lastStatisticsDateTime = new Date(statistics[statLast].end);
let lastStateDateTime = new Date(hass.states["sensor.p1_meter_totale_energie_import"].last_changed);
let stateLastStatic = statistics[statLast].state;
let stateLastState = hass.states["sensor.p1_meter_totale_energie_import"].state
let state = stateLastState-stateLastStatic;
if (state>0){
if (lastStateDateTime.getTime()>lastStatisticsDateTime.getTime()){
xs.push(lastStatisticsDateTime);
ys.push(state);
}else{
ys[statLast]+=state;
}
//debugger
}
return ({ xs,ys })
}
- store_var: import
- fn: console.log
- fn: |
({hass}) => {
console.log(hass.states["sensor.p1_meter_totale_energie_export"])
}
- entity: sensor.p1_meter_totale_energie_export
filters:
- delta
- fn: |
({xs,ys,hass,statistics}) => {
let statLast = statistics.length-1;
let lastStatisticsDateTime = new Date(statistics[statLast].end);
let lastStateDateTime = new Date(hass.states["sensor.p1_meter_totale_energie_export"].last_changed);
let stateLastStatic = statistics[statLast].state;
let stateLastState = hass.states["sensor.p1_meter_totale_energie_export"].state
let state = stateLastState-stateLastStatic;
if (state>0){
if (lastStateDateTime.getTime()>lastStatisticsDateTime.getTime()){
xs.push(lastStatisticsDateTime);
ys.push(state);
}else{
ys[statLast]+=state;
}
//debugger
}
return ({ xs,ys })
}
- store_var: export
- fn: console.log
- fn: |
({hass}) => {
console.log(hass.states["sensor.p1_meter_totale_energie_export"])
}
refresh_interval: auto
fn: |
$fn({getFromConfig, vars})=> {
const range = getFromConfig("visible_range");
const width = range[1] - range[0];
vars.scroll = (label, p) => ({
args: [
{
layout: {
"xaxis.range": [range[0] + width*p, range[1] + width*p],
}
}, {
transition: {
duration: 150,
}
}
],
label,
method: "animate",
})
vars.zoom = (label, h) => ({
args: [
{
layout: {
"xaxis.range": [Date.now()-1000*60*60*h, Date.now()],
}
}
],
label,
method: "animate",
})
}
layout:
barcornerradius: 15
bargap: 0.1
bargroupgap: 0.1
height: 50%
xaxis:
tickangle: -45
updatemenus:
- buttons:
- $fn({vars}) => vars.scroll( '<', -.5)
- $fn({vars}) => vars.scroll( '>', .5)
direction: right
active: -1
pad:
r: 10
t: 0
type: buttons
x: -0.1
xanchor: left
'y': -0.2
yanchor: top
- buttons:
- $fn({vars}) => vars.zoom( '1y', 24*366)
- $fn({vars}) => vars.zoom( '1m', 24*31)
- $fn({vars}) => vars.zoom( '1w', 24*7)
- $fn({vars}) => vars.zoom( '1d', 24)
- $fn({vars}) => vars.zoom( '1h', 1)
direction: right
active: -1
pad:
r: 100
t: 0
type: buttons
x: 0.1
xanchor: left
'y': -0.2
yanchor: top
So far so good.
Now I have two questions, maybe some one can help, as I do not find a solution to the questions:
-
As you can see I copied the code for the āliveā data for the last bar (the
fn:
code within the entity sections), and changed to entity-name in thehass.states[ ]
. I did so, because I need the name of the entity to get the current state of the entity. My question here is:
Is this name accessible as a variable, so I can make this one central code? -
See these two graphs, both showing the same page.
The upper one is opened at 18:52 hours, and the lower one is opened at 18:56 hours.
As you can see the upper one is continuing to increase in the 18:50 column, while the lower one has a new 18:55 column and is increased there.
I assume that the statistics are not updated while viewing the page. Is there a option to update the statistics within the view-time of this page?
Cool, I see you are really squeezing it really well already!
Is this name accessible as a variable, so I can make this one central code?
Yes, use get('.entity')
. The get
function (or the alias getFromConfig
) grabs stuff from other parts of the config, including defaults and stuff that gets populated as the yaml is interpreted. It can do both absolute (from the root) and relative paths (relative to wherever the function lyes). To do relative paths, just start with a dot.
This feature is designed it to enable the kind of advanced stuff like what you are doing
To reuse the function, you can:
- define it at the top and put it in vars, or
- make it part of the entity defaults.
Is there a option to update the statistics within the view-time of this page
refresh_interval: auto may not update statistics data. Try changing it to 10s.
Thanks for your reply!!
Using get() works, though I used let entity = get('entities[0].entity')
as get('.entity')
did not work.
This is my changed code:
type: custom:plotly-graph
title: Plotly
hours_to_show: current_week
time_offset: 8h
stack: false
entities:
- entity: sensor.p1_meter_totale_energie_export
- entity: sensor.p1_meter_totale_energie_import
defaults:
entity:
texttemplate: '%{y}'
type: bar
statistic: state
period:
0s: 5minute
2h: hour
6d: day
360d: month
filters:
- delta
- fn: |
({xs,ys,hass,statistics,get,meta}) => {
let statLast = statistics.length-1;
let entity = get('entities[0].entity')
let lastStatisticsDateTime = new Date(statistics[statLast].end);
let lastStateDateTime = new Date(hass.states[entity].last_changed);
let stateLastStatic = statistics[statLast].state;
let stateLastState = hass.states[entity].state
let state = stateLastState-stateLastStatic;
if (state>0){
if (lastStateDateTime.getTime()>lastStatisticsDateTime.getTime()){
xs.push(lastStatisticsDateTime);
ys.push(state);
}else{
ys[statLast]+=state;
}
}
return ({ xs,ys })
}
refresh_interval: 5
fn: |
$fn({getFromConfig, vars})=> {
const range = getFromConfig("visible_range");
const width = range[1] - range[0];
vars.scroll = (label, p) => ({
args: [
{
layout: {
"xaxis.range": [range[0] + width*p, range[1] + width*p],
}
}, {
transition: {
duration: 150,
}
}
],
label,
method: "animate",
})
vars.zoom = (label, h) => ({
args: [
{
layout: {
"xaxis.range": [Date.now()-1000*60*60*h, Date.now()],
}
}
],
label,
method: "animate",
})
}
layout:
barcornerradius: 15
bargap: 0.1
bargroupgap: 0.1
height: 50%
xaxis:
tickangle: -45
updatemenus:
- buttons:
- $fn({vars}) => vars.scroll( '<', -.5)
- $fn({vars}) => vars.scroll( '>', .5)
direction: right
active: -1
pad:
r: 10
t: 0
type: buttons
x: -0.1
xanchor: left
'y': -0.2
yanchor: top
- buttons:
- $fn({vars}) => vars.zoom( '1y', 24*366)
- $fn({vars}) => vars.zoom( '1m', 24*31)
- $fn({vars}) => vars.zoom( '1w', 24*7)
- $fn({vars}) => vars.zoom( '1d', 24)
- $fn({vars}) => vars.zoom( '1h', 1)
direction: right
active: -1
pad:
r: 100
t: 0
type: buttons
x: 0.1
xanchor: left
'y': -0.2
yanchor: top
Sadly, changing refesh_interval: auto
to refresh_interval: 5
did not work. A new bar is not created when the period is over within the view-time of the page. So statistics is not refreshed here also.
I see. Thinking about it, the cache mechansim may not be compatible with statistics, since they update things that happened in the past (which the cache wonāt do because it already asked for that period and got nothing).
Feel free to open an issue in the repo.
Thanks for your reply
In fact I have 24 fixed values ( from 24 input_numbers), so it is not a long-term statistics of an entity
it is like this
jan upload : a
jan download : b
feb upload: c
feb download: d
and I need to connect a date to themā¦
(I think i have to attach an attribute date to it so I can plot it easier ?)
so 1 jan is a b
1 feb is c and d
I think this discussion should get you started Compare current data with historical data over a period of time (e.g. today with yesterday, same day previous year) Ā· dbuezas/lovelace-plotly-graph-card Ā· Discussion #349 Ā· GitHub
type: custom:plotly-graph
fn: |-
$ex vars.color = (name) => {
return getComputedStyle(document.documentElement)getPropertyValue('--'+name);
}
entities:
- entity: sensor.energy_grid_consumption
line:
color: $ex vars.color('energy-grid-consumption-color')
How did you get the percentage in the top left like that?
Thanks!
Can anyone tell me where to start here?
I have figured out how to set the background color of the plot manually, but the rest of the card is not following the color scheme of HA? Iām a bit confused.
I am trying to move from the seemingly abandoned Apexcharts, but cards not matching everything else would be a dealbreaker. Any help would be appreciatedā¦
type: custom:plotly-graph
title: Cellular Internet Consumption
hours_to_show: 1h
refresh_interval: auto
autorange_after_scroll: true
entities:
- entity: sensor.pfsense_exodus_interface_wan_inbytes_kilobytes_per_second
name: Received
line:
color: rgb(10, 55, 58)
width: 1
fill: tozeroy
fillcolor: rgba(10, 55, 58, 0.25)
show_value: true
- entity: sensor.pfsense_exodus_interface_wan_outbytes_kilobytes_per_second
name: Transmitted
line:
color: rgb(255, 152, 0)
dash: dashdot
width: 2
show_value: true
layout:
height: 250
margin:
r: 100
plot_bgcolor: '#EFDECD'
xaxis:
rangeselector:
'y': 1.2
buttons:
- count: 1
step: hour
label: Hour
- count: 1
step: day
label: Day
- count: 7
step: day
label: Week
- count: 28
step: day
label: Month
Also, is there a place that lists common options for the various things. Obviously, not all the possibilities, but the readme is a bit lacking in examples. For example, for a line, the options are ādotā, ādashā, etcā¦ For an entity, the options are ānameā, āshow_valueā, etcā¦
I couldnāt find that, except in the Plotly documentation, but itās unclear what applies to Home Assistant.
Great integration, BTW! I appreciate all the work that went into this.
Hi thereās, thanks for the nice words.
This card builds upon a plotting library called plotly, to see all options you need to go to Plotly javascript graphing library in JavaScript
You can also google/chatGPT āhow do I xyz with plotlyjsā