Этот девайс больше всего актуален для тех, кто живёт в загородном доме и уже знаком с особыми «сюрпризами» в унитазе, когда дренажный колодец переполняется.

Вы бежите к колодцу, поднимаете тяжеленную крышку, а там... уже всё плавает. А через пару минут доходит осознание: насос благополучно проспал момент включения. Привет, внеплановые 20 минут откачки и «удобрение» участка самым неожиданным способом.

Мой путь борьбы с колодцем: от сложного к простому

Сначала был дренажный насос с герконом. Идея простая: поплавок с герконом плавает, замыкает контакты при достижении уровня воды — насос включается. На деле оказалось, что при вибрации насос болтается, геркон залипает, а иногда просто «молчит как партизан». Фиксировать его — отдельная головная боль.

Потом я поставил надёжного «Малыша» и умную розетку. Включение насоса прямо с телефона, о круто! Но как узнать, что он наполнился? Каждый раз таскать тяжеленную крышку, чтобы заглянуть в колодец, — то ещё удовольствие, включать «наугад»?

Я посмотрел в сторону готовых решений за 3000+ рублей (используют емкостной метод (измеряют точный уровень 0-100%), имеют качественный корпус, готовое приложение и гарантию), но обнаружил, на мой взгляд, подводные камни: мало отзывов — устройства довольно новые на рынке, закрытая система — нельзя ничего доработать под свои нужды.

 А мне было нужно простое, как лопата, решение. Чтобы устройство оповестило меня: «Колодец полный, не желаешь ли включить насос? ПОЖАЛУЙСТА 😠» — и желательно в Telegram, где я точно замечу это сообщение.

Так родилась идея: сердито, эффективно и не дороже 1500 рублей собрать свою систему мониторинга на основе ESP32 и геркона.

Во сколько обойдётся самостоятельная сборка?

Вот приблизительный расчёт от Озон.

Если поискать на антресолях или в сарае, можно сильно сократить расходы.

Что часто уже есть в хозяйстве:

Кабель (сечение до 0.5 мм) → старый от электропроводки (экономия 160 ₽)

Труба → обрезки после ремонта (экономия 100 ₽)

Корпус → пищевой контейнер + герметик (экономия 185 ₽)

Блок питания → зарядка от старого телефона

Что нужно от системы:

Полный контроль — система делает только то, что вы ей сказали.

Гибкость — легко доработать или подключить к другой smart-системе.

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

Независимость — ваш ESP32 перестанет работать только «из-за банкротства вашего счета за интернет».

От идеи к работающей системе: собираем и улучшаем

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

Оживляем ESP8266 и ESP32 за 15 минут без программистских заморочек с помощью MicroPython

WebREPL и uPyLoader: Выбираем способ беспроводного управления ESP

Даем голос ESP: Уведомления в Telegram и ntfy

Сначала логика, потом код: как писать программы для ESP на MicroPython

Вот как это выглядит у меня (возможно немного «неказисто»)

Сборка датчика
Сборка датчика
Установка датчика
Установка датчика
Фото датчика
Фото датчика

Вот код, который установлен у меня, в предыдущей статье я его подробно разбирал:

Скрытый текст

main.py

from machine import Pin, WDT, reset
from time import sleep
from gc import collect
from urequests import get
from config import TELEGRAM_TOKEN, TELEGRAM_CHAT_ID

# НАСТРОЙКИ
SENSOR_PIN = 4
CHECK_INTERVAL = 20
WD_TIME = 35000
REBOOT_INTERVAL = 604800

# ТЕКСТЫ СООБЩЕНИЙ
MSG_WATER_ALARM = "🔴 ВНИМАНИЕ: Вода в колодце! Включите насос!"
MSG_WATER_OK = "🟢 Воды нет. Система мониторинга работает"

# ИНИЦИАЛИЗАЦИЯ ДАТЧИКА
water_sensor = Pin(SENSOR_PIN, Pin.IN, Pin.PULL_UP)
print("water_sensor", water_sensor)
def read_water_sensor():
    """
    Оптимизированное чтение датчика воды
    """
    count = 0
    
    for _ in range(3):
        if water_sensor.value() == 0:
            count += 1
        sleep(0.01)
    
    return count >= 2

def send_telegram_message(message):
    """
    Отправка сообщения в Telegram
    """
    collect()
    
    try:
        url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage"
        url += f"?chat_id={TELEGRAM_CHAT_ID}&text={message}"
        
        response = get(url)
        success = response.status_code == 200
        response.close()
        
        collect()
        if success:
            sleep(2) 
        return success
        
    except Exception as e:
        collect()
        return False

def main():
    """
    Главный цикл мониторинга системы
    """
    # Инициализация сторожевого пса
    wdt = WDT(timeout=WD_TIME)
    send_telegram_message("Система мониторинга воды запущена!")
    sleep(3)
    # Переменная для хранения предыдущего состояния
    previous_water_state = None
    # Счётчик времени работы системы
    system_uptime = 0
    
    # Бесконечный цикл мониторинга
    while True:
        # Сбрасываем сторожевого пса
        wdt.feed()
        
        # Читаем текущее состояние датчика
        current_water_state = read_water_sensor()
        
        # Логика отправки сообщений
        if previous_water_state is None or current_water_state != previous_water_state:
            if current_water_state:
                send_telegram_message(MSG_WATER_ALARM)
            else:
                send_telegram_message(MSG_WATER_OK)
        
        # Сохраняем текущее состояние для следующего цикла
        previous_water_state = current_water_state
        
        # Учет времени для плановой перезагрузки
        system_uptime += CHECK_INTERVAL
        if system_uptime >= REBOOT_INTERVAL:
            send_telegram_message("Плановая перезагрузка системы для профилактики")
            sleep(2)
            reset()
        
        # Пауза перед следующей проверкой
        sleep(CHECK_INTERVAL)
        collect()

