
В прошлой статье мы рассмотрели, как отлаживать код, загружать отредактированные файлы и удалять ненужные файлы на устройстве прямо из браузера (беспроводное управление устройством) через WebREPL и через uPyLoader. Теперь научим устройство "говорить" — отправлять нам сообщения через систему push-уведомлений популярных мессенджеров.
Для сохранения логической целостности цикла статей я включил этот раздел, даже учитывая наличие похожих материалов на Хабре. Цель — не просто повторить известную информацию, а показать проверенные решения, адаптированные под конкретный проект и решающие проблему с русской кодировкой и эмодзи.
Мы протестируем две системы уведомлений:
Telegram-бот — для ESP32, который будет отображать сообщения от модуля, обладающего достаточными ресурсами для обработки SSL-шифрования, требуемого Telegram API.
ntfy — легковесное решение для отображения сообщений для ESP8266, не требующее ресурсоемкого шифрования и идеально подходящее для устройств с ограниченной памятью.
Вы сможете выбрать подходящий вариант для своего проекта.
Чем конкретно займемся?
Созданием Telegram-бота через @BotFather с запуском тестового кода для отправки сообщений в созданный Telegram-бот.
Настройкой ntfy-каналов с запуском тестового кода на ESP8266 для отправки сообщений в топик ntfy.
Создание Telegram бота, получение Токена и Chat ID
Шаг 1: Создаем бота через @BotFather, получаем Токен.

Откройте Telegram и найдите @BotFather (официальный бот для создания ботов)
Отправьте команду: /newbot
Введите имя бота (то, что будут видеть пользователи), например: My ESP32 Assistant
Введите username бота (должен заканчиваться на bot), например: my_esp32_bot
Сохраните Токен который выдаст BotFather.

Шаг 2: Получаем Chat ID

Через специального бота - @userinfobot. Отправьте любую команду, например /help. Сохраните 10-ти значный id (пример Id: 5207544788)
Соблюдайте правила безопасности: НИКОМУ не показывайте Токен — это пароль от вашего бота, не публикуйте Токен в открытом доступе (GitHub, форумы и т.д.).
Документация по Телеграмм боту.
Настройка ESP32: создание файлов через uPyLoader
Предлагаю для ознакомления и тестирования следующую структуру файлов:
upload.py и download.py служебные для загрузки и скачивания файлов в uPyLoader. Создаются при инициализации (в меню File → Init transfer files)
boot.py → Автозапуск WiFi
config.py → Настройки (пароли, токены)
test_send.py → Тест ОТПРАВКИ в Telegram
В прошлой статье я описал способ создания файлов через редактор кода uPyLoader.
Кратко напомню:
1. Запустите uPyLoader
2. Подключитесь к ESP32 (Connection → Connect)
3. Откройте редактор: View → Code Editor
СОЗДАНИЕ КОНФИГУРАЦИОННОГО ФАЙЛА
В поле MCU введите: config.py
Код для нижнего окна:
# НАСТРОЙКИ WiFi
WIFI_SSID = "your_wifi_name" # Имя вашей WiFi сети
WIFI_PASSWORD = "your_wifi_password" # Пароль от WiFi, если ваш пароль состоит из цифр то, не лишним будет оформить его в бинарный режим пример b”12345678”
# НАСТРОЙКИ TELEGRAM БОТА
TELEGRAM_TOKEN = "1234467890:ABCdefGHIjklMNOpqrsTUVwxyz" # Ваш Токен бота
TELEGRAM_CHAT_ID = 123456789 # Ваш Chat ID
Нажмите → Save
СОЗДАНИЕ ФАЙЛА ПОДКЛЮЧЕНИЯ WiFi
В поле MCU введите: boot.py
Код для нижнего окна:
import network # Работа с WiFi
import time # Паузы и задержки
from config import WIFI_SSID, WIFI_PASSWORD
# Основная функция подключения к wifi
def connect_wifi():
wlan = network.WLAN(network.STA_IF) # подключение к WiFi в режиме клиента
wlan.active(True) # включение WiFi-модуля ESP
# Проверяем статус подключения
if wlan.isconnected():
print(f"WiFi уже подключен: {wlan.ifconfig()[0]}")
return True
else:
# Если не подключен - подключаемся
print(f" Подключаемся к {WIFI_SSID}...")
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
# Ожидание и проверка подключения
for i in range(10):
if wlan.isconnected():
print(f" WiFi подключен! IP: {wlan.ifconfig()[0]}")
return True
time.sleep(1)
print(" Не удалось подключиться к WiFi")
return False
# Автозапуск
connect_wifi()
Нажмите → Save
Функция подключения к WiFi выполняет следующие шаги: инициализация клиентского режима, активация WiFi-модуля, проверка текущего статуса подключения, установка соединения при необходимости, ожидание подтверждения подключения и финальная отчетность о результате.
ЗАПУСК ТЕСТА
1. Закройте редактор кода
2. В главном окне выберите файл boot.py
3. Нажмите → Execute
СОЗДАНИЕ ТЕСТОВОГО ФАЙЛА ДЛЯ ОТПРАВКИ
В поле MCU введите: test_send.py
Код для нижнего окна:
import urequests # для отправки запросов
import time
import gc # Чистка памяти
from config import TELEGRAM_TOKEN, TELEGRAM_CHAT_ID
def send_telegram_message(text):
"""Основная функция отправки сообщения в Telegram"""
# Очищаем память перед выполнением запроса
gc.collect()
# Формируем URL для запроса к Telegram API
url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage?chat_id={TELEGRAM_CHAT_ID}&text={text}"
try:
# Отправляем GET-запрос к серверу Telegram
response = urequests.get(url)
# Проверяем статус ответа сервера
if response.status_code == 200:
result = True
print(f" Сообщение отправлено: '{text}'")
else:
result = False
print(f" Ошибка HTTP {response.status_code}: '{text}'")
# Закрываем соединение для освобождения ресурсов
response.close()
return result
except Exception as e:
# Обрабатываем ошибки соединения
print(f" Ошибка соединения: {e}")
return False
finally:
# Гарантированно очищаем память после выполнения запроса
gc.collect()
# ТЕСТИРОВАНИЕ функции, запускается при выполнении файла
messages = [
" ESP32 успешно запущен!",
"? Тестируем отправку сообщений",
"? Русский текст работает.",
"? Эмодзи тоже! ?❤️?"
]
for i, msg in enumerate(messages, 1):
print(f"\n Тест {i}/4")
success = send_telegram_message(msg)
if not success:
print(" Останавливаем тест из-за ошибки")
break
time.sleep(3)
print(" ТЕСТИРОВАНИЕ ЗАВЕРШЕНО!")
Нажмите → Save
Функция send_telegram_message(text) выполняет следующие шаги:
Очистка оперативной памяти перед выполнением запроса
Формирование URL для API Telegram с токеном бота, ID чата и текстом сообщения.
Отправка GET-запроса к серверу Telegram.
Проверка статуса ответа - успешным считается только код 200.
Логирование результата в терминал.
Закрытие соединения для освобождения сетевых ресурсов.
Очистка памяти после выполнения запроса.
Возврат результата (True/False) для дальнейшей обработки.
Обработка ошибок: перехват исключений при проблемах с соединением, логирование ошибок с понятными сообщениями.
Гарантированная очистка памяти даже при сбоях.
Если коротко:"Очистили память, отправили сообщение в Telegram, проверили ответ, почистили за собой и сообщили о результате"
ЗАПУСК ТЕСТА
1. Закройте редактор кода
2. В главном окне выберите файл test_send.py
3. Нажмите → Execute
4. Посмотрите результат в Телеграмм боте

