Софтовый датчик присутствия на Linux AP + ESP8266

    TL;DR

    Наблюдение за изменением уровня 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" все же служить не может.

    Комментарии 22

      +2

      Клиенты постоянно меняют мощность своих передатчиков, поэтому и нет какого-то базового уровня.

        0

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

          0
          в загоовке датчик присутствия, а в абстракте «показывающий наличие активно перемещающихся (фактически, не спящих) людей». меня обманули
            +2

            Да, можно было бы назвать и "обьемный датчик движения". Но присутствовать, не двигаясь — скорее исключение, чем правило.

              +1
              датчиков движения тьма всяких разных, а присутствия не видел нормального. так что это выглядит как кликбейт
                +1

                Суть статьи не в этом. В данном случае датчик — "виртуальный", на уже существующем без него железе, и охватывает всю квартиру.

                  +2
                  я не оспариваю слово софтовый, я говорю о слове присутствия. этот датчик не определяет присутствия, он определяет движение. пусть он три раза софтово-виртуальный, он от этого не станет датчиком присутствия. вы обманываете людей. мне по профилю образования интересны как раз датчики присутствия, я пришел сюда за ним, но уже в абстракте увидел, что заголовок кликбейтный. как принципиально новая ОС BolgenOS. может решение и хорошо, но это не датчик присутствия.
            0
            Прогнать результаты измерений через преобразование Фурье не хотите?
              +2

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

                0
                По спектру можно попробовать определить скорость движения. А нейросеть да, тоже интересно ;)
                  0
                  Не вижу, объективно, практического применения скорости
                  А вот примерного (с точностью до помещения) положения — таки да
                    0

                    Скорость перемещения позволит отсечь ложные срабатывания. Но в любом случае это выглядит как забавная игрушка. Как охранный датчик использовать нельзя, управлять светом нельзя… Использовать как побочный канал утечки — сложно.

              +3

              Установить ограничение скорости в квартире и высылать штрафы за превышения ;)


              Сорри, немного веткой комментария промахнулся с мобилки

                0

                А появление и перемещение по квартире других wifi-устройств (смартфонов, например) не оказывает влияния на сигналы тех, что участвуют в мониторинге?

                  0

                  Нет, они как правило в 5ГГц диапазоне. А если в 2.4 — то на другом канале.

                  +1
                  Самодельные выключатели освещения на базе ESP8266 + MSP430
                  Несколько датчиков температуры/влажности, СО2 и качества воздуха.
                  Это интересно. Уважаемый kornerz, статья будет?

                  Для минимизации влияния низкоскоростных ESP на «рабочую» Wi-Fi сеть — на отдельном Raspberry Pi 3 запущена отдельная Wi-Fi сеть для IoT
                  Каким образом ESP влияет на скорость Wi-Fi базовой станции?
                  Что-то ничего подобного пока слышать не доводилось…
                    +1
                    Каким образом ESP влияет на скорость Wi-Fi базовой станции?


                    Вроде как базовая станция работает на скорости самого медленного клиента. У меня получилось запустить ESP только на 54 MB.
                      +1

                      Именно, базовая станция вынуждена "опуститься до уровня" самого медленного (по поддерживаемым возможностям вроде 40MHz канала, short GI и прочих) клиента.
                      Плюс, в моем случае держать IoT девайсы в отдельной подсети без доступа в Internet тоже имеет смысл.

                      +1
                      Это интересно. Уважаемый kornerz, статья будет?

                      Как только дойдут руки привести в толковый вид исходники и схемы.
                      Пара фоток:
                      https://i.imgur.com/oDVF5dp.jpg — выключатель/диммер, вид спереди. Излучающий ИК светодиод + фотодиод позволяют увидеть наличие руки и примерное до нее расстояние (для диммирования)
                      https://i.imgur.com/ZEInAbQ.jpg он же, вид на плату и ESP-01.
                      https://i.imgur.com/HGjsmEO.png сенсорный блок (сейчас там уже BME680 вместо 280)

                        0
                        Спасибо за ответы!
                        Фотографии лишь подогрели интерес :-)
                        С нетерпением жду статьи про диммер (сам давно в этой теме).
                        Простимулировал Вас поднятием кармы ;-)
                      +1
                      Похоже на ESP-WIFI-CSI: youtu.be/tFxKUzEDSdw

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое