A Lovelace entity-row that displays multiple entities, attributes, and icons in a single row inside an entities card. Modernised on Lit 3 + TypeScript + Rollup with a HA-native visual editor, per-entity custom CSS, state-based icons, and icon coloring.
⚠️ Discontinued. As of July 2026,benct/lovelace-multiple-entity-rowis actively maintained again and has adopted my fixes, features, and visual editor originally built in this fork (see their 4.7.0 release notes, which credit this fork directly). Maintaining two projects with the same feature set doesn't make sense —5.2.5is the final release here. Please migrate:benct/lovelace-multiple-entity-row. Hopefully, this will also mean faster and more consistent maintenance in the future than has been the case so far — it's nice to see that it's active again.
This project was a modernised complete rewrite of the 2020-era benct/lovelace-multiple-entity-row, rebuilt to support the latest Home Assistant frontend stack (HA 2024.4+). All existing 4.x YAML configs continued to work unchanged, and a built-in visual editor (accessible from the HA card picker) meant most settings no longer required touching YAML at all.
For the full history of features, bug fixes, and improvements, see CHANGELOG.md.
- About this fork
- Requirements
- Installation
- Configuration
- Secondary Info
- Actions
- Formatting
- Hiding
- Icon styling
- Custom CSS
- Examples
- Home Assistant 2024.4 or higher (uses
hass.formatEntityStateandhass.performAction) - HACS (recommended) or manual install
- Open HACS in Home Assistant
- Go to Frontend → three-dot menu → Custom repositories
- Add this repository URL, category: Lovelace
- Search for Multiple Entity Row and install
- Reload the browser
- Download
multiple-entity-row.jsfrom the latest release and place it inconfig/www/. - Add to your Lovelace resources:
resources:
- url: /local/multiple-entity-row.js?v=1
type: moduleThis card produces an entity-row and must therefore be configured as an entity inside an entities card.
Minimal config:
type: entities
entities:
- entity: sensor.living_room_temperature
type: custom:multiple-entity-row
entities:
- sensor.living_room_humidity| Option | Type | Default | Description |
|---|---|---|---|
type |
string |
required | custom:multiple-entity-row |
entity |
string |
required | Main entity id (domain.my_entity_id) |
attribute |
string |
— | Show an attribute instead of the state value |
name |
string|bool |
friendly_name |
Override entity friendly name (or false to hide) |
unit |
string|bool |
unit_of_measurement |
Override entity unit (or false to hide) |
icon |
string |
entity icon | Override entity icon |
icon_color |
string |
— | CSS color for the icon — new in 5.2.0 |
state_icon |
object |
— | Map of state → icon ({ on: mdi:..., off: mdi:... }) — new in 5.2.0 |
image |
string |
— | Show an image instead of icon |
toggle |
bool |
false |
Display a toggle (if supported) instead of state |
show_state |
bool |
true |
Set to false to hide the main entity |
show_state_first |
bool |
false |
Render the main state before the entities instead of after — new in 5.2.5 |
state_header |
string |
— | Header text above the main entity state |
state_color |
bool |
false |
Colored icon when the entity is active |
column |
bool |
false |
Show entities in a column instead of a row |
styles |
object |
— | Inline CSS styles applied to the state element |
format |
string |
Formatting | Format main state / attribute value |
entities |
list |
Entity Objects | Additional entity ids or entity objects |
secondary_info |
string|object |
Secondary Info | Custom secondary_info content |
tap_action |
object |
more-info |
Custom tap action on the entity row |
hold_action |
object |
none |
Custom hold action on the entity row |
double_tap_action |
object |
none |
Custom double-tap action on the entity row |
Each item in entities[] can be either an entity id string or an entity object. If you use an object, at least one of entity, attribute, or icon is required.
| Option | Type | Default | Description |
|---|---|---|---|
entity |
string |
— | Entity id (skip to use the main entity) |
attribute |
string |
— | Attribute key for the entity |
name |
string|bool |
friendly_name |
Override entity name (or false to hide) |
unit |
string|bool |
unit_of_measurement |
Override entity unit (or false to hide) |
toggle |
bool |
false |
Display a toggle if supported by the entity domain |
icon |
string|bool |
false |
Default or custom icon instead of state / attribute value |
icon_color |
string |
— | CSS color for the icon (any CSS color value) — new in 5.2.0 |
state_icon |
object |
— | Map of state → icon (e.g. { on: mdi:..., off: mdi:... }) — new in 5.2.0 |
state_color |
bool |
false |
Colored icon when the entity is active |
default |
string |
— | Value shown if the entity does not exist or is hidden |
hide_unavailable |
bool |
false |
Hide the entity if unavailable |
hide_if |
object|any |
Hiding | Hide the entity if value matches specified criteria |
styles |
object |
— | Inline CSS styles applied to this entity |
format |
string |
Formatting | Format entity value |
tap_action |
object |
Actions | Custom entity tap action |
hold_action |
object |
Actions | Custom entity hold action — editor support new in 5.2.4 |
double_tap_action |
object |
Actions | Custom entity double-tap action — editor support new in 5.2.4 |
attribute value |
Renders |
|---|---|
last-changed |
Relative time since the entity last changed state |
last-updated |
Relative time since the entity was last updated |
secondary_info can be:
- A plain string (
"Last updated 14:32") — rendered as-is below the entity name - A HA standard token — one of
entity-id,last-changed,last-updated,last-triggered,position,tilt-position,brightness— HA renders it viahui-generic-entity-row's native secondary-info handling - An object with the same fields as an entity object — custom value, formatter, hide rules, etc.
| Option | Type | Default | Description |
|---|---|---|---|
entity |
string |
— | Entity id (skip to use the main entity) |
attribute |
string |
— | Attribute key for the entity |
name |
string|bool |
friendly_name |
Override entity name (or false to hide) |
unit |
string|bool |
unit_of_measurement |
Override entity unit (or false to hide) |
hide_unavailable |
bool |
false |
Hide if unavailable / not found |
hide_if |
object|any |
Hiding | Hide if value matches specified criteria |
format |
string |
Formatting | Format the value |
This card supports all standard HA actions (tap_action, hold_action, double_tap_action) on the main row and on every additional entity. See Lovelace Actions for the full reference.
| Option | Type | Default | Description |
|---|---|---|---|
action |
string |
required | more-info, toggle, perform-action (formerly call-service), url, navigate, assist, fire-dom-event, none |
entity |
string |
— | Override entity id when action is more-info |
service |
string |
— | Service to call when action is call-service |
service_data |
object |
— | Optional data when action is call-service |
url_path |
string |
— | URL when action is url |
navigation_path |
string |
— | Path when action is navigate |
confirmation |
bool|object |
false |
Show a confirmation dialog |
haptic |
string |
none |
Haptic feedback (success, warning, failure, light, medium, heavy, selection) |
The format option supports:
| Value | Type | Description |
|---|---|---|
relative |
timestamp |
Convert to relative time (5 minutes ago) |
total |
timestamp |
Convert to relative duration (5 minutes) |
date |
timestamp |
Convert timestamp to date |
time |
timestamp |
Convert timestamp to time |
datetime |
timestamp |
Convert timestamp to date and time |
brightness |
number |
Convert brightness value to percentage (0–255 → 0–100) |
percent |
number |
Multiply by 100 and append % (0.85 → 85 %) — new in 5.2.0 |
duration |
number |
Convert seconds to duration (5:38:50) |
duration-m |
number |
Convert milliseconds to duration |
duration-h |
number |
Convert hours to duration |
invert |
number |
Convert number from positive to negative or vice versa |
kilo / kilo0–kilo9 |
number |
Divide by 1,000 (1500 → 1.5) — new in 5.2.3: optional precision digit |
mega / mega0–mega9 |
number |
Divide by 1,000,000 (2500000 → 2.5) — new in 5.2.3 |
milli / milli0–milli9 |
number |
Multiply by 1,000 (0.2 → 200) — new in 5.2.3 |
position |
number |
Reverse a position percentage (70% open → 30% closed) |
precision0–precision9 |
number |
Decimal precision (precision3 → 18.123) |
celsius_to_fahrenheit |
number |
Convert °C to °F |
fahrenheit_to_celsius |
number |
Convert °F to °C |
upper |
string |
Convert text to UPPERCASE — new in 5.2.0 |
lower |
string |
Convert text to lowercase — new in 5.2.0 |
capitalize |
string |
Capitalize the first character — new in 5.2.0 |
title |
string |
Capitalize Each Word ("Title Case") — new in 5.2.0 |
kilo/mega/milli/invert/position only scale or transform the number — they do not change the displayed unit. If you want the unit label to match (e.g. W → kW), set unit: explicitly alongside the format.
Combining formats (new in 5.2.5) — the number-transforming formats above (brightness, percent, invert, position, kilo/mega/milli, precision<0-9>, the temperature conversions) can be combined comma-separated. The value flows through each in order and is locale-formatted once at the end:
format: invert, precision3 # -18.123
format: kilo, precision1 # 1500 -> 1.5
format: invert, kilo3 # 1500 -> -1.500An explicit precision<N> (or a kiloN/megaN/milliN digit suffix) wins wherever it appears in the chain; otherwise the last segment's own default applies. Durations, timestamps, and the string transforms (upper/lower/…) cannot be combined — mixing one into a comma list falls back to plain single-format handling. In the visual editor, type the combined format directly into the Format dropdown (it accepts free text, not just the listed options).
The hide_if option hides the entity if its state / attribute matches the specified criteria. Three forms:
hide_if: 0 # exact value
hide_if: [0, 'off'] # multiple values
hide_if:
above: 100 # range
below: -10
value: ['offline'] # plus exact matches| Option | Type | Description |
|---|---|---|
above |
number |
Hide if numeric value is above the specified value |
below |
number |
Hide if numeric value is below the specified value |
value |
list|any |
Hide if value matches the specified value or any in a list |
entity |
string |
Compare against another entity's state instead of the host entity (new in 5.2.0) |
attribute |
string |
When combined with entity, compare against that entity's attribute |
Compare against another entity — useful when one entity's visibility depends on a separate switch / sensor (e.g. only show the alarm exit-state when the alarm is armed):
- entity: sensor.dsc_exit_state
hide_if:
entity: switch.dsc_armed_away
value: 'off' # hide exit-state when the switch is OFFBehaviour change in 5.2.0: top-level
hide_ifandhide_unavailablenow also apply to the main row state slot — symmetrical to per-entity behaviour. In 4.x they were silently ignored at the top level.
Each entity (main + additional) supports three ways to control its icon:
icon— pick a static MDI icon (mdi:thermometer) or set totrueto use the entity's own attribute iconicon_color(new in 5.2.0) — any CSS color value applied as a CSS variable to the state-badge:red,#ff4500,rgb(255, 100, 0),var(--my-theme-color)state_icon(new in 5.2.0) — map of state → icon path. Takes precedence overiconwhen the current state matches
- type: custom:multiple-entity-row
entity: cover.living_room_shutter
icon_color: 'var(--accent-color)'
state_icon:
open: mdi:window-shutter-open
closed: mdi:window-shutter
opening: mdi:window-shutter-alert
entities:
- entity: binary_sensor.door
icon_color: '#22c55e' # green when displayed via icon: true
icon: true
- entity: light.bedroom
state_icon:
on: mdi:lightbulb
off: mdi:lightbulb-offIn the visual editor, icon_color is a text field directly below the icon picker. state_icon is a row-based editor: each row has a State text field plus an Icon picker, with an "Add state" button below — no YAML needed.
state_icon vs templating: This is an explicit state-to-icon map, not a Jinja template. For full template expression support (e.g.
{% if states('sensor.foo') > 100 %}), use card-mod or wait for a future templating phase.
The styles option attaches inline CSS to the rendered entity element. Available on the main row, on each entry in entities[], and on the secondary_info object form.
- entity: sensor.bedroom_temperature
type: custom:multiple-entity-row
name: Styles
styles:
width: 80px
text-align: right
secondary_info:
attribute: battery_level
styles:
font-weight: bold
entities:
- entity: sensor.bedroom_max_temp
styles:
width: 80px
text-align: leftNote: This is the existing per-entity
stylesfield. A card-mod-like mother-CSS injection is not planned for this card — keep custom styling scoped to the entities you need to adjust.
Using card_mod? Multiple-entity-row has no
<ha-card>of its own — entity-rows live inside the parententities-card. Don't useha-card { ... }selectors; target our shadow-DOM classes directly. The relevant ones:
.entity— every entity div (additional + main).state.entity— only the main state slot.entity span— the small label above values.entity div— the value below labels.entities-row/.entities-column— the layout containerFor shadow-pierced sub-styling (e.g. into
<ha-entity-toggle>'s inner<ha-switch>), card_mod's nested-selector +$:syntax works directly on the row config:type: custom:multiple-entity-row entity: input_boolean.heating entities: - entity: switch.heating_override toggle: true card_mod: style: hui-generic-entity-row .entities-row div.entity: ha-entity-toggle: $: | ha-switch { padding-top: 5px !important; }
- entity: sensor.bedroom_temperature
type: custom:multiple-entity-row
name: One entity
secondary_info: last-changed
entities:
- sensor.bedroom_max_temp- entity: sensor.bedroom_temperature
type: custom:multiple-entity-row
name: Three entities
secondary_info: last-changed
entities:
- entity: sensor.bedroom_humidity
name: humidity
- sensor.bedroom_min_temp
- sensor.bedroom_max_temp- entity: sensor.bedroom_temperature
type: custom:multiple-entity-row
name: Custom secondary_info
secondary_info:
attribute: battery_level
name: Battery
unit: '%'- entity: vacuum.xiaomi_vacuum_cleaner
type: custom:multiple-entity-row
name: Attributes
entities:
- attribute: battery_level
name: Battery
unit: '%'
- attribute: status
name: Status- entity: sensor.bedroom_temperature
type: custom:multiple-entity-row
name: Hide labels
entities:
- entity: sensor.bedroom_min_temp
name: false
- entity: sensor.bedroom_max_temp
name: false- entity: switch.livingroom_tv
type: custom:multiple-entity-row
name: Toggle
toggle: true
state_color: true
entities:
- entity: sensor.livingroom_tv_power
name: Power
- entity: sensor.livingroom_tv_power_total
name: Total- entity: light.living_room
type: custom:multiple-entity-row
name: Icons with tap_action
secondary_info: last-changed
entities:
- entity: light.living_room
icon: mdi:palette
- icon: mdi:lightbulb-off-outline
state_color: true
tap_action:
action: call-service
service: light.turn_off
service_data:
entity_id: light.living_room
- icon: mdi:lightbulb-outline
state_color: true
tap_action:
action: call-service
service: light.turn_on
service_data:
entity_id: light.living_room
confirmation:
text: 'Are you sure?'- entity: sensor.power_meter
type: custom:multiple-entity-row
name: Power
entities:
- entity: sensor.power_today
name: Today
format: kilo
hide_if: 0
- entity: sensor.power_total
name: Total
format: precision1Originally created by @benct — see benct/lovelace-multiple-entity-row.
