Для чего делать возможность в умном доме определять присутствие хозяев, всех или по отдельности? О! Пожалуй, такая возможность позволяет сделать дом не просто умным, а удобным. Если дома никого нет, можно понизить интенсивность отопления и сэкономить. Можно автоматически выключить забытые светильники и сэкономить. А можно, наоборот, запустить имитацию присутствия: включать свет в помещениях - и не быть ограбленным. Можно по приходу конкретного жильца включить свет в его помещении, включить чайник и телевизор. В общем, вы поняли, штука крайне нужная.

Так получилось, что я во многом яббловод. Но для построения умного дома был выбран Sprut.hub. Поэтому первый вариант presence был сделан на основе HomeKit. В Спрутхабе был создан виртуальный выключатель на каждого члена семьи, проброшен в ЯбблоДом, а на iPhone у каждого настроен сценарий: по приходу - включить выключатель, по уходу - выключить. Почему выключатель? Потому, что другими устройствами автоматизация на телефоне управлять не может (ну, имеется в виду кнопка или датчик присутствия). Уже в спрутхабе написаны скрипты, реагирующие на изменение состояний этих выключателей, и выполняющих желаемые действия.

Такой подход показал себя довольно неплохо. Но также были отмечены и недостатки. Во-первых, работает только с Apple и, соответственно, делает наличие Apple Home обязательным. Во-вторых, для передачи команды на переключение "выключателей" нужна какая-либо связь на телефоне. И в третьих, судя по всему, данная функция телефонов от Apple работает на основе спутниковой навигации. И с последними двумя пунктами сейчас не очень.

В общем, появилось желание сделать альтернативный вариант детектирования присутствия. Такой, чтобы не обязательно было на телефоне (или даже не телефоне) что-либо настраивать. Разумеется, пинги не рассматриваем - телефоны засыпают, да и вообще могут на пинги не отвечать. Вообще, хотелось бы, чтобы работал этот механизм ниже IP уровня. Учитывая медленную, но неотвратимую поступь IPv6, это ещё и позволит не делать дважды одну и ту же проверку (ipv4 и ipv6). Вариации на тему ARPWATCH тоже не всегда могут сработать - например, если WiFi вынесен в отдельный VLAN. Поэтому хочу делать определение присутствия по данным WiFi.

Также хочется избежать ручного создания устройств в СХ - они должны обнаруживаться самостоятельно и содержать как можно больше полезной информации, которую можно вытащить из сетевого оборудования. Выбирая между "Определения человека" и "Определение устройства" я склонен выбрать второй вариант - у людей может быть несколько устройств. Соответственно, вытаскиваем их в СХ, а уже дальше на уровне умного дома определяем, сколько устройств нужно, чтобы засечь человека. И, конечно, мы не хотим тащить в виде presence в спрут всякие прочие WiFi устройства: телевизоры (их вообще проводом надо подключать), увлажнители, метеостанции, камеры, и (прости, Господи) WiFi устройства умного дома.

Окей, кажется, требования у нас есть. А что из возможностей? Тут, конечно, разброс большой. Каждый производитель сетевого оборудования делает что-то своё. У меня в доме развёрнута сеть на базе оборудования Mikrotik: роутер и 3 точки доступа WiFi - на разных этажах. Для централизованного управления точками доступа я использую CAPsMAN - это встроенное в RouterOS средство управление. В него заведены все точки доступа. Для моей задачи это очень удобно, т.к. регистрация клиентских устройств в сети WiFi осуществляется централизованно, на роутере. Соответственно, мне достаточно применить нужные настройки и скрипты на одном устройстве, и все данные можно будет централизованно отправлять на спрутхаб - не важно, на какой именно точке доступа зарегистрировалось устройство.
Раз в требованиях числится использование только радио-уровня, то ни в DHCP leases, ни в ARP мы ходить не будем. Нужная нам информация о регистрации (присутствии) в сети есть в

/caps-man registration-table

MAC, уровень сигнала, а ещё есть указание, к какой точке доступа (в виде интерфейса) подключено устройство. Не хватает только имени. Во всяком случае, если не проваливаться в RADIUS и EAP (а я туда пока не провалился). А где бы нам взять имя? Ну, есть в DHCP leases. Но это уже начинается IP. Не подходит.

А что это за поле такое, если смотреть на таблицу регистрации через веб-интерфейс? Comment. Ох ты ж! А его можно заполнить? Нет. Эта таблица - только для чтения. А зачем тогда это поле? Откуда оно заполняется? Гугл мне помог - это поле заполняется из access-list. В моём случае (при использовании CAPsMAN) это
/caps-man access-list

