Так получилось, что личный сервер HomeAssistant у меня один, в моей квартире. И так получилось, у меня есть общая с родственниками дача. Помимо дачи еще есть несколько квартир этих же родственников. У них в квартирах и на нашей даче, есть некоторые умные приборы вроде пылесоса, подсветки для растений, обогревателей и т.п. HomeAssistant нужно понимать, есть ли на даче кто-нибудь в данный момент, чтобы скажем отключить видеонаблюдение с уведомлениями, включить обогреватели в определенных комнатах. В квартирах родственников запустить пылесос по их уходу и т.п.

Мне кажется, отслеживание присутствия людей по Wi-Fi самое лучшее решение из того, что может предложить HomeAssistant. Я пробовал и отслеживание через приложение (субъективно, мне кажется, оно жрет батарею) и через Google Maps (медленно обновляет статус присутствия и субъективно, мне кажется, оно жрет батарею). Сейчас у каждого в кармане есть смартфон, Wi-Fi ни я сам, ни кто-либо из моих родственников не выключает никогда, так почему этим не пользоваться? Даже если смартфон разрядится, ничто не мешает добавить трекинг дополнительно по фитнес браслету, смарт-часам, планшету, ноутбуку и т.д.

В HomeAssistant есть замечательная интеграция ubus для OpenWRT. Она позволяет получать все устройства подключенные к роутеру в виде объектов device_tracker вида device_tracker.ff_ff_ff_ff_ff_ff где ff_ff_ff_ff_ff_ff мак адрес устройства. Но как быть если этих роутеров много? Только на даче их два, а есть еще моя квартира, и несколько квартир родственников.

Объекты device_tracker получаемые через интеграцию ubus, по сути, бинарные - только home и not_home. Получается что если я подключен к любому из роутеров, device_tracker.ff_ff_ff_ff_ff_ff имеет статус home. Вот тут я и хочу поделиться своим "костылем":

И так, настройка ubus хорошо описана в документации к HomeAssistant. Чтобы не повторятся TL;DR такой:

На роутере c OpenWRT:

opkg update
opkg install rpcd-mod-file uhttpd-mod-ubus

Затем создаем файл /usr/share/rpcd/acl.d/user.json с содержимым:

{
  "user": {
    "description": "Read only user access role",
    "read": {
      "ubus": {
        "*": [ "*" ]
      },
      "uci": [ "*" ]
    },
    "write": {}
  }
}

Перезагружаем роутер, роутер готов работать с HomeAssistant.

Переходим к настройке HomeAssistant:

В моем случае я использую packages, для каждого роутера создаю свой. Перед вами пример моего файла home-tracking.yaml

Для остальных роутеров созданы аналогичные по содержанию файлы, понятное дело со своими ip и паролями.

home_tracking:

    device_tracker:

      - platform: ubus
        host: 192.168.101.1
        username: root
        password: secret

Важная оговорка, HomeAssistant будет пытаться подключить к ubus роутера по порту 80. Если веб интерфейс висит у вас на другом порту, перевесьте его обратно на дефолтный 80, по крайней мере для Lan интерфейса.

Перед тем как я покажу свой великий костыль, хочу объяснить еще одну вещь. Допустим мы получаем от какого-то нашего роутера устройство device_tracker.ff_ff_ff_ff_ff_ff.

Если открыть атрибуты этого устройства, можно увидеть атрибут Host, который будет говорить с какого роутера получен данный статус. Именно его мы будем использовать.

Великий костыль

Создадим автоматизацию:

alias: Общее - Отслеживание - user
mode: single
trigger:
  - platform: state
    entity_id:
      - device_tracker.ff_ff_ff_ff_ff_ff
action:
  - if:
      - condition: state
        entity_id: device_tracker.ff_ff_ff_ff_ff_ff
        attribute: host
        state: 192.168.101.1
    then:
      - service: device_tracker.see
        data:
          dev_id: home_user
          host_name: home_user
          location_name: |
            {{states('device_tracker.ff_ff_ff_ff_ff_ff') }}
  - if:
      - condition: or
        conditions:
          - condition: state
            entity_id: device_tracker.ff_ff_ff_ff_ff_ff
            attribute: host
            state: 192.168.201.1
          - condition: state
            entity_id: device_tracker.ff_ff_ff_ff_ff_ff
            attribute: host
            state: 192.168.201.2
    then:
      - service: device_tracker.see
        data:
          dev_id: dacha_user
          host_name: dacha_user
          location_name: |
            {{states('device_tracker.ff_ff_ff_ff_ff_ff') }}

Что делает автоматизация:

Берет объект device_tracker.ff_ff_ff_ff_ff_ff, следит за его состоянием, и в зависимости от атрибута host записывает его состояние в устройство $host_user. $host можно записывать как удобно, в моем примере это, например home_user и dacha_user.

Таким образом, когда user с мак адресом ff_ff_ff_ff_ff_ff, подключится к роутеру, в зависимости от атрибута host, home_user или dacha_user получит значение home. Ровно наоборот произойдет при отключении - объект получит статус not_home.

Тут еще важно добавить, что службе device_tracker.see все равно был ли у вас до этого объект home_user - если его не было, она его создаст автоматически.

А что если нет OpenWRT?

Практически для всего на свете отлично подходит интеграция ping, однако с iOS устройствами это не прокатит. В одной сети с HomeAssistant, для iOS устройств есть прекрасный аддон для HACS - iphonedetect, однако надо учитывать, что это не будет работать с другими вашими сетями, соединенными скажем по Wireguard. В iphonedetect используется ARP (L2). Именно поэтому я в конце концов и пришел к данной реализации.

Так же советую рассмотреть интеграции для роутеров (не OpenWRT). Я слишком давно сижу на OpenWRT и плохо разбираюсь в стоковых прошивках, но в процессе поиска решений мне точно попадались какие-то интеграции для других роутеров.

