
Некоторое время назад у моей семьи появился дом с небольшим садом в очень теплом и засушливом месте, и перед нами встала проблема регулярного полива.
Хотелось, чтобы система полива была автоматической, при этом при ее выборе приходилось учитывать следующие условия:
- очень дорогая вода, которую надо экономить всеми доступными способами
- разные по потребностям во влаге растения в саду, от суккулентов до влаголюбивых
- необходимость полностью автономного полива во время отсутствия людей в доме, желательно с возможностью удаленного контроля
- засушливый климат, не прощающий ошибок с поливом
Оценив готовые решения, которые удалось найти в местных DIY сетях и на Amazon и почитав отзывы об их надежности (как правило, не самой высокой), решили попробовать сделать что-то самостоятельно.
Disclaimer: Автор не является IT-специалистом, и не претендует на профессиональное знание описываемой темы. Уровень исполнения проекта — хобби. Об уровне своих знаний в сфере программирования и электроники автор прекрасно осведомлен и будет очень признателен за предложения по улучшению и оптимизации использованных решений.
Принципиальная схема
Сад был разбит на 4 зоны полива, каждая из них снабжается индивидуальным датчиком влажности почвы и может поливаться по индивидуальному графику и разным количеством воды.
По земле проложены ПНД-трубки капельного полива с перфорацией, которые подключены к трубам сходящимся в водоразборном узле и подключенным через электромагнитные клапаны к водопроводу. Клапаны управляются реле подключенными к ESP8266 (Sonoff 4Ch).
Полив осуществляется по таймерам, в ночное время, чтобы увеличить количество воды, которое впитается в землю и не будет испарено солнцем.
При наступлении запланированного времени полива проверяется соответствие нескольким условиям:
- влажность почвы ниже заданной величины
- отсутствуют прогнозируемые осадки в достаточно большом количестве на ближайшие 2 дня
- не превышен лимит воды по поливу заданного для этой линии
Использованное оборудование
Raspberry Pie с установленным HassIO (уже была)
ESP32 DevKit, прошитая ESPHome, выступающая bluetooth-гейтвеем для MiFlora и принимающая данные от проводных датчиков влажности. Расположена в саду
Проводные датчики влажности Capacitive Soil Moisture Sensor v1.2, измеряющие влажность в ближних к месту установки ESP32 зонам полива
Датчики MiFlora, подключены к ESP32 по BLE, измеряющие влажность в удаленных зонах полива.
SONOFF 4Ch, прошитый ESPHome, расположен в водоразборном узле, куда приходят трубы от всех зон полива
4 Нормально-закрытых электромагнитных клапана на 220В расположены в водоразборном узле и подключены к Sonoff 4Ch. Открывают подачу воды для полива. Выбрана нормально-закрытая модель, с тем чтобы вероятность «наводнения» в случае каких-либо сбоев электрики и электроники была минимальной, и чтобы минимизировать количество требуемых выходов реле.
Импульсный водосчетчик, стоящий на входе в систему полива в водоразборном узле и подключенный к Sonoff 4ch. Позволил полностью передать данные о расходе воды в Home Asssistant и реализовать функционал полива заданным количеством. Весьма удачным оказалось то, что на этой версии sonoff уже распаяны контакты для прошивки и даже есть один свободный GPIO02 – на него и был повешен импульсный счетчик.

Так выглядит коллектор с установленными клапанами и счетчиком воды. Контроллер (sonoff 4Ch) в кадр не попал, он установлен на расстоянии в полметра в щитке IP65
Настройки ESPHome и Home Assistant
Sonoff 4Ch
Код ESPHome для него максимально примитивен, но на всякий случай приведу:
switch: - platform: gpio name: "Система полива линия 1" pin: GPIO12 id: sw1 icon: mdi:water - platform: gpio name: "Система полива линия 2" pin: GPIO5 id: sw2 icon: mdi:water - platform: gpio name: "Система полива линия 3" pin: GPIO4 id: sw3 icon: mdi:water - platform: gpio name: "Система полива линия 4" pin: GPIO15 id: sw4 icon: mdi:water binary_sensor: - platform: gpio name: "WaterCounter" id: button pin: number: GPIO2 mode: INPUT_PULLUP
Capacitive Soil Moisture Sensor v1.2
Кусок кода для ESPHome:
Подключать датчик можно только к аналоговым входам (ADC) микроконтроллера
Датчик придется калибровать, задав предельные значения напряжения для сухого датчика (в моем случае 3.22 В) и погруженного в воду (1,65 В). Я это делал включив демонстрацию log'ов в плагине ESPHome для HassIO и записав показания датчика в сухом виде и при погружении в воду.

