Наблюдение за изменением уровня Wi-Fi сигнала от стационарно расположенных по дому IoT устройств позволяет сделать полностью программный (выделенное железо отсутствует) обьемный датчик движения в квартире, достаточно точно показывающий наличие активно перемещающихся (фактически, не спящих) людей.
Есть обычная “квартира айтишника” с системой “умный дом” на базе Home Assistant:
Самодельные выключатели освещения на базе ESP8266 + MSP430
Несколько датчиков температуры/влажности, СО2 и качества воздуха.
Контроллер вентиляторов в ванной/туалете
пара Sonoff Mini для остального.
Общение девайсов между собой – по Wi-Fi + MQTT. Для минимизации влияния низкоскоростных ESP на “рабочую” Wi-Fi сеть – на отдельном Raspberry Pi 3 запущена отдельная Wi-Fi сеть для IoT, на базе стандартного hostapd. В сумме в IoT Wi-Fi сети – 12 устройств.
Там же на RPi запущен MQTT брокер, рядом на “домашнем сервере” – Home Assistant.
Уровень сигнала Wi-Fi достаточно зависим от наличия и расположения препятствий между точкой доступа и клиентами. Даже открытая/закрытая деревянная межкомнатная дверь может вызвать заметные изменения в RSSI, не говоря уже о прошедшем человеке. При этом, так как сами wi-fi клиенты стационарны – изменения сигнала от других факторов достаточно минимальны.
Если собрать данные о всех подключенных клиентах – скорее всего, их изменение будет достаточно заметным при перемещении людей в помещении, что и позволит реализовать обьемный датчик движения “просто так” – без установки дополнительного железа.
Запустив команду iw dev wlan0 station dump, можно получить достаточно детальную информацию по подключенным клиентам:
Station 60:01:94:21:f8:4c (on wlan0)
inactive time: 8000 ms
rx bytes: 11269629
rx packets: 91423
tx bytes: 6159821
tx packets: 70707
tx failed: 0
signal: -53 [-53] dBm
tx bitrate: 1.0 MBit/s
rx bitrate: 54.0 MBit/s
...
connected time: 763375 seconds
Station 18:fe:34:98:dc:81 (on wlan0)
inactive time: 4000 ms
rx bytes: 11388688
rx packets: 92101
tx bytes: 6143200
tx packets: 70205
tx failed: 39
signal: -40 [-40] dBm
tx bitrate: 1.0 MBit/s
rx bitrate: 18.0 MBit/s
...
connected time: 763378 seconds
Значение RSSI (“signal: -40 [-40] dBm”) обновляется в реальном времени, и вызывая iw достаточно часто – можно собрать статистику уровня сигнала.
Запуская iw два раза в секунду и усреднив RSSI за минуту – можно получить значения с более высокой точностью:
Уже по этому графику видно что ночью сигнал остается стабильным, а днем отдельные клиенты отклоняются от “спокойного” состояния на +/- 10 dBm. Однако представление результата можно улучшить, посчитав среднеквадратичное отклонения сигнала для всех клиентов от “спокойного” уровня.
Первым вариантом алгоритма было:
Собрать статистику по уровням сигналов в отсутствие людей (“базовый уровень”)
Сохранить базовый уровень в файле конфигурации
Посчитать среднеквадратическое отклонение от базового уровня, которое и будет сигналом “обнаружено движение”
После имплементации такого алгоритма оказалось, что базового уровня не существует. После прохода человека по квартире и возврата в первоначальную точку – сигналы стабилизируются, но на других значениях.
Рассмотрим например тот же график в окресностях 4 утра:
Можно заметить ночной поход в ванную в ~4:30. После него сигналы вернулись к стабильности, но некоторые из них – сместились от предыдущих значений. Отсюда можно сделать вывод, что система в целом – метастабильна, и одного фиксированного “состяния покоя” не существует.
Для решения этой проблемы “состояние покоя” тоже нужно считать как среднее – но за значительно более продолжительный промежуток времени.
Раз в 500мс собираем значения RSSI из вывода iw dev wlan0 station dump.
Сама команда достаточно легковесна, чтобы не нагружать Raspberry Pi выполнением с такой частотой.
Для каждого из клиентов считаем скользящее среднее за последние 1024 сэмпла в качестве “базового уровня”:
$RSSI = -65; # Значение из iw dev dump
$baseline = ($RSSI + 1023 * $baseline) / 1024;
Опять же для каждого считаем скользящее среднее за 256 сэмплов по аналогичной формуле в качестве “текущего значения”.
Итоговый показатель “активность движения в доме” считается как корень из суммы квадратов отклонений “текущего” от “базового” для каждого из wi-fi клиентов.
Результат уже намного более нагляден:
Здесь синий график (“IW Signal Distance”) и является среднеквадратическим отклонением. Остальное – индивидуальные отклонения от скользящего среднего.
Эмпирическим путем можно предположить, что значения IW Signal Distance >1 (зеленая горизонталь) соответствуют активности людей в помещении. Но эта граница, скорее всего, будет отличаться для других конфигураций помещения и количества устройств.
Система работает в таком виде уже более двух лет, и достаточно надежно показывает активность внутри квартиры, с минимальным влиянием соседей.
Моя реализация алгоритма доступна на гитхабе (https://github.com/k-korn/misc-scripts/tree/main/iwmon), но она достаточно специфична (Perl + Zabbix + визуализация в Grafana) – и потому готовым решением “plug and play” все же служить не может.
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…
Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…
У частных продавцов на Авито появилась возможность составлять текст объявлений с помощью нейросети. Новый функционал доступен в категории «Обувь, одежда,…
24 апреля 2024 года в Москве состоялась церемония вручения наград международного конкурса Workspace Digital Awards. В этом году участниками стали…
27 июня Яндекс проведет гик-фестиваль Young Con для студентов и молодых специалистов, которые интересуются технологиями и хотят работать в IT.…