Энергия, тепло и вода часть третья: выходим в радио

    Вступление


    В процессе выбора решений для умного дома я стараюсь обходить коробочные решения, требующие наличие связи с внешними облаками или имеющие собственные приложения, особенно решения без возможности прямого подключения к устройству. Все доступные метрики сводятся в один интерфейс — zabbix, там же организовывается система оповещений заинтересованных лиц. Ручки управления реализуются в локально расположенном веб-интерфейсе.

    Предыдущие статьи:


    часть первая (1wire температура, ups, водосчетчик...)
    часть вторая (netping, gidrolock, датчики давления...)

    Решаемые задачи в этой статье


    • Масштабируемая, гибкая система защиты от протечек воды с оповещением через zabbix
    • Прочие устройства на 433mhz: звонок, открытие двери и т п
    • Запихиваем 1wire в MQTT

    Система защиты от протечек


    Требования к системе:


    • множество датчиков, раскиданных по дому (в моём случае — 6 штук в разных локациях)
    • никаких проводов у датчиков
    • быстрое закрытие при обнаружении утечки
    • вся информация о текущем состоянии в zabbix. Там же — оповещение

    Состав системы


    • Raspberry PI
    • RTL2832U USB тюнер
    • Датчики протечек 433mhz
    • Netping + кран gidrolock (см предыдущую статью) для перекрытия магистрали

    Про железо


    В предыдущей статье я описывал решение перекрытия водоснабжения при помощи netping. У меня имеется один проводной датчик для этого решения. Это удобно, если все точки, где может произойти протечка, находятся примерно в одном месте. В моём случае netping установлен прямо на входе магистрали и там же управляет электро-механическим краном gidrolock (см предыдущую статью). Раскидывать netping+gidrolock+проводной датчик по всем точкам — дорого и громоздко. К тому же у меня уже нет возможности протаскивать новые провода по всему дому. Занимать розетки и втюхивать электрокраны — так себе решение. Решение ожидаемое — используем перекрытие общей магистрали на основе сигналов от раскинутых по локациям радио-датчиков.
    Из найденного в интернете — куча различных радио-датчиков от готовых систем. Некоторые можно купить отдельно, контроллеры к датчикам покупать не стал, чтобы не плодить дополнительных элементов в схеме.

    Чем можно ловить 433mhz? Оказывается — тв-тюнером на определённом чипсете. И стоит он сейчас копейки (я взял на авито за 300р) вот такой:

    image

    Заказал к нему отдельную антенку на 12dbi, т к текущая не покрывала весь дом.

    Поскольку я пытался минимизировать управляющие компоненты схемы, было желание затянуть тюнер в свой домашний роутер с Openwrt, который и являлся до этого момента ядром решения умного дома для 1wire, modbus, wifi датчиков/протоколов, но, к сожалению, я исчерпал часть его ресурсов (заканчивается место на встроенной флешке под нужный софт, процессор чем-то догружать — уже будут проблемы с работой сети, а нам ещё 4k смотреть в online:), +на USB уже слишком много всего навешено, что влияет на стабильность сбора данных). Решено постепенно выносить функционал умного дома на внешнее устройство — rarpberry pi (под рукой оказалась одна из первых версий).

    Про софт


    Наигравшись с тв-тюнером в sdr-sharp на стационарном компьютере с windows (попробовав половить чужие рации и переговоры самолётов), стал смотреть, а видит ли «свисток» сами датчики. Да, видит отлично:

    image

    Настройка малинки


    Я выбрал нативный raspbian. Записал на флешку последний образ под mac/linux:

    sudo dd if=2019-07-10-raspbian-buster-lite.img of=/dev/disk2 bs=1048576 conv=sync

    Загружаемся, настраиваем сеть и ssh.

    Далее — ставим на малинку пакеты rtl-sdr, rtl_433:

    sudo apt-get install cmake build-essential python-pip libusb-1.0-0-dev libusb-1.0 python-numpy git
    git clone https://github.com/merbanan/rtl_433.git
    cd rtl_433/
    mkdir build
    cd build
    cmake ..
    make
    make install

    rtl_433 имеет встроенные протоколы, расшифровывающие данные с разных устройств, работающих в диапазоне 433mhz.

    Запускаем rtl_433


    rtl_433 -f 433.9e6

    Опускаем датчики в воду и получаем заветное:

    time      : 2019-09-17 15:04:39
    model     : Smoke detector GS 558                  id        : 16919
    unit      : 1            learn     : 0             Raw Code  : c842e1
    

    Smoke detector? Ок, поставим на оповещение от этих датчиков песню «Smoke on the water»… :)
    А если серьёзно — у нас есть id каждого датчика, по которому в будущем мы будем понимать, где именно у нас протечка (а перекрывать-то будем в любом случае).

    Про датчики протечки


    image image image

    Уже после настройки софтовой части я заметил, что датчики с aliexpress (левое фото) шлют одиночный сигнал при попадании воды на контакты. Плюс одиночный сигнал, если вода перестаёт замыкать контакты. Меня это никак не устраивает (ожидаемое поведение: постоянно слать alarm-сигнал, когда датчик чувствует воду, т к одиночный сигнал может потеряться). Аналогичное поведение наблюдается, если замкнуть контакты проводом. Но что странно — alarm происходит каждые 2-3 секунды, если замыкать контакты руками (кожей). Тут у меня пока два пердположения: либо китайцы напортачили с замерами сопротивления, либо в датчиках есть какой-то другой режим работы, в котором они ведут себя как-то иначе (например спаренный с контроллером), либо есть и другие частоты (пока не нашёл).

    Кстати, отпишите в комментариях, может кто-то работал именно с этими датчиками, можно ли их как-то «научить» слать сигнал о протечке постоянно?

    Я отложил эти датчики, в арсенале был ещё один от rubetek (правое фото) и купленный в леруа: GAL SHW-1005 (среднее фото).

    Поведение rubetek датчика показалось каким-то совсем непредсказуемым (не прогнозируемая реакция «видит воду/не видит»).

    Зато датчик из леруа с ходу показал именно то, что мне и требовалось: есть вода — спамлю в эфир, нет воды — молчу. Единственный его минус — меньший радиус действия, чем у прочих датчиков. Но проблема решена покупкой более чувствительной антенны для приёмника.

    MQTT


    Как же направить вывод rtl_433 в zabbix? Кормить агенту? Отсылать zabbix_sender-ом, анализируя процесс? Может через syslog?

    Тут нужно вспонить, что мой zabbix находится где-то в облаках. И уж точно не стоит перекрывать воду при помощи его триггеров. Пол дома зальёт, пока он примет решение (если вообще будет доступен).

    Хорошая новость — rtl_433 умеет слать информацию по MQTT. Из коробки. При этом данные в брокер отправляются в формате json.

    Значит нужно:

    • Разместить локальный mosquitto брокер (сделаем это на малинке).
    • Сливать инфу в брокер с нужным топиком, чтобы потом это можно было парсить.
    • Подключиться к брокеру локально на малинке и отправлять команды в netping
    • Подключаться к брокеру с места, где будет происходить перенаправление в zabbix ( zabbix-сервер в моём случае тоже является MQTT-клиентом)

    Установка-настройка mosquitto MQTT:


    apt-get install mosquitto mosquitto-clients
    systemctl enable mosquitto
    systemctl start mosquitto

    Отправляем информацию в брокер с указанием id устройства:


    rtl_433 -f 433.88e6 -F mqtt://127.0.0.1,events=/433/[id]

    В mqtt клиенте будем получать примерно следующее:

    
    mosquitto_sub -h 127.0.0.1 -t '#' (подписаться на все топики)
    /433/16919 {"time":"2019-09-18 11:55:29","model":"Smoke detector GS 558","id":16919,"unit":1,"learn":0,"code":"c842e1"}

    Скрипт подключения к брокеру и отправка команды в netping


    Набросал простенький скрипт-клиент MQTT, позволяющий при появлении заданного в конфигурации топика запускать ассоциированный с топиком скрипт. Таким образом можно при срабатывании определённого датчика и появлении информации об этом в «Эфире» (например /433/16919) выполнить какое-либо действие (в случае netping — отправить curl запрос на закрытие крана, см предыдущую статью). Ссылка на скрипт — в конце статьи.

    Перенаправление в zabbix


    Я использовал готовое решение mqtt-zabbix. На его уровне понимаем, в какой item отправить значение (по id).

    В keys.cfg указываем:

    /433/16919,mqtt.ventilation.waterleak::hostname

    где hostname — имя хоста с заведённым item-ом типа «trapper» в Zabbix.

    Важно!!! Имя хоста в настройках должно соответствовать отправляемому имени в скрипте, тип item (элемента данных) — подходить для посылаемых данных (например для json — текст), иначе будете ловить ошибки вида:

    2019-09-18 14:29:48,749 Got response from Zabbix: {u'info': u'processed: 0; failed: 1; total: 1; seconds spent: 0.000055', u'response': u'success'}

    Причём большего дебага (а почему именно failed) от zabbix добиться сложно.

    Настраиваем /etc/mqtt-zabbix/mqtt-zabbix.cfg (указываем ip mqtt брокера и адрес zabbix-сервера).

    Что ещё подключить по 433?


    Да всё что угодно! :)

    Датчики метеостанций


    Пока ковырялся с беспроводными датчиками протечки, случайно словил сигнал внешнего датчика от метеостанции. Выглядело так:

    
    time      : 2019-09-19 10:48:54                    Protocol  : 56
    model     : TFA pool temperature sensor            Id        : 182
    Channel   : 3            Temperature: 19.3 C
    Modulation: ASK          Freq      : 433.9 MHz
    RSSI      : -0.1 dB      SNR       : 35.0 dB       Noise     : -35.2 dB
    
    time      : 2019-09-20 10:57:29                    Protocol  : 12            brand     : OS
    model     : THN132N      House Code: 4
    Channel   : 3            Battery   : OK            Celsius   : 20.00 C
    Modulation: ASK          Freq      : 432.9 MHz
    RSSI      : -0.2 dB      SNR       : 31.5 dB       Noise     : -31.7 dB
    

    Таким образом, бонусом получил возможность мониторинга температуры точек по радиоканалу с отображением в zabbix. Как раз в некоторые помещения не могу протянуть кабель.

    Дверной звонок


    Очень многие радио-звонки работают в том же диапазоне частот ~433mhz. Таким образом, мы можем перехватывать нажатие кнопки звонка (даже не обязательно иметь сам звонок, достаточно только кнопки). Зачем? Например чтобы настроить дополнительное оповещение через СМС/в телеграм/whatever или вывести на монитор изображение с камеры.

    Мною был куплен звонок: Evology QA-688-E RU.

    Чтобы кнопку звонка увидел rtl_433, нужно активировать «тестовые» протоколы, например запустив с опцией «G» или указав конкретный дополнительный протокол, заодно добавим вывод информации о протоколе и частоте:

    rtl_433 -f 433.9e6 -G -M protocol -M level -F mqtt://127.0.0.1,events=/433/[id] &

    Получим в MQTT:

    {"time":"2019-09-30 10:57:00","protocol":72,"model":"RF-tech","id":0,"battery":"LOW","temperature_C":0,"button":0,"mod":"ASK","freq":433.84822,"rssi":-3.5981,"snr":33.77488,"noise":-37.373}

    Тут можно заметить id=0. При этом у меня оказалось несколько устройств, определяющихся как RF-tech. У всех у них id был равен 0. В итоге все устройства в zabbix отображаются как один item. Различить то, какое именно устройство сработало, можно только по частоте.

    Частоту вытаскиваем в отдельный зависимый item: mqtt.outside.doorbell.freq с предобработкой JSON-ом по $.freq (zabbix это умеет с 4-ой версии).

    На этот item делаем триггер с выражением:

    {HOME_PI:mqtt.outside.doorbell.freq.last()}>433.8 and {HOME_PI:mqtt.outside.doorbell.freq.last()}<433.81 and {HOME_PI:mqtt.outside.doorbell.freq.nodata(30)}=0

    Т.е. если вдруг появилось значение в общем item mqtt.outside.doorbell.freq (nodata) и частота находится в заданном диапазоне между 433.8 и 433.81, можем делать вывод, что нам звонят (и например продублировать звонок в СМС).

    Датчики открытия двери/окна


    У меня в наличии есть датчик «проникновения» от rubetek. Посылает следующее:

    {"time":"2019-09-30 14:11:28","protocol":86,"model":"Smoke detector GS 558","id":12262,"unit":16,"learn":0,"code":"e5fcd0","mod":"ASK","freq":433.85021,"rssi":-3.99241,"snr":33.38058,"noise":-37.373}
    
    закрытие двери:
    {"time":"2019-09-30 14:11:28","protocol":68,"model":"Kerui Security","id":46074,"cmd":7,"state":"close","mod":"ASK","freq":433.85021,"rssi":-3.99241,"snr":33.38058,"noise":-37.373}
    
    открытие двери:
    {"time":"2019-09-30 14:11:21","protocol":68,"model":"Kerui Security","id":46074,"cmd":14,"state":"open","mod":"ASK","freq":433.85005,"rssi":-11.0148,"snr":25.1088,"noise":-36.1236}

    Как только последний радиодатчик был добавлен в zabbix, захотелось всё переделать именно на MQTT. Удобная каталогизация, можно topic-ах определять и место размещения и типы устройств. Получаешь общий эфир всех событий.

    1wire to MQTT


    Хочу чтобы всё было в MQTT, как минимум для однотипности реализации. Хочу получить общий «эфир» событий и общий подход в реакции на эти события. Безусловно, zabbix решает задачу реакций, и я оставляю на нём оповещения. Но управление хочется сделать более легковестным, приближенным к системе и «эфиру».

    Готовые решения ретрансляции состояний датчиков из 1wire сети в MQTT существуют, но мне не подошли. Готовые решения на node либо тащат за собой кучу зависимостей, либо съедали весь процессор малинки. Часть решений из топ 10 в поиске гугла заброшено авторами, часть поддерживают только температурные датчики. Ещё есть класс gateway-ев, собирающих информацию через интерфейс gpio. Всё это мне не подошло.

    У меня есть смонтированная псевдо-файловая система с 1wire устройствами в /mnt/1wire, именно оттуда я хочу брать всю необходимую информацию. Для этого достаточно сделать простой однострок на bash, пересылающий данные через mosquitto_pub по каждому из датчиков. Однако появляются вопросы запуска этих скриптов (по крону, загонять в какой-то демон?), нормального представления данных (получение того-же json-а), добавления нового датчика и т п. Чем дальше развивалась мысль — тем больше костылей рождалось. Оказалось проще написать под эту задачу yet another owfs to mqtt шлюз.

    Есть файлик конфигурации, в который нужно заносить id датчиков и те файлы из fuse.OWFS, которые мы хотим паблишить в mqtt.

    На выходе в mqtt получается такая json-ка:

    /1wire/28.0425260a0000 {"type": "DS18B20", "temperature": "30"}
    /1wire/28.bf16270a0000 {"type": "DS18B20", "temperature": "7.9375"}
    /1wire/26.da2f71010000 {"temperature": "25.2812", "IAD": "1", "CA": "0", "VAD": "0.91", "VDD": "4.59", "type": "DS2438"}
    /1wire/28.48b3010b0000 {"type": "DS18B20", "temperature": "40.5625"}
    /1wire/1d.6a9306000000 {"type": "DS2423", "counter.B": "9", "counter.A": "9219"}
    /1wire/28.61cc260a0000 {"type": "DS18B20", "temperature": "12.5"}

    Добавляем в автозапуск, ставим интервал поллинга. Задача решена.

    Ссылки


    github.com/merbanan/rtl_433 — тула для декодинга радио-протоколов
    github.com/kylegordon/mqtt-zabbix — MQTT в Zabbix
    github.com/unlo/1wire2mqtt — 1wire в MQTT, MQTT клиент, позволяющий запускать скрипты при появлении топика
    Поддержать автора
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

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

      0
      Набросал простенький скрипт-клиент MQTT, позволяющий при появлении заданного в конфигурации топика запускать ассоциированный с топиком скрипт. Таким образом можно при срабатывании определённого датчика и появлении информации об этом в «Эфире» (например /433/16919) выполнить какое-либо действие

      Очень рекомендую посмотреть на NodeRed. Это система предназначенная как раз для таких автоматизаций. Имет поддержку MQTT, конфигурируется с помощью блоков и связей между ними. Можно описывать логику на javascript, если не хватает стандартных блоков. Очень мощная штука для автоматизации умного дома.
        0
        Да, оно мне попалось при решении задачи. Но показалось требовательным к ресурсам.
        Может быть и ошибаюсь, попробую как-нибудь на досуге поставить на малинку :)
          –1
          NodeRED можно и на старом Андроид-фоне или таблетке запустить в Termux -е (Termux работает начиная с 5го Андроида). Но если есть малинка — тогда на ней конечно.
        0

        А если к дому подходит хакермошенник и запускает ложные датчики протечки и т. д.
        Вода перекрывается, сигнализация срабатывает, дом пляшет.
        Это возможно?

          0
          Датчики воды срабатывают только при обнаружении протечек и просто так в эфир не спамят. Поэтому перехватить сигнал (понять протокол и id) можно, но нужно сначала дождаться самой протечки, чтобы определить все неизвестные.
          Но имея представление о системе в целом и передатчик с возможностью отправки нужных пакетов — перекрыть воду в радиусе действия — действительно можно.
          Правда я не испытываю по этому поводу никакого беспокойства. Это не открытие ворот/замков/снятие сигнализаций.
          +1
          Сделал что-то подобное на основе датчиков ксяоми (протокол Zigbee). Есть датчики движения, утечки, температуры. Для приема сигнала использую CC2531 USB stick (www.zigbee2mqtt.io). На raspberry запускается прога на nodejs с этого же сайта, которая читает USB stick и шлет инфу на mosquito. Небольшой питоновский скрипт, используя библиотеку paho-mqtt, считывает все эти сигналы, обрабатывает, и шлет в телеграм бот.

          Но воду не перекрывает)))

          Нашел странную особенность датчиков. Если сигнал от USB stick слабый (далеко от него находятся), они могут отключиться через неделю работы. А активировать их снова нужно вручную…

          Поиграю с 433, может стабильней работать будет

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

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