Files
obsidian-vault/family/tech/kitchen-hood-fan-template.md
T

24 KiB
Raw Blame History

title, aliases, created, updated, note, type, namespace, status, tags, related
title aliases created updated note type namespace status tags related
🍳 Вытяжка кухни — смена домена light → fan (`fan.kitchen_hood`, 3 скорости)
kitchen hood
kitchen_hood
вытяжка домен
вытяжка категория свет
TS0003 fan
hood light to fan
fan.kitchen_hood
kitchen-hood-domain-conversion
kitchen-hood-fan-template
2026-09-16 2026-09-16 ЗАКРЫТО полностью: fan.kitchen_hood создан, зона назначена, свет и диагностика скрыты, ссылка в карте этажей home_plan переведена с мёртвого fan.fan_3 на fan.kitchen_hood tech family 🟢 РАБОТАЕТ. fan.kitchen_hood (3 скорости, speed_count: 3) поверх light.kitchen_hood_light[,_2,_3]. Три света + 13 сущностей диагностики скрыты. План этажей починен. Проверено фактом 2026-09-16. ⚠️ Порядок скоростей ждёт физической проверки — §10.
family
tech
smarthome
home-assistant
t610
haos
zigbee
zha
template
family/how-to/home-automation
family/how-to/ha-automations
family/tech/zigbee-t610-z2m-i-zha
family/tech/ha-registry-operations
family/documents/home-automation-wishlist

🍳 Вытяжка кухни — смена домена (light → fan)

Задача Alex (2026-09-16): «можно всё-таки кухонную вытяжку перевести из категории свет в другую?» → ответ: прямого способа нет; сделан fan.kitchen_hood Template-хелпером поверх трёх реле, свет спрятан.

Единственная дока по вытяжке. Раньше было две (kitchen-hood-domain-conversion — исследование, kitchen-hood-fan-template — реализация) — сведены сюда 2026-09-16. Оба имени оставлены в aliases.


1. Ответ на исходный вопрос: «никак нельзя»

Прямого способа сменить домен light.switch./fan. у существующей сущности в HA НЕТ. Проверено по всем четырём путям:

Путь Результат
UI «Показать как» (device_class) Домена не меняет. Для light вообще не применимо
Реестр сущностей (config/entity_registry/update + new_entity_id) Домен менять нельзя, только имя внутри домена. ⚠️ Питфолл 4 в family/tech/zigbee-t610-z2m-i-zha: «Переименование light.switch. запрещено HA»
switch_as_x (офиц. хелпер «Change device type of a switch») Источник — только switch. Конвертирует в Light/Cover/Fan/Lock/Siren/Valve, но light на вход НЕ принимает. Для ZHA-вытяжки бесполезен
Кастомный quirk в zhaquirks ⚠️ Технически возможно (подменить Light-cluster на Switch), но ломается при каждом обновлении HA + переименование сущностей рвёт все ссылки. Отвергнуто
homeassistant: customize: Меняет только атрибуты (device_class/icon), не домен. light. останется light.

📄 switch_as_xhttps://www.home-assistant.io/integrations/switch_as_x/ Ключевая цитата доки: «lets you convert any Home Assistant switch into a Home Assistant Light, Cover, Fan, Lock, Siren, or Valve».

Работает только обход: Template-хелпер создаёт новую сущность рядом, оригинальные прячутся.

⚠️ Почему Template работает там, где switch_as_x пасует: у Template-сущности блок action: может звать любой сервис (light.turn_on), тогда как switch_as_x жёстко ограничен источником-switch. Это и есть обход ограничения домена.

Варианты, которые рассматривались

# Что Итог
A Template fan поверх одного light_2 промежуточный; отвергнут — не даёт 3 скоростей
B Template switch (без percentage) если скорость не нужна, нужен просто «не свет»
C Три fan/switch + автоматизация взаимоблокировки / input_select не понадобилсяset_percentage с choose дал то же самое в одной сущности

2. Железо и что отдаёт ZHA

Устройство: kitchen_hood · IEEE a4:c1:38:07:b6:4c:7f:d4 · _TZ3000_odzoiovu · TS0003 (3-gang реле) · Router · зона kitchen · device_id 200ea4fb25daaa907279045e47a330b5

ZHA отдаёт реле как light, не switch:

Сущность Роль Состояние до работ
light.kitchen_hood_light скорость 1 (33 %) on
light.kitchen_hood_light_2 скорость 2 (66 %) off
light.kitchen_hood_light_3 скорость 3 (100 %) off

Все три: supported_color_modes: ["onoff"], supported_features: 8, платформа zha.

🔑 supported_features: 8 + supported_color_modes: ["onoff"] = чистое реле без яркости. Именно поэтому HA-логика «это лампа» здесь ложная, а переклассификация в fan осмысленна.