Ранее у меня такая настройка не использовалась. Что ж... время пришло. Добавляем названия интересных нам устройств и (обязательно!) последним правилом разрешаем всё

/caps-man access-list
add action=accept comment=Maxim mac-address=00:XX:XX:XX:XX:XX time=0s-1d,sun,mon,tue,wed,thu,fri,sat
add action=accept disabled=no time=0s-1d,sun,mon,tue,wed,thu,fri,sat

Во! в registration table появились названия. Можно брать. Но пока что многовато устройств. Все брать не надо. Надо как-то отфильтровать. В узком случае, можно бы и просто фильтровать по наличию комментария. Например, так

/caps-man registration-table print where comment ~ ".+"

Но в более общем случае в комментариях может быть и другая полезная информация. Чтобы не подраться, сделаем специальную метку. Для интересных нам устройств будем писать префикс "SHP-". В спрут пробрасывать префикс не будем. Но после него до конца коммента - это всё нужное нам имя. Тогда заполнение коммментария выглядит так

/caps-man access-list
add action=accept comment=Maxim mac-address=00:XX:XX:XX:XX:XX time=0s-1d,sun,mon,tue,wed,thu,fri,sat
add action=accept disabled=no time=0s-1d,sun,mon,tue,wed,thu,fri,sat

а запрос к таблице регистрации так

/caps-man access-list print where comment ~ "^SHP-.*"

Ну, а вырезать кусок строки в скрипте можно командой :pick.
Отлично! Нужные нам данные есть. Как их передать в хаб? У Микротика есть API. А sprut умеет в http. Но нет. Не наш метод. SSH - ну тоже такое себе. А есть ли что-то более подходящее для умного дома? Вот за этими тремя буквами IOT? Там вот ещё 4 полезных буквы MQTT. Очень хорошо... MQTT я умею и уже использую.
Для начала убедитесь, что routerOS у вас установлен актуальной версии. Затем установите пакет IOT (если ещё нет). Теперь время настроить MQTT брокер, которому Микротик будет слать сообщения.

/iot mqtt brokers
add address=192.168.X.Y client-id=mikrotik name=spruthub port=44444 username=XXXXXXX password=YYYYYYY

Теперь мы сможем публиковать топики командой /iot/mqtt/publish . Круто! Самое время придумать структуру топиков. Всё, что у меня будет от микротика, хочу держать рядом, поэтому на верхнем уровне будет mikrotik/ Далее чую, что более одной задачи у меня будет для микротика, поэтому весь presence хочу отдельно. Получается mikrotik/presence/. Что сделаем первичным ключом-идентификатором устройства? Имя не уникальное. Остаётся MAC. А в требованиях как раз и числится, что работать мы будем с устройствами. Окей. Имя тоже опубликуем. Далее нам нужен признак присутствия. Пусть будет occupancy. У нас есть под рукой уровень сигнала и имя интерфейса. Тоже берём. Итого у нас получается

mikrotik/presence/00:XX:XX:XX:XX:XX/name
mikrotik/presence/00:XX:XX:XX:XX:XX/interface
mikrotik/presence/00:XX:XX:XX:XX:XX/occupancy
mikrotik/presence/00:XX:XX:XX:XX:XX/signal
mikrotik/presence/00:XX:XX:XX:XX:XX/interface

Можно всё упаковать в скрипт. Не забываем, что спрутхаб требует атрибут retain для топика, который будет использоваться для поиска устройства. Логичным кажется сделать таковым mikrotik/presence/00:XX:XX:XX:XX:XX/name

Итоговый скрипт лежит в моём гитхабе. Качайте и устанавливайте.

/system script
add comment="Publish presence to MQTT for Spruthub" dont-require-permissions=no name=spruthub-presence policy=ftp,read,write,policy,test,sensitive,romon

Текст в команду не прикладываю - загрузите его через веб-интерфейс или WinBox, в зависимости от ваших предпочтений. Признаюсь, с правами не разбирался. Выглядит так, что просто read и write не хватает. Но для меня права в микротике - тёмный лес.

Последний момент с микротиком перед тем, как мы рванём в спрутхаб - это запуск скрипта. Я не нашёл в CAPsMAN события, на которое можно было бы привязать запуск скрипта. Скорее всего, таковое есть где-то в RADIUS, но у меня оный отсутствует. Так что будем запускать по расписанию.

/system scheduler
add comment="Run MQTT presence script" interval=30s name=schedule1 on-event=spruthub-presence policy=ftp,read,write,policy,test,sensitive,romon start-date=2026-01-01 start-time=00:00:00

