Некоторое время назад у моей семьи появился дом с небольшим садом в очень теплом и засушливом месте, и перед нами встала проблема регулярного полива.
Хотелось, чтобы система полива была автоматической, при этом при ее выборе приходилось учитывать следующие условия:
- очень дорогая вода, которую надо экономить всеми доступными способами
- разные по потребностям во влаге растения в саду, от суккулентов до влаголюбивых
- необходимость полностью автономного полива во время отсутствия людей в доме, желательно с возможностью удаленного контроля
- засушливый климат, не прощающий ошибок с поливом
Оценив готовые решения, которые удалось найти в местных 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 литров — именно этот объем является минимальной измеряемой величиной для такого счетчика. Эту проблему можно решить, разобрав счетчик и поменяв местами колесики, но пока до этого не дошли руки.