"Мне нужен не умный дом, мне нужен послушный дом" - / из Интернета /

Хотя концепция "умного дома" в полном объёме мало кем используется в жизни (и ещё меньше, кем самостоятельно реализована), отдельные его компоненты - разного рода датчики, умные розетки, камеры и прочее, с доступом через "облако" - давно не редкость. До покупки дачи меня всё это слабо волновало - в квартире я вполне обходился механическими выключателями и градусником на окне. Тем не менее, необходимость следить за состоянием загородного дома вынудила заняться этим вопросом и я пошёл по самому простому пути с MiHome и кучей датчиков. Конечно, в таком решении хватает проблем - баги, которые не устраняют годами, датчики для разных регионов, периодически [кратковременно] отваливающееся облако. В целом, однако, всё это удовлетворительно работает уже не первый год, технического интереса не представляет и рассказать я хотел не об этом.

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

  1. Ситуация длительного, либо многократного отключения электричества (в теории - на 72 часа, хотя пока максимум было около 48) и разряда аккумуляторов бесперебойника (инвертора), который у меня распространяется на все маломощные потребители.

  2. Пропадание Интернета - используемое оптоволоконное подключение подвержена тем же проблемам с ветром, снегом, деревьями, что и электричество.

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

Воображение уже рисует комментарии с вопросами "А почему было не поставить Home Assistant?". Ну, изначально я так и хотел. Даже купил Raspberry Pi 4B, накатил HA и убедился, что с парой каких-то датчиков это всё работает. Однако, в процессе настройки я осознал, что такое решение - скорее замена MiHome (который меня, в целом, устраивает). Для резерва на случай временной аварии, HA - явный перебор. Причём, перебор не столько в плане функционала (это ещё ладно), а в плане сложности - достаточно уже одного того, что это всё работает поверх ОС и через кучу драйверов, которые неизвестно как и в какой ситуации себя будут вести. Мне же надо как можно тупее, проще, без лишних прослоек. И ещё важно, чтобы поменьше потребляло.

Поскольку я в прошлом немного игрался с STM32 (чисто по-любительски), меня пару раз посещала мысль реализовать нужный функционал на базе какого-нибудь микроконтроллера из этой линейки. Но, честно говоря, объём работ меня слегка пугал. Особенно с учётом, что чипы со встроенным Wi-Fi/BT у них появились сравнительно недавно и dev boards с ними стоят как-то негуманно. Конечно, краем уха я слышал про ESP8266 / ESP32, но оно у меня вызывало нездоровые ассоциации со словом Arduino (забегая вперёд - зря).

В итоге, наткнувшись в очередной раз на какую-то страничку про ESP32, я вчитался повнимательнее и с удивлением узнал что, оказывается, на маленьком недорогом модуле есть одновременно и BT и Wi-Fi и достаточно портов под всё, что мне надо. Это сподвигло меня наконец заняться решением вопроса - вдобавок ещё погода такая мерзкая была, нос из дома высовывать никакого желания. У кого не хватает мотивации что-то написать, рекомендую - переезжайте в Питер.

По-правильному (а ещё, чтобы не называли ардуинщиком) следовало конечно поставить ESP-IDF но, посмотрев наискосок, как это выглядит - мне стало лень. Опять настраивать vscode под очередную платформу и копаться в cmake файлах - не хочу. Хочу решить конкретную задачу. А самореализовываться переставлением битиков и копанием в конфигах предпочитаю на чём-нибудь другом.

Короче, дав слабину, поставил Arduino IDE. Это не VSCode конечно - заметно, что авторы сами не пользуются тем, что разрабатывают, однако, если честно, я ожидал худшего. Достаточно быстро удалось по-отдельности убедиться, что через Wi-Fi данные отправляются, информация с разных датчиков снимается (для обучения удобно использовать симулятор ESP32 - wokwi. Там даже Wi-Fi имитируется).