P.S. Этой статьей я хотел показать не столько конкретную реализацию device_tracking через ubus, сколько костыль метод сбора данных с реального device_tracking и передачи данных в виртуальный device_tracking.

Комментарии (13)


  1. jehy
    11.01.2024 23:48
    +1

    Прикольная штука. Мне бы в голову не пришло делать такой распределённый умный дом с общей сеть на несколько домов и управлять её одним инстансом HA. Хотя в этом явно что-то есть - не надо помнить и обслуживать несколько инстансов, не надо им хардварь отдельную делать, всё в одном месте... А зигби как в таком режиме работает? Кажется, единственный минус, который навскидку приходит в голову - не будет локального управления, и при отключении интернета полетят термостаты и прочее. Но тут зависит от конкретных условий - в квартирах интернет довольно редко пропадает, да и можно резерв с симкой сделать...

    Тоже пользуюсь трекингом, но у меня всего один дом, так что хватает бинарного состояния, а данные о наличии девайсов в сети даёт интеграция с кинетиком. Кстати, у меня их два, но они в меш сети, так что достаточно опросить только мастер.


  1. SantaClaus16 Автор
    11.01.2024 23:48
    +1

    Zigbee у меня только дома и на даче. На даче через Zigstar LAN. При этом это только потолочный свет. Что касается отопления - дом в целом теплый, есть печка, зимой почти никогда не ездим. На весну/осень установлены электрические конвекторы в каждой комнате. В конвекторы встроены (своими руками) esp8266+релюшки на 16А. Данные температуры берутся с перешитых bluetooth датчиков - LYWSD03MMC. Собирает это все дело с них, esp32 с esphome (настроенно как platform: atc_mithermometer). На случай отвала интернета на роутере поднят mqtt сервер, куда esp32 дублирует показания с датчиков. От туда же esp8266 конвектора читает температуру в своей комнате и воображает себя термостатом.
    Получается в случае отвала интернета пропадает только контроль потолочного света, но в ручную то все работает и zigbee сеть не разваливается. Ну а конвекторы вообще получается никак от интернета не зависят, ну только задать температуру... Но для этого у меня предусмотрена физическая кнопка на конвекторе позволяющая тупо включать реле.


    1. jehy
      11.01.2024 23:48
      +2

      Классно. У меня из тех же соображений обогрев террариума сделан на esp и воткнутых в него датчиках :)


  1. sekuzmin
    11.01.2024 23:48

    Интересный способ. А как боретесь с рандомизацией MAC-адресов? Отключаете на всех устройствах?


    1. SantaClaus16 Автор
      11.01.2024 23:48
      +1

      Да, просто отключаю для домашних сетей.


    1. V1tol
      11.01.2024 23:48
      +1

      Рандомизация срабатывает только на неизвестную сеть или если долго не подключались к известной сети. У меня на кинетике стоит регистрация устройств по мак адресу с закидыванием неизвестных в сеть без интернета. Мой 11 айфон, подключённый постоянно к вайфаю, за 2 года свой мак адрес ни разу не поменял (я специально проверял, что рандомизация включена). Айфон брата перерегистрирую каждый раз не смотря на то, что сеть он помнит и соединяется успешно - просто приезжает в гости не чаще 1 раза в пару месяцев.


      1. SantaClaus16 Автор
        11.01.2024 23:48

        Я тоже заметил что некоторые устройства, например друзей приходящих в гости, отображают хоть и подменный, но постоянный мак адрес. Хотя глубоко в вопросе не разбирался. Спасибо что поделились наблюдениями)


  1. michalbl4
    11.01.2024 23:48

    Сам использую Device Tracker на ubus. Но у меня только один роутер, такой проблемы, как у автора, не возникало.
    Идея красивая, но я бы реализовывал ее не через автоматизации, а через template sensor, например. Чтобы следил за состоянием device_tracker, а итоговый state выдавал в зависимости от атрибута. В принципе "под капотом" механика та же самая, но внешне мне кажется логичнее делать сенсор, чем городить автоматизацию


    1. SantaClaus16 Автор
      11.01.2024 23:48

      Так можно сделать, но проблема в том что невозможно именно сделать template device_tracker, просто в HomeAssistant нет такого типа template. А именно device_tracker нужен был мне для красивого отображения в интерфейсе, и привязки к аккаунта пользователя, к которому тоже невозможно привязать что либо кроме device_tracker.


  1. Alternative
    11.01.2024 23:48
    +2

    Это не самый оптимальный вариант. Посмотрите на wifi-presence. Главное преимущество - передает данные сразу при изменении, да и подобные костыли не нужны.


  1. telobezumnoe
    11.01.2024 23:48
    +1

    пробовал делать отслеживание устройств по пингу и мак адресу, чтоб выполнять сценарии, на пример выключать освещение, и активировать режим охраны, но телефон от бездействия уходит в сон, и перестаёт отвечать, конечно можно в настройках не давать ему отключаться и спать, но тогда возрастает энергопотребление и расход аккумулятора. так что пришлось отказаться от этого варианта


    1. lex899
      11.01.2024 23:48
      +1

      Согласен, после множества экспериментов с wifi перешёл на отслеживание телефонов и меток через bluetooth. С небольшими костылями и контролем входной двери даёт 100%


  1. NutsUnderline
    11.01.2024 23:48

    в этой статье было классно сделать опрос: "а вы всегда включаете wifi в телефоне как приходите куда то или просто не выключаете". Для меня это просто удивительно, но раз уж есть paxcounter который именно так поток людей считает (wifi, bluethooth) то история может получиться интересная. синий зуб уже спамят, wifi тоже могут поставить "на поток"