Вот так выглядят мои сообщения от датчика воды:

Telegram Bot API имеет особенность - он позволяет использовать GET-запросы для отправки данных. Хотя технически GET предназначен для получения данных, в случае Telegram это работает и упрощает код для микроконтроллеров и позволяет работать с русским текстом и эмодзи.
Ниже приведен POST-запрос, где приходиться вручную кодировать текст в UTF-8 и формировать тело запроса в бинарном виде, чтобы можно было работать с русским текстом и эмодзи:
Скрытый текст
def send_telegram(text):
""" POST-запрос в Telegram бот"""
# Формируем URL для API Telegram
url = "https://api.telegram.org/bot" + TELEGRAM_TOKEN + "/sendMessage"
# Собираем тело запроса вручную, кодируя каждую часть:
# - chat_id преобразуем в строку и затем в байты
# - текст сообщения кодируем в UTF-8 для поддержки русского и эмодзи
# - собираем все части в бинарном формате для надежной передачи
body = b"chat_id=" + str(TELEGRAM_CHAT_ID).encode() + b"&text=" + text.encode('utf-8')
# Указываем тип содержимого - форма данных веб-форм
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
# Отправляем POST-запрос и проверяем успешность по статусу 200
return urequests.post(url, data=body, headers=headers).status_code == 200Настройкой ntfy-каналов с запуском тестового кода на ESP8266 для отправки сообщений в топик ntfy.
Особенности ntfy:
HTTP вместо HTTPS - не требует шифрования
POST-запросы - стандартный подход для отправки данных
Не требует регистрации - просто укажите topic
Легковесный - идеально для ESP8266
Что понадобится?
Телефон со скаченным приложением ntfy и модуль ESP8266 (NodeMCU, Wemos D1 или др.)
Документация по ntfy
Шаг 1: Установите приложение ntfy
Скачайте ntfy из App Store или Google Play.
Откройте приложение и нажмите "+"
Создайте уникальное имя топика, например: my_esp8266_alerts, нажмите ПОДПИСАТЬСЯ