После перепрошивки ESP32 в Home Assistant ничего настраивать не надо, там автоматически появляется датчик влажности с правильными единицами измерения
sensor: - platform: adc pin: GPIO34 filters: - lambda: |- if (x > 3.22) { return 0; } else if (x < 1.65) { return 100; } else { return (3.22-x) / (3.22-1.65) * 100.0; } name: "Датчик влажности почвы 1 линия проводной" update_interval: 60s attenuation: 11db unit_of_measurement: "%" accuracy_decimals: 0 icon: mdi:water-percent
Подключать датчик можно только к аналоговым входам (ADC) микроконтроллера
Датчик придется калибровать, задав предельные значения напряжения для сухого датчика (в моем случае 3.22 В) и погруженного в воду (1,65 В). Я это делал включив демонстрацию log'ов в плагине ESPHome для HassIO и записав показания датчика в сухом виде и при погружении в воду.

После перепрошивки ESP32 в Home Assistant ничего настраивать не надо, там автоматически появляется датчик влажности с правильными единицами измерения
Импульсный счетчик воды
Я использовал счетчик «Пульсар», но вообще должен подойти любой счетчик с импульсным выходом (идентифицируется по торчащему проводу). Принцип действия таких счетчиков очень простой — рядом с колесиками счетчика расположен геркон, который активируется магнитом, расположенном на одной из цифр колеса учета (у меня — цифра 3 на колесике 10 литров).
Соответственно, подключив провода от счетчика к GND и одному из GPIO мы можем получить простейший бинарный сенсор.
Код для ESPHome при этом примитивен:
В Home Assistant все немного сложнее:
Там я сделал несколько счетчиков (counter), сенсор и автоматизацию для работы с ними
При этом есть общий счетчик истраченной за все время воды (фактически, это виртуальный «двойник» механического счетчика). Он реализован в двух ипостасях — как counter, измеряемый в литрах и растущий в результате реакции на изменения бинарного сенсора из ESPHome, и как sensor, измеряемый в кубических метрах и берущий данные из предыдущего counter (для удобства сравнения цифр со счетами за воду).
Для целей управления поливом и сбора статистики были также созданы по 2 счетчика на каждую линию полива — один за все время, а второй за «сегодня». Так как физический счетчик у нас один, а линий четыре, для получения точных данных расхода по каждой линии полив каждой линии был разнесен по разным временным интервалам и запрещено одновременное их включение.
Соответственно, подключив провода от счетчика к GND и одному из GPIO мы можем получить простейший бинарный сенсор.
Код для ESPHome при этом примитивен:
binary_sensor: - platform: gpio name: "WaterCounter" id: counter pin: number: GPIO2 mode: INPUT_PULLUP
В Home Assistant все немного сложнее:
Там я сделал несколько счетчиков (counter), сенсор и автоматизацию для работы с ними
При этом есть общий счетчик истраченной за все время воды (фактически, это виртуальный «двойник» механического счетчика). Он реализован в двух ипостасях — как counter, измеряемый в литрах и растущий в результате реакции на изменения бинарного сенсора из ESPHome, и как sensor, измеряемый в кубических метрах и берущий данные из предыдущего counter (для удобства сравнения цифр со счетами за воду).
Для целей управления поливом и сбора статистики были также созданы по 2 счетчика на каждую линию полива — один за все время, а второй за «сегодня». Так как физический счетчик у нас один, а линий четыре, для получения точных данных расхода по каждой линии полив каждой линии был разнесен по разным временным интервалам и запрещено одновременное их включение.
Кусок кода для автоматизации (внутри automations.yaml или отдельный файл)
- alias: Подсчет воды по общему счетчику trigger: - entity_id: binary_sensor.watercounter platform: state from: 'on' to: 'off' action: - data: entity_id: - counter.my_water_counter service: counter.increment - alias: Подсчет воды по 1 линии trigger: - entity_id: binary_sensor.watercounter platform: state from: 'on' to: 'off' condition: - condition: state entity_id: switch.sistema_poliva_liniia_1 state: 'on' action: - data: entity_id: - counter.my_water_line1, counter.my_water_line1t service: counter.increment
Кусок кода configuration.yaml общий счетчик воды + два счетчика по одной линии полива
sensor: - platform: template sensors: water_counter: unit_of_measurement: 'M3' value_template: "{{ (states('counter.my_water_counter')| float)/1000 }}" counter: my_water_counter: initial: 2.667 step: 10 my_water_line1: name: "Полив 1 линия за все время (л)" initial: 0 step: 10 my_water_line1t: name: "Полив 1 линия сегодня (л)" initial: 0 step: 10
Датчик MiFlora
Датчик MiFlora при использовании ESPHome настраивается очень просто, инструкцию можно найти на сайте проекта esphome.io
В Home Assistant после такой настройки сразу появляются имеющиеся на датчике сенсоры — влажность, температура, освещенность и «фертильность» почвы. Единственный недостаток — странная работа сенсора заряда батареи, но для моих целей это не было критично.
В Home Assistant после такой настройки сразу появляются имеющиеся на датчике сенсоры — влажность, температура, освещенность и «фертильность» почвы. Единственный недостаток — странная работа сенсора заряда батареи, но для моих целей это не было критично.
Виртуальный сенсор прогнозируемых осадков
Смысл этого сенсора — выдавать в числовом виде прогноз осадков на ближайшие два дня. Эта цифра впоследствии используется в автоматизации и если она превышает заданный порог, полив не происходит.
Изначально сенсор построен на базе данных сервиса darksky. К сожалению, за время настройки системы этот сервис успела купить компания Apple и объявила о постепенном сворачивании работы сервиса «на сторону». API пока работает, но, судя по всему, скоро потребуется искать альтеранативу этому решению, благо в HA довольно много других сервисов погоды. Здесь я привожу настройки для darksky, думаю, что даже с другим сервисом большая их часть сохранит актуальность.
Сначала создаем 2 сенсора по количеству осадков на завтра и послезавтра:
Затем делаем на основе трех прогнозов один template-sensor:
Изначально сенсор построен на базе данных сервиса darksky. К сожалению, за время настройки системы этот сервис успела купить компания Apple и объявила о постепенном сворачивании работы сервиса «на сторону». API пока работает, но, судя по всему, скоро потребуется искать альтеранативу этому решению, благо в HA довольно много других сервисов погоды. Здесь я привожу настройки для darksky, думаю, что даже с другим сервисом большая их часть сохранит актуальность.
Сначала создаем 2 сенсора по количеству осадков на завтра и послезавтра:
Кусок кода configuration.yaml или sensors.yaml для сенсоров прогноза
В результате в HA появляются два сенсора: sensor.dark_sky_precip_intensity_1d и sensor.dark_sky_precip_intensity_2d, которые выдают цифры интенсивности осадков на завтра и послезавтра измеряемые в мм в час.
sensor: - platform: darksky api_key: xxxx_your_API_key_xxxx forecast: - 1 - 2 monitored_conditions: - precip_intensity
В результате в HA появляются два сенсора: sensor.dark_sky_precip_intensity_1d и sensor.dark_sky_precip_intensity_2d, которые выдают цифры интенсивности осадков на завтра и послезавтра измеряемые в мм в час.
Затем делаем на основе трех прогнозов один template-sensor:
Кусок кода configuration.yaml или sensors.yaml для обобщенного сенсора осадков
В HA появляется sensor.rain2days который уже выдает общие осадки в мм на ближайшие 2 дня.
По опыту использования, прогноз от Darksky не особо точен если речь идет о слабеньком дождике, но сильные ливни он предсказывает очень неплохо и для моих целей этого вполне достаточно
sensor: - platform: template sensors: rain2days: unit_of_measurement: 'mm' value_template: "{{ (((states('sensor.dark_sky_precip_intensity_2d')| float)+(states('sensor.dark_sky_precip_intensity_1d')| float))*24)| round(3) }}"
В HA появляется sensor.rain2days который уже выдает общие осадки в мм на ближайшие 2 дня.
По опыту использования, прогноз от Darksky не особо точен если речь идет о слабеньком дождике, но сильные ливни он предсказывает очень неплохо и для моих целей этого вполне достаточно
После того, как все данные собраны, можно приступать непосредственно к поливу.
Вот так у меня выглядит кусок интерфейса с одной из зон в Home Assistant:

