Easy Floorplan: визуальный редактор интерактивных планов прямо в Home Assistant
Вступление
Создание интерактивного плана дома (floorplan) в Home Assistant всегда считалось задачей, требующей терпения и времени. Традиционный подход обычно включает в себя работу в сторонних 3D-редакторах, экспорт изображений, ручной расчет координат и долгое написание сложного YAML-кода для карточки Picture Elements. Однако с появлением Easy Floorplan этот процесс выходит на совершенно новый уровень удобства. Данный компонент представляет собой продвинутую карточку Lovelace, которая позволяет рисовать стены, расставлять мебель и привязывать умные устройства прямо во встроенном визуальном drag-and-drop редакторе. Больше никаких сторонних программ — вся магия происходит прямо в браузере. Ниже представлен подробный разбор возможностей, процесса установки и базовой настройки этого мощного инструмента, который значительно упрощает визуализацию умного дома.
Easy Floorplan
Easy Floorplan — это карточка Lovelace для Home Assistant, предназначенная для создания интерактивного плана этажа с визуальным редактором drag-and-drop. Вы рисуете стены, размещаете двери и окна, добавляете мебель и подписи, а также привязываете сущности Home Assistant в виде иконок, «ряби» (ripple) или живого состояния. Всё масштабируется под размер карточки и экрана.
Возможности
- ✏️ Визуальный редактор — рисуйте стены, размещайте двери и окна с привязкой к стенам, перетаскивайте, перемещайте стрелками, выделяйте несколько элементов, копируйте/вставляйте, отменяйте/повторяйте, масштабируйте.
- Lock in place — закрепление элементов: заблокированный элемент можно выделить, отредактировать и удалить, но нельзя переместить, и он уступает клик незаблокированному элементу поверх него.
- Apply — сохраняет план на дашборд без закрытия редактора. Требуется Home Assistant 2025.3 или новее.
- 🎛️ Устройства — привязка любой сущности к иконке: тап для переключения или открытия more-info, живое состояние или метка атрибута, своя иконка, размер, поворот.
- Presence ripples — датчики присутствия и вибрации рисуются анимированными кольцами.
- Cast light — свет отдаёт собственный цвет и яркость на план; перекрывающиеся пятна смешиваются.
- Only up close — устройство может быть скрыто на общем плане и появляться только при зуме в комнату.
- Conditional text / icon / coloring — правила порогов и состояний перекрашивают элемент по показаниям сущности.
- 📊 Много показаний — одно устройство — сущности добавляются по одной, метка может располагаться снизу, слева или справа от значка.
- 🚪 Анимированные двери и окна — привязка контактного
binary_sensor,coverилиlock; створки открываются, сдвигаются или сворачиваются согласно реальному состоянию, включая частичные положения.- Top-hinged (awning) windows — верхнеподвесные окна.
- Skylights — мансардные окна, «дыра в потолке».
- A sensor per leaf — второй контакт для второй створки.
- 🎯 Цвета для on и off —
inactiveColorкак аналогactiveColorдля устройств и проёмов. - 📴 Offline-устройства — недоступные сущности затемняются или перечёркиваются.
- 🪑 Мебель — 28 серых линейных диаграмм, каждая привязывается к сущности, в поисковом выборе. Каждая — простой JSON-файл с числами.
- 🔤 Живые текстовые метки — привязка текста к сущности.
- 🏠 Области (Areas) — полигоны комнат, которые окрашиваются в реальном времени, с привязкой к областям Home Assistant.
- 📍 Трекеры позиции — один или два датчика расстояния (mmWave / радар) проецируются на маркер, движущийся по плану.
- 🧱 Мёртвые зоны — штриховка пространств, закрытых стенами, куда не ведёт ни одна дверь или окно.
- 🌗 Подстройка под солнце — затемнение плана в сумерках и осветление на рассвете по высоте солнца.
- 🛋️ Мебель с действиями — tap, hold и double-tap действия на любом элементе.
- 🧭 Переключатель этажей в любом месте — перетаскивание кнопок этажей.
- 🌇 Балконные ограждения — стена помечается как ограждение.
- 🏢 Несколько этажей — поэтажные элементы с переключателем.
- 🖼️ Фоновое изображение — трассировка по скану плана, с настраиваемой прозрачностью.
- 🏷️ Именованные цвета — задайте цвет один раз в разделе Project и ссылайтесь на него.
- 🎨 Скины —
default,odnetnin,pastel,tron. - 📐 Автомасштабирование — SVG поверх виртуального координатного пространства.
Установка
HACS (рекомендуется)
Распространяется как custom repository. Добавьте в один клик:
…или добавьте вручную:
- В Home Assistant откройте HACS.
- Справа сверху ⋮ → Custom repositories.
- Добавьте URL репозитория
https://github.com/nicosandller/easy-floorplanс категорией Dashboard (она же Plugin). - Найдите Easy Floorplan в HACS и нажмите Download.
- Жёстко обновите браузер (Cmd/Ctrl-Shift-R).
HACS добавляет ресурс дашборда автоматически.
Вручную
- Скачайте
easy-floorplan-card.jsиз последнего релиза. - Скопируйте его в
<config>/www/easy-floorplan-card.js. - Добавьте как ресурс дашборда (Settings → Dashboards → ⋮ → Resources → Add):
- URL
/local/easy-floorplan-card.js - Type JavaScript module
- URL
- Жёстко обновите браузер.
Быстрый старт
Минимальный пример конфигурации карточки:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
type: custom:easy-floorplan-card title: Living Room width: 1000 height: 600 grid: 20 background: "#fafafa" walls: - { id: w1, x1: 100, y1: 100, x2: 900, y2: 100 } - { id: w2, x1: 900, y1: 100, x2: 900, y2: 500 } - { id: w3, x1: 900, y1: 500, x2: 100, y2: 500 } - { id: w4, x1: 100, y1: 500, x2: 100, y2: 100 } openings: - { id: d1, type: door, x: 300, y: 500, length: 80, angle: 0, entity: binary_sensor.front_door, activeColor: "#ef5350" } - { id: win1, type: window, x: 600, y: 100, length: 140, angle: 0 } items: - { id: i1, entity: light.living_room, x: 240, y: 200, kind: light, glow: true } - { id: i2, entity: binary_sensor.presence, x: 380, y: 380, kind: binary_sensor, display: iconRipple, rippleColor: "#26c6da", rippleSize: 120 } - { id: i3, entity: sensor.living_room_temperature, secondaryEntity: sensor.living_room_humidity, x: 700, y: 380, kind: sensor, showState: true } furniture: - { id: f1, type: sofa, x: 250, y: 420, w: 170, h: 72, angle: 0 } texts: - { id: t1, x: 500, y: 60, text: Living Room, size: 22 } areas: - id: a1 name: Living Room haArea: living_room color: "#26c6da" opacity: 0.15 points: [{ x: 100, y: 100 }, { x: 900, y: 100 }, { x: 900, y: 500 }, { x: 100, y: 500 }] |
Конфигурация
Верхний уровень
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
type |
string | — | custom:easy-floorplan-card |
title |
string | — | Необязательный заголовок карточки. |
width |
number | 1000 |
Виртуальная ширина холста в единицах холста. |
height |
number | 600 |
Виртуальная высота холста. |
grid |
number | 20 |
Шаг сетки в единицах холста. |
snap |
number | следует за grid |
Шаг привязки, всегда абсолютный. |
rotation |
number | 0 |
Поворот карточки на 90, 180 или 270°. |
rotationPortrait |
number | как rotation |
Поворот при портретной ориентации экрана. |
rotationLandscape |
number | как rotation |
Поворот при ландшафтной ориентации. |
showDeadSpaces |
boolean | false |
Штриховать замкнутые стенами пространства. |
sunDimming |
boolean | false |
Затемнение в сумерках и осветление на рассвете. |
sunBrightnessMin |
number | 0.45 |
Яркость при полностью зашедшем солнце, 0–1. |
sunBrightnessMax |
number | 1 |
Яркость при полном дневном свете, 0–1. |
sunlight |
boolean | false |
Пропускать солнце через окна и открытые двери. |
north |
number | 0 |
Где на плане север, в градусах по часовой стрелке от верха холста. |
sunBearing |
number | живое солнце | Компасный азимут, где находится солнце. |
sunShade |
boolean | true |
Затемнять всё, куда свет не попадает. |
sunlightColor |
string | warm white | Цвет света, пропускаемого проёмами. |
sunShadeColor |
string | black | Цвет тени. |
ambientDaylight |
boolean | false |
Мягкий свет неба через внешние проёмы. Требует полигонов Area. |
sunReach |
number | 0.34 |
Как далеко свет несёт от проёма, доля от меньшей стороны плана. |
skylightDrop |
number | 0.55 |
Как далеко пятно света от мансардного окна скользит до пола. |
skin |
string | default |
default, odnetnin, pastel или tron. |
pressEffect |
string | scale |
scale, ripple, flash или none. |
offlineStyle |
string | dim |
dim, strike или none. |
compactHeader |
boolean | false |
Рисовать заголовок внутри плана. |
overlayScale |
string | fixed; plan в новых планах |
plan — единицы холста, fixed — пиксели экрана. |
overlayMinWidth |
number | — | Минимальная отображаемая ширина плана (px) для оверлея под plan. |
zoomedOverlayScale |
number | 1 |
Размер оверлея при зуме. |
background |
string | skin / card bg | Цвет фона холста. |
palette |
Palette[] | — | Именованные цвета для плана. |
floors |
Floor[] | — | Поэтажные группы элементов. |
defaultFloor |
string | первый этаж | Id этажа, показываемого первым. |
floorSwitcher |
{x, y} |
верхний правый угол | Где расположены кнопки этажей на плане. |
walls |
Wall[] | [] |
Сегменты стен. |
openings |
Opening[] | [] |
Двери, окна и мансардные окна. |
items |
Item[] | [] |
Устройства-сущности. |
texts |
Text[] | [] |
Свободные текстовые метки. |
furniture |
Furniture[] | [] |
Серые диаграммы мебели. |
trackers |
Tracker[] | [] |
Живые трекеры позиции. |
areas |
Area[] | [] |
Именованные полигоны комнат. |
symbols |
map | — | Символы мебели, определяемые планом. |
historyReplay |
object | отключено | Управление воспроизведением истории. |
Стена (Wall)
{ id, x1, y1, x2, y2, thickness?, kind?, locked? } — конечные точки в виртуальных единицах.
thickness— ширина штриха в виртуальных единицах, по умолчанию8, максимум10.kind—wall(по умолчанию, никогда не записывается) илиrailing— низкий край балкона, террасы или галереи.
Проём (Opening)
| Поле | Тип | Описание |
|---|---|---|
id |
string | Уникальный id. |
type |
door | window | skylight |
Вид проёма. |
width |
number | Только для мансардных окон: второй размер плана, поперёк length. |
ceilingHeight |
number (0.1–8) | Только для мансардных окон: высота потолка как множитель. |
motion |
swing | slide | roll | fixed | awning |
Как движется. |
sunlight |
boolean | false выводит проём из естественного света. |
glazed |
boolean | Пропускает свет даже закрытым. |
sashSpan |
number (0.05–1) | Доля проёма, которую занимает открывающаяся створка. |
sash |
single | double |
Сколько подвесных створок. |
shutterEntity |
string | Внешние ставни над тем же проёмом. |
shutterStyle |
swing | roll |
Жалюзийные панели или рулонная штора. |
shutterInvert |
boolean | Перевернуть чтение ставней. |
shutterSecondaryEntity |
string | Второй контакт для второй панели ставней. |
shutterActiveColor |
string | Цвет ставней при открытии. |
shutterFlipV |
boolean | Подвешивать панели на стороне створки. |
x, y |
number | Позиция центра. |
length |
number | Длина вдоль стены. |
angle |
number | Поворот в градусах. |
entity |
string | Контактный binary_sensor, cover или lock. |
secondaryEntity |
string | Второй контакт для второй створки. |
invert |
boolean | Перевернуть интерпретацию открыто/закрыто. |
activeColor |
string | Цвет створки/дуги при открытии. |
inactiveColor |
string | Цвет створки/дуги при закрытии. |
flipH |
boolean | Зеркалировать слева↔справа. |
flipV |
boolean | Зеркалировать через стену. |
showIcon |
boolean | Рисовать собственную иконку проёма. |
icon |
string | Переопределить иконку. |
showShutterIcon |
boolean | Рисовать иконку ставней. |
shutterIcon |
string | Переопределить иконку ставней. |
tapTarget |
opening | shutter |
На что действует тап. |
tap_action |
ActionConfig | Стандартное действие Lovelace. |
sliderStyle |
single | bypass | biparting | biparting-bypass | converging |
Для motion: slide. |
locked |
boolean | Закреплён в редакторе. |
Пример:
|
1 2 3 4 5 6 7 8 9 |
openings: # sliding window, patio-door style, driven by a cover - { id: patio, type: window, motion: slide, sliderStyle: biparting, x: 640, y: 500, length: 160, angle: 0, entity: cover.patio_door } # a two-panel patio slider with a contact on each leaf - { id: bay, type: window, motion: slide, sliderStyle: biparting-bypass, x: 300, y: 500, length: 200, angle: 0, entity: binary_sensor.sliding_door_left, secondaryEntity: binary_sensor.sliding_door_right } # a casement window with a contact on each sash - { id: study, type: window, x: 820, y: 100, length: 120, angle: 0, entity: binary_sensor.study_left, secondaryEntity: binary_sensor.study_right } # a swing door hinged on the right, opening into the other room - { id: hall, type: door, x: 300, y: 100, length: 80, angle: 0, flipH: true, flipV: true } |
Устройство (Item)
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
id |
string | — | Уникальный id. |
entity |
string | — | Привязываемая сущность. |
secondaryEntity |
string | — | Устаревшее написание первой строки readings. |
attribute |
string | — | Показывать этот атрибут вместо состояния. |
secondaryAttribute |
string | — | Устаревшее. |
stateColor |
rule[] | — | Правила цвета значка/метки. |
x, y |
number | — | Позиция. |
kind |
light/switch/sensor/… | inferred | Используется для иконки по умолчанию. |
icon |
string | entity icon | Переопределить иконку mdi. |
name |
string | friendly name | Переопределение метки/подсказки. |
size |
number | 34 |
Диаметр значка иконки (px). |
angle |
number | 0 |
Поворот иконки (град). |
display |
badge | ripple | iconRipple |
badge |
Как рисуется устройство. |
iconAnimation |
auto | none | spin | pulse |
auto |
Анимация иконки при активности. |
activeColor |
string | theme color | Цвет значка при включении. |
inactiveColor |
string | theme badge | Цвет значка при выключении. |
rippleColor |
string | activeColor |
Цвет кольца ряби. |
rippleSize |
number | 80 |
Максимальный диаметр ряби (px). |
rippleDirection |
number | 0 |
Направление дуги ряби в градусах. |
rippleWidth |
number | 360 |
Угловая ширина дуги ряби. |
glow |
boolean | false |
Отбрасывать пятно света (только свет). |
glowRadius |
number | 140 |
Радиус пятна при полной яркости. |
glowColor |
string | #ffd9a0 |
Цвет пятна для лампы без цвета. |
badgeContent |
icon | value | none |
icon |
Что содержит значок. |
badgeEntity |
primary | number |
автоматически | Какое показание показывает значок. |
showIcon |
boolean | true |
Устарело — используйте badgeContent. |
hideWhenInactive |
boolean | false |
Скрыть при неактивности. |
showOnlyWhenZoomed |
boolean | false |
Показывать только при зуме в комнату. |
area |
string | полигон, в котором находится | Комната, к которой относится устройство. |
showState |
boolean | только датчики | Показывать состояние сущности в строке метки. |
showName |
boolean | false |
Показывать имя устройства в строке метки. |
readings |
{ entity?, attribute?, showState? }[] |
— | Всё, что устройство читает помимо своего состояния. |
labelPosition |
below | left | right |
below |
Где расположена метка. |
labelSize |
number | 12 |
Размер шрифта строки метки (px). |
tap_action |
ActionConfig | по домену | Стандартное действие Lovelace. |
locked |
boolean | false |
Закреплён в редакторе. |
Область (Area)
{ id, points, name?, showName?, labelSize?, color?, opacity?, haArea?, filterEntities?, entity?, stateColor?, activeColor?, activeOpacity?, borderColor?, borderWidth?, highlight?, zoom?, tap_action?, hold_action?, double_tap_action?, locked? }
points— вершины{ x, y }в порядке рисования.name/showName— метка в центре полигона (showNameпо умолчаниюtrue).labelSize— размер метки,8–40, по умолчанию14.color/opacity— заливка комнаты; по умолчанию primary темы и0.25.haArea— id связанной области Home Assistant.sideWalls— переопределения рёбер прямоугольной комнаты:top,right,bottom,leftсо значениямиwall,dividerилиnone.filterEntities— с заданнымhaAreaсужает выбор сущностей.entity— делает комнату живой.stateColor— правила порогов/состояний.activeOpacity— прозрачность заливки при разрешении цвета.borderColor/borderWidth— статическая обводка.highlight— где красит живой цвет:fill(по умолчанию),borderилиboth.zoom— насколько близко приближает тап,1–10.
Трекер (Tracker)
|
1 2 3 |
{ id, x, y, w, h, angle?, color?, dotSize?, locked?, xSensor?: { entity, min, max, invert?, presence?: { entity, invert? } }, ySensor?: { entity, min, max, invert?, presence?: { entity, invert? } } } |
x,y,w,h— прямоугольник в единицах холста.xSensor/ySensor— каждый необязателен и независим.presence— бинарный гейт на ось.
Мебель (Furniture)
{ id, type, x, y, w, h, angle?, hand?, color?, entity?, activeColor?, stateColor?, goToFloor?, tap_action?, hold_action?, double_tap_action?, locked? }
type называет символ — один из ~26 поставляемых с карточкой (table, sofa, bed, fridge, stairs, …).
Свои символы
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
symbols: wardrobe7: name: wardrobe (7 doors) category: bedroom keywords: [closet, fitted] size: { w: 420, h: 55 } parts: - { rect: [0, 0, 100, 100], rx: 7.3 } - { repeat: 6, step: [14.29, 0], part: { line: [14.29, 0, 14.29, 100], role: line } } - { repeat: 7, step: [14.29, 0], part: { line: [11.4, 40, 11.4, 60], role: line } } furniture: - { id: w1, type: wardrobe7, x: 300, y: 90, w: 420, h: 55 } |
Текст (Text)
{ id, x, y, text, entity?, attribute?, size?, color?, angle?, locked? } — size в px (по умолчанию 16), color CSS/hex, angle в градусах.
|
1 2 3 4 5 6 7 |
texts: # The reading on its own. - { id: pv, x: 300, y: 80, text: "", entity: sensor.pv_output, size: 28 } # Words in front of it: "Grid 0.4 kW". - { id: grid, x: 300, y: 130, text: Grid, entity: sensor.grid_power } # An attribute rather than the state: "Hall 21.5". - { id: hall, x: 300, y: 180, text: Hall, entity: climate.hall, attribute: current_temperature } |
Этаж (Floor)
{ id, name, short?, color?, haFloor?, image?, imageFit?, imageOpacity?, walls, openings, items, texts, furniture, trackers, areas }
imageFit |
Что делает |
|---|---|
stretch (по умолчанию) |
Заполняет холст, искажая при несовпадении пропорций. |
contain |
Масштабирует по размеру, сохраняя пропорции. |
cover |
Заполняет холст, сохраняя пропорции, обрезая излишек. |
Именованные цвета
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
type: custom:easy-floorplan-card palette: - name: Warm color: "#ff8800" - name: Alert color: "#e53935" floors: - id: ground areas: - id: living color: var(--fp-color-warm) items: - id: thermostat entity: sensor.living_temperature stateColor: - above: 25 color: var(--fp-color-alert) - above: 0 color: var(--fp-color-warm) |
Воспроизведение истории (History replay)
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
enabled |
boolean | false |
Показывает кнопку Replay на карточке. |
lookbackSeconds |
number | 3600 |
Начальная длина окна воспроизведения в секундах. |
defaultSpeed |
number | auto | Скорость воспроизведения. |
debug |
boolean | false |
Логировать жизненный цикл воспроизведения. |
numericSteps |
number | не задано | Прореживать числовой дрейф датчика до этого числа уровней. |
Использование
Устройства
Устройство привязывает сущность Home Assistant к точке на плане. Добавьте его через + Add, затем выберите сущность в разделе Element под холстом.
- Tap to act — свет, выключатели, вентиляторы и
input_booleanпереключаются по тапу; всё остальное открывает диалог more-info. - Label line — Show state отображает живое значение; Show name добавляет имя, оба читаются как
Name · state. - Other entities — + Add entity добавляет дополнительные чтения.
- Badge shows — что рисует устройство: Icon — still, spinning или pulsing — его Value, или Nothing.
- Active color — цвет значка, пока сущность включена.
- Color & icon by state — правила перестилизуют значок, метку и иконку по показаниям сущности:
|
1 2 3 4 |
stateColor: - { state: open, color: "#4caf50", icon: mdi:blinds-open } - { above: 26, color: red } - { color: white } # default |
Двери, окна и мансардные окна
Перетащите door или window из панели инструментов — оно привяжется к ближайшей стене. Skylight — исключение: это дыра в потолке, поэтому он ни к чему не привязывается.
- Open / closed — открыто, когда сущность
on/open. - Partial —
cover, сообщающийcurrent_position(0–100), рисуется частично открытым. - Motion — swing (по умолчанию), slide, roll или fixed.
Стили скольжения:
| Стиль | Панели | Куда уходят | Что освобождается |
|---|---|---|---|
| single | одна движущаяся | в стену | весь проём |
| bypass | одна движущаяся, одна фиксированная | за фиксированную | половина |
| biparting (into the walls) | две движущиеся | каждая в свою стену | весь проём |
| biparting (over fixed panels) | две движущиеся, две фиксированные | на фиксированную панель у каждого косяка | средняя половина |
| converging | две движущиеся | навстречу, складываясь в центре | четверть у каждого косяка |
Области (Areas)
Выберите инструмент Area и либо протяните для создания готового прямоугольника, либо кликайте по углам для пользовательского полигона. Точки привязываются к ближайшим углам стен. После 3+ точек кликните по первой точке, чтобы замкнуть фигуру (Backspace удаляет последнюю точку, Escape отбрасывает контур).
Трекеры позиции
Выберите инструмент Tracker, протяните прямоугольник над отслеживаемой областью, затем настройте по осям:
- X sensor / Y sensor — сущность расстояния плюс
minиmax. - Invert — отображать большее показание на ближний край.
- Presence — необязательный бинарный гейт.
Рябь присутствия
Включите тумблер Ripple у устройства, и оно нарисует анимированные концентрические кольца позади значка. Установите Badge shows в Nothing для одних только колец.
Вентиляторы
Иконка работающего вентилятора вращается, активный медиаплеер или пылесос пульсирует.
Блокировка элементов
Выберите что угодно и нажмите замок в заголовке Element. Заблокированный элемент:
- всё ещё выделяется, редактируется и удаляется;
- никогда не перемещается — ни перетаскиванием, ни стрелками;
- уступает клик — любой незаблокированный элемент под указателем выбирается первым.
Цвета для on и off
|
1 2 3 4 5 6 7 8 9 10 11 12 |
items: - id: garage entity: cover.garage_door activeColor: "#2e7d32" # open — fine inactiveColor: "#c62828" # closed — look at me openings: - id: front type: door entity: binary_sensor.front_door activeColor: "#2e7d32" inactiveColor: "#c62828" |
Заключение
Можно с уверенностью сказать, что Easy Floorplan кардинально меняет подход к созданию дашбордов в Home Assistant. Благодаря встроенному визуальному редактору, нативной поддержке многоэтажности, детальной анимации дверей и окон, а также богатым возможностям кастомизации — от расчета теней до трекинга объектов в реальном времени — этот инструмент избавляет от необходимости использовать сложный сторонний софт. Независимо от того, создается ли базовая схема для быстрого управления светом или проработанный до мелочей интерактивный план со сложной логикой отображения состояний, данная карточка предоставляет весь необходимый арсенал функций прямо «из коробки». Это современное и функциональное решение определенно заслуживает того, чтобы занять центральное место в интерфейсе управления умным домом.
Читайте про Свой умный дом локально:
Сайт
Телеграм
Дзен