Настройка ESP8266: создание файлов через uPyLoader
Структура файлов:
upload.py и download.py служебные для загрузки и скачивания файлов в uPyLoader.
boot.py → Автозапуск WiFi
config.py → Настройки (пароли)
test_send_ntfy.py → Тест ОТПРАВКИ в NTFY
СОЗДАНИЕ КОНФИГУРАЦИОННОГО ФАЙЛА
В поле MCU введите: config.py
Код для нижнего окна:
# НАСТРОЙКИ WiFi
WIFI_SSID = "your_wifi_name" # Имя вашей WiFi сети
WIFI_PASSWORD = "your_wifi_password" # Пароль от WiFi, если ваш пароль состоит из цифр то, не лишним будет оформить его в бинарный режим пример b”12345678”
Нажмите → Save
СОЗДАНИЕ ФАЙЛА ПОДКЛЮЧЕНИЯ WiFi – тоже самое, что и для Телеграмм бота
Скрытый текст
import network # Работа с WiFi
import time # Паузы и задержки
from config import WIFI_SSID, WIFI_PASSWORD
# Основная функция подключения к wifi
def connect_wifi():
wlan = network.WLAN(network.STA_IF) # подключение к WiFi в режиме клиента
wlan.active(True) # включение WiFi-модуля ESP
# Проверяем статус подключения
if wlan.isconnected():
print(f"WiFi уже подключен: {wlan.ifconfig()[0]}")
return True
else:
# Если не подключен - подключаемся
print(f" Подключаемся к {WIFI_SSID}...")
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
# Ожидание и проверка подключения
for i in range(10):
if wlan.isconnected():
print(f" WiFi подключен! IP: {wlan.ifconfig()[0]}")
return True
time.sleep(1)
print(" Не удалось подключиться к WiFi")
return False
# Автозапуск
connect_wifi()
Нажмите → Save
СОЗДАНИЕ ТЕСТОВОГО ФАЙЛА ДЛЯ ОТПРАВКИ
В поле MCU введите: test_send_ntfy.py
Код для нижнего окна:
import urequests
import time
import gc
def send_ntfy_message(text, topic="my_esp8266_alerts"):# УКАЗЫВАЕМ ИМЯ СВОЕГО ТОПИКА
"""Основная функция отправки сообщения в ntfy"""
# Очищаем память перед выполнением запроса
gc.collect()
# Формируем URL для запроса к ntfy
url = f"http://ntfy.sh/{topic}"
try:
# ОТПРАВЛЯЕМ КАК В ДОКУМЕНТАЦИИ: данные в теле с UTF-8 кодировкой
response = urequests.post(url, data=text.encode('utf-8'))
# Проверяем статус ответа сервера
if response.status_code == 200:
result = True
print(f"Сообщение отправлено: '{text}'")
else:
result = False
print(f"Ошибка HTTP {response.status_code}: '{text}'")
# Закрываем соединение для освобождения ресурсов
response.close()
return result
except Exception as e:
# Обрабатываем ошибки соединения
print(f" Ошибка соединения: {e}")
return False
finally:
# Гарантированно очищаем память после выполнения запроса
gc.collect()
# ТЕСТИРОВАНИЕ функции, запускается при выполнении файла
messages = [
"? ESP32 успешно запущен!",
"? Тестируем отправку сообщений",
"? Русский текст работает!",
"? Эмодзи тоже! ?❤️?"
]
for i, msg in enumerate(messages, 1):
print(f"\n Тест {i}/4")
success = send_ntfy_message(msg)
if not success:
print("Останавливаем тест из-за ошибки")
break
time.sleep(3)
print(" ТЕСТИРОВАНИЕ ntfy ЗАВЕРШЕНО!")
Topic можно изменить в вызове функции: send_ntfy_message("Сообщение", "my_custom_topic").

Возможные проблемы и решения
Для Telegram:
- "Сообщения не приходят" → Проверьте токен и Chat ID, убедитесь что бот активен
- "Ошибка памяти" → В коде уже используется gc.collect(), но при расширении проекта следите за использованием памяти
- "Не работает русский текст" → В GET-запросе проблем быть не должно, в POST нужна кодировка UTF-8
Для ntfy:
- "Сообщения не приходят" → Проверьте точное имя топика
- "Ошибка подключения" → Проверьте WiFi соединение
Подводя итог тестированию, то видно что ESP32 'тянет' защищенный HTTPS для Telegram, а ESP8266 довольствуется быстрым HTTP в ntfy, но оба решения отлично работают с русским языком и эмодзи!
В следующей статье объединим знания из предыдущих материалов и создадим законченный код системы мониторинга, включающий:
Подключение через WebREPL для удаленного управления
Автоматическое соединение с Wi-Fi
Логику работы с датчиком уровня воды
Полную интеграцию с выбранной системой уведомлений
Оптимизация и работа с памятью модуля
Данный код станет рабочей основой для реального проекта — датчика уровня воды в колодце.
Jury_78
Насколько я помню в micropython строки по умолчанию в utf8.