Add Lovelace dashboard for BMS monitoring
Full-featured dashboard with mushroom overview cards, bar-card cell voltage display with colour thresholds, ApexCharts history graphs for voltage/current/SoC/power, balance quality indicator, and controls/protection panel. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,377 @@
|
|||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Xiaoxiang Smart BMS — Lovelace Dashboard
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
#
|
||||||
|
# REQUIRED HACS CARDS (install via HACS → Frontend):
|
||||||
|
# • Mushroom Cards https://github.com/piitaya/lovelace-mushroom
|
||||||
|
# • ApexCharts Card https://github.com/RomRider/apexcharts-card
|
||||||
|
# • Bar Card https://github.com/custom-cards/bar-card
|
||||||
|
#
|
||||||
|
# SETUP:
|
||||||
|
# 1. Go to Settings → Devices → your BMS device → any entity
|
||||||
|
# 2. Note the entity ID prefix (e.g. "lifepo4_48v" from "sensor.lifepo4_48v_voltage")
|
||||||
|
# 3. Find-and-replace YOUR_BMS with that prefix everywhere below
|
||||||
|
# 4. Adjust cell count: remove unused cell_voltage_N lines at the bottom
|
||||||
|
# 5. Adjust min/max in bar-card to match your chemistry:
|
||||||
|
# LiFePO4: min 2.8 max 3.7
|
||||||
|
# Li-ion: min 2.5 max 4.25
|
||||||
|
#
|
||||||
|
# HOW TO ADD:
|
||||||
|
# Dashboards → Add Dashboard → (name it) → three-dot menu → Edit → Raw config editor
|
||||||
|
# Paste this entire file (or just the `cards:` block into an existing view).
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
views:
|
||||||
|
- title: Battery
|
||||||
|
path: battery
|
||||||
|
icon: mdi:battery-charging
|
||||||
|
cards:
|
||||||
|
|
||||||
|
# ── Status chips ───────────────────────────────────────────────────────
|
||||||
|
- type: custom:mushroom-chips-card
|
||||||
|
chips:
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.YOUR_BMS_state_of_charge
|
||||||
|
icon: mdi:battery
|
||||||
|
content_info: state
|
||||||
|
- type: entity
|
||||||
|
entity: binary_sensor.YOUR_BMS_mos_charge_enabled
|
||||||
|
icon: mdi:battery-arrow-up
|
||||||
|
content_info: none
|
||||||
|
- type: entity
|
||||||
|
entity: binary_sensor.YOUR_BMS_mos_discharge_enabled
|
||||||
|
icon: mdi:battery-arrow-down
|
||||||
|
content_info: none
|
||||||
|
- type: entity
|
||||||
|
entity: binary_sensor.YOUR_BMS_balance_active
|
||||||
|
icon: mdi:approximately-equal
|
||||||
|
content_info: none
|
||||||
|
# Red warning chip — only visible when any protection fires
|
||||||
|
- type: conditional
|
||||||
|
conditions:
|
||||||
|
- condition: or
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity: binary_sensor.YOUR_BMS_prot_cell_overvolt
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity: binary_sensor.YOUR_BMS_prot_cell_undervolt
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity: binary_sensor.YOUR_BMS_prot_charge_overcurrent
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity: binary_sensor.YOUR_BMS_prot_discharge_overcurrent
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity: binary_sensor.YOUR_BMS_prot_short_circuit
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity: binary_sensor.YOUR_BMS_prot_software_lock
|
||||||
|
state: "on"
|
||||||
|
chip:
|
||||||
|
type: template
|
||||||
|
content: Protection triggered
|
||||||
|
icon: mdi:shield-alert
|
||||||
|
icon_color: red
|
||||||
|
|
||||||
|
# ── Primary metrics ────────────────────────────────────────────────────
|
||||||
|
- type: grid
|
||||||
|
columns: 3
|
||||||
|
square: false
|
||||||
|
cards:
|
||||||
|
|
||||||
|
# State of Charge — dynamic icon + colour
|
||||||
|
- type: custom:mushroom-template-card
|
||||||
|
primary: "{{ states('sensor.YOUR_BMS_state_of_charge') }} %"
|
||||||
|
secondary: State of Charge
|
||||||
|
entity: sensor.YOUR_BMS_state_of_charge
|
||||||
|
icon: >
|
||||||
|
{% set s = states('sensor.YOUR_BMS_state_of_charge') | int(0) %}
|
||||||
|
{% if s >= 90 %} mdi:battery
|
||||||
|
{% elif s >= 80 %} mdi:battery-90
|
||||||
|
{% elif s >= 70 %} mdi:battery-80
|
||||||
|
{% elif s >= 60 %} mdi:battery-70
|
||||||
|
{% elif s >= 50 %} mdi:battery-60
|
||||||
|
{% elif s >= 40 %} mdi:battery-50
|
||||||
|
{% elif s >= 30 %} mdi:battery-40
|
||||||
|
{% elif s >= 20 %} mdi:battery-30
|
||||||
|
{% elif s >= 10 %} mdi:battery-20
|
||||||
|
{% else %} mdi:battery-10 {% endif %}
|
||||||
|
icon_color: >
|
||||||
|
{% set s = states('sensor.YOUR_BMS_state_of_charge') | int(0) %}
|
||||||
|
{% if s >= 50 %} green
|
||||||
|
{% elif s >= 20 %} orange
|
||||||
|
{% else %} red {% endif %}
|
||||||
|
fill_container: true
|
||||||
|
tap_action:
|
||||||
|
action: more-info
|
||||||
|
|
||||||
|
# Pack voltage
|
||||||
|
- type: custom:mushroom-template-card
|
||||||
|
primary: "{{ states('sensor.YOUR_BMS_voltage') }} V"
|
||||||
|
secondary: Pack Voltage
|
||||||
|
entity: sensor.YOUR_BMS_voltage
|
||||||
|
icon: mdi:lightning-bolt-circle
|
||||||
|
icon_color: blue
|
||||||
|
fill_container: true
|
||||||
|
tap_action:
|
||||||
|
action: more-info
|
||||||
|
|
||||||
|
# Current — shows charge/discharge direction
|
||||||
|
- type: custom:mushroom-template-card
|
||||||
|
primary: >
|
||||||
|
{% set a = states('sensor.YOUR_BMS_current') | float(0) %}
|
||||||
|
{% if a > 0 %}+{% endif %}{{ a }} A
|
||||||
|
secondary: >
|
||||||
|
{% set a = states('sensor.YOUR_BMS_current') | float(0) %}
|
||||||
|
{% if a > 0.05 %} Charging
|
||||||
|
{% elif a < -0.05 %} Discharging
|
||||||
|
{% else %} Idle {% endif %}
|
||||||
|
entity: sensor.YOUR_BMS_current
|
||||||
|
icon: >
|
||||||
|
{% set a = states('sensor.YOUR_BMS_current') | float(0) %}
|
||||||
|
{% if a > 0.05 %} mdi:battery-charging-outline
|
||||||
|
{% elif a < -0.05 %} mdi:battery-minus-outline
|
||||||
|
{% else %} mdi:battery-check-outline {% endif %}
|
||||||
|
icon_color: >
|
||||||
|
{% set a = states('sensor.YOUR_BMS_current') | float(0) %}
|
||||||
|
{% if a > 0.05 %} green
|
||||||
|
{% elif a < -0.05 %} orange
|
||||||
|
{% else %} grey {% endif %}
|
||||||
|
fill_container: true
|
||||||
|
tap_action:
|
||||||
|
action: more-info
|
||||||
|
|
||||||
|
# ── Secondary metrics ──────────────────────────────────────────────────
|
||||||
|
- type: grid
|
||||||
|
columns: 4
|
||||||
|
square: false
|
||||||
|
cards:
|
||||||
|
- type: custom:mushroom-entity-card
|
||||||
|
entity: sensor.YOUR_BMS_power
|
||||||
|
icon: mdi:flash
|
||||||
|
name: Power
|
||||||
|
fill_container: true
|
||||||
|
- type: custom:mushroom-entity-card
|
||||||
|
entity: sensor.YOUR_BMS_energy_stored
|
||||||
|
icon: mdi:battery-charging-outline
|
||||||
|
name: Stored
|
||||||
|
fill_container: true
|
||||||
|
- type: custom:mushroom-entity-card
|
||||||
|
entity: sensor.YOUR_BMS_temperature_1
|
||||||
|
icon: mdi:thermometer
|
||||||
|
name: Temp
|
||||||
|
fill_container: true
|
||||||
|
- type: custom:mushroom-entity-card
|
||||||
|
entity: sensor.YOUR_BMS_cycle_count
|
||||||
|
icon: mdi:counter
|
||||||
|
name: Cycles
|
||||||
|
fill_container: true
|
||||||
|
|
||||||
|
# ── Cell voltages (bar chart) ──────────────────────────────────────────
|
||||||
|
# Colour zones for LiFePO4 — adjust min/max for your chemistry
|
||||||
|
- type: custom:bar-card
|
||||||
|
title: Cell Voltages
|
||||||
|
columns: 2
|
||||||
|
height: 30px
|
||||||
|
positions:
|
||||||
|
icon: outside
|
||||||
|
indicator: outside
|
||||||
|
name: outside
|
||||||
|
value: outside
|
||||||
|
min: 2.8
|
||||||
|
max: 3.7
|
||||||
|
severity:
|
||||||
|
- from: 0
|
||||||
|
to: 2.9
|
||||||
|
color: "#e74c3c" # critical low
|
||||||
|
- from: 2.9
|
||||||
|
to: 3.1
|
||||||
|
color: "#e67e22" # low
|
||||||
|
- from: 3.1
|
||||||
|
to: 3.5
|
||||||
|
color: "#2ecc71" # healthy
|
||||||
|
- from: 3.5
|
||||||
|
to: 3.65
|
||||||
|
color: "#f39c12" # near full
|
||||||
|
- from: 3.65
|
||||||
|
to: 10
|
||||||
|
color: "#e74c3c" # over-voltage
|
||||||
|
entities:
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_1
|
||||||
|
name: "① "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_2
|
||||||
|
name: "② "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_3
|
||||||
|
name: "③ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_4
|
||||||
|
name: "④ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_5
|
||||||
|
name: "⑤ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_6
|
||||||
|
name: "⑥ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_7
|
||||||
|
name: "⑦ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_8
|
||||||
|
name: "⑧ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_9
|
||||||
|
name: "⑨ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_10
|
||||||
|
name: "⑩ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_11
|
||||||
|
name: "⑪ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_12
|
||||||
|
name: "⑫ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_13
|
||||||
|
name: "⑬ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_14
|
||||||
|
name: "⑭ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_15
|
||||||
|
name: "⑮ "
|
||||||
|
- entity: sensor.YOUR_BMS_cell_voltage_16
|
||||||
|
name: "⑯ "
|
||||||
|
|
||||||
|
# ── Cell balance quality ───────────────────────────────────────────────
|
||||||
|
- type: custom:mushroom-template-card
|
||||||
|
primary: "{{ states('sensor.YOUR_BMS_cell_delta') }} mV spread"
|
||||||
|
secondary: >
|
||||||
|
{% set d = states('sensor.YOUR_BMS_cell_delta') | float(0) %}
|
||||||
|
{% if d < 10 %} Excellent balance
|
||||||
|
{% elif d < 30 %} Good balance
|
||||||
|
{% elif d < 60 %} Acceptable — balancer may activate
|
||||||
|
{% else %} Poor balance — inspect cells {% endif %}
|
||||||
|
entity: sensor.YOUR_BMS_cell_delta
|
||||||
|
icon: mdi:approximately-equal-box
|
||||||
|
icon_color: >
|
||||||
|
{% set d = states('sensor.YOUR_BMS_cell_delta') | float(0) %}
|
||||||
|
{% if d < 10 %} green
|
||||||
|
{% elif d < 30 %} light-green
|
||||||
|
{% elif d < 60 %} orange
|
||||||
|
{% else %} red {% endif %}
|
||||||
|
tap_action:
|
||||||
|
action: more-info
|
||||||
|
|
||||||
|
# ── Voltage + Current history ──────────────────────────────────────────
|
||||||
|
- type: custom:apexcharts-card
|
||||||
|
header:
|
||||||
|
show: true
|
||||||
|
title: Voltage & Current — last 6 h
|
||||||
|
show_states: true
|
||||||
|
colorize_states: true
|
||||||
|
graph_span: 6h
|
||||||
|
all_series_config:
|
||||||
|
stroke_width: 2
|
||||||
|
curve: smooth
|
||||||
|
extend_to: now
|
||||||
|
series:
|
||||||
|
- entity: sensor.YOUR_BMS_voltage
|
||||||
|
name: Voltage
|
||||||
|
color: "#3498db"
|
||||||
|
float_precision: 2
|
||||||
|
yaxis_id: volts
|
||||||
|
- entity: sensor.YOUR_BMS_current
|
||||||
|
name: Current
|
||||||
|
color: "#2ecc71"
|
||||||
|
float_precision: 2
|
||||||
|
yaxis_id: amps
|
||||||
|
yaxis:
|
||||||
|
- id: volts
|
||||||
|
decimals: 1
|
||||||
|
apex_config:
|
||||||
|
title:
|
||||||
|
text: V
|
||||||
|
- id: amps
|
||||||
|
opposite: true
|
||||||
|
decimals: 1
|
||||||
|
apex_config:
|
||||||
|
title:
|
||||||
|
text: A
|
||||||
|
|
||||||
|
# ── State of Charge history ────────────────────────────────────────────
|
||||||
|
- type: custom:apexcharts-card
|
||||||
|
header:
|
||||||
|
show: true
|
||||||
|
title: State of Charge — last 24 h
|
||||||
|
show_states: true
|
||||||
|
colorize_states: true
|
||||||
|
graph_span: 24h
|
||||||
|
series:
|
||||||
|
- entity: sensor.YOUR_BMS_state_of_charge
|
||||||
|
name: SoC
|
||||||
|
color: "#2ecc71"
|
||||||
|
type: area
|
||||||
|
opacity: 0.25
|
||||||
|
stroke_width: 2
|
||||||
|
curve: smooth
|
||||||
|
extend_to: now
|
||||||
|
fill_raw: last
|
||||||
|
yaxis:
|
||||||
|
- min: 0
|
||||||
|
max: 100
|
||||||
|
decimals: 0
|
||||||
|
apex_config:
|
||||||
|
title:
|
||||||
|
text: "%"
|
||||||
|
|
||||||
|
# ── Power history ──────────────────────────────────────────────────────
|
||||||
|
- type: custom:apexcharts-card
|
||||||
|
header:
|
||||||
|
show: true
|
||||||
|
title: Power — last 6 h
|
||||||
|
show_states: true
|
||||||
|
colorize_states: true
|
||||||
|
graph_span: 6h
|
||||||
|
series:
|
||||||
|
- entity: sensor.YOUR_BMS_power
|
||||||
|
name: Power
|
||||||
|
color: "#9b59b6"
|
||||||
|
type: area
|
||||||
|
opacity: 0.2
|
||||||
|
stroke_width: 2
|
||||||
|
curve: smooth
|
||||||
|
extend_to: now
|
||||||
|
fill_raw: last
|
||||||
|
yaxis:
|
||||||
|
- decimals: 0
|
||||||
|
apex_config:
|
||||||
|
title:
|
||||||
|
text: W
|
||||||
|
|
||||||
|
# ── Controls + Protection ──────────────────────────────────────────────
|
||||||
|
- type: grid
|
||||||
|
columns: 2
|
||||||
|
square: false
|
||||||
|
cards:
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Controls
|
||||||
|
entities:
|
||||||
|
- entity: select.YOUR_BMS_mos_control
|
||||||
|
name: MOS Gate
|
||||||
|
- entity: number.YOUR_BMS_nominal_capacity
|
||||||
|
name: Capacity Override
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Protection Status
|
||||||
|
entities:
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_cell_overvolt
|
||||||
|
name: Cell Over-Voltage
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_cell_undervolt
|
||||||
|
name: Cell Under-Voltage
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_pack_overvolt
|
||||||
|
name: Pack Over-Voltage
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_pack_undervolt
|
||||||
|
name: Pack Under-Voltage
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_charge_overtemp
|
||||||
|
name: Charge Over-Temp
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_discharge_overtemp
|
||||||
|
name: Discharge Over-Temp
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_charge_overcurrent
|
||||||
|
name: Charge Over-Current
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_discharge_overcurrent
|
||||||
|
name: Discharge Over-Current
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_short_circuit
|
||||||
|
name: Short Circuit
|
||||||
|
- entity: binary_sensor.YOUR_BMS_prot_software_lock
|
||||||
|
name: Software Lock
|
||||||
Reference in New Issue
Block a user