May 29

Напомни вытащить белье из стиральной машины

Все как обычно - Шаг.1 забыл белье Шаг.2 оно там выдержалось Шаг.3 пришлось запускать заново. Понятно, что нужно тренировать память, не забыть вытащить белье, а то можно совсем облениться. Много раз слышал, что не так трудно встать и выключить свет самому, зачем эти голосовые помощники) Осталось только завести записную книжку с телефонными номерами.

Так ии видит напоминания про стирку

Есть конечно умные машинки, которые могут сообщить что стирка закончилась. Я вообще думал что параноик, но в рекламе попалась машинка которая подает свежий воздух что бы вещи не протухли (!) … даже название технологии придумали. Значит проблема не придумана из воздуха.

Функция конечно прикольная, да и лучше брать машинку с “мозгами”, но у нас другая дорога - сделаем уведомление для любой стиральной машинки.

Цель и средства

С точки зрения практичности

Основная задача - напомнить когда стирка закончена и нужно вытащить белье. Когда начал тестировать то сразу понял, что мощность прыгает от 0-5 ватт до 2,5 кВт, поэтому простой подход (триггер) по нулевому потреблению не подходит. Нужно еще отправить сообщение на колонки с Алисой, а также в телеграм и в дополнение проговорить голосом через телефон. Самое важное - определить что стирка закончена, только тогда высылать сообщения.

Главным хабом для сообщений должен быть телеграм, так как уведомления через родное приложение мне не нравятся. Телеграм у меня уже давно используется для данных от камер, напоминалок по домашним делам и прочей информации. Например, мощные напоминания Из хаоса в порядок: когда Home Assistant и Telegram превращают Todoist в домашнего ассистента

Сообщения можно пропустить или они могут прийти во время просмотра кино на самой экшен сцене. Нужно иметь возможность перенести напоминание и уже позже вытащить белье. Удобно будет если можно на 5, 15 или 30 минут передвинуть напоминание.

Если мы добавляем колонки - нужно предусмотреть ночной режим. Совсем не хочется проснуться ночью от требования вытащить белье, значит должны быть рамках (дозволенного).

Интересно, а сколько стоит одна стирка ночью и днем? Тоже заложим в программу и и узнаем.

Чему можно научиться

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

Я почувствовал боль при использовании чужой автоматизации у себя - поиск и замену сущностей под замену. Весело и увлекательно, но я решил строить автоматизации через переменные variables. Проще как в отладке, так и в правке - тексты и прочая информация доступна в одном месте.

Классический мем из интернета Гарольд испытывает боль

Когда автоматизация становится очень громоздкой - то правка становится крайне сложной, а объяснить другим что куда копировать/заменять ещё сложнее. Поэтому решил сделать блупринт, второй заход на снаряд, потому что в первый раз не было ни времени ни желания бороться с ИИ. Процесс затянул меня надолго, постоянное унижение Chat GPT, Copilit, qwen, deepseek и свежевыловленного Gemini и смена 2х IDE привели меня к рабочему варианту который возьму на вооружение в будущих проектах.

“Железо”

Стиральная машина у меня без возможности подключения к умному дому, поэтому нужно было найти инструмент для снятия потребления.

Розетка была уже установлена обычная, поэтому пришлось брать “розетку-в-рокетку”, что очень не рекомендуется делать с мощными приборами, а в стиралке есть ТЭН который нехило греет. Почему нельзя? Слабый контакт ⇒ нагрев ⇒ пожар.

Хотел давно протестить розетку на matter и тест провалился, розетка постоянно отваливалась и были большие задержки в передачи показаний. Думаю что просто попалась дешевая розетка … относительно дешевая.

Второй заход был с розеткой от Tuya по wi-if. В начале работала нормально, хотя и передавала данные с задержкой. После одной из перезагрузок отвалилась - так как была через облако.

Частое обновление данных нужно не для красивой статистики, а как раз для нормальной работы автоматизации. Если розетка “залипнет” на данных ниже нужного порога то автоматизация решит что все постирано. Частые обновления будут дергать триггер часто и как только реально мощность упадет - продолжит выполнять программу.

