Хитрый Device tracker с помощью OpenWRT

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Так получилось, что личный сервер 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.

Источник: https://habr.com/ru/articles/785868/


Интересные статьи

Интересные статьи

Интеграция с БД - привычно сложная и хрупкая часть большинства кодобаз, постоянно отвлекающая внимание разработчиков и раздувающая сроки. Какой бы хайпующий фреймворк вы ни пробовали, вы неизбежно обн...
Добрый день, Хабр! Меня зовут Иван Колотилов и я фронтенд-разработчик. Я разрабатываю современные веб-приложения, специализируюсь на финансовых продуктах, работал в финтех-стартапах. Сегодня я хочу ра...
Если посмотреть, на какой базе сегодня обучают школьников в кружках робототехники, то окажется, что в большинстве своем это Лего-подобные наборы с контроллером Arduino. Однако в этой статье мы рассмот...
За прошлый год я собрал и настроил автоматизацию для небольшой квартиры около оживленной дороги. В этой статье я расскажу об использованных решениях в климатической системе, освещении, мультимеди...
Привет Хабр. Сегодня мы продолжим тему SDR-приема и обработки сигналов. Приемом аналогового ТВ я заинтересовался совершенно случайно, после вопроса одного из читателей. Однако это оказалось не...