В этой публикации рассмотрим контроль открытой системы «Умный дом» независимым от системы устройством - простым смартфоном, используя функции, для которых и изначально создавался мобильный телефон: звонки и SMS.
В статье осуществим возможность контроля как системы домашней автоматизации (в моем случае Majordomo), так и отдельных элементов экосистемы и окружения умного дома. Основная идея статьи - контроль и отправка оповещений через мобильную сеть, без использования интернета. Алгоритм простой, в случае проблемы выполняем следующее: SMS -> повторный SMS -> звонок через мобильную сеть.
Статья является продолжением предыдущей Не совсем умный дом на телефоне. Termux, zigbee/zigbee2mqtt и Android У меня уже установлен Termux и его дополнения (из одного источника).
Начнём с простого - команду ping, думаю большинство знает и использует. Немного усложним её условиями вывода информации о статусе. Проверим одной командой в терминале доступность роутера:
ping -c 1 -W 1 192.168.1.1 &>/dev/null && echo "СТАТУС: Роутер в сети! Можно работать." || echo "СТАТУС: Роутер НЕ ОТВЕЧАЕТ!"
Преобразуем команду в небольшой скрипт проверки доступности роутера, сервера системы домашней автоматизации (я использую MajorDoMo), немного изменив команду и условия - проверяем не только роутер, но и доступность сети Internet (в качестве примера используя IP адрес DNS Google):
nano step1_ping.sh
#!/bin/bash SERVER_IP="192.168.1.123" ROUTER_IP="192.168.1.1" INTERNET_IP="8.8.8.8" echo "Проверяем связь с сервером $SERVER_IP..." # -c 1 (один пакет), -W 1 (время ожидания 1 секунда) if ping -c 1 -W 1 "$SERVER_IP" &>/dev/null; then echo "СТАТУС: Сервер в сети!" else echo "СТАТУС: Сервер УД НЕ ОТВЕЧАЕТ!" fi echo "Проверяем связь с роутером $ROUTER_IP..." if ping -c 1 -W 1 "$ROUTER_IP" &>/dev/null; then echo "СТАТУС: Роутер в сети!" else echo "СТАТУС: Роутер НЕ ОТВЕЧАЕТ!" fi echo "Проверяем связь с Интернетом $INTERNET_IP..." if ping -c 1 -W 1 "$INTERNET_IP" &>/dev/null; then echo "СТАТУС: Интернет доступен!" else echo "СТАТУС: Нет доступа к Интернету!" fi
Дальше, как обычно, сохраняем (Ctrl+O, затем Enter, для выхода Ctrl+X) и делаем скрипт исполняемым и запускаем его для проверки (прерывание программы - CTRL+C).
chmod +x step1_ping.sh ./step1_ping.sh
Проверка портов сервисов УД
Перед началом установим утилиты nc (netcat) и curl в Termux, если они ещё не установлены:
pkg install netcat-openbsd curl -y
В разных системах домашней автоматизации открыты разные порты, но есть несколько стандартных, которые встречаются довольно часто:
22 - SSH,
80 - HTTP (веб-интерфейс системы автоматизации ),
1883 - MQTT-брокер,
8080 - веб-интерфейс Zigbee2MQTT (по умолчанию).
Для проверки возьмём два сервиса: порт 80 (MajorDoMo) и порт 8080 (Zigbee2MQTT). Ниже - два варианта скрипта: простой (через nc) и более глубокий (через curl).
Вариант 1: быстрая проверка доступности портов через nc
Создадим ещё один скрипт и вставим содержимое:
nano step2_ports.sh
#!/bin/bash SERVER_IP="192.168.1.123" # Массив портов для проверки: "ПОРТ:ОПИСАНИЕ" SERVICES=( "80:MajorDoMo Web" "8080:Zigbee2MQTT Web" ) echo "Проверяем работу сервисов на $SERVER_IP..." for item in "${SERVICES[@]}"; do # Разделяем порт и описание по символу ":" PORT="${item%%:*}" NAME="${item#*:}" # nc -z: режим сканирования, -w 1: таймаут 1 секунда if nc -zv -w 1 "$SERVER_IP" "$PORT" &>/dev/null; then echo " [ OK ] $NAME (порт $PORT) работает." else echo " [FAIL] $NAME (порт $PORT) НЕ ОТВЕЧАЕТ!" fi done
Вариант 2: глубокая проверка HTTP-сервисов через curl
Этот вариант не просто проверяет, «открыт ли порт», а смотрит, отдаёт ли сервис корректную страницу (HTTP-код 200). Создадим отдельный скрипт (или перезапишем тот же файл — на выбор):
#!/bin/bash SERVER_IP="192.168.1.123" echo "=== Глубокая проверка веб-сервисов ===" # Функция для проверки HTTP-кода check_http() { local url=$1 local name=$2 # --silent: скрыть прогресс-бар # --output /dev/null: не сохранять тело страницы # --write-out "%{http_code}": вывести только HTTP-код # --max-time 3: ограничить ожидание 3 секундами STATUS_CODE=$(curl --silent --output /dev/null --write-out "%{http_code}" --max-time 3 "$url") if [ "$STATUS_CODE" -eq 200 ]; then echo " [ OK ] $name отдаёт страницу (Код: 200)" elif [ "$STATUS_CODE" = "000" ]; then # 000 — curl не смог соединиться (таймаут, хост недоступен и т.п.) echo " [FAIL] $name ВООБЩЕ НЕ ОТВЕЧАЕТ (Таймаут или сервис выключен)" else echo " [WARN] $name доступен, но вернул ошибку сервера (Код: $STATUS_CODE)" fi } # Проверяем MajorDoMo (порт 80) check_http "http://$SERVER_IP:80" "MajorDoMo Web" # Проверяем Zigbee2MQTT (порт 8080) check_http "http://$SERVER_IP:8080" "Zigbee2MQTT Web"
В ответе практически то же самое, но сам алгоритм проверки, несколько другой. Перейдём к проверке главной функции смартфона.
Взаимодействие с мобильной сетью (Звонки и SMS)
Теперь начнём тестировать основную функцию смартфона в этой публикации: отправке SMS и совершение звонков. Именно эти каналы станут нашими «резервными» оповещениями, когда интернет недоступен, а мобильная сеть остаётся рабочей. Чтобы Termux мог отправлять SMS или делать звонки понадобится официальное дополнение Termux:API. Оно связывает консоль Linux с функциями Android, не только телефония, но и другие функции смартфона.
Предварительная подготовка (выполняется один раз)
Убеждаемся, что на телефоне установлено приложение дополнение Termux:API (из того же источника, откуда скачивали сам Termux — например, F-Droid). Запускаем его на телефоне один раз и предоставляем необходимые разрешения.
Устанавливаем пакет утилит командной строки внутри Termux:
pkg install termux-api -y
Тестирование SMS и звонка
Напишем небольшой скрипт, который проверит, работают ли команды связи на устройстве. Будем использовать две основные команды: termux-sms-send и termux-telephony-call.
Вставим в него код ниже. Заменяем +XXXXXXXXXXX на свой номер телефона:
#!/bin/bash # Указываем номер телефона, на который будем звонить, в международном формате MY_NUMBER="+XXXXXXXXXXX" echo "=== Тест мобильных функций ===" # 1. Проверка отправки SMS echo "Пробуем отправить тестовое SMS..." termux-sms-send -n "$MY_NUMBER" "Termux: Тест связи. Сервер Умного Дома ок!" echo "Запрос на SMS отправлен. Проверьте входящие сообщения." echo "-----------------------------------" # 2. Проверка звонка echo "Внимание! Сейчас телефон совершит тестовый вызов на $MY_NUMBER" echo "Вы можете сразу сбросить его." read -p "Нажмите Enter для начала звонка..." termux-telephony-call "$MY_NUMBER"
!!! При первом звонке и отправке SMS сообщения Android запросит разрешения для приложения Termux для звонков и SMS – обязательно выдаем их, без разрешений - не заработает.
Финал
Скомбинировав предыдущие действия и объединив их вместе в один скрипт, получаем финальную версию - готовый мониторинг, который работает в цикле и оповещает через мобильную сеть.
Логика работы
Проверка выполняется каждые 30 секунд (интервал задаётся переменной INTERVAL). Мониторятся четыре цели:
1. Сервер умного дома - по пингу. Если сервер не отвечает, проверка веб‑сервисов (MajorDoMo, Zigbee2MQTT) пропускается, а их локальные счётчики сбрасываются, чтобы избежать спама параллельных уведомлений.
2. Роутер — по пингу.
3. Доступность интернета — по пингу (в примере используем DNS Google 8.8.8.8).
4. Веб‑сервисы (MajorDoMo на порту 80 и Zigbee2MQTT на порту 8080) — через HTTP‑запрос с проверкой кода ответа. Проверяются только если сервер доступен по пингу.
Эскалация оповещений
Для каждой цели ведётся отдельный счётчик ошибок подряд. Алгоритм эскалации одинаковый для всех: 2 ошибки подряд время обнаружения около минуты отправляется первое SMS сообщение; 4 ошибки подряд, ещё через минуту - второе сообщение; и наконец после трёх минут и 6 ошибок поступает «пустой» звонок.
При восстановлении связи отправляется SMS с текстом «OK: … ВОССТАНОВЛЕНА», но только если до этого уже было отправлено хотя бы одно уведомление об аварии, сделано, чтобы не спамить при кратковременных колебаниях связи.
#!/bin/bash # --- НАСТРОЙКИ --- SERVER_IP="192.168.1.123" ROUTER_IP="192.168.1.1" WAN_IP="8.8.8.8" MY_NUMBER="+XXXXXXXXXXXX" # Ваш номер телефона INTERVAL=30 # Интервал опроса в секундах # --- СЧЕТЧИКИ ОШИБОК (0 - всё ок) --- err_server=0 err_router=0 err_wan=0 err_md=0 # Для MajorDoMo err_z2m=0 # Для Zigbee2MQTT # --- СТАТУСЫ УВЕДОМЛЕНИЙ (0-нет, 1-СМС1, 2-СМС2, 3-Звонок) --- alert_server=0 alert_router=0 alert_wan=0 alert_md=0 alert_z2m=0 # Функция для проверки пинга (0 - ок, 1 - упал) check_ping() { ping -c 1 -W 1 "$1" &>/dev/null return $? } # Функция для проверки HTTP статуса (0 - ок (200), 1 - упал/ошибка) check_http_status() { local url="$1" # Запрашиваем только код ответа, таймаут 2 секунды local code=$(curl --silent --output /dev/null --write-out "%{http_code}" --max-time 2 "$url") if [ "$code" -eq 200 ]; then return 0 else return 1 fi } # Функция обработки логики эскалации # Аргументы: $1-имя для переменной, $2-имя для текста СМС, $3-текущий счетчик, $4-статус алерта process_incident() { local var_name="$1" local text_name="$2" local count=$3 local alert_status=$4 # 2 ошибки подряд = 1 минута аварии if [ $count -eq 2 ] && [ $alert_status -eq 0 ]; then termux-sms-send -n "$MY_NUMBER" "ALERT: Проблема с [$text_name] (уже 1 минута)!" eval "alert_${var_name}=1" echo "[СМС] Отправлено первое уведомление для $text_name" # 4 ошибки подряд = около 2 минут аварии elif [ $count -eq 4 ] && [ $alert_status -eq 1 ]; then termux-sms-send -n "$MY_NUMBER" "ALERT: [$text_name] ВСЕ ЕЩЕ ЛЕЖИТ (уже 2 минуты)!" eval "alert_${var_name}=2" echo "[СМС] Отправлено второе уведомление для $text_name" # 6 ошибок подряд = около 3 минуты аварии elif [ $count -eq 6 ] && [ $alert_status -eq 2 ]; then echo "[ЗВОНОК] Инициирую экстренный вызов по причине: $text_name" termux-telephony-call "$MY_NUMBER" eval "alert_${var_name}=3" fi } echo "=== Запуск расширенного мониторинга УД (Интервал: ${INTERVAL}с) ===" while true; do echo "--- Проверка $(date '+%H:%M:%S') ---" # 1. ПРОВЕРКА СЕРВЕРА (ПИНГ) if check_ping "$SERVER_IP"; then if [ $err_server -gt 0 ]; then [ $alert_server -gt 0 ] && termux-sms-send -n "$MY_NUMBER" "OK: Связь с сервером $SERVER_IP ВОССТАНОВЛЕНА." echo "✅ Сервер снова в сети." err_server=0; alert_server=0 fi # --- СЕРВИСЫ ПРОВЕРЯЕМ ТОЛЬКО ЕСЛИ САМ СЕРВЕР ПИНГУЕТСЯ --- # 1.1 ПРОВЕРКА MAJORDOMO (PORT 80) if check_http_status "http://$SERVER_IP:80"; then if [ $err_md -gt 0 ]; then [ $alert_md -gt 0 ] && termux-sms-send -n "$MY_NUMBER" "OK: Сервис MajorDoMo (порт 80) восстановил работу." echo "✅ MajorDoMo Web [OK]" err_md=0; alert_md=0 fi else ((err_md++)) echo "❌ MajorDoMo Web упал. Ошибок подряд: $err_md" process_incident "md" "MajorDoMo Web" $err_md $alert_md fi # 1.2 ПРОВЕРКА ZIGBEE2MQTT (PORT 8080) if check_http_status "http://$SERVER_IP:8080"; then if [ $err_z2m -gt 0 ]; then [ $alert_z2m -gt 0 ] && termux-sms-send -n "$MY_NUMBER" "OK: Сервис Zigbee2MQTT (порт 8080) восстановил работу." echo "✅ Zigbee2MQTT Web [OK]" err_z2m=0; alert_z2m=0 fi else ((err_z2m++)) echo "❌ Zigbee2MQTT Web упал. Ошибок подряд: $err_z2m" process_incident "z2m" "Zigbee2MQTT Web" $err_z2m $alert_z2m fi else ((err_server++)) echo "❌ Сервер полностью недоступен по пингу. Ошибок подряд: $err_server" process_incident "server" "Сервер УД (Ping)" $err_server $alert_server # Если сам сервер лежит, сбрасываем локальные счетчики веб-сервисов, # чтобы они не генерировали лишний спам параллельно с аварией сервера. err_md=0; err_z2m=0 fi # 2. ПРОВЕРКА РОУТЕРА if check_ping "$ROUTER_IP"; then if [ $err_router -gt 0 ]; then [ $alert_router -gt 0 ] && termux-sms-send -n "$MY_NUMBER" "OK: Связь с роутером $ROUTER_IP ВОССТАНОВЛЕНА." echo "✅ Роутер снова в сети." err_router=0; alert_router=0 fi else ((err_router++)) echo "❌ Роутер упал. Ошибок подряд: $err_router" process_incident "router" "Роутер" $err_router $alert_router fi # 3. ПРОВЕРКА ИНТЕРНЕТА if check_ping "$WAN_IP"; then if [ $err_wan -gt 0 ]; then [ $alert_wan -gt 0 ] && termux-sms-send -n "$MY_NUMBER" "OK: Доступ в Интернет ВОССТАНОВЛЕН." echo "✅ Интернет снова доступен." err_wan=0; alert_wan=0 fi else ((err_wan++)) echo "❌ Интернет упал. Ошибок подряд: $err_wan" process_incident "wan" "Интернет" $err_wan $alert_wan fi sleep $INTERVAL done
Дальнейшие шаги
Дальнейшие действия — по усмотрению. В зависимости от производителя и версии Android можно и нужно:
Включить Termux в автозагрузку. Для теста использовал три смартфона Xiaomi с Android 10, 13 (основной на котором всё тестировалось) и 16 это работало по-разному: на 13-й версии запустить при старте телефона никак не удавалось, обошёл через MacroDroid.
Отключить энергосбережение для Termux. В настройках смартфона — режим без ограничений, иначе система рано или поздно «убьёт» фоновый процесс. Так же можно организовать и питание с контролем заряда/разряда телефона.
Добавить скрипт в автозапуск Termux. Способов несколько — например, через .bashrc или Termux:Boot.
Доработать под свои нужды: ночной режим, логирование, дополнительные проверки — всё на ваше усмотрение.
Эта статья - не исчерпывающее руководство, а всего лишь старт и направление действий.
select26
Красивое решение!
Колхоз, конечно, но в ряде случаев за пару минут из того что есть в коробке можно сделать мониторинг.
Автор , а можно как-то использовать встроенный сенсор температуры телефона, чтобы мониторить перегрев? Или это уже все внешними датчиками?
Еще здорово было бы добавить сетевую карту и UART - получить оба Modbus и управлять уже всем, чем угодно. Можно это через USB hub сделать?
udvnl Автор
Как я понимаю, только батареи, косвенно можно судить о перегреве
termux-battery-status | jq -r ‘.temperature’ 24.7Многие другие функции требуют root или сторонние утилиты и обходные пути.