«SIM800/900 против старого телефона: битва за дачу»

В системах удалённого мониторинга часто требуется передача данных из точек без покрытия интернета. Классическое решение — GSM-модули семейства SIM800/SIM900, управляемые через AT-команды, но у этого подхода, на мой личный взгляд и опыт, есть недостаток - написать кучу AT-команд.

 Одна из альтернатив — использование старого Android-смартфона как GSM-шлюза. У него уже есть: сотовая связь (для SMS), Wi-Fi (для локальной сети без интернета с ESP), установленное приложение MacroDroid и аккумулятор, зарядкой которого тоже можно управлять через MacroDroid

Осталось только «подружить» его с микроконтроллером.

В этой статье я предлагаю архитектуру двусторонней связи между ESP и телефоном через SMS с использованием HTTP-протокола в локальной сети. Рассмотрены сценарии:

Запрос статуса от пользователя (SMS от пользователя  → Телефон с MacroDroid →  ESP → Телефон с MacroDroid → SMS пользователю)

 Экстренные уведомления от ESP (ESP → Телефон с MacroDroid → SMS пользователю)

 Всё работает без интернета, без облачных сервисов, без SIM800/900. Только ESP c MicroPython и  старый сотовый телефон с MacroDroid, в который мы вдохнем жизнь и пусть он проведет остаток своей жизни с пользой.

 Прежде чем приступить к описанию сценариев, необходимо уточнить несколько технических моментов.

 1. Схема сети

Телефон работает в режиме точки доступа (AP) название в телефоне примерно «Мобильная точка доступа и модем», WiFi должен быть отключен (желательно в настройках убрать галочку с Автоматическое включение WiFi). В созданной телефоном локальной сети телефон (он же роутер) обычно имеет IP-адрес 192.168.43.1. В настройках «Мобильная точка доступа и модем» есть название сети и пароль (или вы сами их можете задать), которые необходимы для подключения к сети и нужен для написания кода на микроконтроллере.

 ESP подключается к телефону как клиент (STA_IF) и получает IP-адрес вида 192.168.43.x. Адрес выдаётся по DHCP, и при каждом переподключении он может меняться. Чтобы ESP всегда был доступен по одному адресу, необходимо закрепить за ним статический IP:

 sta.ifconfig(("192.168.43.99", "255.255.255.0", "192.168.43.1", "8.8.8.8"))

 Это гарантирует, что ESP всегда будет доступен по адресу, который вы укажете в настройках MacroDroid.

Вот мы их и «подружили» и они находятся в одной сети.

 Устройства общаются по протоколу HTTP:

ESP слушает порт 80 (стандартный для HTTP) или любой другой (например, 8080). Если используете порт 80, имейте в виду: на некоторых сборках MicroPython для ESP32-S3 порт 80 может быть занят системой, тогда используйте порт 8080.

 MacroDroid на телефоне слушает порт 8080 (настраивается в триггере «HTTP-запрос (сервер)»).

 Расстояние: стабильная работа гарантирована на расстоянии 8–10 метров в помещении, до 20 метров на открытом пространстве. Сигнал можно проверить в настройках телефона: «Подключённые устройства» → найти свой ESP по имени.

Детальную настройку сети и сервера я описал в статье «Клиент-сервер на ESP (MicroPython): чистый socket и прикладной HTTP — конспект-справочник»

 2. Роль MacroDroid

 MacroDroid выполняет две функции:

Сервер — принимает HTTP-запросы от ESP (например, /alert_temp) и отправляет SMS

Клиент — отправляет HTTP-запросы на ESP (например, /status) при получении SMS или событии.

 3. Формат данных

 Все ответы от ESP — короткие текстовые строки: on, off, 24.5. Это сделано для экономии SMS-символов и упрощения обработки в MacroDroid.

 4. Ограничения MacroDroid

 В бесплатной версии доступно только 5 макросов. Поэтому мы используем один макрос на каждый сценарий.

 5. Управление зарядкой

 Телефон должен работать 24/7. Чтобы аккумулятор не деградировал от постоянной зарядки (литиевые аккумуляторы «не любят» находиться на зарядке при 100%), необходимо предусмотреть автоматизацию:

 Вариант 1: Умная розетка

Готовая умная розетка (желательно механическая из-за отсутствия интернета) с таймером. Настраивается по времени: заряжать, например, с 02:00 до 04:00.

 Вариант 2: Самодельная умная розетка на ESP

