Home Assistant: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
| (не показано 17 промежуточных версий этого же участника) | |||
| Строка 24: | Строка 24: | ||
=<code>Zigbee2Mqtt</code>= |
=<code>Zigbee2Mqtt</code>= |
||
| − | Важнейший |
+ | Важнейший компонент |
| + | <BR> |
||
| + | * Служит бриджом между MQTT (откуда читает команды) и устройсвами ZigBee |
||
| + | * Для подключения к ZigBee нужен адаптер который может быть USB или в сети (у меня - в сети https://noname.com.ua/mediawiki/index.php/Zigbee_Sonoff_Zigbee_Bridge_pro) |
||
| + | <BR> |
||
| + | Первое что нужно сделать - мониторит подключенные устройства |
||
| + | <BR> |
||
| + | Очень неприятно если какая-то автоматизация отвалится когда устройство ушло в off-line |
||
| + | <BR> |
||
| + | |||
| + | {{caution|text= |
||
| + | * Конфиг исправлять '''ТОЛЬКО''' при выключенном процессе |
||
| + | * '''ВСЕГДА''' иметь бекап - изменение Network Key потребует перепривязывание всех устройств что здорово выбесит |
||
| + | }} |
||
| + | <PRE> |
||
| + | homeassistant: |
||
| + | enabled: true |
||
| + | legacy_action_sensor: false |
||
| + | <PRE> |
||
| + | Этот шаг нужен (как минимум на сегодня) что бы отправлять данные которые считаются диагностическими (по умолчанию это не делается) |
||
| + | <PRE> |
||
| + | device_options: |
||
| + | homeassistant: |
||
| + | linkquality: |
||
| + | enabled_by_default: true |
||
| + | last_seen: |
||
| + | enabled_by_default: true |
||
| + | voltage: |
||
| + | enabled_by_default: true |
||
| + | current: |
||
| + | enabled_by_default: true |
||
| + | power: |
||
| + | enabled_by_default: true |
||
| + | energy: |
||
| + | enabled_by_default: true |
||
| + | battery_low: |
||
| + | enabled_by_default: true |
||
| + | entity_category: diagnostic |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | timestamp_format: YYYY-MM-DD HH:mm:ss |
||
| + | </PRE> |
||
| + | Отправлять доступность устройств - иначе не ясно будет как давно устройство "пропало" |
||
| + | <PRE> |
||
| + | availability: |
||
| + | enabled: true |
||
| + | </PRE> |
||
| + | |||
| + | Можно еще так |
||
| + | <PRE> |
||
| + | device_options: |
||
| + | homeassistant: |
||
| + | linkquality: |
||
| + | expire_after: 3600 |
||
| + | </PRE> |
||
| + | |||
| + | ==Настройка в HA== |
||
| + | |||
| + | Далее через UI HA сделать панель |
||
| + | * настройка -> панели -> новая панель (синяя кнопка внизу справа). |
||
| + | |||
| + | Когда панель добавлена |
||
| + | * Перейти в панель |
||
| + | * Справа вверху - редактировать |
||
| + | * Три точки справа вверху - выбрать текстовый редактор |
||
| + | Код панели: |
||
| + | <PRE> |
||
| + | views: |
||
| + | - title: Статус Zigbee |
||
| + | sections: |
||
| + | - type: grid |
||
| + | cards: |
||
| + | - type: heading |
||
| + | heading: Статус Zigbee |
||
| + | - type: markdown |
||
| + | content: >- |
||
| + | {% set devs = states.sensor |
||
| + | | selectattr('entity_id','search','_linkquality$') | list %} |
||
| + | {% set off = devs | selectattr('state','eq','unavailable') | list |
||
| + | %} **Всего:** {{ devs | length }} | **Онлайн:** {{ (devs | length) |
||
| + | - (off | length) }} | **Офлайн:** {{ off | length }} |
||
| + | - type: custom:auto-entities |
||
| + | card: |
||
| + | type: entities |
||
| + | title: Zigbee — OFFLINE |
||
| + | show_header_toggle: false |
||
| + | filter: |
||
| + | include: |
||
| + | - entity_id: sensor.*_linkquality |
||
| + | state: unavailable |
||
| + | sort: |
||
| + | method: name |
||
| + | show_empty: false |
||
| + | - type: custom:auto-entities |
||
| + | card: |
||
| + | type: entities |
||
| + | title: Zigbee — все устройства |
||
| + | show_header_toggle: false |
||
| + | filter: |
||
| + | include: |
||
| + | - entity_id: sensor.*_linkquality |
||
| + | sort: |
||
| + | method: name |
||
| + | </PRE> |
||
| + | |||
| + | =Разделение на файлы= |
||
| + | |||
| + | что list, что mapping |
||
| + | |||
| + | ==<code>automation:</code>== |
||
| + | список <code>!include_dir_merge_list</code>\ |
||
| + | * <code>automation: !include_dir_merge_list automations/</code> |
||
| + | * Пример: <code>automations/kitchen/kitchen_dishwasher.yaml</code> |
||
| + | <PRE> |
||
| + | - id: kitchen_dishwasher_is_on |
||
| + | alias: "kitchen DishWasher is on" |
||
| + | description: Тостер на кухне включен |
||
| + | trigger: |
||
| + | - platform: state |
||
| + | entity_id: |
||
| + | - binary_sensor.kitchen_dishwahser_power_on_off_sensor |
||
| + | from: 'off' |
||
| + | to: 'on' |
||
| + | condition: |
||
| + | action: |
||
| + | - service: notify.chat |
||
| + | data: |
||
| + | message: | |
||
| + | 🟢 🍽 ️🫧 Посудомойка Включена {{ now().strftime('%H:%M:%S') }} |
||
| + | </PRE> |
||
| + | |||
| + | ==<code>scene:</code>== |
||
| + | список <code>!include_dir_merge_list</code> |
||
| + | ** Пример |
||
| + | каждая сцена — с - |
||
| + | ==<code>template:</code>== |
||
| + | список блоков <code>!include_dir_merge_list</code> |
||
| + | ** Пример |
||
| + | каждый блок — с -; внутри sensor:/binary_sensor: тоже списки с - |
||
| + | ==<code>sensor:</code>== |
||
| + | !include_dir_merge_list sensors/ |
||
| + | sensor: !include_dir_merge_list sensors/ |
||
| + | |||
| + | ==<code>script:</code>== |
||
| + | словарь <code>!include_dir_merge_named</code> |
||
| + | * Пример |
||
| + | ключи сценариев без - |
||
| + | ==<code>input_select:</code>== |
||
| + | словарь <code>!include_dir_merge_named</code> |
||
| + | * Пример |
||
| + | ключи без - |
||
| + | ==<code>input_boolean:</code>== |
||
| + | словарь <code>!include_dir_merge_named</code> |
||
| + | * Пример |
||
| + | ключи без - |
||
| + | ==<code>input_number:</code>== |
||
| + | словарь <code>!include_dir_merge_named</code> |
||
| + | * Пример |
||
| + | ключи без - |
||
=Ссылки= |
=Ссылки= |
||
Текущая версия на 12:09, 3 октября 2025
Home Assistant
Пока это заготовка статьи про домашнюю автоматизацию и реализацию некоторых фич
Прежде чем начать
Для удобства работы (что б меньше возиться c UI) удобно выпустить токен и читать данные через API
- Профиль (снизу справа)
- Безопасность
- Долгосрочные токены доступа
Токен выглядит как-то так
eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp <пропущенно-много-букав> sImlhdCI6MTcyMTkwNzUzNywiZXhwIjoyMDM3MjY3NTM3fQ.YDLTNoOFebK4BVHFo-V1q7a84Cs78Z0b3H2e-F5mBpk"
Сразу сохранить, в открытом виде он показывается один раз
Zigbee2Mqtt
Важнейший компонент
- Служит бриджом между MQTT (откуда читает команды) и устройсвами ZigBee
- Для подключения к ZigBee нужен адаптер который может быть USB или в сети (у меня - в сети https://noname.com.ua/mediawiki/index.php/Zigbee_Sonoff_Zigbee_Bridge_pro)
Первое что нужно сделать - мониторит подключенные устройства
Очень неприятно если какая-то автоматизация отвалится когда устройство ушло в off-line
|
homeassistant:
enabled: true
legacy_action_sensor: false
<PRE>
Этот шаг нужен (как минимум на сегодня) что бы отправлять данные которые считаются диагностическими (по умолчанию это не делается)
<PRE>
device_options:
homeassistant:
linkquality:
enabled_by_default: true
last_seen:
enabled_by_default: true
voltage:
enabled_by_default: true
current:
enabled_by_default: true
power:
enabled_by_default: true
energy:
enabled_by_default: true
battery_low:
enabled_by_default: true
entity_category: diagnostic
timestamp_format: YYYY-MM-DD HH:mm:ss
Отправлять доступность устройств - иначе не ясно будет как давно устройство "пропало"
availability: enabled: true
Можно еще так
device_options:
homeassistant:
linkquality:
expire_after: 3600
Настройка в HA
Далее через UI HA сделать панель
- настройка -> панели -> новая панель (синяя кнопка внизу справа).
Когда панель добавлена
- Перейти в панель
- Справа вверху - редактировать
- Три точки справа вверху - выбрать текстовый редактор
Код панели:
views:
- title: Статус Zigbee
sections:
- type: grid
cards:
- type: heading
heading: Статус Zigbee
- type: markdown
content: >-
{% set devs = states.sensor
| selectattr('entity_id','search','_linkquality$') | list %}
{% set off = devs | selectattr('state','eq','unavailable') | list
%} **Всего:** {{ devs | length }} | **Онлайн:** {{ (devs | length)
- (off | length) }} | **Офлайн:** {{ off | length }}
- type: custom:auto-entities
card:
type: entities
title: Zigbee — OFFLINE
show_header_toggle: false
filter:
include:
- entity_id: sensor.*_linkquality
state: unavailable
sort:
method: name
show_empty: false
- type: custom:auto-entities
card:
type: entities
title: Zigbee — все устройства
show_header_toggle: false
filter:
include:
- entity_id: sensor.*_linkquality
sort:
method: name
Разделение на файлы
что list, что mapping
automation:
список !include_dir_merge_list\
automation: !include_dir_merge_list automations/- Пример:
automations/kitchen/kitchen_dishwasher.yaml
- id: kitchen_dishwasher_is_on
alias: "kitchen DishWasher is on"
description: Тостер на кухне включен
trigger:
- platform: state
entity_id:
- binary_sensor.kitchen_dishwahser_power_on_off_sensor
from: 'off'
to: 'on'
condition:
action:
- service: notify.chat
data:
message: |
🟢 🍽 ️🫧 Посудомойка Включена {{ now().strftime('%H:%M:%S') }}
scene:
список !include_dir_merge_list
- Пример
каждая сцена — с -
template:
список блоков !include_dir_merge_list
- Пример
каждый блок — с -; внутри sensor:/binary_sensor: тоже списки с -
sensor:
!include_dir_merge_list sensors/
sensor: !include_dir_merge_list sensors/
script:
словарь !include_dir_merge_named
- Пример
ключи сценариев без -
input_select:
словарь !include_dir_merge_named
- Пример
ключи без -
input_boolean:
словарь !include_dir_merge_named
- Пример
ключи без -
input_number:
словарь !include_dir_merge_named
- Пример
ключи без -
Ссылки
Пока что тут в основном ссылки
- WebOS : https://www.home-assistant.io/integrations/webostv/
- ModKam Реле https://www.youtube.com/watch?v=u3zDXNGVbgo
- (рус) Базовая установка в контейнерах https://habr.com/ru/articles/731110/
- (рус) Тут кой-какие примеры ручного добавления в конфиги - https://sprut.ai/article/home-assistant-statya-3-dobavlyaem-ustroystva (но качество статьи спорное)
- Прошивки
Zigbee2Tasmota
- Тут вроде бы должно быть описание как интегрироваться с ХА ноя ничего не понял https://thehelpfulidiot.com/how-to-use-zigbee2tasmota-with-home-assistant
Прошивки
- Tasmota https://zigbee.blakadder.com/Sonoff_ZBBridge-P.html
- Еще одна инструкция по прошивке бриджа https://dialedin.com.au/blog/sonoff-zbbridge-p-setup
- Ещ инструкция (по-моему самая полная и правильная) https://notenoughtech.com/home-automation/tasmota-on-sonoff-zb-bridge-pro/#flash
Термины и понятия
Когда что использовать
- Срабатывание по условию -> automation (с trigger описывающим условие)
- Если automation сложный, то код можно разбить на несколько скриптов
automation = логика запуска + условия + действия;
automation
Automation — правило “если-то”:
automation:
- alias: Door opened → notify
trigger:
- platform: state
entity_id: binary_sensor.external_door
from: 'off'
to: 'on'
condition: []
action:
- service: notify.chat
data: {message: "Дверь открыта"}
script
Script — именованная последовательность action (шагов).
Не имеет триггера, запускается вручную (кнопкой/сервисы) или из automation.
Скрипт можно так же рассматривть как процедуру (для группировки и переиспользования кода)
script:
send_door_alert:
alias: Send door alert
sequence:
- service: notify.chat
data: {message: "Дверь открыта"}
Вызов из automation:
action: - service: script.send_door_alert
Пример скрипта
Помещать в файл scripts.yaml или любой другой определенный в script: !include scripts.yaml
tv_living_room_wol:
alias: "TV Living Room: Power On (WOL)"
sequence:
- service: wake_on_lan.send_magic_packet
data:
mac: "38:8c:50:00:a3:14"
Что бы запустить скрипт можно добавить кнопку
Настройки панели --> добавить карточку (справа внизу) --> Объект (что бы вписать вкод вручную)
type: button
name: Включить ТВ
icon: mdi:television
tap_action:
action: call-service
service: script.turn_on
target:
entity_id: script.tv_living_room_wol
hold_action:
action: none
double_tap_action:
action: none
show_state: false
trigger
Trigger — часть automation. Это событие, которое запускает automation: смена состояния, время, MQTT-сообщение, вебхук, нажатие кнопки и т.д. Сам по себе trigger вне automation не существует.
Примеры триггеров:
state (изменение состояния сущности) time / time_pattern event / webhook mqtt device (из интеграций) numeric_state (порог)
script = только действия;
trigger = причина старта automation.
Разбор примера автоматизации
- alias: external_door_open_logged
description: "Открытие Внешней Двери (с логированием)"
mode: parallel
trigger:
- platform: state
entity_id: binary_sensor.sonoff_external_door_sensor_contact # твоя сущность
from: 'off'
to: 'on'
variables:
from: "{{ trigger.from_state.state if trigger.from_state is not none else 'none' }}"
to: "{{ trigger.to_state.state if trigger.to_state is not none else 'none' }}"
action:
- choose:
- conditions: [] # сюда твои прежние условия (если были)
sequence:
- service: logbook.log
data:
name: "door_automation"
entity_id: binary_sensor.external_door
message: "TRIGGERED ({{ from }} → {{ to }})"
- service: system_log.write
data:
logger: automation.door
level: info
message: "[door] sending notify ({{ from }} → {{ to }})"
- service: system_log.write
data:
logger: automation.door
level: info
message: "[door] notify SENT"
default:
- service: system_log.write
data:
logger: automation.door
level: info
message: "[door] SKIPPED: conditions not met ({{ from }} → {{ to }})"
mode
alias: external_door_open_loggedПо этомdescription: "Открытие Внешней Двери (с логированием)"mode: parallelРежим выполнения автоматики при повторном запуске до завершения предыдущего- single — новый запуск игнорируется.
- restart — оборвать текущий, начать заново.
- queued — поставить в очередь (можно max).
- parallel — запустить ещё один экземпляр параллельно.
Тут я хочу запускать автоматизацию не зависимо от того есть ли уже запущенная -> parallel
trigger
trigger:- начало секции триггеров
platform
- platform: state
основные платформы триггеров
Состояния/шаблоны
- state — смена состояния сущности.
- numeric_state — пороги (above/below) для числовых значений/атрибутов.
- template — когда Jinja-шаблон стал true.
Время
- time — в заданный момент (at: "08:30:00").
- time_pattern — по шаблону, типа cron (minutes: "/5").
- calendar — начало/конец события календаря.
Астрономия
- sun — рассвет/закат (+ оффсеты).
- zone — вход/выход из зоны (для device_tracker/person).
- geo_location — объекты geo_location (например, оповещения о землетрясениях).
События/внешние источники
- event — любое событие шины HA (например, telegram_command).
- homeassistant — события ядра (start, shutdown, т.п.).
- webhook — входящий вебхук.
- mqtt — сообщение в топике MQTT.
- tag — скан NFC-тега.
- device — триггеры, определяемые конкретной интеграцией/устройством (кнопки, клики, движения и т.д.).
entity_id
entity_id: binary_sensor.sonoff_external_door_sensor_contactКакой именно сенсор братьfrom: 'off'переход из состоянияto: 'on'в состояние
Тут можно указать только одно - тогда например будет срабатывать при переходе их unknown
condition
condition:(на уровне с trigger)
Дополнительные условия ограничивающие срабатывания
- Временное окно:
condition:
- condition: time
after: "08:00:00"
before: "23:00:00"
- Только когда нет дома
condition:
- condition: state
entity_id: person.max
state: not_home
- Только в темноте (через 30 минут после захода солнца):
condition:
- condition: sun
after: sunset
after_offset: "-00:30:00"
- Батарея датчика > 10% (если конечно такой датчик есть)
condition:
- condition: numeric_state
entity_id: sensor.sonoff_external_door_sensor_battery
above: 10
Шаблон (кастомная логика):
condition:
- condition: template
value_template: "{{ states('alarm_control_panel.home') == 'armed_away' }}"
variables
variables:from: "Шаблон:Trigger.from state.state if trigger.from state is not none else 'none'}}"to: "{{{{ trigger.to_state.state if trigger.to_state is not none else 'none' }}}}"
actions
action:
choose
choose не обязателен. Это просто “ветвление” внутри action (как if / elif / else):
проверяет наборы conditions;
выполняет первую подходящую sequence;
если ни одна не подошла — выполняет default (если есть).
Когда нужен:
разные действия при разных условиях;
нужно сделать fallback (например, залогировать «пропущено»), даже если условия не прошли.
Когда не нужен:
одно действие без условий → вызывай сервис напрямую.
Примеры
1) Без условий (тебе хватит этого):
action:
- service: notify.chat
data:
message: "Дверь открыта"
2) Условие “сверху” (без choose):
condition:
- condition: time after: "08:00:00" before: "23:00:00"
action:
- service: notify.chat
data:
message: "Дверь открыта"
Минус: если условие не прошло — ничего не выполнится (и ты не залогируешь «пропущено»).
3) Ветвление с choose (и default):
action:
- choose:
- conditions:
- condition: sun
after: sunset
sequence:
- service: notify.chat
data: {message: "Дверь открыта (ночью)"}
default:
- service: notify.chat
data: {message: "Дверь открыта (днём)"}
4) Логировать “пропущено” (то, ради чего я предлагал choose):
action:
- choose:
- conditions:
- condition: time
after: "08:00:00"
before: "23:00:00"
sequence:
- service: notify.chat
data: {message: "Дверь открыта"}
default:
- service: system_log.write
data:
logger: automation.door
level: info
message: "[door] SKIPPED: conditions not met"
- choose:- conditions: []sequence:
Запись в лог датчика
- service: logbook.logdata:name: "door_automation"entity_id: sensor.sonoff_external_door_sensor_batterymessage: "TRIGGERED (Шаблон:From → Шаблон:To)"
Запись в системный лог
- service: system_log.writeЗапись в системнвй логdata:logger: automation.doorlevel: infoУровень логгированияmessage: "[door] sending notify (Шаблон:From → Шаблон:To)"текст сообщения
- service: system_log.writedata:logger: automation.doorlevel: infomessage: "[door] notify SENT"
default:- service: system_log.writedata:logger: automation.doorlevel: infomessage: "[door] SKIPPED: conditions not met (Шаблон:From → Шаблон:To)"
Устранение дребезга
- delay_on
- delay_off
в определении binary_sensor (например, template / mqtt / zha через template-обёртку).
Что делают:
delay_on — переводит сенсор в on только если условие держалось всё это время.
delay_off — аналогично для перехода в off.
Зачем: «приглушить» дребезг на уровне сущности — все автоматизации и UI увидят уже устоявшееся состояние (короткие всплески не попадут в историю/логбук).
Пример (template binary_sensor):
template:
- binary_sensor:
- name: tea_kettle_kitchen_on_off_sensor
device_class: power
state: "Шаблон:(states('sensor.kettle power')"
delay_on: "00:00:05" # нужно 5 с непрерывно >500 Вт
delay_off: "00:00:10" # и 10 с непрерывно ≤500 Вт, чтобы погасить
(Формат длительности: "HH:MM:SS" или блоком seconds: 5.)
for: — в триггере автоматизации
Где: в trigger конкретной automation.
Что делает: автоматизация сработает только если целевое состояние держится указанное время. На саму сущность/историю не влияет — только на эту автоматизацию.
Пример:
automation:
- alias: external_door_open_logged
trigger:
- platform: state
entity_id: binary_sensor.external_door
from: 'off'
to: 'on'
for: "00:00:02" # дверь должна быть открыта ≥2 с
action:
- service: notify.chat
data: {message: "Дверь открыта"}
for: также работает с numeric_state, template и др. триггерами.
Когда что использовать
Хотите «успокоить» сам сенсор для всего (UI, истории, всех автоматизаций) → delay_on/off в сущности.
Нужна задержка только для конкретной реакции → for: в триггере.
Можно комбинировать: небольшой delay_on/off для сглаживания + for: в важной автоматизации.
Если покажешь конкретный тип сенсора/конфиг (template/mqtt/… ) — дам точный вариант вставки.