Поначалу я себе представлял задачу предельно просто - хотел ограничиться замером температуры и напряжения до и после ИБП (инвертора), а принимать и показывать информацию простеньким скриптом на PHP. Однако, в процессе того, как я разбирался с ESP32, аппетиты росли прямо на глазах. В результате минимальные требования к устройству изменились. Мне захотелось:

  1. Получения данных о температуре внутри устройства, рядом с устройством, за стенкой от устройства (на улице). Для этого я выбрал onewire датчики DS18B20 (один на плате, два с проводами 1-2 метра).

  2. Получения данных о температуре и влажности рядом с трубами на полу в другой комнате и на полу рядом с аккумуляторами ИБП - в третьей комнате (куда проводами уже не дотянуться). Для этого я использовал популярные bluetooth датчики LYWSD03MMC, предварительно перешитые другим firmware.

  3. Измерение напряжения в сети 220в до и после ИБП при помощи модулей ZMPT101B (там трансформатор с усилителем).

  4. Определение наличия человека в комнате, где расположено устройство. PIR датчик HC-SR501.

  5. Определение замыкания/размыкания геркона (установленного на дверь). Геркон с магнитом подключён непосредственно к порту МК.

  6. Реле, которым можно управлять, меняя ответ сервера на запрос устройства.

Схема
Схема

Измерения периодически, раз в несколько минут, планировалось отсылать через Wi-Fi на сервер, обычным POST запросом с json содержимым (и да, я знаю о существовании MQTT).

Для сети Wi-Fi используется отдельный мобильный роутер ZTE MF910 с симкартой на самом дешёвом тарифе для "интернета вещей".

И устройство и роутер питаются по USB от аккумулятора, который постоянно подзаряжается от блока питания включённого в 220 в. Таким образом, получается своего рода второй независимый ИБП, о котором надо сказать особо.

Дело в том, что обычный среднестатистический power bank не может без вмешательства оператора работать в режиме ИБП - т.е. обеспечивать сквозное питание устройства с переключением на внутренний аккумулятор при пропадании питания. Тем не менее, некоторые всё же могут, причём информация об этой возможности не скажу, что легко доступна - думаю, производители не особо заинтересованы её афишировать, т.к. подобный режим для литиевых аккумуляторов не слишком полезен.

Сначала я купил power bank под названием Soshine E3S. Между прочим, довольно интересное и неплохое устройство. По-видимому, больше не производится, но найти в продаже можно.

Нужный мне режим работы оно обеспечивает (более того, там на индикаторе прямо так и пишется про "UPS mode"). Однако, уже где-то в середине разработки я случайно увидел в продаже нечто под названием "UPS Power Module (B) для Jetson Nano" и решил, что это более удачный вариант. Особенно мне понравилось, что оно умеет отдавать по I2C информацию о состоянии ИБП (там внутри INA219) - пустяк, а приятно. Soshine остался в качестве резервного варианта, тем более что и там и там используются четыре стандартных аккумулятора 18650.

Делать печатную плату я не стал, иначе бы проект затянулся на совсем неопределённое время - взята обычная макетка с отверстиями и соединения выполнены проводами из витой пары.

В плане корпуса меня волновало следующее:

  1. Если всё это добро (особенно, аккумуляторы) воспламенится, это не должно привести к пожару

  2. Внутрь корпуса должны влезать вышеупомянутый ИБП на 4x18650, само устройство и Wi-Fi-GSM роутер

  3. При этом содержимое не должно слишком переохлаждаться и слишком перегреваться

  4. Корпус, понятно, не должен быть металлическим, чтобы роутер работал

  5. Если сверху потечёт вода (когда падающее дерево или метеорит в дождливую погоду пробьёт крышу), внутрь она попасть не должна

В итоге была взята большая пластмассовая распределительная коробка 150 x 110 x 70 и между ней и стеной дополнительно проложен лист огнеупорного гипсокартона.

Устройство в сборе, на стене (ИБП позади платы, на колонках)
Устройство в сборе, на стене (ИБП позади платы, на колонках)

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

Алгоритм первоначально был незатейливым - каждые N минут снимаем показания температуры и напряжения и сразу шлём их на сервер. Что касается геркона и PIR датчика, то их срабатывание вызывает обработчик прерывания, в котором соответствующий датчику флаг устанавливается в true и его значения отсылается в своё время, вместе с температурой и напряжением.

Первым делом я сделал отсылку тестового json'а POST запросом по Wi-Fi с использованием библиотеки WiFiClientSecure (Secure - это с поддержкой SSL. Кстати, если лень заморачиваться с сертификатом, можно это решить через client.setInsecure() ).
JSON можно было бы сформировать руками, но мне что-то приспичило сделать аккуратно, для чего я выбрал ArduinoJson v7.
Кроме, собственно, отсылки данных, я поначалу добавил ещё синхронизацию часов по NTP, чтобы отсылать время. Но потом убрал, т.к. практической пользы эта информация не несёт.