Собрать розетку на основе ESP и реле, которая будет управляться через MacroDroid. В этом случае MacroDroid отслеживает уровень заряда:

 Триггер: Уровень батареи < 20% → отправляет HTTP-запрос на ESP → ESP включает реле зарядки.

 Триггер: Уровень батареи > 95% → отправляет HTTP-запрос на ESP → ESP выключает реле зарядки.

 Этот вариант полностью автономен, не требует интернета и использует ту же локальную сеть, что и основная система.

 6. Сим карта для телефона.

 Для работы шлюза необходима SIM-карта с активным сотовым подключением. Важно, чтобы телефон находился в зоне покрытия сети (можно уточнить у оператора или посмотреть зону покрытия оператора).

 Я использовал SIM-карту для умных устройств от МТС 2G: стоимость: 150 руб/месяц, включено: 50 SMS в месяц.

Этого объёма достаточно для ежедневной проверки статуса (2-3 SMS), аварийных уведомлений (температура, свет), управления системой (включение/выключение).

 Если ваш оператор предоставляет пакет SMS, убедитесь, что их количества достаточно для ваших сценариев.

Запрос статуса от пользователя (SMS от пользователя  → Телефон с MacroDroid →  ESP → Телефон с MacroDroid → SMS пользователю)

Шаг 1: Открываем MacroDroid и создаём макрос

 Откройте приложение MacroDroid на телефоне.

В нижней части экрана нажмите на вкладку «Макросы» (иконка списка).

Нажмите на «+» (Добавить макрос) в правом нижнем углу.

В появившемся окне введите название макроса: например «Запрос».

Нажмите «ОК» или галочку, чтобы сохранить название или можно после создания макроса «Сохранить изменения»

 Шаг 2: Настраиваем триггер «Получение SMS»

 Нажмите «+» рядом с полем «Триггер».

В списке категорий выберите «Вызовы и смс».

В открывшемся списке выберите «Получение SMS».

Появится окно настройки триггера:

 «Получатель»: Оставьте «Любой» (если хотите, чтобы макрос срабатывал на SMS с любого номера) или выберите конкретный контакт (если вы хотите, чтобы команды принимались только от вас).

 «Тип»: Оставьте «Любой тип» (это позволяет макросу срабатывать на любые SMS, даже если они не являются стандартными текстовыми).

 «Содержит текст»: В этом поле можно оставить пустым, потому что мы будем фильтровать SMS внутри макроса. Это нужно для нашего сценария. Если вы укажете текст status в триггере, макрос будет срабатывать только когда в SMS есть это слово.

Нажмите «ОК», чтобы сохранить триггер.

 Шаг 3: Настраиваем действие «HTTP-запрос»

 Нажмите «+» рядом с полем «Действия».

В списке категорий выберите «Взаимодействие с сетью».

 Выберите «HTTP-запрос».

 В настройках HTTP-запроса заполните:

 Метод запроса: GET

Введите URL-адрес: http://192.168.43.96:80/ !!!ЗДЕСЬ НАЖИМАЕМ СИНИЙ КВАДРАТИК СПРАВА И ВЫБИРАЕМ «Текст входящего сообщения» нажимаем ОК и у вас должно получиться

http://192.168.43.96:80/{sms_message}

где 192.168.43.96 — IP-адрес вашего ESP в сети телефона,

:80 – порт который вы укажите на ESP при настройке сервера,

{sms_message} – это текст входящего сообщения. Например вы отправляете смс с текстом status, MacroDroid автоматически добавит его в URL и полный вариант для запроса будет http://192.168.43.96:80/ status.

 ВАЖНО!!! Поставьте галочку(выберете пункт) «Блокировать следующие действия» - блокирующий режим запроса «пока не выполню никаких действий». Без неё — макрос не дожидается сервера и работает дальше, что приведет к отправке старых команд и адресат получает либо пустое сообщение, либо старое значение из переменной от предыдущего запроса.

 Тайм-аут (сек): 5-10 (если ESP не ответит за 5 секунд, запрос прервётся)

Опускаемся вниз и включаете опцию «Сохранить ответ в строковую переменную»:

Выбираете «Локальная переменная» Имя переменной, например, response

В этой переменной будет храниться ответ от сервера, который потом уйдет по смс обратно

Нажмите «ОК», чтобы сохранить переменную.

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

 Шаг 4: Настраиваем действие «Отправить SMS»

 Нажмите «+» рядом с полем «Действия» (добавляем второе действие).

 В списке категорий выберите «Сообщения».

 Выберите «Отправить SMS».

 В настройках заполните:

 «Получатель»: Введите номер телефона, на который нужно отправить ответ.

Можно из выпадающего списка выбрать «Контакт входящего смс» (появиться {sms_name}) или «Номер входящего смс» (появиться {sms_number}) они автоматически подставит номер отправителя исходного SMS.

 «Сообщение»: Из выпадающего списка выберите «Локальная переменная» – ОК – выбираем переменную  response — это переменная, в которую мы сохранили HTTP-ответ от ESP. Или просто вбейте {lv= response}

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

 Тестовый код

