Ограничение карточки number в Mushroom для Home Assistant: разбор issue и патч
В карточке Mushroom Number для Home Assistant на Lovelace UI drag-управление работает неочевидно и ограничивает пользовательский опыт. В статье разобрана причина такого поведения и предложен патч (issue #1832), улучшающий взаимодействие с карточкой.
В Telegram-канале @iot7m_ru публикуются практические заметки по Home Assistant: опыт эксплуатации устройств, интеграция с различным оборудованием, создание дашбордов и разбор типовых проблем. Многие материалы основаны на реальных запросах и консультациях. Подпишитесь на @iot7m_ru, если используете Home Assistant на практике.
Проблема
В карточке Mushroom Number Card наблюдается некорректное поведение при перемещении ползунка, когда связанная сущность обновляется извне с высокой частотой. Проблема зафиксирована на версии Mushroom v5.0.8 и особенно заметна в реальных проектах умного дома, где значения могут обновляться десятки раз в секунду — например, при интеграции с системами учёта электроэнергии или промышленными контроллерами вроде Wiren Board. В небольших инсталляциях это может быть почти незаметно, но в крупных системах проблема сразу бросается в глаза: при взаимодействии пользователя значение number сбрасывается на текущее состояние, приходящее от Home Assistant, что делает настройку неудобной.
Воспроизведение проблемы
Для демонстрации проблемы используется простой сценарий: создаются две number-сущности input_number. Первая обновляется автоматически из автоматизации с периодичностью примерно раз в секунду. Вторая используется для ручного управления через интерфейс и не обновляется автоматически. Все сущности выводятся на один дашборд для наглядного сравнения поведения карточек. В результате на экране присутствуют четыре карточки: две для сущностей, которые обновляются автоматически, и две для сущностей без автоматического обновления. В каждой группе используется одна стандартная карточка number и одна карточка Mushroom Number Card. При попытке перемещать ползунок становится заметно различие в поведении карточек. В группе карточек, где происходит автоматическое обновление значения, в стандартной карточке number значение ползунка отображается во всплывающем тултипе и отражает текущее положение слайдера во время движения. В Mushroom Number Card значение также визуально меняется на карточке, однако при каждом обновлении состояния от Home Assistant оно перезаписывается значением, приходящим из Home Assistant, даже если пользователь ещё удерживает ползунок и не завершил перемещение.

Причина поведения
Причина заключается в том, как Mushroom Number Card обрабатывает входящие обновления состояния. Со стороны Home Assistant регулярно приходят события обновления состояния сущности number. Mushroom Number Card применяет эти обновления сразу же, даже в тот момент, когда пользователь уже начал перемещать ползунок, но ещё не отпустил его. В результате любое внешнее обновление немедленно перезаписывает ввод пользователя, даже в процессе активного взаимодействия.
Предложенное решение
Решение заключается в отслеживании начала и окончания движения ползунка и игнорировании обновлений состояния от Home Assistant в этот промежуток времени. Пока пользователь перемещает ползунок, входящие обновления игнорируются, а синхронизация с состоянием происходит после завершения действия. Такой подход соответствует поведению стандартной number-карточки Home Assistant и заметно улучшает пользовательский опыт.
Для этого в карточку добавляется отслеживание начала и окончания перемещения ползунка (pointer events). Пока пользователь удерживает ползунок, внешние обновления значения игнорируются. После завершения взаимодействия синхронизация со state сущности восстанавливается.
diff --git a/src/cards/number-card/number-card.ts b/src/cards/number-card/number-card.ts
index f223f7a69..15762e2b6 100644
--- a/src/cards/number-card/number-card.ts
+++ b/src/cards/number-card/number-card.ts
@@ -79,10 +79,20 @@ export class NumberCard
@state() private value?: number;
+ @state() private isDragging = false;
+
+ private _onPointerDown = () => {
+ this.isDragging = true;
+ };
+
+ private _onPointerUp = () => {
+ this.isDragging = false;
+ };
+
updateValue() {
+ if (this.isDragging) return;
this.value = undefined;
}
@@ -158,7 +170,10 @@ export class NumberCard
- <div class="actions" ?rtl=${rtl}>
+ <div class="actions" ?rtl=${rtl}
+ @pointerdown=${this._onPointerDown}
+ @pointerup=${this._onPointerUp}
+ @pointercancel=${this._onPointerUp}>
Согласно правилам проекта Mushroom pull request не принимаются до тех пор, пока проблема официально не признана ошибкой. Поэтому на данный момент исправление оформлено в виде локального патча и обсуждается в рамках issue.
Итог
Предложенное решение приводит поведение Mushroom Number Card в соответствие со стандартной number-карточкой Home Assistant: значение ползунка больше не перезаписывается во время активного взаимодействия пользователя, а синхронизация с состоянием происходит корректно после завершения движения.
Обзорная статья Home Assistant dashboard: как собрать удобный интерфейс дашборда из карточек содержит описание структуры интерфейса Home Assistant и базовых принципов работы с карточками.
Полезные ссылки
- Документация Mushroom Number Card — официальное описание карточки
- Issue #1832 — обсуждение проблемы в официальном репозитории lovelace-mushroom
Приложение
Конфигурация input_number
input_number:
comfort:
name: "Comfort"
icon: mdi:heating-coil
min: 5
max: 45
step: 1
initial: 22
unit_of_measurement: "°C"
mode: slider
eco:
name: "Eco"
icon: mdi:heating-coil
min: 5
max: 45
step: 1
initial: 22
unit_of_measurement: "°C"
mode: slider
Автоматизация с обновлением значения каждую секунду
- id: setup_random_comfort_every_second
alias: "Setup random value for comfort input number every second"
trigger:
- platform: time_pattern
seconds: "/1"
action:
- service: input_number.set_value
target:
entity_id: input_number.comfort
data:
value: >
{{ range(5, 46) | random }}%
Пример дашборда для воспроизведения проблемы
title: Number
icon: mdi:numeric
cards:
- type: entities
entities:
- entity: input_number.comfort
name: Comfort(update by timer)
- entity: input_number.eco
name: Eco
- type: custom:mushroom-number-card
entity: input_number.comfort
name: Comfort(update by timer)
- type: custom:mushroom-number-card
entity: input_number.eco
name: Eco