Вторым по значимости я счёл получение информации от BT датчиков. И с этим пришлось повозиться. Задумка была такой - сканируем всё BLE устройства, которые отзываются, из них отбираем те, у которых serviceUUID = 0x181a (Temperature and Humidity sensor). Таким образом, для добавления нового датчика не потребуется трогать устройство - данные будут поступать со всех доступных.

Обычно в такой ситуации используют библиотеку BLEDevice. С одной стороны, она безусловно работает. Но вскоре обнаружилось, что при опросе в цикле начинает течь память. Сначала думал, что я тормоз (ввиду минимального опыта программирования на C, эта версия казалась наиболее правдоподобной), но через пару дней возни наткнулся на жалобы других людей на аналогичные симптомы в очень похожей на мою ситуации. В итоге перешёл на библиотеку NimBLEDevice (за основу взят этот пример) и, о чудо, память течь перестала!

Я уже было обрадовался и оставил код несколько дней настояться. getFreeHeap() отсылался в каждом HTTP запросе и я видел, что с памятью проблем нет. Но, где-то в середине вторых суток сканирование вдруг стало возвращать 0 устройств и сопровождаться ошибкой "scan_evt timeout". RESET помог, но через день или два история повторилась снова. Вновь углубившись в гугленье, снова обнаружил себя в компании таких же несчастных. Причём, их было намного больше, чем предыдущих (с текущей памятью). Насколько мне удалось понять, проблема тут серьёзнее и уже не в библиотеке, а в реализации BT стека в самом ESP32. Проблеме не один год - проявляется она не у всех (вероятно, мало кто в цикле непрерывно сканирует BLE устройства, да ещё сутками). В итоге, вопрос был решён примитивным if (count==0) esp_restart();

Кстати, если нужно получать имена устройств, setActiveScan должен быть вызван с true.

Отдельно упомяну, что когда я объединил сканирование BLE с отправкой данных по WiFi, результат поначалу не влез в прошивку (у меня ESP32 с 4MB Flash - насколько я знаю, это максимум из широкодоступного). Это решается так: Tools / Partition scheme / No OTA (large app).

С остальными датчиками, которые подключены непосредственно к портам ESP32, проблем не возникло - это известные модули и в сети есть множество примеров. Поскольку у ESP32 оставались ещё незадействованные порты, я приделал реле, которое включается, если на POST запрос сервер возвращает {"relay":true}. Аналогичным образом сделано изменение периода опроса и принудительный сброс устройства.

В первых версиях фиксировались данные с PIR датчика и данные с геркона. Тем не менее, спустя какое-то время я отказался от геркона (добавив вместо него второй PIR датчик). За этой, казалось бы, мелочью, скрывается довольно много потраченных нервов и времени. Фиксация замыкания простого контакта была последним, от чего я ожидал сложностей, а вышло всё ровно наоборот. Поначалу ничто не предвещало - на столе всё замечательно стабильно работало (у меня был настроен INPUT_PULLUP на GPIO25, повешен обработчик прерываний на CHANGE для этой ноги). Первые звоночки, в прямом и переносном смысле, появились, когда я повесил уже отлаженное устройство на стену, воткнув в него все датчики, включая подачу 220в на трансформаторы. Изредка я стал замечать ложные срабатывания. Уж не знаю, сыграл ли роль провод к геркону длиной несколько метров или присутствие трансформаторов 220в прямо рядом с ESP32. Отлаживать уже установленное устройство на даче мне было лень и я, до поры до времени, махнул на эту проблему рукой - тем более, эти датчики были скорее приятным бонусом, а не основным функционалом.

Спустя несколько недель у меня появилось нездоровое желание отказаться от прерываний (на которых висел этот геркон и PIR датчик) и сделать, чтобы устройство всё время спало и просыпалось:

а). через заданные промежутки времени, чтобы отправить данные о температуре и напряжении;
б). немедленно, при замыкании/размыкании геркона и сигнале от PIR датчика, отправляя данные вне очереди.

Заодно я отказался от первоначальной схемы работы с WiFi, когда соединение устанавливалось один раз и возобновлялось лишь при обнаружении разрыва соединения - в новом варианте соединение заново устанавливалось каждый раз перед отправкой данных (ну, в случае со сном иначе и быть не могло).

С deep sleep я заморачиваться на стал, т.к. при этом стирается память и пришлось бы возиться с сохранением данных в RTC. Остановился на light sleep и ext1 режиме, позволявшим просыпаться при возникновении высокого уровня на любой из заданных ног. Примерно так:

esp_sleep_enable_timer_wakeup(requestPeriod * 1000000); 