"""
Тестовый HTTP-сервер на ESP для проверки сценария №1
Режим: блокирующий (ожидает запросы последовательно)
Порт: 80
"""

import time
import socket
import network

# ===== НАСТРОЙКИ =====
SSID = "ВАШЕ ИМЯ СЕТИ"        # Имя сети телефона (точки доступа)
PASSWORD = "ВАШ ПАРОЛЬ"         # Пароль от сети

# ===== ПОДКЛЮЧЕНИЕ К WI-FI =====
print("📡 Подключение к Wi-Fi...")
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.connect(SSID, PASSWORD)

while not sta.isconnected():
    time.sleep(0.5)
    print(".", end="")

print("\n✅ Подключено! IP:", sta.ifconfig()[0])

# ===== СОЗДАНИЕ СЕРВЕРА =====
print("🌐 Создание сервера...")

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(addr)
server.listen(5)

print("🌐 Сервер запущен на порту 80")
print("🔄 Ожидание запросов...")
print("-" * 40)

# ===== ОСНОВНОЙ ЦИКЛ (БЛОКИРУЮЩИЙ) =====
while True:
    # Ждём подключения клиента (БЛОКИРУЮЩИЙ ВЫЗОВ!)
    print("⏳ Ожидание входящего соединения...")
    conn, addr = server.accept()
    print(f"📨 Получен запрос от {addr}")
    
    # Читаем запрос
    request = conn.recv(1024).decode()
    print(f"   Запрос (первые 100 символов): {request[:100]}...")
    
    # Извлекаем путь из запроса
    if request:
        first_line = request.split('\r\n')[0]
        parts = first_line.split(' ')
        if len(parts) >= 2:
            path = parts[1]
            print(f"   ➜ Путь: {path}")
        else:
            path = "/"
            print("   ➜ Путь: / (не удалось распарсить)")
    else:
        path = "/"
        print("   ➜ Путь: / (пустой запрос)")
    
    # ===== ОБРАБОТЧИКИ =====
    if path == '/status':
        print("   📋 Обработчик: /status")
        response = "All GOOD, BE Happy"
        
    elif path == '/temp':
        print("   📋 Обработчик: /temp")
        response = "24.5 HOT"
        
    else:
        print(f"   ⚠️ Неизвестный путь: {path}")
        response = "USE command status or temp"
    
    print(f"   📤 Ответ: {response}")
    
    # Формируем и отправляем HTTP-ответ
    response_bytes = response.encode('utf-8')
    conn.send("HTTP/1.1 200 OK\r\n")
    conn.send("Content-Type: text/plain; charset=utf-8\r\n")
    conn.send(f"Content-Length: {len(response_bytes)}\r\n")
    conn.send("Connection: close\r\n")
    conn.send("\r\n")
    conn.send(response_bytes)
    print("   ✅ Ответ отправлен")
    
    # Закрываем соединение
    conn.close()
    print(f"   🔒 Соединение закрыто")
    print("-" * 40)

Сценарий №2: Экстренные уведомления от ESP32 (ESP → MacroDroid → SMS)

В этом сценарии ESP сам отправляет HTTP-запрос на телефон, когда происходит критическое событие. Макрос в MacroDroid принимает запрос, извлекает текст из тела POST-запроса и отправляет SMS на указанный номер.

 Порядок действий по созданию нового макроса как и в предыдущей главе: Откройте MacroDroid → Макросы → «+» → Название: например «Alert»

Шаг 1: Настраиваем триггер «HTTP-запрос (сервер)»

Нажмите «+» рядом с полем «Триггер».

 В списке категорий выберите «Взаимодействие с сетью» (в некоторых версиях — «Связь» или «Подключение»).

 В открывшемся списке выберите «HTTP-запрос (сервер)».

 Появится окно настройки триггера.

 Основные настройки:

«Путь»: Введите /alert — это путь, по которому ESP будет отправлять POST-запросы.

 «Порт»: Оставьте 8080 (по умолчанию)  — главное, чтобы он совпадал с портом, на который ESP отправляет запросы. В нашем проекте мы используем порт 8081.

 Важно! В этом триггере мы используем POST-запросы, так как ESP передаёт текст сообщения в теле запроса, а не в URL.

 Сохраняем тело запроса в переменную

Опуститесь вниз настроек триггера и включите опцию «Сохранить тело запроса в строковую переменную»:

 Выберите «Локальная переменная».

 Введите имя переменной: alert.

 Нажмите «ОК».

 Что это даёт: Тело POST-запроса (текст сообщения) будет сохранено в переменную alert. Именно её мы будем использовать при отправке SMS.

 Настройка HTTP-ответа