# ЗАПУСК СИСТЕМЫ
main()

boot.py

from network import WLAN, STA_IF #  Wi-Fi модуль +  режим клиента (подключение к роутеру) 
from time import sleep # Отслеживаем время 
from gc import collect # Уборка памяти 
from config import WIFI_SSID, WIFI_PASSWORD, WEBREPL_PASSWORD, WEBREPL_SSID, WEBREPL_WIFI_PASSWORD # Необходимые настройки 
  
def connect_wifi(): 
    """WiFi-инженер - подключает к интернету""" 
    collect()# Уборка памяти 
    wlan = WLAN(STA_IF) # Создаем соединение в режиме клиента 
    wlan.active(True) # Активируем/включаем соединение 
    
    # Если не подключено, то передаем пароль и пробуем законектиться (даем 15 попыток), при каждой попытке – чистим память, если в одной из попыток – сработало, сохраняем результат True, если неудачно, то фиксируем результат  False 
    if not wlan.isconnected(): 
        wlan.connect(WIFI_SSID, WIFI_PASSWORD) 
        for i in range(15): 
            if wlan.isconnected(): 
                collect()  # Финальная очистка перед возвратом    
                return True 
            sleep(1) 
            collect()     
    return wlan.isconnected()
def start_webrepl(): 
    """WebREPL-администратор - настраивает точку доступа и запускает сервер""" 
    if WEBREPL_PASSWORD: 
        collect()# Уборка памяти 
  
       #  Создаем и настраиваем точку доступа 
        from network import WLAN, AP_IF 
        ap = WLAN(AP_IF) 
        ap.active(True) 
        
        #  Создаем настройки 
        ap.config( 
            essid=WEBREPL_SSID, 
            password=WEBREPL_WIFI_PASSWORD, 
            security=3, # WPA2-PSK (рекомендуется), если без пароля, то значение 0 
            channel=6, # Wi-Fi канал, более стабильный 
            hidden=False       # Видимая сеть 
        ) 
        collect()# Уборка памяти 
        # Запускаем WebREPL 
        import webrepl 
        webrepl.start(password=WEBREPL_PASSWORD) 
        collect() 
        return True  #  Успешный запуск 
        
    else: 
        return False  #  WebREPL отключен 
connect_wifi()
start_webrepl()
print("Boot.py: WiFi и WebREPL запущены")

config.py

WIFI_SSID = "Ваша сеть"
WIFI_PASSWORD = b"Ваш пароль"
TELEGRAM_TOKEN = "Ваш токен"
TELEGRAM_CHAT_ID = 5308543785 # Ваш чат ID
WEBREPL_PASSWORD = "1234"        # ← пароль WebREPL тут
WEBREPL_SSID = "ESP32-WebREPL-Water"    # Имя точки доступа (можно изменить) 
WEBREPL_WIFI_PASSWORD = "12345678" # Пароль Wi-Fi сети (можно изменить)

Что я поменял «в бою»:

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

  1. Сторожевой пёс (Watchdog Timer). Это система антизависания. Теперь при любом сбое система не висит мёртвым грузом — она перезагружается и снова выходит на связь.

  2. Плановая еженедельная перезагрузка. Даже самая стабильная программа в MicroPython может со временем начать подъедать память или в ней могут накапливаться ошибки. Раз в неделю система сама себя перезагружает, чтобы начать с чистого листа. Это профилактика для долгосрочной стабильности.

 WEBREPL: инструмент на любителя

Честно говоря, за всё время я использовал WebREPL лишь однажды — для первоначальной отладки. Если вы не планируете активно удалённо менять код прямо на устройстве, смело можете его отключить. Это сэкономит немного оперативной памяти и упростит конфигурацию. Ставьте, только если вам реально нужен удалённый доступ к консоли.

Итоги: что получилось

Независимо: Работает автономно, лишь изредка требуя вашего внимания через уведомления.

Надёжно: Само восстанавливается после сбоев питания и чистит свою память.

Доступно: Его стоимость в разы ниже рыночных аналогов, а ремонтопригодность — на порядок выше.

Гибко: Вы можете легко адаптировать его под свои нужды — добавить второй датчик, сменить текст оповещений или интегрировать в другую систему умного дома.

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

 Творите, экспериментируйте и пусть ваш унитаз больше не оповещает вас о проблемах!

P.S. Возможно, найдутся те, кто скажет, что на C++ с библиотеками вроде Arduino можно сделать лучше и проще, но акцентирую ваше внимание, я ни в коем случае не агитирую против C++ и не утверждаю, что MicroPython — это «лучше», просто делюсь своим опытом. Так как я погружен в Python, то для решения бытовых задач (считать датчик, отправить данные)  мне ближе MicroPython, так как оказался удобным способом погрузиться в мир МК, и мне не надо переключаться на совершенно новую парадигму, а использовать уже знакомые модели и через REPL в реальном времени «пощупать» железо для начальных стадий прототипирования.