esp_sleep_enable_ext1_wakeup( GPIO_SEL_xx | GPIO_SEL_yy , ESP_EXT1_WAKEUP_ANY_HIGH );  

esp_light_sleep_start();  

[...спим....]

gpio_wakeup = (log(esp_sleep_get_ext1_wakeup_status()))/log(2) ;

[...проснулись и выяснили, за какую ногу нас дёргали (или это просто будильник зазвонил...]

Первое, с чем я столкнулся - просыпаться можно только если нас дёргают за вполне определённые ноги (присоединённые к RTC). PIR датчик у меня на такой и висел, а вот геркон нет. Пришлось всё вытаскивать и перепаивать.

Дальше обнаружилось, что сигнал на ноге появляется даже если просто подходишь к столу. Т.е. она явно floating, несмотря на установленный pinMode. Изучение вопроса показало, что в спящем режиме внутренние резисторы не работают. Ладно, припаял снаружи - всё стало срабатывать четко, НО - только если читать ногу через digitalRead(). Если же использовать esp_sleep_enable_ext1_wakeup() то, такое впечатление, что за эту ногу его дёргают непрерывно. Причём, что интересно - esp_sleep_get_ext1_wakeup_status() возвращает разную ерунду - т.е. либо 0, либо какие-то странные значения. Но при замыкании геркона - возвращает верное значение. Я уже изолировал всё это в отдельный исходник, выключил просыпание по таймеру, оставил только просыпание по этой одной ноге (GPIO26), ничего не изменилось - происходит то чего, по идее, в принципе не может происходить.

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

Тут надо признаться, что всё эти пляски со сном были, по большому счёту, излишними - общее потребление связки "устройство + wifi роутер" упало совсем незначительно. Т.е. до переделки это всё работало от четырёх 18650 38.5 часов, после добавления сна - 40.3 часа.

Потребление роутера около 0.15A (постоянно). Что касается устройства, то до переделки на сон потребление выглядело так (увеличение тока - это отправка данных):

После - не было возможности измерить.

Сервер

Поначалу я набросал "на коленке" пару простых PHP скриптов, один из которых принимал json от устройства и клал его в postgres базу, а второй выводил данные в табличках. Убедившись, что всё работает плюс-минус как планировалось, решил заморочиться с чем-то более правильным и красивым (да, я знаю что лучшее - враг хорошего).

Как сказано выше, данные хранятся в Postgres базе. Всё достаточно примитивно - в основную табличку пишется общая информация по каждому POST запросу от устройства - номер устройства, состояние аккумулятора, WiFi RSSI, heap (чтобы видеть, не течёт ли память) и т.п.

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

Поскольку предполагается, что в будущем устройств будет больше одного, и может быть не только на даче, предусмотрены табличка st_locs для мест и st_srcs для устройств (для упрощения отладки они в таблицах пока продублированы). В st_srcs для каждого устройства есть столбцы для управления - время между отсылками данных, состояние реле и прочее.

Сервер реализован на nodejs / express и наружу торчат три endpoint'a:

'/graphql' - Данные для веб приложения (которое рисует виджеты/графики и имеет интерфейс для передачи настроек устройству) сервер отдаёт в виде graphql с использованием postgraphile.
По сути, postgraphile даёт возможность делать запросы к postgres через graphql. Это удобно - одной строчкой app.use(postgraphile()) получаем почти весь нужный функционал.
Причём, queries и mutations он создаёт из postgres схемы сам и автоматически обновляет их при, скажем, переименовании таблиц или добавлении в них столбцов.
Правда, этого достаточно только для типовых случаев вида "получить строки из таблицы A и связанных с ней таблиц B и C где поле x = значение, с сортировкой". Если надо добавить или изменить строку в таблице по заданому id, это тоже типовой случай. А вот если условие чуть посложнее или надо поместить значение не в одну таблицу, а ещё и в связанные с ней - тут уже придётся написать хранимую процедуру, которую postgraphile тоже автоматически увидит и позволит использовать в виде custom mutation с именем соответствующим этой функции.

конструктор запросов и ответ (справа) в отладочном интерфейсе Postgraphile
конструктор запросов и ответ (справа) в отладочном интерфейсе Postgraphile

'/api' - Данные от самого устройства приходят сюда в виде json. Формировать graphql запросы на esp32 мне показалось излишне замороченным (хотя, сейчас я уже начал в этом сомневаться). В результате, нужно было либо из этого обработчика как-то обращаться к postgraphile (что довольно нетривиально), либо использовать обычные SQL запросы через pg. Я пошёл наиболее простым - вторым путём.

Сначала полученные данные кладутся в базу, затем оттуда, из st_srcs, достаются параметры, которые мы хотим передать устройству в ответ (нужно ли его сбрасывать, нужно ли включить реле, желаемое время между передачей нам данных).

'/' - Последняя функция nodejs сервера - отдавать html/css собранного react приложения. Просто appWeb.use(express.static("public"));

Веб приложение

Здесь можно видеть, в том числе, разряд ИБП и два отключения устройства
Здесь можно видеть, в том числе, разряд ИБП и два отключения устройства

Достаточно типовой подход с использованием React, MUI, Apollo Client и Recharts.

Поскольку данные поступают от устройства через заданные промежутки времени, нет смысла заморачиваться с subscription, web sockets и прочим. Apollo client просто периодически (в два раза чаще, чем они приходят от устройства на сервер) забирает данные за последние N часов.

Для каждого датчика показываются виджеты с иконкой, значением параметра и описанием. Плюс куча графиков изменений этих параметров. На самом деле их больше, чем нужно (как пошутил знакомый: "уровень мониторинга - АЭС"), но мне тут помимо прочего важно было оценить корректность работы устройства.
В любой точке графика наведением мышки можно смотреть численные значения.

Для каждого виджета определены диапазоны значений, считающихся нормой. При выходе из этих диапазоовы на виджете появляется красная отметка. Если данных от устройства долго (дольше установленного периода отсылки информации) нет, на графиках отмечаются соответствующие места, с указанием пропущенного времени.
Пунктирность линий от BT датчиков связана с тем, что не всегда в момент сканирования датчики выдают в эфир свою информацию.

Исходники (клиент, сервер, прошивка) - https://github.com/petersobolev/dsensors

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

Некоторое беспокойство у меня вызывает температура внутри корпуса устройства. Если зимой, как показала практика, она почти наверняка будет выше нуля, то сейчас (конец мая) я уже однажды фиксировал максимальное значения +32 (хотя обычно не более +27). В жаркую летнюю погоду температура может стать проблемой для аккумуляторов, решить её будет непросто. Если сделать отверстия, зимой это всё может переохладиться. Т.е. по-хорошему нужен клапан перекрывающий вентиляционные отверстия. Не хочу об этом пока думать.

Из возможных усовершенствований:

  • Сделать больше одного устройства (например, добавить мониторинг расхода воды и общей потребляемой домом мощности)

  • Использовать поляризованные реле, т.к. сейчас замкнутое реле будет потреблять энергию и, соответственно, греть устройство

  • Вместо ZTE роутера использовать отдельный GSM модуль - таким образом избавиться от идиотской передачи данных по WiFi на расстояние полтора сантиметра и существенно увеличить время автономной работы. Очень сооблазнительно, но у меня эта WiFi сеть используется ещё и как резервная, а не только лишь для этого устройства.

  • Разобраться всё-таки со стабильным определением срабатывания геркона. Может опторазвязку сделать?

  • Сделать, чтобы веб приложение забирало с сервера только новые данные (особого смысла нет, т.к. весь пакет, чтобы увидеть полные данные за сутки занимает около 100кб)

  • Сделать уведомления на email или telegram о выходе значений за пределы диапазонов

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

Эпилог

Хотя проект делался исключительно для себя, пара проходящих мимо людей высказались в духе: "А почему бы это всё не продавать?", "А мне такое можешь сделать?".

Никакой новизной и оригинальностью мои решения, ясное дело, не отличаются, однако, несмотря на это, вопросы вполне логичны. Дело в том, что среднестатистическому человеку не нужны решения вида MiHome, HA и подобные им - с кучей беспроводных датчиков, выключателей и мрачно замороченных настроек (вдобавок, не отличающиеся стабильной работой).
Задача, которую волнует большинство - иметь представление о трёх-четырёх основных параметрах и смотреть статистику / получать уведомления по их изменениям.

В этом плане идеальное устройство должно выглядеть как единый небольшой модуль, который втыкается в 220в, содержит внутри себя аккумулятор, WiFi или GSM, несколько датчиков, камеру с IR подсветкой, пару разъёмов для подключения внешних OneWire термометров и одну или две управляемых розетки 220в. Всё. Послушный дом мечты.

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

В IT все привыкли к такому положению вещей и воспринимают это как данность - кто-то берёт себе фиксированный IP, кто-то колдует с DDNS, поднимают свои сервера и прочее. Обычные же люди таких слов не знают и даже не представляют, что такая проблема вообще есть. Они покупают, скажем, камеру видеонаблюдения или умную розетку и не догадываются, что без какого-то сервера (чаще всего, где-то в далёком Китае) всё это работать не будет в принципе.

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


  1. dsoastro
    25.05.2024 11:59

    У меня основное решение для мониторинга дачи - самописный телеграм бот бегающий на 2 raspberri pi. К одному подсоединены датчки к GPIO, а другому датчики zigbee (проект zigbee2mqtt). В качестве запасного варианта использую готовую sms сигнализацию с аккумулятором. Она всегда сможет измерить температуру батарей и скажет есть ли электричество


  1. frozzzen
    25.05.2024 11:59

    Кто-то покупает банальную GSM - сигнализацию с двумя симкартами и свинцовым аккумулятором. Сигналы типа "пожар", "потоп" и "отключение электроэнергии" поступают в телефон пользователя посредством банальных СМС. Вполне себе дачный вариант.


    1. frog Автор
      25.05.2024 11:59
      +1

      Проблема в том, что этого часто недостаточно. Личный опыт уже есть и суть в том, что нужно существенно больше информации, чтобы понять причины и прогноз. Ну т.е. само по себе отключение электроэнергии - ничего не значит, из-за этого не надо всё бросать и срываться ехать - ведь рано или поздно электричество включат.
      А вот когда в связи с этим отключением замёрзнут трубы - это зависит как от динамики изменения внутренней температуры, так и температуры на улице. Причём, скажем на кухне она может меняться совершенно не так, как в ванной (потому что на кухне ввод трубы в дом и там холод проникает быстрее). Ну и т.д. Всё не так просто - на практике оказывается, что ситуации бывают очень странные (типа самопроизвольного срабатывания УЗО один раз за три года из-за грозы!).


      1. frozzzen
        25.05.2024 11:59

        Теплоизоляция трубы на вводе в дом?

        Материальное исполнение ввода гофротрубой из нержавеющей стали?

        Греющий кабель?

        Электромагнитный клапан аварийного сброса воды по температуре вводной трубы?


    1. DieSlogan
      25.05.2024 11:59
      +2

      Да, но мы же на Хабре. Тут люди любят делать что-то своими руками


  1. DieSlogan
    25.05.2024 11:59
    +1

    Если будет совсем выворачивать от Arduino Studio, то можно поставить в связке VSCode + PlatformIO.

    По мне, так это единственный вменяемый вариант работы с ESP32, если дополнительно требуется Arduino Core.

    Для встраивания в Home Assistant есть экзотические варианты типа ESPHome (https://esphome.io/) . По опыту советую что-то очень простое делать, иначе замучаешься в YAML-е не правильный отступ искать.

    Есть также интересные проекты, вроде языка Toit (https://toit.io/). С дровами вроде порядок. Из особенностей, он как бы ставит на ESP32 свою виртуальную машину и дальше само приложение очень бистро загружается и вполне себе быстро работает. У меня самого пока руки не дошли поиграться с этим.

    А для любителей dotnet есть dotnet nano framework (https://www.nanoframework.net/) . Тоже виртуалка, но пишем на CSharp. Также всё неплохо с драйверами и поддержка не только ESP32.


    1. GennPen
      25.05.2024 11:59
      +4

      Для встраивания в Home Assistant есть экзотические варианты типа ESPHome (https://esphome.io/) . По опыту советую что-то очень простое делать, иначе замучаешься в YAML-е не правильный отступ искать.

      Почему экзотические? Вполне приличный проект, который отлично интегрируется в Home Assistant. Еще плюсом в использовании Home Assistant в том, что можно сделать различные автоматизации.

      У самого есть нечто подобное на Home Assistant, который крутится на простеньком мини-пк, который подключен к мини-UPS на 12в.

      А еще можно на Zigbee сделать свои датчики например на PTVO.


    1. fio
      25.05.2024 11:59

      в Home Assistant есть экзотические варианты типа ESPHome

      Очень понравился ESPHome низким порогом входа. Перевел некоторые свои устройства на эту платформу, хотя до этого долго писал свою прошивку для них.

      Сложную логику можно вынести на уровень HomeAssistant.


  1. vazir
    25.05.2024 11:59
    +3

    Вместо HA который имеет в 10 раз больше аналитики и esphome которые оттестированы и работают годами без нареканий вы нагородили кучу вермишеле кода, пользуете чьето облако и считаете это решение надежным...


    1. frog Автор
      25.05.2024 11:59

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


  1. SpiderEkb
    25.05.2024 11:59

    Основная сложность в том, что Интернет, увы, так устроен, что просто передать несколько байт между двумя компьютерами, которые к нему подсоединены - гигантская проблема.

    На самом деле нет.

    Если на вашем "сервере" белый статический IP (т.е. к нему легко достучаться извне), то никакой проблемы тут вообще нет. Можете написать свой TCP-сервер (это несколько десятков строк кода в самос простом случае), можете просто использовать UDP. Вам же не надо огромные объемы там прокачивать. Достаточно коротенькие пакеты - запрос состояния устройства, получение ответа на запрос.

    Поверьте, опыт есть - в своей время занимался разработкой системы мониторинга инженерного оборудования зданий. Средняя по размерам диспетчерская - это несколько десятков контроллеров верхнего уровня, на каждом из которых висит 5-30 контроллеров нижнего уровня (и на каждом по несколько десятков конечных устройств разных типов). Каждый контроллер занимается опросом того, что к нему подключено и передает информацию ("сигналы") о событиях тому, к чему подключен он сам. Сигнал - короткая посылка из адреса источника, кода события и (при необходимости) данных о событии. На нижних уровнях работаем по RS-485, контроллер верхнего уровня на диспетчерскую работает по UDP - простой в реализации и легкий протокол.

    На диспетчерской работает "микроядро" - сервис куда прилетают сообщения от контроллеров по UDP и у которого есть TCP сервер к которому подключаются интерфейсный клиенты (это уже визуализация того, что происходит в системе). Никаких "браузерных решений", никаких http. Никаких облаков. Визуализацией занимается клиент. Вся коммуникация крайне простая. Если ограничится масштабами одного дома - вообще делать нечего.

    Для любителей MQTT есть промышленные LTE роутеры типа той же Teltonika с поддержкой MQTT в режимах subscriber/publisher/bridge (правда, цена не обрадует) - фактически получите собственное "облако". Да еще с возможность посылать смс/e-mail уведомления о событиях разных.

    Основная проблема тут - получить белый статический IP.

    В условиях деревенского дома проблемы будут другие. Само по себе отключение электричества не беда. У меня в доме (правда, ПМЖ) стоит вот такое

    3кВА инвертор (чистый синус) + 2 АКБ по 12В 100Ач (на вход инвертора идет 24В, АКБ последовательно, емкость можно наращивать, подключая нужно количество пар АКБ - 2, 4, 6...) У меня через инвертор запитан насос в скважине (750ВА, работает через гидроаккумулятор т.е. там периодическое кратковременное включение для поддержки давления в ГА), компрессор в ЛОС (60ВА) и розетки в кабинете (ноутбуки, внешние мониторы, роутер, настольная лампа и т.п.) В нормальном режиме (работаем в кабинет, иногда в туалет, руки помять и т.п.) 8-10 часов даже на двух АКБ оно выдерживает легко. Добавить еще пару АКБ и убрать насос и компрессор (только компы) - несколько суток легко выдержит.

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


    1. frog Автор
      25.05.2024 11:59
      +1

      Если на вашем "сервере" белый статический IP

      У меня есть всё, что необходимо. Но это потому, что я в этой сфере работаю и в курсе ситуации.
      Фраза же из эпилога относилась к обычным людям, которые в теории могли бы купить подобное устройство (я там специально ведь это подчеркнул). Обычный человек не знает, что такое "сервер", "статический IP" и прочее. Поэтому он будет вынужден к устройству покупать ещё и услугу, надёжность которой от него не зависит. Нельзя просто продавать устройство - необходимо продавать ещё и услугу. В этом суть.

      Что касается электричества, я в статье подчеркнул, что важна автономность этого устройства. У меня в доме есть инвертор, AGM аккумуляторы (2 x 200) - они довольно долго обеспечивают 220в. А теперь представьте - допустим, в дом влезает вор. Первое его действие - отключить всё электричество (знаю, о чём говорю - уже сталкивался). Вы никак не спрячете здоровенные аккумуляторы и инвертор (с работающим вентилятором!). А моё устройство просто никто не заметит - оно будет продолжать отсылать информацию если вырубить вообще всё, похожее на электричество. Есть и другие ситуации. Моё решение - оно не просто так, я исходя из реального опыта.

      Насчёт питания вышек сотовой связи - за три года в моей деревне (Ленобласть) я фиксировал пропадание сотовой связи один раз, примерно на час. И это не было связано с электричеством (скорее всего, они что-то ремонтировали). Там, насколько я знаю, после разряда аккумулятора включается дизель. На сотовую связь много что завязано - например, работоспособность охраны объектов, поэтому они к этим вопросам очень серьёзно относятся.


      1. SpiderEkb
        25.05.2024 11:59

        Ну я из своего опыта говорю. В первую очередь - мониторинг большого количества разнородных устройств (десятки тысяч), распределенных на очень больших площадях.

        Причем, там никаких облаков и вообще внешних серверов не предусматривалось изначально. Поэтому и архитектуру свою и протоколы все сами разрабатывали. Поэтому и говорю - есть IP и номер порта, то гонять сообщения (датаграммы) по сети - вообще не проблема. Чуть сложнее чем Hello World.

        Во-вторую - ситуация с пригородах. Вот у нас 3-го мая с.г. накрыло снегом. Местами до 50см выпало. По области - 80тыс человек без электричества (налипание на провода, падение деревьев на провода) в течении 2-3 суток.

        Конкретно наш поселок - повезло. Аварий не было. А у коллеги дача неподалеку - 2 дня без электричества и, что характерно, без связи. Вообще какой-либо связи. Ни одна из вышек в округе не работала.


  1. nixtonixto
    25.05.2024 11:59

    Разобраться всё-таки со стабильным определением срабатывания геркона.

    Конденсатор 100 нФ на землю добавьте. Чтобы при этом не залипали контакты геркона - последовательно контактам поставить 100 Ом.


    1. frog Автор
      25.05.2024 11:59

      Я в статье не упомянул, но там дело не в залипании именно геркона, так как я отлаживал эту проблему, поставив вместо геркона обычную кнопку. Т.е. проблема устойчиво воспроизводилась без геркона. Вообще, когда я полез гуглить, то был удивлён (как человек, к электронике имеющий лишь косвенное отношение), насколько много людей пытается решить проблему с устойчивым определением срабатывания состояния кнопки ESP'шкой. Речь даже не про дребезг, с этим понятно, а просто определения замкнуто-разомкнуто. Причём, в сравнительно идеальных условиях - типа отсутствия помех по питанию (если питание от батареи).


      1. nixtonixto
        25.05.2024 11:59

        Там дело в микросекундных импульсных помехах, которые ловятся контроллером и отсутствии аппаратной/программной фильтрации импульсов короче десятков мс. Судя по тексту, написать программную фильтрацию для вас будет сложней чем сделать аппаратную, да и она плохо совместима с прерываниями и сном, поэтому предложил впаять конденсатор и резистор.


        1. SpiderEkb
          25.05.2024 11:59

          Подавление дребезга - это одно. Есть еще программная логика. Когда делали свою систему, у нас даже был отдельный тип устройства - концевик с задержкой. Т.е. "аварией" считался факт непрерывного его пребывания в аварийном состоянии в течении заданного времени.

          Правда, это было для другого - РИТО (реле индикации точной остановки) и РКД (реле контроля дверей) в старых советских лифтах (где не было лифтовых контроллеров типа УБДЛ и иже с ними). Там суть в том, что когда лифт на этаже - РИТО замкнуто. Когда едет - оно разомкнуто с кратковременным замыканием при проходе очередного этажа. И то и другое - норма. А вот когда оно непрерывно разомкнуто долго (скажем, дольше 20-30сек) - это плохо - лифт завис между этажами. Это уже авария.

          Эта логика у нас на уровне контроллера была реализована (начинали в 90-х с контроллеров на 8080, современные версии были на STM32). Подробностей не знаю - под контроллеры не я писал (я микроядром занимался), но там что-то типа таймера было - обнаружили "аварийное состояние" - запустили таймер, обнаружили норму - сбросили - если состояние аварийное и таймер превысил пороговое значение - формируется сигнал об аварии.

          Это все, естественно, уже поверх чисто аппаратных решений типа интегрирующих антиидребезговых цепочек.


  1. fio
    25.05.2024 11:59

    Проблему с герконом можно было решить внешним подтягивающим резистором. Внутренние не обеспечивают достаточный ток и на длинный провод ловятся помехи.

    Ещё не стоит использовать прерывания, если задействован WiFi - могут быть глюки в обработке прерываний.


    1. frog Автор
      25.05.2024 11:59

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


    1. fio
      25.05.2024 11:59

      Сорри, поторопился. Дочитал что вы это и так поняли