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

Так получилось, что я во многом яббловод. Но для построения умного дома был выбран 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 (не проверял работу).

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

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


  1. sokoloid
    23.01.2026 22:28

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


    1. ramax Автор
      23.01.2026 22:28

      Чтобы связать устройство с пользователем для начала нужна сущность "пользователь". А его в HomeKit (а sprut.hub как раз сделан так, что его модель сущностей полностью взята оттуда - это и позволяем ему легко интегрировать с другими системами) нет. Была бы такая сущность - можно было бы затащить.


  1. GennPen
    23.01.2026 22:28

    Все эти способы по пингованию телефона через WiFi ненадежны. Если телефон в спящем режиме, то задержка может составлять минуты.

    Единственный надежный способ - это BLE-брелок и любой сканер, например на том же ESP32.


    1. ramax Автор
      23.01.2026 22:28

      Я как раз и описал непингование. При засыпании телефона регистрация на WiFi не пропадает. Да, IP не работает, но это и неважно.


  1. igrblkv
    23.01.2026 22:28

    На всех телефонах отключено стандартное поведение со случайным МАСом?


    1. ramax Автор
      23.01.2026 22:28

      Да вот как-то у меня ни на одном устройстве не нашлось случайного MAC, хотя проверял специально. Вроде как WiFi точка в списке доверенных, и MAC для неё постоянный.


  1. Micha1l
    23.01.2026 22:28

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

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


    1. ramax Автор
      23.01.2026 22:28

      MAC - это да. Но устройства меняются всё-таки не так быстро. Да и даже раз в год пару строчек настроить - не проблема. А можно и автоматическое "слияние" по имени сделать уже средствами Sprut.hub. Так что физические устройства меняются, а персональный presence будет работать.
      Что касается "роутеры меняются". Да, меняются. Но операционки достаточно стабильны. Вот мне в личку человек написал, что уже форкнул мой скрипт для работы с новым CAPsMAN (он появился с новыми точками доступами). Правка тоже заняла пару строк. Так что лет на 5 работать будет вообще без правок.

      У меня были мысли собрать все три варианта с микротика (локальный, старый CAPsMAN и новый CAPsMAN) в один скрипт, но придумать хороший алгоритм слияния результатов из разных мест я не смог, а принцип "всё равно использовать будут что-то одно" мне не понравился (возможно, и зря).
      Что касается микроволнового датчика, то для детектирования занятости помещения на предмет включения света - незаменимая штука да. Но вот человека от собаки они ещё как-то различают, а одного человека от другого - уже нет. Т.е. включить свет в моей комнате, когда я на крыльце - не решит такой задачи.
      Опять-таки, то, что хорошо для квартиры - не очень для дома. В доме одним датчиком не обойдёшься. А WiFi уже есть.
      По наблюдениям за чатом поддержки, сценарии, завязанные на условия "что-то (не) происходит в течение какого-то времени" показывают свою низкую надёжность. Да и зачем мне узнать "через несколько дней", что никого нет дома, если я вечером вернусь? А вот когда днём дома никого - можно не греть горячую воду. И температуру комнатную снизить. В течение дня, да.


      1. Micha1l
        23.01.2026 22:28

        Это всё хорошо пока вы живёте один и программист.

        А теперь добавляем сюда типичного заказчика системы Умный Дом у которого жена, несколько детей и несколько объектов недвижимости. И гаджеты у которых меняются раз в год по мере выхода последней модели.

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

        Это что касается вообще идеи по удешевлению обнаружения присутствия людей дома.

        Тоже касается сценариев индивидуальной работы освещения для каждого члена семьи.. Помимо того что сложно будет работать если в комнате больше 2 человек - нужен ещё удобный способ чтобы пользователи сами могли вносить изменения - иначе помимо штатной домработницы потребуется ещё штатный программист.


    1. PbIXTOP
      23.01.2026 22:28

      Случайный MAC используется для поиска-сканирования сетей, иногда при подключении к открытым сетям. Если сеть использует ключ то МАК всегда постоянен для работы с этой сетью