🔑 Ключевое для понимания: TS0003 — это три независимых реле, а «3 скорости вытяжки» на железе = три провода, из которых активен ровно один. Поэтому HA изначально показала их как три света, а не как одну вентиляционную сущность. Один fan с процентами склеивает их логически.

Прочие сущности того же устройства (позже скрыты, см. §8): select.kitchen_hood_indicator_mode (LightWhenOn), select.kitchen_hood_power_outage_memory (Off), sensor.kitchen_hood_power / _voltage / _current / _energy (все 0.0), button.kitchen_hood_identify, update.kitchen_hood_firmware, sensor.kitchen_hood_lqi / _rssi.

🔴 sensor.kitchen_hood_lqi / _rssi → HTTP 404 через /api/states. Это норма: disabled_by: integration — сущности в реестре есть, в runtime их нет. Не считать поломкой.


3. Что сделано — шаг 1: Template-фан

3.1. Бэкап

/config/configuration.yaml.bak-fanhood-20260916-081926   (30108 байт)

3.2. Новый блок template: в /config/configuration.yaml

Добавлен 16-м блоком template: (после fan_3), перед - cover:. speed_count: 3 → шаг 33 % в UI.

  - fan:
    - name: Kitchen hood
      unique_id: kitchen_hood_fan
      default_entity_id: fan.kitchen_hood
      speed_count: 3
      state: >
        {{ is_state('light.kitchen_hood_light','on')
           or is_state('light.kitchen_hood_light_2','on')
           or is_state('light.kitchen_hood_light_3','on') }}
      percentage: >
        {% if is_state('light.kitchen_hood_light_3','on') %}100
        {% elif is_state('light.kitchen_hood_light_2','on') %}66
        {% elif is_state('light.kitchen_hood_light','on') %}33
        {% else %}0
        {% endif %}
      turn_on:
        - action: light.turn_on
          target:
            entity_id: light.kitchen_hood_light
      turn_off:
        - action: light.turn_off
          target:
            entity_id:
              - light.kitchen_hood_light
              - light.kitchen_hood_light_2
              - light.kitchen_hood_light_3
      set_percentage:
        - action: light.turn_off
          target:
            entity_id:
              - light.kitchen_hood_light
              - light.kitchen_hood_light_2
              - light.kitchen_hood_light_3
        - choose:
            - conditions:
                - condition: template
                  value_template: "{{ percentage | int(0) > 0 and percentage | int(0) <= 33 }}"
              sequence:
                - action: light.turn_on
                  target:
                    entity_id: light.kitchen_hood_light
            - conditions:
                - condition: template
                  value_template: "{{ percentage | int(0) > 33 and percentage | int(0) <= 66 }}"
              sequence:
                - action: light.turn_on
                  target:
                    entity_id: light.kitchen_hood_light_2
            - conditions:
                - condition: template
                  value_template: "{{ percentage | int(0) > 66 and percentage | int(0) <= 100 }}"
              sequence:
                - action: light.turn_on
                  target:
                    entity_id: light.kitchen_hood_light_3

Логика: set_percentage сначала гасит все три реле, затем зажигает одно нужное → взаимоисключение гарантировано, состояние «две скорости одновременно» невозможно by design.

🔴 ИСПРАВЛЕНО 2026-09-16 (было ошибочно в первой версии доки): ранняя версия утверждала, что «Template-fan с percentage не даст настоящую скорость — он включит одно реле». Факт опроверг: один Template-fan с set_percentage + choose даёт полноценные 3 скорости — 33/66/100 % выбирают нужное реле, percentage читается обратно из состояния. Взаимоблокировку обеспечивает set_percentage, отдельная автоматизация и input_select не нужны. Проверено живым прогоном — §4.

Порядок применения: правка YAML → локальный парс → scp на t610 → check_confighomeassistant.restart (не reload!) → RUNNING.

3.3. Скрытие света

Три сущности скрыты через WS config/entity_registry/update с hidden_by: "user". Скрипт: ~/tmp-t610/hood_hide.py (возврат — тот же скрипт с --unhide).


4. Проверка на живом железе

Шаг fan.kitchen_hood light_1 light_2 light_3
baseline off / 0 off off off
set_percentage 33 on / 33 on off off
set_percentage 66 on / 66 off on off
set_percentage 100 on / 100 off off on
turn_off off / 0 off off off

fan.kitchen_hood: supported_features: 49 = TURN_ON | TURN_OFF | SET_SPEED

speed_count не отдаётся как атрибут состояния — HA его не публикует. Шаги ползунка считаются из percentage_step. Это норма, не дефект.


5. 🔴 Шаг 2: доводка UI — «вижу показатели kitchen hood и нет нового вентилятора»

