Files
Jannis c00d9b66c2 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>
2026-04-11 20:49:26 +02:00

378 lines
15 KiB
YAML

# ─────────────────────────────────────────────────────────────────────────────
# 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