В итоге заказал простую розетку на zigbee - тут все круто, связь стабильная и быстрая передача показаний. Можно поставить режим восстановления питания после отключения и восстановления питания + отключить кнопку (Child lock). Так ещё эта розетка является роутером, усиливая сигнал для сети zigbee.

Я брал такую розетку Умная ZigBee розетка 16А Tuya, но лучше взять типа такой Умная розетка Bseed ZigBee черная страиваемая. У меня аналогичная от Aqara стоит для отключения утюга.

Розетка в розетку

Али https://aliclick.shop/r/c/1swzms78hs6txtpd?erid=2SDnjecPViD

ЯМ https://market.yandex.ru/cc/6tWMxz?erid=5jtCeReNx12oajvF3qkJHcn

Розетка встраиваемая

Али https://aliclick.shop/r/c/1swzn7iapi4xbxgl?erid=2SDnjdfYHmP

ЯМ https://market.yandex.ru/cc/6tWRen?erid=5jtCeReNx12oajvF3qkJHmb

Вот такая у меня, что бы сделать накладную розетку можно взять обычный накладной короб или для встраиваемых короб

Автоматизация и принцип работы

! Важно, автоматизация рассчитана на работу с телеграм ботом, что бы настроить нужно пройти этот путь Телеграм для Home Assistant и полезные автоматизации

При запуске стирки мы получаем сообщение о начале в телеграм и на колонки. Уведомления на колонки и телефон приходит с 8 до 24, но в телеграм приходит всегда. После окончания стирки мы получаем сообщение о завершении + стоимость стирки + время завершения стирки. Даже если мы отложим напоминание, все равно будем получать в напоминаниях время завершения стирки.

Blueprint - Проект (Легкий путь).

Это мой первый блупринт, сообщите плиз в комментариях если что не так - поправлю.

Блупринты оказались очень удобны для заведения автоматизаций. Можно сказать что блупринт это такой “трафарет” после заполнения которого сохраняется автоматизация. Так как это трафарет - то хранить данные сразу в переменных не получается, для этого создаются дополнительные сущности.

Если любая ошибка в обычной автоматизации тебя встречает ошибкой, то блупринт сразу ошибку не выдаст, только когда он станет “отпечатан” в качестве автоматизации. Это и съело у меня много времени пока все оттестировал - разные сценарии и разное заполнение параметров.

Через блупринт дополнительные сущности очень просто создать вспомогательные сенсоры (кроме интегрального сенсора). Любые настройки можно в любой момент поменять и пересохранить и они сразу начнут действовать.

Не получилось у меня остановиться на простом блупринте, поэтому можно менять тексты сообщений при старте/финише/напоминаниях по всем каналам Телеграм/Колонки/Телефон.

Можно выбрать время при котором будут отправляться сообщения голосом на телефон и колонки.

Гибко настроить напоминания по времени по 3 кнопкам.

Можно подсчитать стоимость стирки в зависимости от тарифа. У меня сенсоры тарифов используются в разных местах и через интеграцию с МосОблЭнерго обновляются автоматически = приходят новые тарифы тогда обновляются input.number с дневным/ночным тарифами. Получается что добавил 1 раз и больше не трогаешь.

В блупринте можно прописать все инструкции - что тоже удобно, не надо расписывать статьи.

Если что-то поправил - обновил блупринт и он работает по новым настройкам.

Как установить Blueprint:

Берем ссылку https://gist.github.com/smirnowegor/b95080bbda37b72dd3cbdceb96d82ae1#file-washingmachine-yaml**

  • Перейдите в Настройки Home Assistant.
  • Выберите Автоматизации и сцены → Проекты.
  • Нажмите Импортировать проект.
  • Вставьте URL блюпринта (Gist-ссылку).
  • Подтвердите импорт – блюпринт появится в списке доступных.

В результате получаем такое в телеграм. Видно, что напоминания сохраняют время завершения стирки - для понимания сколько уже там тухнет. Я не стал дату вводить, так как думаю что белье развесят в течении суток :)))

Автоматизация (сложный путь)

Тут придется заменять сущности в самой автоматизации, но можно понять принцип работы кода. Его основа заложена в блупринте.