Симптом Alex: «Я в кухне до сих пор вижу показатели kitchen hood и нет нового вентилятора».

Две причины, обе найдены фактом:

# Причина Факт
1 fan.kitchen_hood создан без зоны — Template-сущность из YAML не привязана к устройству → area_id: null, на кухне не видна WS-реестр: area=null. У fan.fan_3 зона kitchen была → он и торчал на кухне вместо нового
2 Диагностика устройства не скрыта — «показатели kitchen hood» = 4 сенсора + 2 select + update + button, все hidden_by=None Найдено сканом config/entity_registry/list

Фикс — скрипт ~/tmp-t610/hood_cleanup.py (обратимо флагом --unhide):

  1. fan.kitchen_hoodarea_id: kitchen
  2. Скрыто hidden_by: user13 сущностей:
    • fan.fan_3 (мёртвый template-фан «Вытяжка Кухня»)
    • switch.fan_3_low / _medium / _high + script.set_fan_3_speed — подтверждены unavailable (slave 10 / AT2 офлайн)
    • sensor.kitchen_hood_energy / _power / _voltage / _current
    • select.kitchen_hood_indicator_mode / _power_outage_memory
    • update.kitchen_hood_firmware
    • button.kitchen_hood_identify

Проверено чтением обратно: все 13 → hidden_by=user; fan.kitchen_hoodarea=kitchen, hidden_by=None.


6. 🔴 Шаг 3: настоящая причина «он не открыт» — карта этажей

Симптом Alex: «Нихуя он не открыт!» — на кухне в UI по-прежнему старая вытяжка, новый fan.kitchen_hood отсутствует.

Причина — дашборд home_plan ссылался руками на мёртвую сущность.

Дашборд home_plan (storage-mode, /config/.storage/lovelace.home_plan) содержит picture-elements с иконкой:

{ "type": "state-icon", "entity": "fan.fan_3", "tap_action": {"action": "more-info"},
  "style": {"top": "18.0%", "left": "86.3%"} }

fan.fan_3 = мёртвый template-фан (источник switch.fan_3_* закомментирован, slave 10 офлайн). Иконка на кухне вела на него.

Диагностика — как найти мёртвую ссылку:

# все entity, на которые ссылается план
jq -r '.. | objects | select(.entity? != null) | .entity' /config/.storage/lovelace.home_plan | sort -u
# что из них реально живо — сверить со /api/states

🔴 hidden_by: user НЕ влияет на дашборды со storage-mode. Ссылки в .storage/lovelace.* вписаны руками — скрытие сущности их не трогает. Тот же класс проблемы, что питфолл «план этажей ссылался на снесённого призрака light.smart_light_stairs_l1» (family/tech/zigbee-t610-z2m-i-zha §13.3). 🔴 Второе: hidden_by не влияет и на area_entities() в шаблонах. area_entities("kitchen") продолжает отдавать скрытые сущности — это два независимых механизма. Если сущность нужна «невидимой» реально, её надо disabled_by, либо убрать ссылку из дашборда.

Фикс — скрипт ~/tmp-t610/fix_plan_hood.py (dry-run по умолчанию, --apply для записи):

  1. Рекурсивный обход JSON плана → замена fan.fan_3fan.kitchen_hood
  2. assert что fan.fan_3 не осталось в выводе
  3. Бэкап remote → scp на t610

Результат: заменено 1 вхождение (.data.config.views[0].sections[0].cards[0].elements[6]). Бэкап lovelace.home_plan.bak-hoodfan-20260916-074008.

Проверено фактом на t610: fan.fan_3 в плане = 0, fan.kitchen_hood = есть, jq -e . → JSON валиден.

⚠️ Дашборд читает .storage при загрузке страницы → нужен hard-refresh (Cmd+Shift+R), обычный F5 может отдать кэш.

6.1. Итоговая цепочка причин (три штуки, каждая выглядела как «не работает»)

# Что было Как выглядело Фикс
1 fan.kitchen_hood без зоны (area_id: null) «на кухне нет нового вентилятора» WS area_id: kitchen
2 диагностика реле не скрыта «вижу показатели kitchen hood» 8 сущностей → hidden_by: user
3 план этажей ссылался на fan.fan_3 «старая вытяжка вместо новой» fix_plan_hood.py --apply

🔑 ГЛАВНЫЙ УРОК: «создал сущность» ≠ «пользователь её видит». Проверять четыре вещи:

  1. /api/states/<entity> отвечает
  2. area_id в реестре не null (Template-сущности из YAML зону не получают — нет device_id → назначать вручную WS config/entity_registry/update с area_id)
  3. диагностика устройства скрыта (hidden_by: user)
  4. дашборды/план этажей не ссылаются на мёртвые сущности (jq по .storage/lovelace.*)

7. Питфоллы