Здесь можно задать количество воды для полива (ползунком) и посмотреть значения основных сенсоров и счетчиков. Я привел интерфейс для одной из линий, для остальных все аналогично, только на линиях с проводными датчиками данных несколько меньше.
В интерфейсе можно заметить одну «лишнюю» деталь — вспомогательный сенсор «Достигнута норма». Его пришлось ввести, т.к. мне не удалось заставить работать condition:template для остановки автоматизации при достижении нормы по количеству воды, и в результате автоматизация просто проверяет значение этого сенсора. Уверен, что эту часть автоматизации можно сделать проще и элегантней, но моего уровня для этого не хватило.
Ниже код получившегося «костыльного» темплейт-сенсора:
Сенсор достаточности полива (внутри configuration.yaml или отдельный файл)
- platform: template sensors: line4_status: friendly_name: "Линия 4 - достигнута норма" value_template: >- {% if states('counter.my_water_line4t')|float > states('input_number.slider4')|float %} yes {% elif states('counter.my_water_line4t')|float == states('input_number.slider4')|float %} yes {% else %} no {% endif %}
Автоматизация для запуска полива в конечном итоге выглядит так:
Запуск полива (внутри automations.yaml или отдельный файл)
- alias: Включение полива 4я линия в 23.01 trigger: platform: time at: "23:01:00" condition: condition: and conditions: # ПРОВЕРЯЕМ НОРМУ ПО ОСАДКАМ - condition: numeric_state entity_id: sensor.rainfor2days below: 5 # ПРОВЕРЯЕМ НОРМУ ПО ПОКАЗАНИЮ ДАТЧИКА ВЛАЖНОСТИ - condition: numeric_state entity_id: sensor.miflora_1_moisture below: 50 # ПРОВЕРЯЕМ, НАДО ЛИ ЕЩЕ ПОЛИВАТЬ СЕГОДНЯ ПО КОЛИЧЕСТВУ - condition: state entity_id: 'sensor.line4_status' state: 'no' action: - service: switch.turn_on entity_id: switch.sistema_poliva_liniia_4
Полив запускается поздно вечером, при этом каждая линия запускается в свой временной интервал. Разделение по времени запуска позволяет использовать один счетчик воды на входе для получения данных по 4 линиям.
При запуске проверяются три условия:
- не превышен ли лимит по количеству воды на сегодня (если, например, включали полив вручную)
- не превышает ли влажность 50% (по наблюдениям в наших условиях свежеполитая почва имеет влажность не более 60%)
- не ожидается ли осадков более 5 мм в ближайшие два дня.
Следующая автоматизация — отключение полива:
Отключение полива (внутри automations.yaml или отдельный файл)
- alias: Выключение полива 4й линии trigger: #Отключение по достижению лимита воды на полив - entity_id: sensor.line4_status platform: state to: 'yes' for: seconds: 5 #Отключение по времени - platform: time at: "23:59:00" #Отключение по достижению предельной влажности - platform: numeric_state entity_id: sensor.miflora_1_moisture above: 65 #Отключение по времени нахождения крана в открытом состоянии - platform: state entity_id: switch.sistema_poliva_liniia_4 to: 'on' for: minutes: 60 action: - service: switch.turn_off entity_id: switch.sistema_poliva_liniia_4
В автоматизации использовано целых 4 варианта триггеров, но в большинстве случаев она срабатывает по первому — «костыльному» сенсору, который отслеживает превышение лимита по количеству воды. Остальные триггеры сделаны в большой степени для подстраховки.
Ну и последняя относящаяся к проблеме автоматизация — обнуление ежедневного счетчика
Обнуление ежедневного счетчика (внутри automations.yaml или отдельный файл)
- alias: Обнуление ежедневного таймера 4я линия trigger: - platform: time at: "00:00:01" action: - service: counter.reset entity_id: counter.my_water_line4t
Экономика проекта
Затраты на управляющую часть системы полива получились следующие:
(Raspberry PIE c HassIO на борту и WiFi router с покрытием в саду уже были до начала проекта, их я не учитываю)
Электромагнитный клапан UNIPUMP BCX-15 1/2" (нормально закрытый) 4*20 евро
Sonoff 4CH 17 евро
Счетчик импульсный Пульсар 8 евро
ESP32 DevKitC 3.5 евро
Capacitive Soil Moisture Sensor v1.2 2*0.67 евро
Датчики MiFlora 2*16 евро
Щитки, коллектор, провода, фиттинги все вместе около 50 евро
ИТОГО: около 190 евро
Затраты времени на настройку датчиков и МК — примерно 3-4 вечера по нескольку часов, но большая часть времени была потрачена на «изобретение велосипедов» и придумывание «костылей», в целом работы там немного. Физическая сборка системы заняла около 2 вечеров.
В целом, ожидается экономия воды примерно в 20-50% по сравнению с «глуповатой» системой на таймерах и при местных ценах на воду система должна окупиться за один-два сезона.
Недостатки и планы по доработке
По итогам выполнения проекта вскрылись некоторые нюансы и возможности для дальнейшего совершенствования.
В частности, я бы заменил электромагнитные клапана 220В на модель 24В — это напряжение являются стандартными для систем полива. В этом случае пришлось бы добавить в систему трансформатор на 24В и сменить Sonoff 4Ch на что-то с сухим контактом (например, Sonoff 4CH Pro или что-то самосборное). Сами клапана при этом стоят дешевле (от 8 евро) и снижают вероятность поражения электрическим током.
Также выяснилось, что для работы с пластиковыми трубопроводами давление из водопровода является слишком высоким, и фитинги могут подтекать во время цикла полива. В моем случае это не критично, все фитинги расположены над поливаемой землей, но по-хорошему надо добавить на входе редуктор для понижения давления.
Еще немного расстроила невозможность учета количества воды для полива в объемах меньших чем 10 литров — именно этот объем является минимальной измеряемой величиной для такого счетчика. Эту проблему можно решить, разобрав счетчик и поменяв местами колесики, но пока до этого не дошли руки.
