У нас стал сохнуть фикус.
Не просто фикус, а красивый фикус Бенджамина, переплетёный такой. И вот тут, наконец, дозрело желание купить анализатор почвы для растений, который, вроде бы, и не особо нужен был, но при желании декорировать квартиру красивыми растениями, весьма капризными и непредсказуемыми, в хозяйстве пригодится.
Так что на ближайшей распродаже, которые водятся на AliExpress чуть ли не каждый месяц, была прикуплена пара датчиком Xiaomi Flower Care.
Понимая, в общем-то, отсутствие острой необходимости удалённого контроля за растениями, победа всё равно осталась за гиковской натурой и выбор пал в пользу "умных" датчиков с возможностью прикрутить их к Home Assistant. Но есть такие же, но без беспроводного модуля, состояние которых можно смотреть непосредственно на лампочке, встроенной в модуль.
Подключение к MiHome
Итак, датчики заказаны и приехали. Упакованы красиво и надёжно. Батарейка в комплекте, защищена от разряда плёночкой, отделяющей её от контактов. В комплекте простыня-инструкция, согласно которой нужно включить датчик и подключить его к MiHome. Для человека, у которого уже зоопарк датчиков от Xiaomi и Ko - ничего нового.
После подключения датчика начинается его настройка - первым делом предлагается выбрать растение для мониторинга. Ничего не понятно по-китайски, но можно в поиске вводить название на латыни, предварительно загуглив своё растение в википедии. Для выбранного растения подтягиваются его комфортные значения.
И вот датчик в MiHome, показывает какие-то значения:
Оригинальная версия MiHome из Google Play показывала сплошные китайские кракозябры и переключиться на любой более читаемый язык у меня не получилось, но помог в очередной раз мод от Vevs, в нём информация отображается хотя бы по-английски. Что тут есть:
- soil moisture - уровень влажности почвы, не пора ли полить цветочек;
- soil fertility - уровень питательности почвы, показывает, не пора ли подложить удобрений;
- light intensity - освещённость, которую любит цветочек;
- air temperature - текущая и комфортная температура воздуха.
В целом, как оказалось, показатели цветка в норме. Подключаем второй датчик - для юкки. Там не хватает воды и удобрений, хотя внешне растение бодрое и здоровое, не то что этот фикус.
Для удобства быстрого мониторинга можно в настройках MiHome переключиться на режим карточек, и тогда все параметры будут открываться не в новом окне, а в виде всплывающего баннера:
Но раз уж мы оказались в этом блоге - давайте подключать мониторинг цветочков в Home Assistant.
Подключение к Home Assistant
Для этого нам нужен старый добрый компонент ble_monitor и ble_token для датчика. Про компонент я писал тут, про то, как изъять токен - тут. Найти MAC стало сложнее, но и не нужно - компонент сам находит новые устройства и предлагает их в списке для добавления, осталось вписать только токен.
После добавления можно зайти в сенсоры нового устройства и переименовать их в читаемый и понятный вид:
Тут видно, что интеграция добавляет набор сенсоров для отслеживаемого растения, и можно произвольно их куда-нибудь добавить. Но просто добавить в панель Glance - неинтересно. Надо поискать что-то красивое.
Первый вариант, предусмотренный из коробки - карточка "Растение":
По сути - тот же Glance, но с подсветкой цветом состояний, не укладывающихся в рамки комфорта. Чтобы всего этого добиться, нужно создать новый тип данных - plant. Для этого в configuration.yaml прописываем:
plant:
edik:
sensors:
moisture: sensor.eduard_moisture
battery: sensor.eduard_battery
temperature: sensor.eduard_temperature
conductivity: sensor.eduard_conductivity
brightness: sensor.eduard_illuminance
min_moisture: 15
max_moisture: 60
min_conductivity: 350
max_conductivity: 2000
min_temperature: 10
max_temperature: 35
То есть перечисляем все наши сенсоры, а заодно задаём минимальные и максимальные комфортные значения для каждого сенсора. .
После того, как plant создан - его можно вставить в виде отдельной карточки:
Но это всё же не то, поэтому отправимся на поиски кастомных карточек.
Найден старый, 2019го года, репозиторий в гитхабе, который делает вот такую красоту:
А так же его форк:
Выглядит симпатично, но настрока очень геморройная и, не побоюсь этого слова, таинственная, потому что в обоих случаях фигурируют некие "справочники", которые надо скачать, конвертировать с помощью некоего скрипта на питоне, подложить куда следует и рядом ещё выкачать базу данных картинок.
Поэтому я пошёл третьим путём, так же подсмотренным на просторах hass-комьюнити - с помощью карточек picture-elements.
Конфиг одной такой карточки, для примера:
type: picture-elements elements:
- type: state-icon
entity: sensor.eduard_moisture
style:
height: 40px
left: 30px
top: 120px
width: 40px
background-color: rgba(255,255,255,1)
border: 2px solid green
border-radius: 100px
color: black
text-align: center
- type: state-label
entity: sensor.eduard_moisture
style:
left: 30px
top: 140px
width: 40px
height: 20px
background-color: green
border-radius: 20px
font-size: .6em
line-height: .5em
color: white
- type: state-icon
entity: sensor.eduard_conductivity
style:
background-color: rgba(255,255,255,1)
border: 2px solid green
border-radius: 100px
color: black
height: 40px
left: 80px
top: 120px
width: 40px
text-align: center
- type: state-label
entity: sensor.eduard_conductivity
style:
left: 80px
top: 140px
width: 40px;
height: 20px;
background-color: green
border-radius: 20px
font-size: .6em
line-height: .5em
color: white
- type: state-icon
entity: sensor.eduard_temperature
style:
background-color: rgba(255,255,255,1)
border: 2px solid green
border-radius: 100px
color: black
height: 40px
left: 130px
top: 120px
width: 40px
text-align: center
- type: state-label
entity: sensor.eduard_temperature
style:
left: 130px
top: 140px
width: 40px
height: 20px
background-color: green
border-radius: 20px
font-size: .6em
line-height: .5em
color: white
- type: state-icon
entity: sensor.eduard_illuminance
style:
background-color: rgba(255,255,255,1)
border: 2px solid green
border-radius: 100px
color: black
height: 40px
left: 180px
top: 120px
width: 40px
text-align: center
- type: state-label
entity: sensor.eduard_illuminance
style:
left: 180px
top: 140px
width: 40px;
height: 20px;
background-color: green
border-radius: 20px
font-size: .6em
line-height: .5em
color: white
image: [ссылка на фоновую картинку]
Уведомления в Telegram
Ну и раз уж мы стали уведомлять сами себя о происходящем в Телеграм, то и состояние наших цветов раз в сутки тоже можно отправлять.
Чтобы отправлять осмысленный текст вместо стандартных статусов интеграции plant, создадим кастомный сенсор на основе темплейтов в файле sensors.yaml (напомню, что мы вынесли домен сенсоров в отдельный файл):
- platform: template
sensors:
plant_edik:
friendly_name: 'Эдуард'
value_template: >
{% set prob = states.plant.edik.attributes.problem %}
{% if prob == 'none' %}
всем доволен
{% elif prob == 'conductivity low' %}
хочет удобрений
{% elif prob == 'conductivity high' %}
перекормлен
{% elif prob == 'moisture low' %}
хочет воды
{% elif prob == 'moisture high' %}
залит водой
{% elif prob == 'temperature low' %}
мёрзнет
{% elif prob == 'temperature high' %}
страдает от жары
{% else %}
чем-то недоволен
{% endif %}
Теперь мы получили новый сенсор sensor.plant_edik, который возвращает текущие пожелания нашего растения. Например, прямо сейчас наш фикус хочет удобрений. В таком виде и будем слать в Телеграм. И для этого удобно использовать блупринты (шаблоны), вместо того, чтобы писать отдельные автоматизации на каждый сенсор.
Готового блупринта я не нашёл, поэтому взял блупринт для уведомлений о необходимости полива (и только полива) и переработал его для опроса статуса и отправки всего, что есть:
blueprint:
name: State all plant sensors
description: Regularly test all plant sensors.
domain: automation
input:
time:
name: Time to test on
description: Test is run at configured time
default: '20:00:00'
selector:
time: {}
day:
name: Weekday to test on
description: 'Test is run at configured time either everyday (0) or on a given
weekday (1: Monday ... 7: Sunday)'
default: 0
selector:
number:
min: 0.0
max: 7.0
mode: slider
step: 1.0
exclude:
name: Excluded Sensors
description: Plant sensors (e.g. cactus) to exclude from detection. Only entities are supported, devices must be expanded!
default: {entity_id: []}
selector:
target:
entity:
domain: plant
actions:
name: Actions
description: Notifications or similar to be run. {{sensors}} is replaced with
the names of sensors being low on moisture.
selector:
action: {}
variables:
day: !input 'day'
exclude: !input 'exclude'
sensors: >-
{% set result = namespace(sensors=[]) %}
{% for state in states.sensor | selectattr('entity_id', 'match', '(.*)plant_') %}
{% set result.sensors = result.sensors + [state.name + ' ' + state.state] %}
{% endfor %}
{{result.sensors|join('\n')}}
trigger:
- platform: time
at: !input 'time'
condition:
- '{{ sensors != '''' and (day | int == 0 or day | int == now().isoweekday()) }}'
action:
- choose: []
default: !input 'actions'
mode: single
Блупринт создан, настраиваем на основе него автоматизацию, используем визуальный интерфейс, ибо в текстовом виде мы уже достаточно поделали. Идём в Настройки - Автоматизации, создаём новую:
И начинаем настраивать по тем параметрам, которые мы оставили от предыдущего блупринта или добавили самостоятельно. Сначала задаём название, которое будет видно в списке автоматизаций:
Затем задаём интервал сканирования и оповещения:
Здесь:
- Используемый проект - наш блупринт;
- Time to test on - время, в которое собирать статусы, я в скрипте вписал дефолтное время 20:00, но здесь могу в любой момент изменить на нужное мне;
- Weekday to test on - я оставил от предыдущего шаблона, мало ли пригодится. Это день недели, в который собирать статусы. Если нужно каждый день - оставляем 0, если нужен конкретный день недели, то указываем цифру от 1(пн) до 7 (вс). Пока - мониторю каждый день.
Следующий блок - исключения и действия:
Можно исключить какие-то данные типа plant из сканирования. Но у меня их пока всего два, пусть будут.
И самое интересное: Actions - действия. Я модифицировал скрипт проекта так, что он возвращает в переменной sensors массив строк в формате [sensor.friendly_name] [sensor.status]. Поэтому достаточно просто этот массив отправить без преобразований в интеграцию уведомлений. Поскольку темплейты в визуальном редакторе не поддерживаются - переключаемся в текстовый режим и вставляем:
service: notify.[название бота в HA]
data:
message: Наши цветочки{{ ':' }}{{ '\n' -}}{{sensors}}
При желании можно добавить других действий, например заорать Алисой на весь дом.
Всё, сохраняем полученную автоматизацию. При создании или редактировании через визуальный интерфейс ничего перезагружать не надо, автоматизация готова к использованию. Можно тут же в списке автоматизаций нажать кнопку "Запустить действия" и посмотреть, как новая автоматизация отрабатвает. Мой результат:
Ну вот и всё. Здоровья вам и вашим цветам, а я пошёл кормить цветочки, раз хотят.