Max Solar Power Heatmap over Azimut and Elevation #408
Replies: 4 comments 20 replies
-
Really cool! |
Beta Was this translation helpful? Give feedback.
-
Is there a way to render a cross or dot for the current Elevation/Azimuth on top of the heatmap? |
Beta Was this translation helpful? Give feedback.
-
Totally. I’m traveling so I can only past a bit ugly
- entity: sensor.sun_solar_elevation x: >- $fn ({ hass }) =>
[1,1].map(x=>parseFloat(hass.states['sensor.sun_solar_azimuth'].state))
'y': >- $fn ({ hass }) =>
[1,1].map(x=>parseFloat(hass.states['sensor.sun_solar_elevation'].state))
z: >- $fn ({ hass }) =>
[1,1].map(x=>parseFloat(hass.states['sensor.solar_power'].state)) type:
scatter mode: markers marker: size: - 15 - 7 color: - black - yellow
symbol: - circle - star
Ladislav Feldsam ***@***.***> schrieb am Di. 21. Mai 2024 um
09:50:
… Is there a way to render a cross or dot for the current Elevation/Azimuth
on top of the heatmap?
—
Reply to this email directly, view it on GitHub
<#408 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAS47MV7W5TWVTUMN3RVSELZDL4FZAVCNFSM6AAAAABGGBGIYGVHI2DSMVQWIX3LMV43SRDJONRXK43TNFXW4Q3PNVWWK3TUHM4TKMBVGEZDA>
.
You are receiving this because you authored the thread.Message ID:
<dbuezas/lovelace-plotly-graph-card/repo-discussions/408/comments/9505120@
github.com>
|
Beta Was this translation helpful? Give feedback.
-
i have improved your code a bit. type: custom:plotly-graph
raw_plotly_config: true
hours_to_show: 1y
refresh_interval: 5m
title: Max Solar Power [W]
layout:
autosize: true
margin:
t: 0
l: 55
r: 45
b: 65
xaxis:
title: Azimuth [°]
yaxis:
title: Elevation [°]
entities:
- entity: sensor.sun_solar_azimuth
internal: true
period: 5minute
fn: |-
$fn ({ xs, ys, vars }) => {
vars.azimuth_raw_x_ = xs.map(x => x.getTime());
vars.azimuth_raw_y_ = ys;
}
- entity: sensor.sun_solar_azimuth
internal: true
statistic: mean
period: hour
fn: |-
$fn ({ xs, ys, vars }) => {
const xs_ = xs.map(x => x.getTime());
const i = xs_.findIndex(x => x > vars.azimuth_raw_x_[0]);
vars.azimuth_raw_x = xs_.slice(0, i);
vars.azimuth_raw_y = ys.slice(0, i);
}
- entity: sensor.sun_solar_elevation
internal: true
period: 5minute
fn: |-
$fn ({ xs, ys, vars }) => {
vars.elevation_raw_x_ = xs.map(x => x.getTime());
vars.elevation_raw_y_ = ys;
}
- entity: sensor.sun_solar_elevation
internal: true
statistic: mean
period: hour
fn: |-
$fn ({ xs, ys, vars }) => {
const xs_ = xs.map(x => x.getTime());
const i = xs_.findIndex(x => x > vars.elevation_raw_x_[0]);
vars.elevation_raw_x = xs_.slice(0, i);
vars.elevation_raw_y = ys.slice(0, i);
}
- entity: sensor.solar_power
internal: true
period: 5minute
fn: |-
$fn ({ xs, ys, vars }) => {
vars.power_raw_x_ = xs.map(x => x.getTime());
vars.power_raw_y_ = ys;
}
- entity: sensor.solar_power
internal: true
statistic: mean
period: hour
fn: |-
$fn ({ xs, ys, vars }) => {
const xs_ = xs.map(x => x.getTime());
const i = xs_.findIndex(x => x > vars.power_raw_x_[0]);
vars.power_raw_x = xs_.slice(0, i);
vars.power_raw_y = ys.slice(0, i);
}
- entity: ""
type: heatmap
hoverongaps: false
colorscale: Rainbow
fn: |-
$fn ({ xs, ys, vars }) => {
const x = Array.from({ length: 220 + 1 }, (e, i) => 70 + i);
const y = Array.from({ length: 55 + 1 }, (e, i) => 0 + i);
const z = Array(y.length).fill(null).map(() => Array(x.length).fill(NaN));
for (let i = 0; i < vars.power_raw_y.length; i++) {
const pw = vars.power_raw_y[i];
const ix = vars.power_raw_x[i];
const azi = vars.azimuth_raw_x.indexOf(ix);
const eli = vars.elevation_raw_x.indexOf(ix);
if (azi >= 0 && eli >= 0) {
const az = vars.azimuth_raw_y[azi];
const el = vars.elevation_raw_y[eli];
const pos_az_min = x.indexOf(Math.floor(az));
const pos_el_min = y.indexOf(Math.floor(el));
const pos_az_max = x.indexOf(Math.ceil(az));
const pos_el_max = y.indexOf(Math.ceil(el));
if (pos_az_min >= 0 && pos_el_min >= 0 && pos_az_max >= 0 && pos_el_max >= 0) {
for (let pos_az = pos_az_min; pos_az <= pos_az_max; pos_az++) {
for (let pos_el = pos_el_min; pos_el <= pos_el_max; pos_el++) {
if (isNaN(z[pos_el][pos_az])) {
z[pos_el][pos_az] = pw;
} else {
z[pos_el][pos_az] = Math.max(z[pos_el][pos_az], pw);
}
}
}
}
}
}
for (let i = 0; i < vars.power_raw_y_.length; i++) {
const pw = vars.power_raw_y_[i];
const ix = vars.power_raw_x_[i];
const azi = vars.azimuth_raw_x_.indexOf(ix);
const eli = vars.elevation_raw_x_.indexOf(ix);
if (azi >= 0 && eli >= 0) {
const az = vars.azimuth_raw_y_[azi];
const el = vars.elevation_raw_y_[eli];
const pos_az_min = x.indexOf(Math.floor(az));
const pos_el_min = y.indexOf(Math.floor(el));
const pos_az_max = x.indexOf(Math.ceil(az));
const pos_el_max = y.indexOf(Math.ceil(el));
if (pos_az_min >= 0 && pos_el_min >= 0 && pos_az_max >= 0 && pos_el_max >= 0) {
for (let pos_az = pos_az_min; pos_az <= pos_az_max; pos_az++) {
for (let pos_el = pos_el_min; pos_el <= pos_el_max; pos_el++) {
if (isNaN(z[pos_el][pos_az])) {
z[pos_el][pos_az] = pw;
} else {
z[pos_el][pos_az] = Math.max(z[pos_el][pos_az], pw);
}
}
}
}
}
}
vars.x = x;
vars.y = y;
vars.z = z;
};
x: $fn ({ vars }) => vars.x
"y": $fn ({ vars }) => vars.y
z: $fn ({ vars }) => vars.z |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Please read entire post. Below others significantly improved the code - including but not limited to long term statistics.
Do you want to see, what your best solar power was over azimut and elevation? Then enjoy this:
Also inspired by 215
PS: Because the power is NaN at night, somehow the array azimuth/elevation compared to power had not the same length, therefore I passed on the xs'es to sort the power values in manually.
Beta Was this translation helpful? Give feedback.
All reactions