В коде автоматизации можно подставить, для удобства все тексты в variables в конце автоматизации.

  • sensor.girlianda_power и sensor.girlianda_energy_kwh — датчики мощности и потребления энергии вашей стиральной машины.
  • media_player.yandex_station_r1067c000tzgvg и media_player.yandex_station_ffb8f006472cbdf3004b3817 — ваши медиаплееры для воспроизведения TTS.
  • tts.google_en_com — ваш TTS-сервис.
  • notify.mobile_app_egor_super — ваше push-уведомление.
  • telegram_bot.send_message и telegram_bot.answer_callback_query — ваш Telegram-бот.

Для подсчета потребляемой электроэнергии нужно создать Интегральный сенсор (звучит громко, но все просто). Сенсор вычисляет накопленное потребление энергии (кВт·ч) на основе мгновенной мощности устройства, позволяя отслеживать реальное энергопотребление:

  • Перейдите в "Настройки" → "Устройства и службы" → "Вспомогательные элементы".
  • Найдите или создайте новый элемент типа Интегральный сенсор.
  • В качестве исходного сенсора выберите тот, который измеряет мгновенную мощность вашей стиральной машины в ваттах (в нашем случае sensor.girlianda_power).
  • Выберите метод интеграции (рекомендуется метод трапеции).
  • Укажите префикс (например, "k" для преобразования ватт в кВт∙ч) и настройте округление (например, 7 знаков после запятой).
  • Итоговый сенсор будет накапливать данные и использоваться для расчёта разницы потребленной энергии, что позволит оценить стоимость стирки с учетом заданных тарифов.

sensor.girlianda_power это наш сенсор мгновенной мощности в ваттах.

Сам код:

alias: "Автостиральная машина: уведомления и обработка напоминанийОригинал"
description: Автостиральная машина
triggers:
  - entity_id: sensor.girlianda_power
    above: 10
    for:
      minutes: 1
    trigger: numeric_state
  - event_type: telegram_callback
    trigger: event