Я выбрал периодичность запуска 30 сек. Вы можете уменьшить период (так обновление статуса будет прилетать быстрее, но вырастет нагрузка и на микротик, и на хаб) или увеличить на своё усмотрение.

Теперь к спруту. Если вы ещё не настроили MQTT брокер и MQTT контроллер, то самое время сделать это. На сайте СХ есть инструкция по настройке брокера, и есть инструкция по настройке MQTT контроллера. Инструкции хорошие, с картинками. Рекомендую.

После настройки MQTT на СХ запускаем наш любимый MQTT explorer и убеждаемся, что данные публикуются на брокере.

Чтобы превратить топики MQTT в устройства, которые понятны СХ (и далее - другим системам, которые интегрируются с ним, например, HomeKit или Умный Дом Яндекс) нужен шаблон. Какое устройство выбрать для обозначения присутствия человека (телефона)? Смотрим варианты на самом хабе, в меню Настройки - Типы сервисов. Мне показалось правильным выбрать OccupancySensor (это в оригинальной задумке - "радар", но тут очень подходяще выглядит). Пишем шаблон для идентификации устройства (ModelID)
"modelIds": [
"mikrotik/presence/(.*)/name"
],
В таком случае, MAC станет ключом-идентификатором устройства в хабе. Удобно.
Описываем сервис. Он тут будет один ("type": "OccupancySensor"), но с несколькими характеристиками. Во-первых, Имя
{
"type": "Name",
"link": [
{
"type": "String",
"topicGet": "mikrotik/presence/(1)/name"
}
]
},
Собсно, признак присутствия
{
"type": "OccupancyDetected",
"link": [
{
"type": "Integer",
"topicGet": "mikrotik/presence/(1)/occupancy"
}
]
}
Куда положим уровень сигнала? А вот что за прекрасный C_Distance? Да, сигнал у нас в дБ, а расстояние в метрах. Но уровень сигнала позволяет оценить, далеко ли устройство. Т.е. по своей логике тоже показывает расстояние. И это потенциально полезно в сценариях. Так что точно надо вывести в характеристиках. Но сигнал у нас отрицательный. И двухзначный. Вряд ли столько метров будет логично. Штош... разделим сигнал на -10 и скажем, что это метры. Но в уме держим, что это достаточно условная величина. Да будет так.

    {
      "type": "C_Distance",
      "link": [
        {
          "type": "Double",
          "topicGet": "mikrotik/presence/(1)/signal",
          "inFunc": "value / -10"
        }
      ]
    }

Остаётся у нас имя интерфейса (точки доступа). Его отправляем в опции (это то, что в интерфейсе - в Настройках устройства)

{
  "link": [
    {
      "type": "String",
      "topicGet": "mikrotik/presence/(1)/interface"
    }
  ],
  "name": "Интерфейс",
  "description": "Интерфейс точки доступа, где зарегистрировано устройство",
  "inputType": "TEXT",
  "write": false,
  "type": "String"
}

Шаблон тоже выложен на гитхаб по ссылке выше (если вы его уже скачали, установили и собираетесь мне писать, что не работает, читайте дальше, да)
Добавляем шаблон по инструкции. В меню СХ идём в контроллеры и запускаем поиск для контроллера MQTT. Устройства появились. Вот только почему они все называются одинаково? Мы же имя заполнили и передали? Увы, это либо баг (если верить встроенной справке по типам сервисов), либо фича (если справка врёт). В чатик поддержки я об этом написал. Будем надеятся, что исправят. Неприятно же.... Ну, а чтобы можно было попроще идентифицировать устройства, и вручную переименовать, в шаблон я добавил это же имя в раздел options. Т.е. в интерфейсе будет рядом с именем точки доступа.

Для появления нового устройства в СХ в качестве датчика присутствия нужно:

  • на микротике настроить capsman access-list c указанием в комментарии SHP-ИМЯ для нужного MAC. Новая строка должна быть выше последней, разрешающей всё - иначе комментарий "не прилипнет"

  • на спрутхабе запустить поиск устройств в контроллере MQTT.

Механизм получился высокочувствительным. Если первый вариант с использованием ябблодома позволял уйти довольно далеко от границ участка перед срабатыванием, то новый механизм срабатывает почти сразу за пределами дома (уличных точек доступа у меня на данном этапе нет). Опять-таки, надёжность нового механизма явно выше. Наконец-то я завёл андроидные устройства. И судя по всему, часы с WiFi тоже могут работать меткой присутствия.
Если вы не используете CAPsMAN, скрипт достаточно легко адаптировать к /interface/wireless/ Там те же registration-table и access-list (не проверял работу).

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