В том же разделе настроек триггера найдите опцию «Отправить ответ»:

 Включите её.

 В поле «Текст ответа» введите OK.

 Код ответа оставьте 200.

 Зачем это нужно: ESP ожидает получить HTTP-ответ после отправки запроса. Если ответа не будет, ESP32 может считать, что запрос «завис», и повторить его, что приведёт к дублированию SMS.

 Настройка HTTP-сервера

Опуститесь вниз настроек триггера и нажмите «Настройки HTTP-сервера».

 В открывшемся окне необходимо:

 Отключить показ веб-страницы — снимите галочку с опции «Показывать веб-страницу».

 Установить «Тайм-аут запроса HTTP сервера (сек)» = 30.

 Почему мы увеличили таймаут до 30 секунд?

 По умолчанию в MacroDroid параметр «Тайм-аут запроса HTTP сервера» установлен в 10 секунд. В процессе отладки мы обнаружили, что при таком значении SMS-уведомления от ESP32 дублировались и приходили дважды, хотя макрос был только один.

 Причина: Если макрос выполняется дольше 10 секунд, MacroDroid считает запрос «зависшим» и повторно обрабатывает его. Это приводит к двойной отправке SMS.

 Решение: Мы увеличили таймаут до 30 секунд — этого времени достаточно для выполнения всех действий в макросе, и дублирование полностью исчезло.

 Сохраняем триггер

Нажмите «ОК», чтобы сохранить настройки триггера.

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

Шаг 2: Настраиваем действие «Отправить SMS»

 Нажмите «+» рядом с полем «Действия».

В списке категорий выберите «Сообщения».

Выберите «Отправить SMS».

В настройках действия заполните:

 «Получатель»: Введите номер телефона, на который нужно отправить уведомление.

 «Сообщение»: Нажмите на поле, затем в выпадающем списке выберите «Локальная переменная» → выберите alert. Либо введите вручную {lv=alert}.

 Нажмите «ОК», чтобы сохранить действие.

 Нажмите на галочку в правом верхнем углу, чтобы сохранить макрос.

 Тестовый код для проверки

"""
Сценарий №2: Экстренные уведомления от ESP
ESP32 → MacroDroid → SMS
"""

import time
import network
import urequests

# ===== НАСТРОЙКИ =====
SSID = "Android000000"  # Ваша сеть точки доступа телефона
PASSWORD = "000000000" # Пароль указать

PHONE_IP = "192.168.43.1"      # IP телефона (точка доступа)
MACRODROID_PORT = 8080         # Порт, который слушает MacroDroid

# ===== ПОДКЛЮЧЕНИЕ К WI-FI =====
def connect_wifi():
    sta = network.WLAN(network.STA_IF)
    sta.active(True)
    sta.connect(SSID, PASSWORD)

    print(" Подключение к Wi-Fi...")
    while not sta.isconnected():
        time.sleep(0.5)
        print(".", end="")

    print("\nПодключено! IP:", sta.ifconfig()[0])
    return True

# ===== ОТПРАВКА УВЕДОМЛЕНИЯ =====
def send_alert(message):
    url = f"http://{PHONE_IP}:{MACRODROID_PORT}/alert"

    try:
        print(f"Отправка уведомления: {message}")
        r = urequests.post(
            url,
            data=message.encode('utf-8'),
            headers={'Content-Type': 'text/plain; charset=utf-8'},
            timeout=10
        )
        print(f"Код: {r.status_code}")
        r.close()
        return True
    except Exception as e:
        print(f"Ошибка: {e}")
        return False

# ===== ТЕСТ =====
def test_alerts():
    if not connect_wifi():
        print("Нет подключения к Wi-Fi")
        return

    # Отправка тестовых уведомлений
    send_alert("⚠️ ВНИМАНИЕ! Температура в помещении упала ниже 10°C!")
    time.sleep(3)
    send_alert("🔌 Пропало электричество! Работаю от ИБП!")

# ===== ЗАПУСК =====
test_alerts()

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

ESP — работает как HTTP-сервер (порт 80) и клиент. Отвечает на команды, собирает данные с датчиков, управляет реле.

Телефон — выступает точкой доступа Wi-Fi (AP) и HTTP-сервером (порт 8080). Обеспечивает связь и работает как SMS-шлюз.

MacroDroid — выполняет роль автоматизатора: принимает запросы от ESP, отправляет их по SMS и наоборот.

HTTP-протокол — используется для локальной связи: GET для команд, POST для текстовых уведомлений.

Ключевое преимущество: всё работает без интернета, без облачных сервисов и без GSM-модулей. Только ESP и старый телефон с MacroDroid.