conditions: []
actions:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ trigger.platform == 'event' }}"
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.data == '/reminder_cancel' }}"
                sequence:
                  - data:
                      callback_query_id: "{{ trigger.event.data.id }}"
                      message: "{{ reminder_cancel_text }}"
                      show_alert: false
                    action: telegram_bot.answer_callback_query
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.event.data.data in ['/reminder_10',
                      '/reminder_30', '/reminder_60'] }}
                sequence:
                  - choose:
                      - conditions:
                          - condition: template
                            value_template: "{{ trigger.event.data.data == '/reminder_10' }}"
                        sequence:
                          - delay: "00:00:01"
                      - conditions:
                          - condition: template
                            value_template: "{{ trigger.event.data.data == '/reminder_30' }}"
                        sequence:
                          - delay: "00:30:00"
                      - conditions:
                          - condition: template
                            value_template: "{{ trigger.event.data.data == '/reminder_60' }}"
                        sequence:
                          - delay: "01:00:00"
                  - choose:
                      - conditions:
                          - condition: template
                            value_template: "{{ reminder_notify_enabled }}"
                        sequence:
                          - data_template:
                              message: "{{ reminder_text }}"
                            action: telegram_bot.send_message
                  - data:
                      callback_query_id: "{{ trigger.event.data.id }}"
                      message: "{{ reminder_callback_text }}"
                      show_alert: false
                    action: telegram_bot.answer_callback_query
                  - choose:
                      - conditions:
                          - condition: time
                            after: "08:00:00"
                            before: "23:55:00"
                        sequence:
                          - choose:
                              - conditions:
                                  - condition: template
                                    value_template: "{{ tts_reminder_notify_enabled }}"
                                sequence:
                                  - data_template:
                                      cache: true
                                      media_player_entity_id: >-
                                        media_player.yandex_station_r1067c000tzgvg
                                      message: "{{ tts_reminder_text }}"
                                    target:
                                      entity_id: tts.google_en_com
                                    action: tts.speak
                                  - data_template:
                                      cache: true
                                      media_player_entity_id: >-
                                        media_player.yandex_station_ffb8f006472cbdf3004b3817
                                      message: "{{ tts_reminder_text }}"
                                    target:
                                      entity_id: tts.google_en_com
                                    action: tts.speak
                          - choose:
                              - conditions:
                                  - condition: template
                                    value_template: "{{ reminder_notify_enabled }}"
                                sequence:
                                  - data_template:
                                      message: TTS
                                      data:
                                        ttl: 0
                                        priority: high
                                        channel: alarm_strem_max
                                        tts_text: "{{ tts_reminder_text }}"
                                      title: ""
                                    action: notify.mobile_app_egor_super
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ trigger.platform != 'event' }}"
        sequence:
          - variables:
              cycle_start_time: "{{ now().timestamp() }}"
              cycle_start_energy: "{{ states('sensor.girlianda_energy_kwh') | float }}"
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ message_start_notify_enabled }}"
                sequence:
                  - data_template:
                      message: >
                        {{ message_start_prefix }} Время: {{
                        now().strftime('%H:%M') }} Мощность: {{
                        states('sensor.girlianda_power') }} Вт
                    action: telegram_bot.send_message
          - choose:
              - conditions:
                  - condition: time
                    after: "08:00:00"
                    before: "23:55:00"
                sequence:
                  - choose:
                      - conditions:
                          - condition: template
                            value_template: "{{ tts_start_notify_enabled }}"
                        sequence:
                          - data_template:
                              cache: true
                              media_player_entity_id: media_player.yandex_station_r1067c000tzgvg
                              message: "{{ tts_start_text }}"
                            target:
                              entity_id: tts.google_en_com
                            action: tts.speak
                          - data_template:
                              cache: true
                              media_player_entity_id: >-
                                media_player.yandex_station_ffb8f006472cbdf3004b3817
                              message: "{{ tts_start_text }}"
                            target:
                              entity_id: tts.google_en_com
                            action: tts.speak
                  - choose:
                      - conditions:
                          - condition: template
                            value_template: "{{ push_start_notify_enabled }}"
                        sequence:
                          - data_template:
                              message: TTS
                              data:
                                ttl: 0
                                priority: high
                                channel: alarm_strem_max
                                tts_text: "{{ push_start_text }}"
                              title: ""
                            action: notify.mobile_app_egor_super
          - wait_for_trigger:
              - entity_id: sensor.girlianda_power
                below: 5
                for:
                  minutes: 1
                trigger: numeric_state
          - variables:
              cycle_end_time: "{{ now().timestamp() }}"
              cycle_end_energy: "{{ states('sensor.girlianda_energy_kwh') | float }}"
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ message_end_notify_enabled }}"
                sequence:
                  - data_template:
                      message: >
                        {% if cycle_end_time is defined and cycle_start_time is
                        defined and cycle_end_energy is defined and
                        cycle_start_energy is defined %}
                          {{ message_end_prefix }} Длительность: {{ ((cycle_end_time - cycle_start_time) // 60) | int }} мин {{ ((cycle_end_time - cycle_start_time) % 60) | int }} сек. Потреблено: {{ (cycle_end_energy - cycle_start_energy) | round(3) }} кВт·ч.
                        {% else %}
                          {{ message_end_prefix }} Данные не получены.
                        {% endif %}
                      inline_keyboard:
                        - Напомнить через 10 минут:/reminder_10
                        - Напомнить через 30 минут:/reminder_30
                        - Напомнить через 60 минут:/reminder_60
                        - Отменить напоминание:/reminder_cancel
                    action: telegram_bot.send_message
          - choose:
              - conditions:
                  - condition: time
                    after: "08:00:00"
                    before: "23:55:00"
                sequence:
                  - choose:
                      - conditions:
                          - condition: template
                            value_template: "{{ tts_end_notify_enabled }}"
                        sequence:
                          - data_template:
                              cache: true
                              media_player_entity_id: media_player.yandex_station_r1067c000tzgvg
                              message: "{{ tts_end_text }}"
                            target:
                              entity_id: tts.google_en_com
                            action: tts.speak
                          - data_template:
                              cache: true
                              media_player_entity_id: >-
                                media_player.yandex_station_ffb8f006472cbdf3004b3817
                              message: "{{ tts_end_text }}"
                            target:
                              entity_id: tts.google_en_com
                            action: tts.speak
                  - choose:
                      - conditions:
                          - condition: template
                            value_template: "{{ push_end_notify_enabled }}"
                        sequence:
                          - data_template:
                              message: TTS
                              data:
                                ttl: 0
                                priority: high
                                channel: alarm_strem_max
                                tts_text: "{{ push_end_text }}"
                              title: ""
                            action: notify.mobile_app_egor_super
variables:
  message_start_notify_enabled: true
  message_end_notify_enabled: true
  tts_start_notify_enabled: false
  push_start_notify_enabled: false
  tts_end_notify_enabled: true
  push_end_notify_enabled: true
  reminder_notify_enabled: true
  tts_reminder_notify_enabled: true
  message_start_prefix: 🧺 Стирка запущена! 🚀
  message_end_prefix: 🧺 Стирка завершена! ✅
  reminder_text: "Напоминаем: стирка завершена! Пожалуйста, заберите бельё."
  reminder_cancel_text: Напоминание отменено!
  reminder_callback_text: Напоминание сработало!
  tts_reminder_text: >-
    Напоминаем: стирка завершена! Пожалуйста, сучара ебаная блядь пидор, забери
    свое тухлое белье .
  tts_start_text: "Стирка запущена!  "
  push_start_text: "Стирка запущена! Время старта: {{ now().strftime('%H:%M') }}. ВАУ"
  tts_end_text: Стирка завершена!
  push_end_text: >-
    Стирка завершена! Цикл окончен. Если необходимо, воспользуйтесь
    напоминанием.
mode: single

Управление уведомлениями происходит через переменные:

variables:
  message_start_notify_enabled: true  # Включает отправку текстового уведомления в Telegram при запуске стирки
  message_end_notify_enabled: true    # Включает отправку текстового уведомления в Telegram при завершении стирки
  tts_start_notify_enabled: false     # Включает голосовое уведомление через TTS при запуске стирки
  push_start_notify_enabled: false    # Включает push-уведомление на мобильное устройство при запуске стирки
  tts_end_notify_enabled: true        # Включает голосовое уведомление через TTS при завершении стирки
  push_end_notify_enabled: true       # Включает push-уведомление на мобильное устройство при завершении стирки
  reminder_notify_enabled: true       # Включает отправку текстового напоминания в Telegram после завершения стирки
  tts_reminder_notify_enabled: true   # Включает голосовое напоминание через TTS после завершения стирки

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

Удобно?

Оказалось очень даже удобной функцией. Даже если пропустил уведомления через колонки, голосом через телефон - то горящее уведомление в телеге напомнит. Так или иначе - в телеграм я заглядываю очень часто, да и и сообщения от других автоматизаций тоже залетают в телегу - ещё повод проверить стиралку.

Можно использовать автоматизацию и блупринт для посудомоечной машины, утюга и прочих бытовых приборов которые требудет внимания. В блупринте вообще все тексты уведомлений легко настроить.

Единственное - заказал нормальную розетку, так на всякий случай.

Можно ещё добавить датчик открытия дверцы - что бы напоминать до того как откроется крышка и высылать сообщения каждый раз когда попадаешься на датчики движения в доме. Продвигаясь дальше в перфекционизме - добавляем цветную умную лампу информер, которая будет гореть красным пока не вытащит кожаный свое белье. У меня там лампы gx 53 и можно взять такую https://market.yandex.ru/cc/6tbeQv?erid=5jtCeReNx12oajvF3qoFFar достаточно редкие пока лампы.

Тестов было тьма… телеграм у меня стирал целый день, но если будет баг - плиз напишите.

Способ 1 Поддержать автора

Способ 2 https://donate.stream/yoomoney410013774736621

или через криптокошелёк (Только USDT) TCHekdJZFndXpDrHZGuTmqFNcqhWBTTzPr


Связаться со мной. (Консультации, проектирование и обучение)

Новый подход к электрике и дизайну помещений. Некоторые провода уже не нужно тянуть, какие-то решения можно принять после ремонта. Перенести выключатель, запустить кондиционер с телефона - возможно автоматизировать любую рутину.

Мой телеграм канал, там все быстрее обновляется телеграм.

Сайт smart4home.ru и альтернативный Умный дом на любом этапе

Соц сети: RuTube канал Удобный дом / You Tube канал Удобный дом Яндекс Дзен: Удобный дом / InGram

Платформы специалистов: Авито / Профи.ру / Яндекс Услуги https://uslugi.yandex.ru/profile/EgorSmirnov-2294380?from=telek


Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158 Реклама. ООО «ЯНДЕКС», ИНН 7736207543