# Питфолл Обход
1 switch_as_x не принимает light Источник только switch. Для ZHA-light бесполезен — нужен Template
2 Домен сущности сменить нельзя Только Template-хелпер рядом + скрыть оригинал
3 !include ломает yaml.safe_load при локальной проверке Заглушка: L.add_multi_constructor('!', ...) — иначе проверка конфига локально невозможна
4 🔴 check_config через сервис отдаёт [] Это не ошибка — сервис не возвращает тело. Проверять GET /api/config.state или /api/template
5 _1/_2/_3 ≠ порядок скоростей автоматически ZHA нумерует по endpoint'ам, не по физической скорости. ⚠️ Требует физической проверки — §10
6 Template turn_on без аргумента fan.turn_on без percentage → скорость 1 (33 %). Задано явно
7 🔴 Правка configuration.yaml требует restart HA Core automation reload здесь не поможет — новый template-блок не подхватится
8 🔴 REST POST без -H "Content-Type: application/json" → пустой ответ Всегда ставить заголовок
9 🔴 Заголовок авторизации рвётся маскировщиком Hermes в скриптах Собирать по частям либо Python + urllib (пример — hood_scan.py, hood_hide.py, hood_cleanup.py)
10 sensor.kitchen_hood_lqi / _rssi → 404 в /api/states disabled_by: integration — норма, не поломка
11 🔴 Template-сущность из YAML не получает area_id → «создал, а в UI нет» Назначать зону вручную WS config/entity_registry/update
12 🔴 hidden_by: user не влияет на дашборды и area_entities() Правки кэширует UI → hard-refresh; ссылки в .storage/lovelace.* править руками
13 🔴 Правка .storage/lovelace* вступает в силу только при загрузке страницы Hard-refresh (Cmd+Shift+R), F5 может отдать кэш

8. Итоговое состояние кухни (вытяжка)

Видно пользователю Скрыто (hidden_by: user)
fan.kitchen_hood (зона kitchen) fan.fan_3, switch.fan_3_low/medium/high, script.set_fan_3_speed
light.kitchen_hood_light / _2 / _3 sensor.kitchen_hood_energy/power/voltage/current
select.kitchen_hood_indicator_mode / _power_outage_memory
update.kitchen_hood_firmware, button.kitchen_hood_identify

sensor.kitchen_hood_lqi / _rssidisabled_by: integration, не отображаются нигде (норма).

Карта этажей home_plan: иконка на кухне (elements[6], 18 %/86.3 %) переведена на fan.kitchen_hood.

fan.fan_3 не удалён — только скрыт. Возврат: hood_cleanup.py --unhide.


9. Роадмап вентиляции

family/documents/home-automation-wishlist §2 п.1 ожидает «Kitchen Hood» как конечный узел алгоритма вентиляции по CO₂ (Node-RED: Demand Aggregator → Intake Allocation → Discretization → Damper Outputs → Exhaust Arbitration → Fans → Kitchen Hood). Ранее узел был мёртв вместе с контуром AT2 — теперь у вытяжки есть рабочая сущность fan.kitchen_hood, на которую можно вешать автоматику. Ждёт решения по slave 10 (AT2 снят Alex'ом).


10. ⚠️ ОТКРЫТО — требует проверки Alex

  1. 🔴 Порядок скоростей не подтверждён физически. Принято как _1=33 / _2=66 / _3=100, но какое реле = какая скорость — не проверялось. Нужно встать у вытяжки: поставить 33 % и 100 %, убедиться что низкая/высокая. Если перепутано — правка трёх строк в percentage и set_percentage.
  2. ⚠️ light.kitchen_hood_light мог быть лампой подсветки, а не скоростью. До работ он был on (горел), после рестарта HA стал off. Если это лампа подсветки вытяжки — вынести отдельно, фан её не должен гасить.

📌 Проверка для будущей сессии (одной командой): поставить fan.set_percentage на 33 и на 100 и сравнить, какое реле зажглось и что физически слышно. Маппинг в коде — три строки в percentage и три ветки choose в set_percentage.


11. Артефакты

Файл Назначение
~/tmp-t610/configuration.yaml.current рабочая копия конфига (с новым блоком)
~/tmp-t610/hood_scan.py read-only скан: devices + entities + device_class + area + states
~/tmp-t610/hood_hide.py скрыть/показать три light.* (--unhide)
~/tmp-t610/hood_cleanup.py зона kitchen + скрытие 13 сущностей (--unhide)
~/tmp-t610/fix_plan_hood.py правка ссылки в home_plan (dry-run / --apply)
~/tmp-t610/home_plan.json локальная копия карты этажей

Бэкапы на t610: configuration.yaml.bak-fanhood-20260916-081926 · lovelace.home_plan.bak-hoodfan-20260916-074008


Связанные