Releases: woopstar/hsem
Releases · woopstar/hsem
v4.1.0
Changes
🚀 Features
📦 Dependencies
- #184 build(deps): bump homeassistant from 2025.10.3 to 2025.10.4 @dependabot[bot]
v4.0.1
v4.0.0
Changes
Be aware that this is a full breaking change of the HSEM sensor that now uses 15-minute interval and forecasting.
The new dashboard is available at https://github.com/woopstar/hsem/wiki/Dashboard-4.0
⚒️ Breaking Changes
📦 Dependencies
- #181 build(deps): bump isort from 6.0.1 to 7.0.0 @dependabot[bot]
- #183 build(deps): bump homeassistant from 2025.3.3 to 2025.10.2 in the pip group across 1 directory @dependabot[bot]
- #182 build(deps): bump homeassistant from 2025.3.3 to 2025.10.3 @dependabot[bot]
- #174 build(deps): bump black from 25.1.0 to 25.9.0 @dependabot[bot]
v4.0.0-beta9
Changes
Be aware this is a full breaking change of the HSEM sensor that now uses 15 minutes interval and forecasting.
🚀 Features
Full Dashboard v4.0 HSEM Sensor
views:
- title: HSEM
badges: []
sections:
- type: grid
cards:
- type: heading
heading: HSEM Working Mode Recommendation
heading_style: title
grid_options:
columns: full
rows: 2
- type: custom:apexcharts-card
update_interval: 5m
experimental:
disable_config_validation: true
grid_options:
columns: full
layout_options:
grid_columns: 3
grid_rows: 1
header:
show: false
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 120
stroke:
curve: stepline
xaxis:
labels:
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 500
yaxis:
show: false
min: 0
max: 1
tickAmount: 1
series:
- name: Batteries Charge From Grid
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_grid' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#ef4444'
- name: Batteries Charge From Solar
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_solar' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#22c55e'
- name: Batteries Discharge Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_discharge_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#f59e0b'
- name: Batteries Wait Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_wait_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#8b5cf6'
- name: EV Smart Charging
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'ev_smart_charging' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#3b82f6'
- name: Time Passed
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'time_passed' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#d1d5db'
- type: tile
entity: sensor.hsem_workingmode_sensor
features_position: bottom
vertical: false
grid_options:
columns: 24
rows: 1
- type: heading
heading: Battery
heading_style: title
- type: custom:apexcharts-card
update_interval: 10m
apex_config:
chart:
height: 150px
legend:
show: false
xaxis:
labels:
show: true
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 10
header:
show: true
show_states: true
colorize_states: true
all_series_config:
type: area
opacity: 0.3
stroke_width: 1
series:
- entity: sensor.batteries_state_of_capacity
type: line
color: yellow
yaxis_id: pct
opacity: 1
stroke_width: 2
- entity: sensor.power_import
yaxis_id: watt
group_by:
func: avg
duration: 5min
yaxis:
- id: pct
show: true
opposite: false
decimals: 0
max: 100
min: 0
- id: watt
show: true
opposite: true
decimals: 0
min: 0
- type: custom:apexcharts-card
update_interval: 5m
header:
show: true
title: batteries_charged
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 180
stroke:
curve: stepline
width: 1
...
v4.0.0-beta8
Changes
Be aware this is a full breaking change of the HSEM sensor that now uses 15 minutes interval and forecasting.
🚀 Features
Full Dashboard v4.0 HSEM Sensor
views:
- title: HSEM
badges: []
sections:
- type: grid
cards:
- type: heading
heading: HSEM Working Mode Recommendation
heading_style: title
grid_options:
columns: full
rows: 2
- type: custom:apexcharts-card
update_interval: 5m
experimental:
disable_config_validation: true
grid_options:
columns: full
layout_options:
grid_columns: 3
grid_rows: 1
header:
show: false
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 120
stroke:
curve: stepline
xaxis:
labels:
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 500
yaxis:
show: false
min: 0
max: 1
tickAmount: 1
series:
- name: Batteries Charge From Grid
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_grid' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#ef4444'
- name: Batteries Charge From Solar
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_solar' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#22c55e'
- name: Batteries Discharge Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_discharge_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#f59e0b'
- name: Batteries Wait Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_wait_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#8b5cf6'
- name: EV Smart Charging
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'ev_smart_charging' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#3b82f6'
- name: Time Passed
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'time_passed' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#d1d5db'
- type: tile
entity: sensor.hsem_workingmode_sensor
features_position: bottom
vertical: false
grid_options:
columns: 24
rows: 1
- type: heading
heading: Battery
heading_style: title
- type: custom:apexcharts-card
update_interval: 10m
apex_config:
chart:
height: 150px
legend:
show: false
xaxis:
labels:
show: true
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 10
header:
show: true
show_states: true
colorize_states: true
all_series_config:
type: area
opacity: 0.3
stroke_width: 1
series:
- entity: sensor.batteries_state_of_capacity
type: line
color: yellow
yaxis_id: pct
opacity: 1
stroke_width: 2
- entity: sensor.power_import
yaxis_id: watt
group_by:
func: avg
duration: 5min
yaxis:
- id: pct
show: true
opposite: false
decimals: 0
max: 100
min: 0
- id: watt
show: true
opposite: true
decimals: 0
min: 0
- type: custom:apexcharts-card
update_interval: 5m
header:
show: true
title: batteries_charged
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 180
stroke:
curve: stepline
width: 1
...
v4.0.0-beta7
Changes
Be aware this is a full breaking change of the HSEM sensor that now uses 15 minutes interval and forecasting.
🚀 Features
Full Dashboard v4.0 HSEM Sensor
views:
- title: HSEM
badges: []
sections:
- type: grid
cards:
- type: heading
heading: HSEM Working Mode Recommendation
heading_style: title
grid_options:
columns: full
rows: 2
- type: custom:apexcharts-card
update_interval: 5m
experimental:
disable_config_validation: true
grid_options:
columns: full
layout_options:
grid_columns: 3
grid_rows: 1
header:
show: false
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 120
stroke:
curve: stepline
xaxis:
labels:
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 500
yaxis:
show: false
min: 0
max: 1
tickAmount: 1
series:
- name: Batteries Charge From Grid
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_grid' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#ef4444'
- name: Batteries Charge From Solar
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_solar' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#22c55e'
- name: Batteries Discharge Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_discharge_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#f59e0b'
- name: Batteries Wait Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_wait_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#8b5cf6'
- name: EV Smart Charging
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'ev_smart_charging' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#3b82f6'
- name: Time Passed
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'time_passed' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#d1d5db'
- type: tile
entity: sensor.hsem_workingmode_sensor
features_position: bottom
vertical: false
grid_options:
columns: 24
rows: 1
- type: heading
heading: Battery
heading_style: title
- type: custom:apexcharts-card
update_interval: 10m
apex_config:
chart:
height: 150px
legend:
show: false
xaxis:
labels:
show: true
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 10
header:
show: true
show_states: true
colorize_states: true
all_series_config:
type: area
opacity: 0.3
stroke_width: 1
series:
- entity: sensor.batteries_state_of_capacity
type: line
color: yellow
yaxis_id: pct
opacity: 1
stroke_width: 2
- entity: sensor.power_import
yaxis_id: watt
group_by:
func: avg
duration: 5min
yaxis:
- id: pct
show: true
opposite: false
decimals: 0
max: 100
min: 0
- id: watt
show: true
opposite: true
decimals: 0
min: 0
- type: custom:apexcharts-card
update_interval: 5m
header:
show: true
title: batteries_charged
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 180
stroke:
curve: stepline
width: 1
...
v4.0.0-beta6
Changes
Be aware this is a full breaking change of the HSEM sensor that now uses 15 minutes interval and forecasting.
🚀 Features
Full Dashboard v4.0 HSEM Sensor
views:
- title: HSEM
badges: []
sections:
- type: grid
cards:
- type: heading
heading: HSEM Working Mode Recommendation
heading_style: title
grid_options:
columns: full
rows: 2
- type: custom:apexcharts-card
update_interval: 5m
experimental:
disable_config_validation: true
grid_options:
columns: full
layout_options:
grid_columns: 3
grid_rows: 1
header:
show: false
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 120
stroke:
curve: stepline
xaxis:
labels:
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 500
yaxis:
show: false
min: 0
max: 1
tickAmount: 1
series:
- name: Batteries Charge From Grid
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_grid' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#ef4444'
- name: Batteries Charge From Solar
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_solar' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#22c55e'
- name: Batteries Discharge Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_discharge_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#f59e0b'
- name: Batteries Wait Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_wait_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#8b5cf6'
- name: EV Smart Charging
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'ev_smart_charging' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#3b82f6'
- name: Time Passed
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows =
(Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation })
=> {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'time_passed' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: '#d1d5db'
- type: tile
entity: sensor.hsem_workingmode_sensor
features_position: bottom
vertical: false
grid_options:
columns: 24
rows: 1
- type: heading
heading: Battery
heading_style: title
- type: custom:apexcharts-card
update_interval: 10m
apex_config:
chart:
height: 150px
legend:
show: false
xaxis:
labels:
show: true
format: HH
rotate: -45
rotateAlways: true
hideOverlappingLabels: true
style:
fontSize: 10
fontWeight: 10
header:
show: true
show_states: true
colorize_states: true
all_series_config:
type: area
opacity: 0.3
stroke_width: 1
series:
- entity: sensor.batteries_state_of_capacity
type: line
color: yellow
yaxis_id: pct
opacity: 1
stroke_width: 2
- entity: sensor.power_import
yaxis_id: watt
group_by:
func: avg
duration: 5min
yaxis:
- id: pct
show: true
opposite: false
decimals: 0
max: 100
min: 0
- id: watt
show: true
opposite: true
decimals: 0
min: 0
- type: custom:apexcharts-card
update_interval: 5m
header:
show: true
title: batteries_charged
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 180
stroke:
curve: stepline
width: 1
...
v4.0.0-beta5
Changes
Be aware this is a full breaking change of the HSEM sensor that now uses 15 minutes interval and forecasting.
🚀 Features
Dashboard v4.0 HSEM Sensor
type: custom:apexcharts-card
update_interval: 5m
experimental:
disable_config_validation: true
grid_options:
columns: full
layout_options:
grid_columns: 3
grid_rows: 1
header:
show: false
title: Recommendations
graph_span: 48h
span:
start: day
now:
show: true
color: red
label: Now
apex_config:
chart:
height: 120
stroke:
curve: stepline
xaxis:
labels:
format: HH
rotate: -90
rotateAlways: true
hideOverlappingLabels: false
style:
fontSize: 10
fontWeight: 500
yaxis:
show: false
min: 0
max: 1
tickAmount: 1
series:
- name: Batteries Charge From Grid
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows = (Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation }) => {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_grid' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: "#ef4444"
- name: Batteries Charge From Solar
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows = (Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation }) => {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_charge_solar' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: "#22c55e"
- name: Batteries Discharge Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows = (Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation }) => {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_discharge_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: "#f59e0b"
- name: Batteries Wait Mode
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows = (Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation }) => {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'batteries_wait_mode' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: "#8b5cf6"
- name: EV Smart Charging
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows = (Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation }) => {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'ev_smart_charging' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: "#3b82f6"
- name: Time Passed
entity: sensor.hsem_workingmode_sensor
attribute: hourly_recommendations
type: area
opacity: 1
show:
legend_value: false
data_generator: >
const rows = (Array.isArray(entity.attributes.hourly_recommendations) ?
entity.attributes.hourly_recommendations : [])
.slice()
.sort((a,b) => new Date(a.start) - new Date(b.start));
const out = []; rows.forEach(({ start, end, recommendation }) => {
const s = new Date(start).getTime();
const e = new Date(end).getTime();
const on = recommendation === 'time_passed' ? 1 : null;
out.push([s, on], [e, on]);
}); return out;
color: "#d1d5db"
v3.5.0
Changes
🚀 Features
- #161 feat(hsem): Add setting to set likelihood for Solcast forecasts @woopstar
- #163 feat(hsem): Add option to set winter/spring months in config flow @woopstar
- #164 feat(hsem): add spike-aware reweighting, capping, and reliability scaling for hourly energy averages @woopstar
- #165 refactor(hsem): improve entity state fetching with unified error handling @woopstar
- #171 refactor(hsem): Make the update options method generic @woopstar
- #172 refactor(hsem): convert_to_time should always return time @woopstar
🐛 Bug Fixes
- #159 bug(hsem): add fix to set excess pv energy use in tou mode @woopstar
- #162 bug(hsem): set correct winter and summer months @woopstar
- #166 bug(hsem): Clear missing input entities list on reload @woopstar
- #167 bug(hsem): Fix missing inputs is optional for ev settings @woopstar
- #168 bug(hsem): Set batteries useable capacity correctly to max rated capacity @woopstar
- #169 bug(hsem): Improve the calculation of batteries capacity @woopstar
- #170 bug(hsem): Add null check when resolving entity id from unique id @woopstar
v3.5.0-beta7
Changes
🚀 Features
- #161 feat(hsem): Add setting to set likelihood for Solcast forecasts @woopstar
- #163 feat(hsem): Add option to set winter/spring months in config flow @woopstar
- #164 feat(hsem): add spike-aware reweighting, capping, and reliability scaling for hourly energy averages @woopstar
- #165 refactor(hsem): improve entity state fetching with unified error handling @woopstar
- #171 refactor(hsem): Make the update options method generic @woopstar
- #172 refactor(hsem): convert_to_time should always return time @woopstar
🐛 Bug Fixes
- #159 bug(hsem): add fix to set excess pv energy use in tou mode @woopstar
- #162 bug(hsem): set correct winter and summer months @woopstar
- #166 bug(hsem): Clear missing input entities list on reload @woopstar
- #167 bug(hsem): Fix missing inputs is optional for ev settings @woopstar
- #168 bug(hsem): Set batteries useable capacity correctly to max rated capacity @woopstar
- #169 bug(hsem): Improve the calculation of batteries capacity @woopstar
- #170 bug(hsem): Add null check when resolving entity id from unique id @woopstar