<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Isaenkov.Pro</title><generator>teletype.in</generator><description><![CDATA[Сложные решения домашней автоматизации]]></description><image><url>https://img4.teletype.in/files/ff/37/ff372e0b-c266-46ec-84a5-b1b812eae8b2.png</url><title>Isaenkov.Pro</title><link>https://isaenkov.pro/</link></image><link>https://isaenkov.pro/?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/isaenkov.pro?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/isaenkov.pro?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Tue, 05 May 2026 11:58:10 GMT</pubDate><lastBuildDate>Tue, 05 May 2026 11:58:10 GMT</lastBuildDate><item><guid isPermaLink="true">https://isaenkov.pro/bathroom-light-control</guid><link>https://isaenkov.pro/bathroom-light-control?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro</link><comments>https://isaenkov.pro/bathroom-light-control?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro#comments</comments><dc:creator>isaenkov.pro</dc:creator><title>Лучшая автоматизация света в ванной | Node-RED, Home Assistant</title><pubDate>Sat, 24 Jul 2021 19:24:12 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/82/5e/825e4095-2fc0-48ea-b035-3c3990f2cea9.jpeg"></media:content><description><![CDATA[<img src="https://img4.teletype.in/files/7f/03/7f0355e6-aaaf-4189-97e6-1552774d7024.png"></img>Казалось бы, простой вопрос: «Как сделать включение света автоматическим?». Решается это, действительно, очень просто. Но вот «Как сделать автоматическим, а, главное, корректным, его выключение?» — совсем не то же самое.]]></description><content:encoded><![CDATA[
  <figure id="l5ZK" class="m_column">
    <img src="https://img4.teletype.in/files/7f/03/7f0355e6-aaaf-4189-97e6-1552774d7024.png" width="1754" />
  </figure>
  <p id="tIrv">Казалось бы, простой вопрос: «Как сделать включение света автоматическим?». Решается это, действительно, очень просто. Но вот «Как сделать автоматическим, а, главное, корректным, его выключение?» — совсем не то же самое.</p>
  <p id="3oZV">Суть задачи сводится к определению наличия человека в помещении. И сейчас я покажу, как с нуля построить вот такой сценарий в Node-RED, используя датчик движения и датчик открытия двери.</p>
  <figure id="3F7E" class="m_column">
    <img src="https://img2.teletype.in/files/1c/07/1c07b2d8-8bcd-41fc-9d3f-45583bd650e3.png" width="1826" />
    <figcaption>Код всего Node-RED-flow доступен на <a href="https://raw.githubusercontent.com/isaenkovpro/configs/master/006%2520Bathroom%2520Light%2520Control/nodered_flow.json" target="_blank">GitHub</a>.</figcaption>
  </figure>
  <p id="TROm"></p>
  <figure id="vTCi" class="m_column">
    <iframe src="https://www.youtube.com/embed/w4kYax-Pl5k?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="Ck7l"></p>
  <p id="VJPu">Ещё с самого начала пути внедрения умного дома в 2012 году мне никак не удавалось решить вторую часть этой головоломки, а именно — выключение света в ванной. Встроенные и сторонние инструменты создания сценариев в используемых тогда мною контроллерах не имели никаких шансов на это.</p>
  <ul id="p115">
    <li id="ME3Y"><strong>Vera Lite</strong> — любой более-менее сложный сценарий автоматизации на этом контроллере решался только с помощью сторонних модулей. Причём, насколько я помню, надёжностью это решение не очень отличалось.</li>
    <li id="vmY8"><strong>Fibaro Home Center Lite</strong> — это iPhone в мире контроллеров домашней автоматизации, только версии Lite. Красиво, просто, для хомячков. Сложные сценарии создавались путём дробления алгоритма на несколько частей с последующей их связкой. Но это не спасало, и для еще большей гибкости нужно было писать сценарии на языке LUA.</li>
    <li id="Z5Pl"><strong>Raspberry Pi</strong> — хардкорное решение с Raspbian и Domoticz. Такой инструмент как Blockly позволял реализовывать по-настоящему сложные вещи. Тогда мне казалось, что я решил поставленную задачу. Пусть с костылями и нагромождениями блоков. Но, нет, осечки и ложные выключения всё еще случались.</li>
  </ul>
  <p id="dzW3"></p>
  <p id="GkJD">Лишь в 2018 году, когда я переехал на более-менее юзабельную версию Home Assistant, примерно 0.40, я познакомился с Node-RED — прекрасный, гибкий, мощнейший инструмент автоматизации. И в нём то я и обнаружил тот заветный компонент для решения моей задачи — state-machine.</p>
  <figure id="mtTv" class="m_custom">
    <img src="https://img3.teletype.in/files/61/4b/614b48e4-b18c-48d6-a91d-2b799f27138a.png" width="507" />
  </figure>
  <p id="AVp5">State-машина или Конечный автомат в рамках Node-RED — это нода, имеющая определённое количество состояний и триггеров, которые вызывают её переход из одного состояния в другое. В любой момент времени нода может находиться только в одном из состояний и переходить в другое лишь, когда сработает определённый для этого состояния триггер. Один и тот же триггер может быть использован для перехода более чем из одного состояния.</p>
  <p id="tPkW">Вот схематичный пример того, как будет выглядеть будущий сценарий:</p>
  <figure id="hGui" class="m_column">
    <img src="https://img4.teletype.in/files/f9/34/f934ee65-2edc-458b-80f8-d53aa55659b9.png" width="1674" />
  </figure>
  <ul id="4rEK">
    <li id="ookL">Я открываю дверь (2) — свет включился.</li>
    <li id="k5SJ">Захожу внутрь (3) — движение обнаружилось (4).</li>
    <li id="oQnf">Закрываю дверь (5) и начинаю делать свои дела (6) — свет остаётся включённым, и при выполнении следующего условия по обнаружению движения (7), помещение помечается занятым (8). С этого момента свет сам не погаснет.</li>
    <li id="NjN6">Выхожу из санузла (9) и закрываю дверь (5) — свет выключится через заданный промежуток времени (10).</li>
    <li id="ATRk">Если оставить дверь открытой (2, 9, 14), то свет погаснет по таймауту после последнего события об отсутствии движения (11). Состояние помещения до тех пор не меняется.</li>
    <li id="N57B">Если, находясь внутри, выключить свет выключателем (12), то при следующем обнаружении движения, он включится (13).</li>
  </ul>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Fg2q">Детальное описание сценария Node-RED доступно в <a href="https://youtu.be/w4kYax-Pl5k?t=169" target="_blank">видео</a>.</p>
  </section>
  <p id="QvtC"></p>
  <p id="QbbU">В примере показан сценарий с использованием датчика движения Fibaro.</p>
  <figure id="BJF0" class="m_custom">
    <img src="https://img2.teletype.in/files/d5/cf/d5cf7c4f-5ccc-49f7-8c81-277c14fe6eb0.jpeg" width="303" />
  </figure>
  <p id="LUN2">В нём можно настраивать период, после которого контроллеру отправляется сообщение о том, что движения больше нет. Я поставил 15 секунд.</p>
  <p id="r7yO">Если вместо него использовать, например, датчик от Aqara, то немного поменяется логика определения повторного движения для перехода в состояние «занято».</p>
  <figure id="w4mB" class="m_custom">
    <img src="https://img1.teletype.in/files/cf/d4/cfd4aad8-1b5f-4413-96a1-a3173e8bbe39.jpeg" width="301" />
  </figure>
  <p id="rZR5">Так как он отправляет контроллеру статус о том, что движения больше нет, только спустя 1 минуту после последнего обнаружения, то 90 секунд, заданных в таймере в примере, гарантированно достаточно для того, чтобы точно определить наличие человека внутри, при условии, что дверь не открывалась.</p>
  <p id="Jk1S">Еще пару лет с момента создания я неспешно доводил этот сценарий до ума, вылавливая разные редкие глюки и ложные срабатывания. Поэтому, кроме как лучшей, эту автоматизацию ни назвать.</p>
  <p id="ymz5"></p>
  <hr />
  <p id="m2fQ">Все конфигурации, описанные в статье, доступны на <a href="https://github.com/isaenkovpro/configs/tree/master/006%20Bathroom%20Light%20Control" target="_blank">GitHub</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://isaenkov.pro/water-softener-salt-level</guid><link>https://isaenkov.pro/water-softener-salt-level?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro</link><comments>https://isaenkov.pro/water-softener-salt-level?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro#comments</comments><dc:creator>isaenkov.pro</dc:creator><title>Умягчитель воды в доме: считаем остаток соли в баке | ESP8266</title><pubDate>Sat, 24 Jul 2021 18:50:46 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/37/9e/379e8947-13b4-4743-b09b-b4988ed03282.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/2a/d3/2ad33256-f502-4594-898d-530e97aa78ae.png"></img>В загородных домах часто используются умягчители воды, внутри которых находится фильтрующий материал (в моём случае — это ионообменная
смола), и который необходимо периодически промывать раствором
поваренной соли.]]></description><content:encoded><![CDATA[
  <figure id="hMJy" class="m_column">
    <img src="https://img3.teletype.in/files/2a/d3/2ad33256-f502-4594-898d-530e97aa78ae.png" width="1594" />
  </figure>
  <p id="roMD">В загородных домах часто используются умягчители воды, внутри которых находится фильтрующий материал (в моём случае — это ионообменная<br />смола), и который необходимо периодически промывать раствором<br />поваренной соли.</p>
  <p id="PGLT">Основной процедурой обслуживания умягчителя является — пополнение солевого бака. Сейчас я расскажу о том, как я сделал отображение в Home Assistant примерного остатка соли и настроил уведомление о необходимости пополнения бака.</p>
  <figure id="vbN0" class="m_column">
    <iframe src="https://www.youtube.com/embed/RquFeXZ_I5c?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="PcrZ"></p>
  <p id="877O">Мой умягчитель настроен на промывку смолы через каждые 5 кубов потреблённой воды. И 50-ти кг соли, которые я засыпаю в бак, хватает примерно на 5-6 циклов промывки. Поэтому, первым делом, я думал подключиться к контроллеру для подсчета этих циклов, но в нём не нашлось никакой штатной возможности для этого.</p>
  <figure id="91Av" class="m_column">
    <img src="https://img1.teletype.in/files/87/2e/872e3f1f-bb2e-4b70-9090-28237b325a9c.png" width="1391" />
  </figure>
  <p id="fRsJ"></p>
  <p id="YLe0">Дальше я захотел применить ультразвуковой датчик для измерения расстояния. Но опыт использования во влажной среде показал, что работают они не дольше<br />нескольких месяцев, после чего выходят из строя из-за коррозии. А бак с солью – это очень даже влажная среда.</p>
  <figure id="0Dfc" class="m_custom">
    <img src="https://img4.teletype.in/files/7e/9a/7e9a9bb6-87f7-4346-bc28-b6039dd84c27.jpeg" width="226" />
  </figure>
  <p id="3umq">Поэтому я остановился на варианте с косвенным подсчетом уровня соли через мониторинг потребления воды. Благо, у счетчика оказался в наличии импульсных выход, и можно вести подсчёт с точностью до 1 литра. Опытным путём я выяснил, что соль нужно досыпать в бак примерно через каждые 30 кубов потреблённой воды.</p>
  <figure id="LNPV" class="m_column">
    <img src="https://img1.teletype.in/files/02/09/02093e1c-096f-4ea7-89f9-7a0eadb63ae1.png" width="1919" />
  </figure>
  <p id="B1CK">Идея следующая: когда я открываю крышку для пополнения бака, показания счетчика воды фиксируются, и начинается отсчёт 30-ти кубов, по достижении<br />которых я получаю уведомление. При следующем открывании крышки цикл повторяется вновь.</p>
  <p id="GnnU">Для реализации задуманного я задействовал устройство на базе ESP8266, которое спаял несколько лет назад для подключения двух счётчиков<br />воды. Ранее на нём была прошивка NodeMCU с написанным мною кодом. Теперь я загрузил в него прошивку ESPHome, которая изначально была создана для тесного взаимодействия с Home Assistant через API.</p>
  <figure id="PWC7" class="m_column">
    <img src="https://img2.teletype.in/files/9c/a5/9ca5b4c2-7e4c-4df9-b73a-351244f50cbe.jpeg" width="2878" />
  </figure>
  <p id="XE7N"></p>
  <h3 id="8df9">Схема подключения</h3>
  <figure id="iAY2" class="m_column">
    <img src="https://img1.teletype.in/files/4f/13/4f132899-5ac9-400f-a98e-c38a250d2c92.png" width="685" />
  </figure>
  <p id="VcSW">Один из проводов счетчика и датчика открытия вместе подключаются к пину Ground. Каждый оставшийся провод подключается к свободному цифровому пину платы, кроме GPIO0 и 2, чтобы не возникла проблема с загрузкой. Также добавляется подтягивающий резистор по схеме. Для дополнительной защиты от дребезга контактов можно добавить конденсатор.</p>
  <p id="RhYS">Вообще для упрощения подключения питания и прошивки модуля я бы рекомендовал использовать готовую плату вроде Wemos D1 mini.</p>
  <figure id="th11" class="m_custom">
    <img src="https://img1.teletype.in/files/c9/56/c9569b6e-7a55-49d2-ae2f-f4d9c91bf902.png" width="263" />
  </figure>
  <p id="DclT"></p>
  <h3 id="J8Nw">Прошивка</h3>
  <p id="3gJa"></p>
  <figure id="IuOr" class="m_column">
    <img src="https://img2.teletype.in/files/97/a2/97a298a1-b0e8-40a4-9be0-6d807557446b.png" width="1919" />
  </figure>
  <p id="aZJp">ESPHome — это система для настройки модулей ESP8266 и ESP32 с помощью простых и мощных конфигурационных файлов, и удаленного управления ими с помощью систем домашней автоматизации.</p>
  <p id="Jrgv">Код конфигурации модуля ESP представлен ниже:</p>
  <pre data-lang="yaml" id="roB1">esphome:
  name: esp-watercounter
  platform: ESP8266
  board: d1_mini
  on_boot:
    - logger.log: &quot;Wait for MQTT connected&quot;
    - wait_until:
        mqtt.connected:
    - delay: 3s
    - if:
        condition:
          mqtt.connected:
        then:
        - globals.set:
            id: water_count_var
            value: !lambda |-
              return id(water_counter).state;

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  manual_ip:
    static_ip: 172.16.1.120
    subnet: 255.255.255.0
    gateway: 172.16.1.1
    dns1: 172.16.1.1

logger:
api:
ota:

mqtt:
  broker: !secret mqtt_host
  username: !secret mqtt_user
  password: !secret mqtt_pass
  discovery: false

globals:
  - id: water_count_var
    type: int
    restore_value: no

time:
  - platform: sntp
    on_time:
      - seconds: 0
        minutes: /5
        then:
          - if:
              condition:
                lambda: |-
                  return id(water_count_var) &gt; 0;
              then:
              - mqtt.publish:
                  topic: /pantry/watercounter
                  retain: true
                  payload: !lambda |-
                    return to_string(id(water_count_var));

binary_sensor:
  - platform: gpio
    name: &quot;Pantry Tank cap&quot;
    device_class: window
    pin:
      number: 5
      mode: INPUT_PULLUP
    filters:
      - delayed_on: 150ms
      - delayed_off: 150ms

  - platform: gpio
    name: &quot;Pantry Water usage&quot;
    id: water_usage
    internal: true
    pin:
      number: 4
      mode: INPUT_PULLUP
    filters:
      - delayed_on: 100ms
      - delayed_off: 100ms
    on_press:
      then:
        - if:
            condition:
              lambda: |-
                return id(water_count_var) &gt; 0;
            then:
              - lambda: &#x27;id(water_count_var) += 1;&#x27;

sensor:
  - platform: mqtt_subscribe
    name: &quot;Pantry Water count (L)&quot;
    icon: &quot;mdi:water-pump&quot;
    id: water_counter
    accuracy_decimals: 0
    unit_of_measurement: &#x27;L&#x27;
    topic: /pantry/watercounter</pre>
  <p id="8NSd">В секции wifi указываем статический IP-адрес, который будет назначен устройству после загрузки в него прошивки, либо позволяем DHCP-серверу назначить IP-адрес автоматом. Главное, не забыть затем зарезервировать его за конкретным устройством, во избежание возможной потери связи с Home Assistant.</p>
  <p id="raj3">Имя точки доступа и пароль к ней записываю в виде секретов в отдельном окне редактора.</p>
  <figure id="5kTR" class="m_column">
    <img src="https://img3.teletype.in/files/ae/f1/aef1d39c-2891-4344-9085-8caf13a12cee.png" width="1803" />
  </figure>
  <p id="O3y6">Далее следуют параметры подключения к MQTT-брокеру. И основная часть — описание подключенных к модулю датчиков.</p>
  <p id="RAyj">Геркон на крышке бака подключен к пятому цифровому пину, device_class: window будет передавать статус Открыто/Закрыто, вместо on/off.</p>
  <p id="mCth">Счётчик воды подключен к 4-му пину, у него также есть защита от дребезга,<br />а сам компонент помечен как внутренний, т. к. его отображение в Home Assistant не требуется, и его использование не выходит за пределы модуля ESP.</p>
  <p id="aISf">Суть конфигурации сводится к следующему:</p>
  <ul id="A7UM">
    <li id="EhCy">создаётся глобальная переменная, в которую записываются текущие показания счетчика, хранимые в mqtt-брокере.</li>
    <li id="Vxsm">для счетчика прописана автоматизация, которая при замыкании контактов<br />после каждого потреблённого литра воды, увеличивает значение глобальной переменной на этот самый 1 литр, а затем публикует обновлённое значение в mqtt-топике.</li>
    <li id="GtvF">дополнительно создан сенсор, задача которого — отображать полученное из mqtt-топика значение показаний счетчика, т. к. этот сенсор уже будет виден в Home Assistant.</li>
  </ul>
  <p id="L3tG">После сборки и загрузки прошивки в модуль, его можно добавить в Home Assistant через меню интеграций:</p>
  <figure id="LWqq" class="m_column">
    <img src="https://img2.teletype.in/files/96/7a/967ac4f4-9b0e-4bd0-adbc-3b30eba03e7b.png" width="701" />
  </figure>
  <p id="zkFm"></p>
  <p id="3vNC">Смотрим, что появились два новых устройства. И можно написать первый<br />небольшой сценарий, в котором будут фиксироваться текущие показания счётчика воды для дальнейших расчётов:</p>
  <figure id="079z" class="m_column">
    <img src="https://img1.teletype.in/files/c1/e5/c1e51b27-9134-41a8-ad30-e3947ee6849b.png" width="1570" />
    <figcaption>Код всего Node-RED-flow доступен на <a href="https://raw.githubusercontent.com/isaenkovpro/configs/master/003%2520Water%2520Softener%2520Salt%2520Level/nodered_flow.json" target="_blank">GitHub</a>.</figcaption>
  </figure>
  <p id="qKWB"></p>
  <p id="2tmn">Проверяем, что крышка открыта, сбрасываем флаг, и считываем текущее значение показаний счетчика, которое публикуем в отдельный MQTT-топик. Сам счётчик добавлен как сенсор в Home Assistant:</p>
  <pre data-lang="yaml" id="sr2L">- platform: template
  sensors:
    pantry_water_count:
      friendly_name: &quot;Pantry Water count&quot;
      unit_of_measurement: &#x27;m³&#x27;
      icon_template: &quot;mdi:water-pump&quot;
      value_template: &gt;-
          {% if states(&#x27;sensor.pantry_water_count_l&#x27;) in [&#x27;unavailable&#x27;, &#x27;unknown&#x27;, &#x27;none&#x27;] %}
            unavailable
          {% else %}
            {{ states(&#x27;sensor.pantry_water_count_l&#x27;)|float / 1000 }}
          {% endif %}</pre>
  <p id="ol1A"></p>
  <p id="5hSI">Для отображения зафиксированных показаний счётчика, при которых была открыта крышка бака, я создал другой сенсор:</p>
  <pre data-lang="yaml" id="A9iT">- platform: mqtt
  name: Pantry Tank last refill
  icon: mdi:basket-fill
  state_topic: &quot;/pantry/watercounter/salt_refill&quot;
  unit_of_measurement: &quot;m³&quot;</pre>
  <p id="b3Cq"></p>
  <p id="VXzK">Непосредственно для расчёта остатка соли создал еще один сенсор на основе шаблона:</p>
  <pre data-lang="yaml" id="jbF9">- platform: template
  sensors:
    pantry_tank_salt_left:
      friendly_name: &quot;Pantry Tank salt left&quot;
      unit_of_measurement: &quot;%&quot;
      value_template: &gt;-
        {% if 0 &lt; ((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0) &lt;= 100 %}
          {{ ((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0) }}
        {% elif ((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0) &lt;= 0 %}
          0
        {% endif %}
      icon_template: &gt;-
        {% if 60 &lt; (((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0)) &lt; 100 %}
          mdi:delete
        {% elif 30 &lt; (((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0)) &lt; 60 %}
          mdi:delete-outline
        {% elif 10 &lt; (((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0)) &lt; 30 %}
          mdi:delete-alert-outline
        {% elif (((30 - (states(&#x27;sensor.pantry_water_count&#x27;)|float - states(&#x27;sensor.pantry_tank_last_refill&#x27;)|float))/30*100) | round(0)) &lt; 10 %}
          mdi:delete-forever-outline
        {% endif %}</pre>
  <p id="b79s">В строке value_template происходит следующее:</p>
  <p id="0bws">30 — полученный опытным путём примерный объем потреблённой воды, на который хватает одной засыпки соли. Сначала из этого объема вычитается разница между текущим значением показаний счётчика воды (sensor.pantry_water_count) и фиксированным значением (sensor.pantry_tank_last_refill), при котором засыпалась новая порция соли, а затем полученное округлённое значение преобразуется в проценты.</p>
  <p id="poA6">Т.к. в MQTT-топике значения хранятся в виде строк, то в этих местах они преобразуются в числа с плавающей точкой (float).</p>
  <p id="B0Mz">В icon_template описаны условия для отображения разных иконок в зависимости от текущего уровня соли.</p>
  <p id="Dm7P"></p>
  <p id="Bszz">Сценарий для отправки уведомления делает следующее:</p>
  <p id="qElA">Каждые 12 часов проверяется текущее значение уровня соли, которое записывается в отдельную переменную (msg.salt_level), проверяется состояние<br />флага, который предотвращает повторную отправку уведомлений при следующей проверке, а сам является обычным виртуальным переключателем input_boolean:</p>
  <pre data-lang="yaml" id="uCJa">pantry_water_tank_refill_flag:
  name: Pantry Tank refill flag
  icon: mdi:delete-alert-outline</pre>
  <p id="XEwu"></p>
  <p id="Nwb8">Следом в Function- ноде происходит проверка условий, что флаг (input_boolean) ещё не был включен, а остаток соли менее 10%, и далее включается флаг и формируется уведомление в Telegram, в текст которого подставляется переменная со значением остатка:</p>
  <figure id="kXDn" class="m_custom">
    <img src="https://img2.teletype.in/files/96/2b/962b8fd0-09a9-4738-a9d8-371bd9d71a37.png" width="320" />
  </figure>
  <p id="EJLR"></p>
  <p id="P8L0">Вот так всё это выглядит в Home Assistant:</p>
  <figure id="gBEM" class="m_original">
    <img src="https://img1.teletype.in/files/87/0a/870aad82-05c8-47a9-b72e-569a42dcf6e6.png" width="494" />
  </figure>
  <p id="mgb2"></p>
  <p id="mk2E">Эту систему я тестировал и дорабатывал в течение нескольких месяцев, и сейчас она прекрасно справляется со своей задачей.</p>
  <p id="YFNf"></p>
  <hr />
  <p id="4euM">Все конфигурации, описанные в статье, доступны на <a href="https://github.com/isaenkovpro/configs/tree/master/003%20Water%20Softener%20Salt%20Level" target="_blank">GitHub</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://isaenkov.pro/heating-control-unit</guid><link>https://isaenkov.pro/heating-control-unit?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro</link><comments>https://isaenkov.pro/heating-control-unit?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro#comments</comments><dc:creator>isaenkov.pro</dc:creator><title>Контроллер системы отопления для умного дома | ESPHome, Home Assistant</title><pubDate>Sat, 24 Jul 2021 18:08:14 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/26/11/2611b66b-aa94-44c0-a874-235a763ca587.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/85/5e/855e3a5d-1d2b-4fa0-a4f7-b14b56f6bc01.png"></img>Одной из самых сложных для меня тем, которая вызывала много вопросов по реализации, была – регулировка температуры радиаторов отопления.]]></description><content:encoded><![CDATA[
  <figure id="uYEX" class="m_column">
    <img src="https://img1.teletype.in/files/85/5e/855e3a5d-1d2b-4fa0-a4f7-b14b56f6bc01.png" width="1840" />
  </figure>
  <p id="ibqw">Одной из самых сложных для меня тем, которая вызывала много вопросов по реализации, была – регулировка температуры радиаторов отопления.</p>
  <figure id="VyCU" class="m_column">
    <iframe src="https://www.youtube.com/embed/wFwaG3vrZbc?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="bUSm">Лет 7 назад я установил на один из радиаторов термоголовку Danfoss с Z-Wave. И за пару месяцев использования, мне так и не удалось совладать с ней. Основными факторами, сыгравшими против, было то, что температура замерялась непосредственно возле радиатора и сильно отличалась от всего помещения. А также скорость реакции термоголовки на изменение уставки со стороны контроллера была неприемлемо низкой.</p>
  <figure id="lLCw" class="m_column">
    <img src="https://img2.teletype.in/files/59/15/5915c16d-e4f0-4bba-8dd3-bae67b26f179.jpeg" width="1836" />
  </figure>
  <p id="2WQB">Чуть позже я опробовал еще одно подобное устройство от Stella Z, но проблема с замером температуры непосредственно возле отопительного прибора никуда не делась.</p>
  <figure id="aW0O" class="m_original">
    <img src="https://img3.teletype.in/files/ab/0a/ab0adaa2-cd3b-4837-ae6d-2a4f13851fcf.jpeg" width="500" />
  </figure>
  <p id="ktYW">Да, существуют термоголовки от того же Danfoss с выносным термодатчиком,<br />но выглядит это довольно ужасно. К тому же оставался вопрос, как подружить такое устройство с умным домом.</p>
  <p id="DRTx">Спустя какое-то время Fibaro представили свою термоголовку с отдельным беспроводным датчиком температуры. И это уже выглядело интереснее предыдущих вариантов.</p>
  <figure id="DXRF" class="m_column">
    <img src="https://img4.teletype.in/files/33/b9/33b947e1-e15e-41fa-949b-f26f9d47bfbb.jpeg" width="553" />
  </figure>
  <p id="nmuN">К сожалению, это устройство обошло меня стороной.</p>
  <p id="s7rc">Вновь к этой теме я вернулся, когда ручная регулировка температуры в доме стала доставлять массу неудобств, потому что приходилось крутить неудобные вентили на клапанах радиаторов.</p>
  <figure id="Qe3h" class="m_column">
    <img src="https://img4.teletype.in/files/fb/4d/fb4d8fc2-2af2-4d2e-a7dd-f8f65e6513eb.png" width="1134" />
  </figure>
  <p id="Ng6j">Сначала я, конечно, вспомнил про Fibaro, но было неясно, как его нормально здесь использовать. При всём при этом стоимость всего мероприятия выходила бы совсем уж неприятной.</p>
  <p id="g6Kr">В поисках решения, которое можно было бы приладить к моим радиаторам, я наткнулся на термоприводы для коллекторов отопления. И тут меня осенило. Зачем пытаться что-то регулировать в конечных точках, когда это можно сделать централизованно на коллекторе.</p>
  <figure id="qGxI" class="m_column">
    <img src="https://img2.teletype.in/files/55/6a/556a9096-969e-4a5f-983a-675a8eaa73c8.jpeg" width="2700" />
  </figure>
  <p id="0KvL">Конкретно такие приводы имеют только два положения: открыто или закрыто.</p>
  <p id="C3tb">Кстати, при желании, их всё же можно использовать на радиаторах, если на них<br />установлен термостатический клапан с резьбой M30x1.5.</p>
  <figure id="AUJu" class="m_custom">
    <img src="https://img2.teletype.in/files/5e/cb/5ecb4938-1262-4833-ab15-c435acef0ff6.jpeg" width="357" />
  </figure>
  <p id="LbL5"></p>
  <h3 id="z7MP">Схема подключения</h3>
  <figure id="PdZt" class="m_column">
    <img src="https://img2.teletype.in/files/50/a4/50a4a77e-ee21-402a-9644-7629cfaee74d.png" width="1920" />
  </figure>
  <p id="nP1y">Все термоприводы — нормально-закрытые. Когда модуль ESP подаёт сигнал<br />на твердотельное реле, термопривод открывается. Занимает это несколько минут.</p>
  <p id="0R7f">В собранном виде контроллер вместе с реле и блоком питания помещается в какую-то стандартную распаячную коробку.</p>
  <figure id="b0aR" class="m_column">
    <img src="https://img3.teletype.in/files/e0/99/e09929d1-b645-4c25-8426-751c4e7c02ed.jpeg" width="4032" />
  </figure>
  <p id="pQCJ"></p>
  <p id="bCRL">Я решил не заморачиваться с установкой настенных термостатов, потому что<br />всё ручное управление осуществляется с телефона или компьютера.</p>
  <figure id="dvjK" class="m_custom">
    <img src="https://img4.teletype.in/files/32/9f/329f85aa-8c63-4eb2-bf0d-45ae51f75be4.jpeg" width="335" />
  </figure>
  <p id="bFCK">В каждом помещении, где есть радиатор, я установил температурный датчик от Aqara, расположив их в местах, где предполагается самое частое присутствие людей.</p>
  <figure id="QkYg" class="m_custom">
    <img src="https://img2.teletype.in/files/d2/a4/d2a48010-60bd-457e-9c72-6c18fdfa8ff8.jpeg" width="300" />
  </figure>
  <p id="EoKO"></p>
  <h3 id="IcSm">Прошивка</h3>
  <p id="5OSW"></p>
  <p id="IAtF">Код для модуля ESP с прошивкой ESPHome также предельно простой. </p>
  <pre data-lang="yaml" id="9mnD">esphome:
  name: esp16-heating-control-unit-1
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  domain: !secret wifi_domain
  manual_ip:
    static_ip: 172.16.1.116
    subnet: 255.255.255.0
    gateway: 172.16.1.1
    dns1: 172.16.1.1

logger:
api:
ota:

dallas:
  - pin: 2

sensor:
  - platform: dallas
    address: 0xB1031635D6C6FF29
    name: &quot;1 Heating Flow Temperature&quot;

switch:
  - platform: gpio
    name: &quot;Office Heater&quot;
    icon: &quot;mdi:radiator&quot;
    pin: 16
    inverted: no
  - platform: gpio
    name: &quot;Pantry Heater&quot;
    icon: &quot;mdi:radiator&quot;
    pin: 14
    inverted: no
  - platform: gpio
    name: &quot;Livingroom Heater&quot;
    icon: &quot;mdi:radiator&quot;
    pin: 13
    inverted: no
  - platform: gpio
    name: &quot;Kitchen Heater&quot;
    icon: &quot;mdi:radiator&quot;
    pin: 12
    inverted: no</pre>
  <ul id="0uWj">
    <li id="Uasu">Описывается каждый вывод, который подключен к реле (pin).</li>
    <li id="4JZM">Если бы термопривод был нормально-открытый, то у параметра <strong>inverted</strong> было бы значение <em>yes</em>.</li>
    <li id="pKp4">Опционально к коллектору прицеплен датчик температуры DS18B20.</li>
  </ul>
  <p id="Q2vM"></p>
  <p id="u3OA">После подключения модуля ESP к Home Assistant, в интерфейсе появляются выключатели, управляющие термоприводами. Но сами по себе они не имеют особой пользы.</p>
  <figure id="yADf" class="m_column">
    <img src="https://img1.teletype.in/files/0c/bf/0cbf3caa-09db-4029-b3f5-bd38e451910d.png" width="1919" />
  </figure>
  <p id="nlNR"></p>
  <p id="6TNF">На удивление, термостат, реализованный средствами <a href="https://www.home-assistant.io/integrations/generic_thermostat/" target="_blank">базовой интеграции</a> Home Assistant, обладает всем необходимым функционалом. А то я сначала собирался самостоятельно строить логику управления в Node-RED. Тут тоже всё просто:</p>
  <pre data-lang="yaml" id="npKG">- platform: generic_thermostat
  name: Livingroom Thermostat
  heater: switch.livingroom_heater
  target_sensor: sensor.livingroom_temperature
  min_temp: 23
  max_temp: 27
  ac_mode: false
  cold_tolerance: 0.3
  hot_tolerance: 0.1
  min_cycle_duration:
    minutes: 5
  initial_hvac_mode: &quot;off&quot;
  precision: 0.1</pre>
  <ul id="fjWi">
    <li id="fj3U">указывается переключатель, управляющий термоприводом (heater)</li>
    <li id="kGlM">датчик температуры, по которому термостат будет ориентироваться (target_sensor)</li>
    <li id="hCfl">диапазон регулировки термостата (min_temp, max_temp)</li>
    <li id="DrYz">гистерезис (cold_tolerance, hot_tolerance)</li>
    <li id="dTRW">начальное состояние (initial_hvac_mode)</li>
    <li id="Q3Q9">точность управления уставкой (precision)</li>
  </ul>
  <p id="zzhL"></p>
  <p id="2Fpa">По поводу начального состояния. После перезагрузки, все термостаты по умолчанию выключены. Есть отдельная автоматизация, которая при запуске Home Assistant проверяет, отопительный ли сейчас сезон, чтобы включить все термостаты:</p>
  <pre data-lang="yaml" id="mbRk">- id: &#x27;1604184082358&#x27;
  alias: Термостаты в отопительный сезон
  description: &#x27;&#x27;
  trigger:
  - platform: homeassistant
    event: start
  condition:
  - condition: state
    entity_id: input_boolean.heating_season
    state: &#x27;on&#x27;
  action:
  - service: homeassistant.turn_on
    data: {}
    entity_id: group.all_thermostats
  mode: single</pre>
  <p id="tA2f"></p>
  <p id="zT03">Проверка основывается на состоянии виртуального переключателя (input_boolean), которое зависит от среднесуточной температуры, собираемой с помощью встроенного <a href="https://www.home-assistant.io/integrations/statistics/" target="_blank">модуля статистики</a>:</p>
  <pre data-lang="yaml" id="ixTG">heating_season:
  name: Heating season
  icon: mdi:snowflake-melt</pre>
  <p id="r0e3"></p>
  <p id="WPmU">Показания температуры воздуха собираются с периодичностью 5 раз в час и хранятся 15 суток:</p>
  <figure id="zNI4" class="m_column">
    <img src="https://img4.teletype.in/files/b6/a0/b6a07298-f13e-4518-bec9-692d0d8c09f0.png" width="1919" />
  </figure>
  <p id="MlGD"></p>
  <p id="PFXQ">В Node-RED для этого есть небольшой сценарий:</p>
  <figure id="q6Qd" class="m_column">
    <img src="https://img3.teletype.in/files/65/04/65041b76-61e0-4eda-a1f1-682852df8e85.png" width="1009" />
  </figure>
  <p id="02VX">Что касается точности работы контроллера, то на примере графика за сутки видно, как при ночной уставке в 25.5 градусов, температура в кабинете колебалась в пределах двух десятых от нее:</p>
  <figure id="dd0r" class="m_column">
    <img src="https://img2.teletype.in/files/10/ff/10ff1d91-9f68-4e20-9aad-b258830e7b3a.png" width="1919" />
  </figure>
  <p id="cwyS">Дневная температура 26 градусов также стабильно поддерживалась, за исключением моментов с попаданием в комнату прямых солнечных лучей.</p>
  <p id="JYav">Выше — оранжевый график показывает, когда был открыт термопривод. И видно, как это совпадает с колебанием температуры в помещении.</p>
  <p id="v0jl">Решение прекрасно пережило текущую зиму, и я остался доволен работой. Дополнительно написал пару сценариев для Node-RED, срабатывающих по времени суток или по присутствию.</p>
  <p id="6aCL">Со стороны котла я решил не делать никаких подключений, так как максимум, на что он способен — включаться по внешнему сигналу, и это пока оказалось ненужным.</p>
  <p id="mR12">Предвидя вопрос, «А что, если отключат свет?». Будет всё равно, потому что<br />котёл тоже выключится. А, в случае, выхода из строя контроллера или термопривода, последний в одно движение снимается с коллектора.</p>
  <p id="XXJm"></p>
  <hr />
  <p id="JgfE">Все конфигурации, описанные в статье, доступны на <a href="https://github.com/isaenkovpro/configs/tree/master/005 Heating control unit" target="_blank">GitHub</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://isaenkov.pro/kodi-camera-preview</guid><link>https://isaenkov.pro/kodi-camera-preview?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro</link><comments>https://isaenkov.pro/kodi-camera-preview?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro#comments</comments><dc:creator>isaenkov.pro</dc:creator><title>Kodi: вывожу видео с камеры на TV при звонке в дверь</title><pubDate>Sat, 17 Jul 2021 19:10:18 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/f4/3e/f43e25ed-5ab7-4d46-9513-54a0cfde049f.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/c0/dd/c0dd4352-1040-4deb-8f10-3ab7a84653e5.png"></img>В первом видео я упомянул об отображении потока с камеры на экране телевизора при звонке в дверь. Сегодня я продолжу эту тему и расскажу о настройке.]]></description><content:encoded><![CDATA[
  <figure id="BcOv" class="m_column">
    <img src="https://img1.teletype.in/files/c0/dd/c0dd4352-1040-4deb-8f10-3ab7a84653e5.png" width="1919" />
  </figure>
  <p id="Yvoy">В первом видео я упомянул об отображении потока с камеры на экране телевизора при звонке в дверь. Сегодня я продолжу эту тему и расскажу о настройке.</p>
  <figure id="sqz4" class="m_column">
    <iframe src="https://www.youtube.com/embed/nPGOyVoT3QU?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="aXS1">Для просмотра контента на телевизоре я использую медиа-центр Kodi, работающий на Raspberry Pi 3 с дистрибутивом <a href="https://libreelec.tv" target="_blank">LibreELEC</a>.</p>
  <p id="rs5z">Перед настройкой дополнений в Kodi необходимо включить опцию для возможности их установки из сторонних источников.</p>
  <figure id="KOXW" class="m_column">
    <img src="https://img3.teletype.in/files/2e/af/2eaf7b41-3a6a-4bc8-9e5c-2c25b51769c8.png" width="1918" />
  </figure>
  <p id="kg2d">А также изменить режим отображения настроек на <strong>Экспертный</strong>.</p>
  <figure id="yVtO" class="m_original">
    <img src="https://img3.teletype.in/files/a2/88/a288e91e-c0ab-4f80-9b40-a4e92c1a4133.png" width="546" />
  </figure>
  <p id="ntxr">Для вывода изображения с камеры, я установил <a href="https://github.com/maikito26/repository.maikito26.storage/raw/master/plugin.video.surveillanceroom/plugin.video.surveillanceroom-1.2.3.zip" target="_blank">плагин Surveillance Room</a>, предварительно загрузив архив на Raspberry Pi.</p>
  <p id="rjY3">Следом поставил <a href="https://github.com/joshjowen/script.json-cec/raw/master/script.json-cec.zip" target="_blank">плагин JSON-CEC</a> для возможности управления телевизором через HDMI, чтобы иметь возможность переключения на Kodi с других источников<br />сигнала. Главное, убедиться, что в настройках телевизора включена технология HDMI-CEC, потому что производителями она преподносится под разными торговыми названиями.</p>
  <figure id="WMcI" class="m_original">
    <img src="https://img1.teletype.in/files/86/47/86476c18-212e-48b3-8292-a4b369b25ea2.png" width="532" />
  </figure>
  <p id="tPYC">В настройках дополнения включаю новую камеру, ввожу название и адреса<br />основного видеопотока с камеры, MJPEG-потока для окна предпросмотра, и одиночного снимка.</p>
  <figure id="3XCZ" class="m_column">
    <img src="https://img2.teletype.in/files/9a/95/9a95ea7d-e5f9-49d1-ba0f-bc640ca4f2d5.png" width="1918" />
  </figure>
  <figure id="VDua" class="m_column">
    <img src="https://img3.teletype.in/files/28/b1/28b1ce55-13fe-4a85-9ba3-9152a81685c2.png" width="1918" />
    <figcaption>Параметры ниже меняю по своему усмотрению.</figcaption>
  </figure>
  <p id="Gp1t"></p>
  <p id="CagQ">Теперь перехожу к настройке сценария в Node-RED.</p>
  <p id="Hzeh">Я добавил новый блок с нодами, в которых происходит вызов различных действий в Kodi.</p>
  <p id="98dT">Перед этим я предварительно настроил <a href="https://www.home-assistant.io/integrations/kodi/" target="_blank">интеграцию</a> медиа-плеера с Home Assistant и подключил его в качестве <a href="https://www.home-assistant.io/integrations/kodi/#notifications" target="_blank">платформы для уведомлений</a> согласно документации на сайте.</p>
  <p id="Q5TJ">В первой ноде проверяется состояние медиа-плеера, проигрывается ли что-то<br />на нём в данный момент или нет.</p>
  <figure id="iMoy" class="m_column">
    <img src="https://img3.teletype.in/files/27/64/27643d73-9c08-4f2b-993f-5d626e29f4ff.png" width="1707" />
    <figcaption>Итоговый вид сценария претерпел изменения. Код обновлённого flow доступен ниже.</figcaption>
  </figure>
  <p id="cWqs">Если да, то через платформу уведомлений в Kodi создается всплывающее сообщение со следующим содержимым, где displaytime – это время отображения<br />в мс.</p>
  <figure id="1lGd" class="m_column">
    <img src="https://img4.teletype.in/files/3e/cc/3ecc498a-24db-4141-ad2f-c048f2afc741.png" width="621" />
  </figure>
  <p id="yWt1">Одновременно с этим на 30 секунд всплывает окно предпросмотра видеопотока<br />с камеры, которое вызывается следующим запросом к плагину.</p>
  <figure id="h542" class="m_original">
    <img src="https://img1.teletype.in/files/42/af/42afb186-9ecb-4519-871b-f8a724e57aa8.png" width="600" />
    <figcaption>Пример взят из <a href="https://github.com/maikito26/plugin.video.surveillanceroom/blob/master/README.md" target="_blank">документации</a> к плагину.</figcaption>
  </figure>
  <p id="3x0o">Далее следует задержка, где дополнительные 4 секунды отведены на запуск и остановку трансляции, после которой отдельным вызовом имитируется нажатие кнопки Назад, чтобы вернуться в исходную точку на экране, т. к. плагин сам этого почему-то не делает.</p>
  <p id="ETHJ">В случае, когда на медиа-плеере ничего не запущено, то также создается всплывающее уведомление с текстом, и запускается уже полноэкранная<br />трансляция видео с камеры, вызов которой отличается строкой с параметрами обращения к плагину.</p>
  <figure id="um43" class="m_original">
    <img src="https://img4.teletype.in/files/b6/30/b630a9dd-4f24-4206-8f0b-7ef247d7f3a6.png" width="625" />
    <figcaption>Пример взят из <a href="https://github.com/maikito26/plugin.video.surveillanceroom/blob/master/README.md" target="_blank">документации</a> к плагину.</figcaption>
  </figure>
  <p id="05tS">А после задержки дополнительно происходит остановка трансляции.</p>
  <p id="zqiS">Чтобы не создавать лишнюю активность в Kodi, когда телевизор выключен, я добавил дополнительную проверку. Она основана на состоянии бинарного сенсора, показывающего включен или выключен телевизор:</p>
  <pre data-lang="yaml" id="9Ykt">- platform: template
  sensors:
    livingroom_tv_state:
      friendly_name: &quot;Livingroom TV State&quot;
      value_template: &quot;{{ states(&#x27;media_player.cast_livingroom&#x27;) != &#x27;unknown&#x27; and not(is_state(&#x27;media_player.cast_livingroom&#x27;, &#x27;unavailable&#x27;)) }}&quot;</pre>
  <p id="suQL">Сам сенсор является шаблоном, который смотрит на статус подключенного к телевизору Chromecast’а. Если Chromecast подключен к сети и доступен для воспроизведения контента, то телевизор считается включенным, потому что Chromecast воткнут в USB-порт телевизора, питание на котором появляется только при его включении. Сам Chromecast добавлен в Home Assistant через меню <a href="https://www.home-assistant.io/integrations/cast/" target="_blank">интеграций</a>.</p>
  <p id="uiCg">Полученный сценарий можно расширить, добавив большее количество медиа-центров Kodi, если таковые имеются. При этом, усложняется и схема.<br />Для этого некоторые ноды размещаются друг за другом, где последовательно происходит считывание состояния каждого устройства.</p>
  <figure id="FhyL" class="m_original">
    <img src="https://img3.teletype.in/files/a4/22/a422a8f8-17bf-4db8-bd75-298227c66926.png" width="613" />
  </figure>
  <p id="CbIP">В двух блоках (TV status) состояние записывается в отдельную переменную.<br />Далее проверяется состояние Kodi. И также, если проигрывается, создаётся новая переменная (Kodi status) со значением playing, если не проигрывается, то со значением, которое имеется на данный момент.<br />С Chromecast’ом та же история (Cast status): если проигрывается — записывается playing, если не проигрывается — записывается текущее состояние.</p>
  <p id="VAgA">В ноде Function (data) есть небольшой скрипт, который, в зависимости от состояния устройств, выполняет то или иное действие. Здесь есть несколько переменных, в которых указывается имя нотификатора, имя медиа-плеера Kodi и выключатель, который переключает источник сигнала на телевизоре на Kodi:</p>
  <figure id="HSHN" class="m_column">
    <img src="https://img3.teletype.in/files/2d/76/2d766912-505e-42a3-a9ec-05bb3dd76ddd.png" width="881" />
    <figcaption>Function-нода</figcaption>
  </figure>
  <p id="iVRl">switch.yaml:</p>
  <pre data-lang="yaml" id="RKI6">- platform: template
  switches:
    livingroom_tv_kodi:
      friendly_name: Livingroom TV Kodi
      value_template: &quot;{{ is_state(&#x27;switch.livingroom_tv_kodi&#x27;, &#x27;on&#x27;) }}&quot;
      icon_template: mdi:kodi
      turn_on:
        - service: script.kodi_livingroom_turn_on_action
        - service: switch.turn_off
          entity_id: switch.livingroom_tv_kodi
      turn_off:
        delay:
          seconds: 0</pre>
  <p id="Y6Mt"></p>
  <p id="AamI">scripts.yaml:</p>
  <pre data-lang="yaml" id="klc3">kodi_livingroom_turn_on_action:
  alias: Turn ON Livingroom TV HDMI to Kodi
  sequence:
  - data:
      addonid: script.json-cec
      entity_id: media_player.kodi_livingroom
      method: Addons.ExecuteAddon
      params:
        command: activate
    service: kodi.call_method</pre>
  <p id="PCHg">Например, если в Kodi в данный момент что-то проигрывается, то скрипт идёт по первому пути, где вызывается всплывающее уведомление. Параллельно с этим воспроизведение ставится на паузу, и также параллельно с этим вызывается предпросмотр с камеры через плагин.</p>
  <p id="C576">В случае, когда на медиа-центре Kodi ничего не воспроизводится, либо включен какой-то другой источник сигнала, то вызывается полноэкранный поток с камеры<br />и происходит переключение источника сигнала на телевизоре на Kodi.</p>
  <p id="X7tq">Здесь ещё также добавлена задержка, которая нужна, чтобы телевизор успел переключиться на Kodi, после чего создаётся всплывающее уведомление<br />с характерным звуком.</p>
  <p id="OBnB">Код всего Node-RED-flow представлен ниже:</p>
  <pre id="4gYn">[{&quot;id&quot;:&quot;fd15b534.04ee48&quot;,&quot;type&quot;:&quot;tab&quot;,&quot;label&quot;:&quot;Flow 2&quot;,&quot;disabled&quot;:false,&quot;info&quot;:&quot;&quot;},{&quot;id&quot;:&quot;9f016b89.edeb18&quot;,&quot;type&quot;:&quot;server-state-changed&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Звонок в дверь&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;exposeToHomeAssistant&quot;:false,&quot;haConfig&quot;:[{&quot;property&quot;:&quot;name&quot;,&quot;value&quot;:&quot;&quot;},{&quot;property&quot;:&quot;icon&quot;,&quot;value&quot;:&quot;&quot;}],&quot;entityidfilter&quot;:&quot;switch.corridor_doorbell_ding&quot;,&quot;entityidfiltertype&quot;:&quot;substring&quot;,&quot;outputinitially&quot;:false,&quot;state_type&quot;:&quot;str&quot;,&quot;haltifstate&quot;:&quot;on&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;outputs&quot;:2,&quot;output_only_on_state_change&quot;:false,&quot;for&quot;:&quot;&quot;,&quot;forType&quot;:&quot;num&quot;,&quot;forUnits&quot;:&quot;minutes&quot;,&quot;ignorePrevStateNull&quot;:false,&quot;ignorePrevStateUnknown&quot;:false,&quot;ignorePrevStateUnavailable&quot;:false,&quot;ignoreCurrentStateUnknown&quot;:false,&quot;ignoreCurrentStateUnavailable&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;eventData&quot;},{&quot;property&quot;:&quot;topic&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;triggerId&quot;}],&quot;x&quot;:100,&quot;y&quot;:160,&quot;wires&quot;:[[&quot;96fbc9f0.88a2e8&quot;],[]]},{&quot;id&quot;:&quot;96fbc9f0.88a2e8&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;rate&quot;,&quot;timeout&quot;:&quot;5&quot;,&quot;timeoutUnits&quot;:&quot;seconds&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;120&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:true,&quot;x&quot;:320,&quot;y&quot;:160,&quot;wires&quot;:[[&quot;65c28ed9.0a8e6&quot;,&quot;eed3b3a.5d4555&quot;]]},{&quot;id&quot;:&quot;65c28ed9.0a8e6&quot;,&quot;type&quot;:&quot;stoptimer&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;duration&quot;:&quot;1&quot;,&quot;units&quot;:&quot;Second&quot;,&quot;payloadtype&quot;:&quot;str&quot;,&quot;payloadval&quot;:&quot;&quot;,&quot;name&quot;:&quot;Timeout&quot;,&quot;x&quot;:560,&quot;y&quot;:160,&quot;wires&quot;:[[&quot;4a1d76bc.4213b8&quot;],[]]},{&quot;id&quot;:&quot;6a886333.f832cc&quot;,&quot;type&quot;:&quot;telegram event&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Еще снимок&quot;,&quot;bot&quot;:&quot;f6e2842.9c49078&quot;,&quot;event&quot;:&quot;callback_query&quot;,&quot;autoanswer&quot;:true,&quot;x&quot;:470,&quot;y&quot;:120,&quot;wires&quot;:[[&quot;7d5306e4.b68658&quot;]]},{&quot;id&quot;:&quot;7d5306e4.b68658&quot;,&quot;type&quot;:&quot;switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;property&quot;:&quot;payload.content&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;RING MORE PIC&quot;,&quot;vt&quot;:&quot;str&quot;}],&quot;checkall&quot;:&quot;true&quot;,&quot;repair&quot;:false,&quot;outputs&quot;:1,&quot;x&quot;:595,&quot;y&quot;:120,&quot;wires&quot;:[[&quot;4a1d76bc.4213b8&quot;]],&quot;l&quot;:false},{&quot;id&quot;:&quot;4a1d76bc.4213b8&quot;,&quot;type&quot;:&quot;http request&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;method&quot;:&quot;GET&quot;,&quot;ret&quot;:&quot;bin&quot;,&quot;paytoqs&quot;:&quot;ignore&quot;,&quot;url&quot;:&quot;http://192.168.1.51/ISAPI/Streaming/channels/101/picture?snapShotImageType=JPEG&quot;,&quot;tls&quot;:&quot;&quot;,&quot;persist&quot;:false,&quot;proxy&quot;:&quot;&quot;,&quot;authType&quot;:&quot;digest&quot;,&quot;x&quot;:750,&quot;y&quot;:140,&quot;wires&quot;:[[&quot;ff3c4b90.e504a8&quot;]]},{&quot;id&quot;:&quot;ff3c4b90.e504a8&quot;,&quot;type&quot;:&quot;switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;property&quot;:&quot;payload.chat.id&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;9999999&quot;,&quot;vt&quot;:&quot;str&quot;},{&quot;t&quot;:&quot;null&quot;},{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;8888888&quot;,&quot;vt&quot;:&quot;str&quot;}],&quot;checkall&quot;:&quot;true&quot;,&quot;repair&quot;:false,&quot;outputs&quot;:3,&quot;x&quot;:910,&quot;y&quot;:140,&quot;wires&quot;:[[&quot;3edab718.b8c668&quot;],[&quot;3edab718.b8c668&quot;,&quot;4295b732.a42978&quot;],[&quot;4295b732.a42978&quot;]],&quot;outputLabels&quot;:[&quot;Sergey&quot;,&quot;Empty&quot;,null]},{&quot;id&quot;:&quot;3edab718.b8c668&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Chat ID&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;chatId&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;99999999&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:1060,&quot;y&quot;:120,&quot;wires&quot;:[[&quot;d0a52ed6.209b5&quot;]]},{&quot;id&quot;:&quot;d0a52ed6.209b5&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Data&quot;,&quot;func&quot;:&quot;context.global.keyboard = { messageId : msg.payload.messageId };\n\nvar opts = {\n  reply_to_message_id: msg.payload.messageId,\n  reply_markup: JSON.stringify({\n    \&quot;inline_keyboard\&quot;: [[\n                {\n                    \&quot;text\&quot;: \&quot;📷 Eщё снимок\&quot;,\n                    \&quot;callback_data\&quot;: \&quot;RING MORE PIC\&quot;\n                }]\n            ]\n  })\n};\n\nmsg.payload = {\n    chatId: msg.chatId,\n    type: \&quot;photo\&quot;,\n    content: msg.payload,\n    caption: \&quot;🔔 Звонок в дверь\&quot;,\n    options: opts\n};\nreturn msg;\n&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:1210,&quot;y&quot;:140,&quot;wires&quot;:[[&quot;9a15c39c.d532&quot;]]},{&quot;id&quot;:&quot;9a15c39c.d532&quot;,&quot;type&quot;:&quot;telegram sender&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;bot&quot;:&quot;f6e2842.9c49078&quot;,&quot;haserroroutput&quot;:false,&quot;outputs&quot;:1,&quot;x&quot;:1390,&quot;y&quot;:140,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;4295b732.a42978&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Chat ID&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;chatId&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;8888888&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:1060,&quot;y&quot;:160,&quot;wires&quot;:[[&quot;d0a52ed6.209b5&quot;]]},{&quot;id&quot;:&quot;eed3b3a.5d4555&quot;,&quot;type&quot;:&quot;api-current-state&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;TV Livingroom&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:2,&quot;outputs&quot;:2,&quot;halt_if&quot;:&quot;on&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;entity_id&quot;:&quot;binary_sensor.livingroom_tv_state&quot;,&quot;state_type&quot;:&quot;str&quot;,&quot;blockInputOverrides&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entity&quot;},{&quot;property&quot;:&quot;topic&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;triggerId&quot;}],&quot;x&quot;:300,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;9dfd6ea5.6255&quot;],[&quot;631679c3.141578&quot;]]},{&quot;id&quot;:&quot;9dfd6ea5.6255&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;TV status&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;livingroom_tv_status&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;on&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:480,&quot;y&quot;:280,&quot;wires&quot;:[[&quot;56da301b.3477a&quot;]]},{&quot;id&quot;:&quot;631679c3.141578&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;TV status&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;livingroom_tv_status&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;off&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:480,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;56da301b.3477a&quot;]]},{&quot;id&quot;:&quot;56da301b.3477a&quot;,&quot;type&quot;:&quot;api-current-state&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi Livingroom&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:2,&quot;outputs&quot;:2,&quot;halt_if&quot;:&quot;playing&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;entity_id&quot;:&quot;media_player.kodi_livingroom&quot;,&quot;state_type&quot;:&quot;str&quot;,&quot;blockInputOverrides&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entity&quot;},{&quot;property&quot;:&quot;topic&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;triggerId&quot;}],&quot;x&quot;:300,&quot;y&quot;:380,&quot;wires&quot;:[[&quot;3078c290.948d9e&quot;],[&quot;3e2fb6b7.4a64ea&quot;]]},{&quot;id&quot;:&quot;3078c290.948d9e&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi status&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;livingroom_kodi_status&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;playing&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:490,&quot;y&quot;:360,&quot;wires&quot;:[[&quot;b8cd7ae8.3af688&quot;]]},{&quot;id&quot;:&quot;3e2fb6b7.4a64ea&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi status&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;livingroom_kodi_status&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;payload&quot;,&quot;tot&quot;:&quot;msg&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:490,&quot;y&quot;:400,&quot;wires&quot;:[[&quot;b8cd7ae8.3af688&quot;]]},{&quot;id&quot;:&quot;b8cd7ae8.3af688&quot;,&quot;type&quot;:&quot;api-current-state&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Cast Livingroom&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:2,&quot;outputs&quot;:2,&quot;halt_if&quot;:&quot;playing&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;entity_id&quot;:&quot;media_player.cast_livingroom&quot;,&quot;state_type&quot;:&quot;str&quot;,&quot;blockInputOverrides&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entity&quot;},{&quot;property&quot;:&quot;topic&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;triggerId&quot;}],&quot;x&quot;:300,&quot;y&quot;:460,&quot;wires&quot;:[[&quot;198da4af.354efb&quot;],[&quot;872594d2.187c58&quot;]]},{&quot;id&quot;:&quot;198da4af.354efb&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Cast status&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;livingroom_cast_status&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;playing&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:490,&quot;y&quot;:440,&quot;wires&quot;:[[&quot;44b931b4.dde44&quot;]]},{&quot;id&quot;:&quot;872594d2.187c58&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Cast status&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;livingroom_cast_status&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;payload&quot;,&quot;tot&quot;:&quot;msg&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:490,&quot;y&quot;:480,&quot;wires&quot;:[[&quot;44b931b4.dde44&quot;]]},{&quot;id&quot;:&quot;44b931b4.dde44&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;data&quot;,&quot;func&quot;:&quot;if (msg.livingroom_tv_status == \&quot;on\&quot;) {\n    msg.kodi_service = \&quot;kodi_livingroom_notifier\&quot;\n    msg.kodi_name = \&quot;media_player.kodi_livingroom\&quot;\n    msg.tv_source = \&quot;switch.livingroom_tv_kodi\&quot;\n    if ((msg.livingroom_kodi_status == \&quot;playing\&quot;) &amp;&amp; (msg.livingroom_cast_status != \&quot;playing\&quot;)) {\n        return [msg, null]\n    } else if ((msg.livingroom_kodi_status != \&quot;playing\&quot;) &amp;&amp; (msg.livingroom_cast_status != \&quot;playing\&quot;)) {\n        return [null, msg]\n    }\n}&quot;,&quot;outputs&quot;:2,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:710,&quot;y&quot;:380,&quot;wires&quot;:[[&quot;f978d275.ceb4c&quot;,&quot;c0f778fa.ac9448&quot;,&quot;177f145e.c9c52c&quot;,&quot;b3b9bba.5bfe148&quot;],[&quot;b9933d4b.f5e5d&quot;,&quot;177f145e.c9c52c&quot;]]},{&quot;id&quot;:&quot;f978d275.ceb4c&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Ding&quot;,&quot;func&quot;:&quot;msg.payload = {\n    service: msg.kodi_service,\n    data: {\n        \&quot;title\&quot;: \&quot;Звонок в дверь\&quot;,\n        \&quot;message\&quot;: \&quot;Звонок в дверь\&quot;,\n        \&quot;data\&quot;: {\n            \&quot;displaytime\&quot;: 10000,\n            \&quot;icon\&quot;: \&quot;http://172.16.1.3:8123/local/images/kodi_ding.png\&quot;\n        }\n    }\n}\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:910,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;1b038a66.796fc6&quot;]]},{&quot;id&quot;:&quot;c0f778fa.ac9448&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Fullscreen&quot;,&quot;func&quot;:&quot;msg.payload = {\n    data: {\n        \&quot;entity_id\&quot;: msg.kodi_name,\n        \&quot;method\&quot;: \&quot;Addons.ExecuteAddon\&quot;,\n        \&quot;addonid\&quot;: \&quot;plugin.video.surveillanceroom\&quot;,\n        \&quot;params\&quot;: \&quot;action=single_camera_no_controls&amp;camera_number=2\&quot;\n    }\n}\n\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:930,&quot;y&quot;:420,&quot;wires&quot;:[[&quot;984d1a26.905238&quot;,&quot;1fb046db.e41fe9&quot;]]},{&quot;id&quot;:&quot;177f145e.c9c52c&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Preview&quot;,&quot;func&quot;:&quot;msg.payload = {\n    data: {\n        \&quot;entity_id\&quot;: msg.kodi_name,\n        \&quot;method\&quot;: \&quot;Addons.ExecuteAddon\&quot;,\n        \&quot;addonid\&quot;: \&quot;plugin.video.surveillanceroom\&quot;,\n        \&quot;params\&quot;: \&quot;action=show_preview&amp;camera_number=2\&quot;\n    }\n}\n\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:920,&quot;y&quot;:380,&quot;wires&quot;:[[&quot;984d1a26.905238&quot;,&quot;ac428d66.c98c8&quot;]]},{&quot;id&quot;:&quot;b3b9bba.5bfe148&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi name&quot;,&quot;func&quot;:&quot;msg.payload = {\n    data: {\n        \&quot;entity_id\&quot;: msg.kodi_name\n    }\n}\n\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:930,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;7c68d79f.b82308&quot;]]},{&quot;id&quot;:&quot;b9933d4b.f5e5d&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Source&quot;,&quot;func&quot;:&quot;msg.payload = \n{\n    data: {\n        \&quot;entity_id\&quot;: msg.tv_source,\n    }\n}\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:920,&quot;y&quot;:460,&quot;wires&quot;:[[&quot;905a9a46.5470f8&quot;,&quot;856436ab.16a478&quot;]]},{&quot;id&quot;:&quot;905a9a46.5470f8&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;delay&quot;,&quot;timeout&quot;:&quot;4&quot;,&quot;timeoutUnits&quot;:&quot;seconds&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;1&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:false,&quot;x&quot;:740,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;f978d275.ceb4c&quot;]]},{&quot;id&quot;:&quot;1b038a66.796fc6&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi notify&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;notify&quot;,&quot;service&quot;:&quot;&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:1130,&quot;y&quot;:280,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;984d1a26.905238&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi call&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;kodi&quot;,&quot;service&quot;:&quot;call_method&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:1120,&quot;y&quot;:400,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;1fb046db.e41fe9&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;delay&quot;,&quot;timeout&quot;:&quot;32&quot;,&quot;timeoutUnits&quot;:&quot;seconds&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;1&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:false,&quot;x&quot;:1120,&quot;y&quot;:440,&quot;wires&quot;:[[&quot;df077307.48a3b&quot;]]},{&quot;id&quot;:&quot;ac428d66.c98c8&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;delay&quot;,&quot;timeout&quot;:&quot;36&quot;,&quot;timeoutUnits&quot;:&quot;seconds&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;1&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:false,&quot;x&quot;:1120,&quot;y&quot;:360,&quot;wires&quot;:[[&quot;d9f0be42.1e56e&quot;]]},{&quot;id&quot;:&quot;7c68d79f.b82308&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Media pause&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;media_player&quot;,&quot;service&quot;:&quot;media_play_pause&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:1130,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;b83a0255.369fe&quot;]]},{&quot;id&quot;:&quot;856436ab.16a478&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Set TV source&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;switch&quot;,&quot;service&quot;:&quot;turn_on&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:1140,&quot;y&quot;:480,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;d9f0be42.1e56e&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Back&quot;,&quot;func&quot;:&quot;msg.payload = {\n    data: {\n        \&quot;entity_id\&quot;: msg.kodi_name,\n        \&quot;method\&quot;: \&quot;Input.Back\&quot;\n    }\n}\n\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:1250,&quot;y&quot;:360,&quot;wires&quot;:[[&quot;984d1a26.905238&quot;]]},{&quot;id&quot;:&quot;df077307.48a3b&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Name&quot;,&quot;func&quot;:&quot;msg.payload = {\n    entity_id: msg.kodi_name\n}\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:1310,&quot;y&quot;:440,&quot;wires&quot;:[[&quot;7d3a4f11.178c3&quot;]]},{&quot;id&quot;:&quot;b83a0255.369fe&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;delay&quot;,&quot;timeout&quot;:&quot;2&quot;,&quot;timeoutUnits&quot;:&quot;minutes&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;1&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:false,&quot;x&quot;:1280,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;67d3df46.400d5&quot;]]},{&quot;id&quot;:&quot;7d3a4f11.178c3&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Camera stop&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;media_player&quot;,&quot;service&quot;:&quot;media_stop&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:1470,&quot;y&quot;:440,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;67d3df46.400d5&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Media play&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;media_player&quot;,&quot;service&quot;:&quot;media_play&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:1430,&quot;y&quot;:320,&quot;wires&quot;:[[]]}]</pre>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="PimW">Использованные в сценарии модули Node-RED:<br /><strong>node-red-contrib-stoptimer<br />node-red-contrib-telegrambot<br />node-red-contrib-interval</strong></p>
  </section>
  <p id="Kzk5"></p>
  <p id="EqyS">Дальше этот сценарий можно расширять в зависимости от потребностей и насколько хватит воображения.</p>
  <figure id="LJAo" class="m_column">
    <img src="https://img1.teletype.in/files/8f/ff/8fff72a7-d949-47b6-9e02-86175e1a9624.png" width="1549" />
    <figcaption>Итоговый Node-RED flow</figcaption>
  </figure>
  <p id="fJsU"></p>
  <hr />
  <blockquote id="QeNF">Все конфигурации, описанные в статье, доступны на <a href="https://github.com/isaenkovpro/configs/tree/master/002%20Kodi%20camera%20preview" target="_blank">GitHub</a>.</blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://isaenkov.pro/doorbell</guid><link>https://isaenkov.pro/doorbell?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro</link><comments>https://isaenkov.pro/doorbell?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=isaenkov.pro#comments</comments><dc:creator>isaenkov.pro</dc:creator><title>Как сделать обычный дверной звонок умным</title><pubDate>Thu, 15 Jul 2021 18:59:47 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/7c/f8/7cf86673-fc2a-4297-bc95-1158abc85013.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/02/13/0213b370-9aea-459f-8896-47493a10e3b9.png"></img>Сегодня я расскажу о том, как автоматизировать обычный дверной звонок, чтобы он умел работать по расписанию, в беззвучном режиме, а также слать ведомления на смартфон при нажатии на кнопку. В этом мне поможет система домашней автоматизации на базе Home Assistant.]]></description><content:encoded><![CDATA[
  <figure id="4Z6v" class="m_column">
    <img src="https://img1.teletype.in/files/02/13/0213b370-9aea-459f-8896-47493a10e3b9.png" width="1919" />
  </figure>
  <p id="i71T">Сегодня я расскажу о том, как автоматизировать обычный дверной звонок, чтобы он умел работать по расписанию, в беззвучном режиме, а также слать уведомления на смартфон при нажатии на кнопку. В этом мне поможет система домашней автоматизации на базе Home Assistant.</p>
  <p id="6gv9"></p>
  <figure id="PnLp" class="m_column">
    <iframe src="https://www.youtube.com/embed/voNgwWWmwW8?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="pP1N">Однажды возникла необходимость выключать звук дверного звонка, чтобы случайные посетители перестали меня беспокоить, особенно в ночное время. </p>
  <p id="Y9jl">Я начал с того, что определил схему подвода питания к звонку. Фаза уже присутствовала на нём, вместо того, чтобы подаваться на него в момент нажатия кнопки. В дальнейшем это сыграет свою роль.</p>
  <p id="B823">Для реализации задуманного функционала я добавил в цепь реле. Это двухканальный релейный модуль от компании Fibaro. Работает по протоколу Z-Wave. Почему именно он, станет понятно чуть позже.</p>
  <figure id="pHFn" class="m_custom">
    <img src="https://img3.teletype.in/files/e7/cf/e7cf70cc-b5ba-4be2-ad62-6ae17fc3db4a.png" width="241" />
  </figure>
  <p id="Cr6i"></p>
  <p id="soWY">Хотя, конкретно в этом месте можно использовать любое другое устройство, будь то Fibaro, Sonoff или простой релейный модуль для Arduino.</p>
  <figure id="YMHY" class="m_original">
    <img src="https://img4.teletype.in/files/79/1f/791fe689-bb4b-4680-9843-43b458cb91a3.png" width="726" />
  </figure>
  <h3 id="mKKr"></h3>
  <h3 id="UsMU">Схема подключения</h3>
  <p id="NEwj"></p>
  <p id="Jf46">Фаза подаётся на вход реле, а из первого выхода она идёт на звонок. Нулевой провод остаётся нетронутым.</p>
  <figure id="KsD6" class="m_original">
    <img src="https://img2.teletype.in/files/d1/b7/d1b7df13-8aab-432b-8c28-f7386f6e2250.png" width="761" />
  </figure>
  <p id="nAWc"></p>
  <p id="tQ2q">В случае, если звонок подключен так, что кнопка разрывает фазу, а не ноль,<br />то схема подключения будет такой — кнопка не будет работать, пока выключен выход реле O1:</p>
  <figure id="0JzV" class="m_original">
    <img src="https://img2.teletype.in/files/dd/1e/dd1ebb3e-2739-496f-b2ed-ff2ce850ab58.png" width="761" />
  </figure>
  <p id="etEj"></p>
  <p id="OtQf">Либо такой, где фаза при нажатии кнопки подается на вход реле, а звонок звенит, только, если выход О1 включен:</p>
  <figure id="a7Ot" class="m_original">
    <img src="https://img1.teletype.in/files/83/08/83088414-c950-4782-b899-38d7429010ad.png" width="761" />
  </figure>
  <p id="U9VG"></p>
  <h3 id="KcJV">Программная часть</h3>
  <p id="lcJU"></p>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <figure id="yBrV" class="m_custom">
      <img src="https://img1.teletype.in/files/4e/ed/4eede09b-7ca7-4a29-b9cb-e52bc8383b24.png" width="100" />
    </figure>
  </section>
  <p id="sSa1">Я использую Home Assistant. Это довольно молодая, активно развивающаяся, очень мощная и гибкая система домашней автоматизации. Поддерживается огромным мировым сообществом энтузиастов, которые занимаются разработкой как самой платформы, так и компонентов, расширяющих ее функционал для работы со множеством устройств, платформ и сервисов.</p>
  <p id="DdzG">Home Assistant у меня работает на Raspberry Pi 3 в Docker-контейнере. Поставляется в виде готового решения под названием Hass.io.</p>
  <p id="7bUm">Также к Raspberry Pi у меня подключен Z-Wave-контроллер в виде платы расширения.</p>
  <figure id="m4Vz" class="m_custom">
    <img src="https://img2.teletype.in/files/18/0e/180ec684-0a14-4d53-9fac-cc8f1f0fa92d.jpeg" width="335" />
    <figcaption>RaZberry</figcaption>
  </figure>
  <p id="XHnl"></p>
  <p id="G4lH">После подключения модуля к сети и добавления его в Home Assistant, для удобства, я переименую Z-Wave-ноду и поменяю имя и ID объекта непосредственно у реле.</p>
  <figure id="77TF" class="m_original">
    <img src="https://img4.teletype.in/files/3a/c6/3ac6dd59-6a24-42dc-b6ed-714b4aac2933.png" width="530" />
  </figure>
  <figure id="wVOF" class="m_original">
    <img src="https://img4.teletype.in/files/b2/b6/b2b61f56-d5d2-487c-9542-bc7ecbf0f790.png" width="504" />
  </figure>
  <p id="IzMz"></p>
  <p id="ihLV">После добавления устройства в конфигурационный файл, оно появляется в интерфейсе. Этот переключатель позволяет управлять звонком в ручном режиме.</p>
  <figure id="8VPh" class="m_original">
    <img src="https://img4.teletype.in/files/f4/4a/f44a5a45-e400-4ee4-a1e8-724159cf3498.png" width="512" />
  </figure>
  <p id="oCdi">Для работы по расписанию я покажу пример, допустим, чтобы звонок не реагировал на нажатие кнопки с 10 вечера до 9 утра.</p>
  <p id="zbrk">В этом мне поможет Node-Red.</p>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <figure id="2ppZ" class="m_custom">
      <img src="https://img4.teletype.in/files/32/f2/32f21047-5765-4abc-8941-fd7abecc732b.png" width="100" />
    </figure>
  </section>
  <p id="EIci">Node-RED — это open-source инструмент, который служит для связи железа и сервисов. Здесь используются графические линий связи, по которым пересылаются сообщения между узлами. Таким образом различные блоки связываются просто мышкой без использования программирования. Вся разработка в Node-RED ведется через браузер, а ядро можно запустить на различных платформах.</p>
  <p id="QjvV">У меня оно также работает в Docker-контейнере в виде плагина для Hass.io.</p>
  <p id="u7WO">Я добавил interval node, которая раз в минуту будет дёргать следующую ноду с настройкой периода времени, где я указал желаемый диапазон.</p>
  <figure id="gpdC" class="m_original">
    <img src="https://img4.teletype.in/files/f9/a2/f9a2e449-3c7d-47de-b841-80e79a344c6c.png" width="726" />
  </figure>
  <p id="SlRy">Если текущий момент времени попадает в заданный мною интервал, то звонок выключится после проверки его состояния.</p>
  <p id="1lmx">Если он уже был выключен ранее, то команда не пойдет дальше. Аналогично и со вторым выходом.</p>
  <p id="yIWm">Если текущее время не попадает в интервал, то проверяем статус, и включаем звонок, если этого не было сделано ранее.</p>
  <p id="Xzsg">Код этого Node-RED-flow представлен ниже:</p>
  <pre data-lang="jsx" id="zVfG">[{&quot;id&quot;:&quot;e0f64da0.c0817&quot;,&quot;type&quot;:&quot;interval&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;interval&quot;,&quot;interval&quot;:&quot;1&quot;,&quot;onstart&quot;:true,&quot;msg&quot;:&quot;ping&quot;,&quot;showstatus&quot;:false,&quot;unit&quot;:&quot;minutes&quot;,&quot;statusformat&quot;:&quot;YYYY-MM-D HH:mm:ss&quot;,&quot;x&quot;:110,&quot;y&quot;:160,&quot;wires&quot;:[[&quot;b43c9154.0a918&quot;]]},{&quot;id&quot;:&quot;b43c9154.0a918&quot;,&quot;type&quot;:&quot;time-range-switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Sleeptime&quot;,&quot;lat&quot;:&quot;55.00&quot;,&quot;lon&quot;:&quot;37.00&quot;,&quot;startTime&quot;:&quot;22:00&quot;,&quot;endTime&quot;:&quot;09:00&quot;,&quot;startOffset&quot;:&quot;0&quot;,&quot;endOffset&quot;:0,&quot;x&quot;:260,&quot;y&quot;:160,&quot;wires&quot;:[[&quot;70939410.71bf1c&quot;],[&quot;a71468e9.d47168&quot;]]},{&quot;id&quot;:&quot;70939410.71bf1c&quot;,&quot;type&quot;:&quot;api-current-state&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Статус звонка&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:2,&quot;outputs&quot;:2,&quot;halt_if&quot;:&quot;on&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;entity_id&quot;:&quot;switch.corridor_doorbell&quot;,&quot;state_type&quot;:&quot;str&quot;,&quot;blockInputOverrides&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entity&quot;}],&quot;override_topic&quot;:false,&quot;state_location&quot;:&quot;payload&quot;,&quot;override_payload&quot;:&quot;msg&quot;,&quot;entity_location&quot;:&quot;data&quot;,&quot;override_data&quot;:&quot;msg&quot;,&quot;x&quot;:460,&quot;y&quot;:140,&quot;wires&quot;:[[&quot;f28e5d04.a653b&quot;],[]]},{&quot;id&quot;:&quot;f28e5d04.a653b&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Дверной звонок&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;switch&quot;,&quot;service&quot;:&quot;turn_off&quot;,&quot;entityId&quot;:&quot;switch.corridor_doorbell&quot;,&quot;data&quot;:&quot;&quot;,&quot;dataType&quot;:&quot;jsonata&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:680,&quot;y&quot;:140,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;a71468e9.d47168&quot;,&quot;type&quot;:&quot;api-current-state&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Статус звонка&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:2,&quot;outputs&quot;:2,&quot;halt_if&quot;:&quot;off&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;entity_id&quot;:&quot;switch.corridor_doorbell&quot;,&quot;state_type&quot;:&quot;str&quot;,&quot;blockInputOverrides&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entity&quot;}],&quot;override_topic&quot;:false,&quot;state_location&quot;:&quot;payload&quot;,&quot;override_payload&quot;:&quot;msg&quot;,&quot;entity_location&quot;:&quot;data&quot;,&quot;override_data&quot;:&quot;msg&quot;,&quot;x&quot;:460,&quot;y&quot;:180,&quot;wires&quot;:[[&quot;9796db3.788e328&quot;],[]]},{&quot;id&quot;:&quot;9796db3.788e328&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Дверной звонок&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;switch&quot;,&quot;service&quot;:&quot;turn_on&quot;,&quot;entityId&quot;:&quot;switch.corridor_doorbell&quot;,&quot;data&quot;:&quot;&quot;,&quot;dataType&quot;:&quot;jsonata&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:680,&quot;y&quot;:180,&quot;wires&quot;:[[]]}]}]</pre>
  <p id="TrEc"></p>
  <h3 id="Hb4r">Уведомление в Telegram</h3>
  <p id="Ewg9"></p>
  <p id="59cO">Как раз для этого идеально подходит релейный модуль от Fibaro, т.к. он имеет возможность управления выходами с помощью подключенных выключателей<br />или кнопок к клеммам S1 и S2.</p>
  <figure id="ndP3" class="m_original">
    <img src="https://img3.teletype.in/files/a6/23/a6232763-7529-426e-848b-c2d9f5a12207.png" width="388" />
  </figure>
  <p id="gaeS">При подаче фазы на один из этих входов срабатывает соответствующий ему выход реле O1 или O2. Так как у меня выход O1 уже занят самим звонком, то я задействую вход S2.</p>
  <p id="64xO">Из-за того, что в моём случае схема такова, что кнопкой разрывается ноль, а на вход S2 нужно подать фазу, то задача усложняется. Потребуется дополнительный элемент в виде твердотельного реле, управляемого переменным током.</p>
  <figure id="sJqC" class="m_original">
    <img src="https://img2.teletype.in/files/d3/f9/d3f9883e-6b23-4bf1-a20a-dbb800e0777e.png" width="761" />
    <figcaption>Реле SSR-40 DA</figcaption>
  </figure>
  <p id="DsTD"></p>
  <p id="Q7Z0">К одному из входов для обеспечения работы этого реле подключается фаза. Эта же фаза подключается и к одному из выходов, для дальнейшей её передачи на модуль в качестве управляющего сигнала. Ноль для питания реле берём от звонка.</p>
  <figure id="Bg2J" class="m_original">
    <img src="https://img1.teletype.in/files/ca/b2/cab2407d-a4fc-41c3-bc20-09cd1022aae3.png" width="761" />
  </figure>
  <p id="pKyP"></p>
  <p id="druZ">Таким образом, при нажатии на кнопку, реле включается, его выход закрывается,<br />и управляющий сигнал попадает на вход S2 модуля Fibaro.</p>
  <figure id="qSna" class="m_original">
    <img src="https://img4.teletype.in/files/bc/0a/bc0a0963-8d84-485c-830d-9c15780b0ce0.png" width="761" />
  </figure>
  <p id="H6X0"></p>
  <p id="4Ipy">Опять же, в случае, где кнопкой разрывается фаза, всё гораздо проще, и надо всего лишь соединить между собой общий вход реле и вход S2.</p>
  <figure id="dE0i" class="m_original">
    <img src="https://img2.teletype.in/files/12/aa/12aadcaf-5e68-4abd-ba27-de848abfe5eb.png" width="761" />
  </figure>
  <p id="vRmQ">Итак, с железной частью разобрались. Перейдем к настройке.</p>
  <p id="jIrx">В свойствах релейного модуля (конфигурация Z-Wave) необходимо обязательно задать два параметра. Первый отвечает за то, что при нажатой кнопке реле включено, а при отпущенной выключено.</p>
  <figure id="bWIa" class="m_original">
    <img src="https://img2.teletype.in/files/df/c3/dfc3a82c-324c-4c71-8c90-6d707892bd3a.png" width="624" />
  </figure>
  <p id="Kr0w"></p>
  <p id="2TD9">А второй то, что кнопка является двухпозиционным выключателем. Иначе схема не будет работать.</p>
  <figure id="tXui" class="m_original">
    <img src="https://img1.teletype.in/files/c3/a2/c3a26158-ecd0-49ef-8d82-d64178aeeb3a.png" width="609" />
  </figure>
  <p id="ePYV"></p>
  <p id="ox8W">Аналогично меняю имя и ID у переключателя, который соответствует второму реле модуля Fibaro,</p>
  <figure id="P3NR" class="m_original">
    <img src="https://img1.teletype.in/files/0e/03/0e03e022-1b01-4cbc-862d-5e5a042956dd.png" width="407" />
  </figure>
  <p id="Owi1">и перехожу к созданию сценария для получения уведомления.</p>
  <figure id="5j5u" class="m_original">
    <img src="https://img2.teletype.in/files/1a/fe/1afecfa6-afc6-42e0-b9b9-f87c58e3b534.png" width="698" />
    <figcaption>Итоговый вид сценария претерпел изменения. Код обновлённого flow доступен ниже.</figcaption>
  </figure>
  <ul id="zgwT">
    <li id="yHq2">Добавляем ноду и указываем в ней ID устройства, срабатывающего при нажатии кнопки.</li>
  </ul>
  <figure id="9dhh" class="m_original">
    <img src="https://img1.teletype.in/files/47/0a/470a19dc-88a7-4e10-a8f9-74ae25c64f12.png" width="502" />
  </figure>
  <ul id="cvAZ">
    <li id="ETpi">Далее включаем ограничение получения сообщений не чаще одного раза в 2 минуты, чтобы не плодить уведомления при многократном нажатии кнопки.</li>
  </ul>
  <figure id="Yx9A" class="m_original">
    <img src="https://img4.teletype.in/files/32/a6/32a65eb2-0342-46e5-bb9f-a1c7bbd31244.png" width="509" />
  </figure>
  <ul id="7EkE">
    <li id="N9F1">И непосредственно отправка.</li>
  </ul>
  <figure id="Sklf" class="m_original">
    <img src="https://img4.teletype.in/files/f3/d9/f3d90a44-e6c2-4612-afe4-c33b6b685771.png" width="556" />
  </figure>
  <p id="birA">Для взаимодействия с telegram-ботом необходимо установить модуль<br /><strong>node-red-contrib-telegrambot</strong> для Node-RED.</p>
  <ul id="3nKK">
    <li id="K9Vd">Выбираем своего настроенного бота, в параметрах которого заполняется имя, токен, полученный при создании бота, и разрешенные для общения с ним Chat ID через запятую.</li>
    <li id="gY6U">Указываем свой Chat ID для получения сообщений от бота и произвольный текст уведомления в виде шаблона, взятого из документации к ноде, работа методов которой, в свою очередь, основана на документации Telegram Bot API.</li>
  </ul>
  <p id="W1mk"></p>
  <h3 id="5jrV">Снимок с камеры при звонке</h3>
  <p id="ZMe0"></p>
  <p id="W3wB">Как видно, сообщение почти сразу приходит после нажатия кнопки.</p>
  <figure id="Kmwf" class="m_column">
    <img src="https://img4.teletype.in/files/7e/c3/7ec36866-d03c-46d2-b32b-6a715e6d3693.png" width="877" />
  </figure>
  <p id="A5n2">Как и задумано, повторное нажатие кнопки ничего не даёт.</p>
  <p id="gPHg">Дальше мне захотелось видеть звонящего. Я остановил свой выбор на аналоговой камере в виде дверного глазка.</p>
  <figure id="Vhot" class="m_original">
    <img src="https://img4.teletype.in/files/f7/9e/f79ecd1f-e719-41ac-bd02-8cbc11504dc6.jpeg" width="418" />
  </figure>
  <p id="K0IH">Единственным её плюсом является возможность установки в дверь на уровне глаз. Потому как низкая стоимость камеры нивелируется необходимостью покупки видеорегистратора для получения цифрового сигнала.</p>
  <figure id="bypN" class="m_original">
    <img src="https://img4.teletype.in/files/b9/c9/b9c9df79-ed5c-48a9-b545-f2fc54df6723.jpeg" width="400" />
  </figure>
  <p id="tlb2">Для получения снимка с камеры в уведомлении изменим сценарий, добавив ноду<br />HTTP request.</p>
  <figure id="gsvk" class="m_column">
    <img src="https://img3.teletype.in/files/ec/3b/ec3ba2a2-a18c-4b2c-a377-cc95e984c762.png" width="1285" />
    <figcaption>Итоговый вид сценария претерпел изменения. Код обновлённого flow доступен ниже.</figcaption>
  </figure>
  <p id="KwMk"></p>
  <p id="h0wf">В ней указываем адрес, который отдаёт статическое изображение (его можно взять из документации к камере или видеорегистратору).</p>
  <figure id="HzTc" class="m_original">
    <img src="https://img3.teletype.in/files/6a/0f/6a0f3861-f1dd-4830-babd-b6fb062a15fa.png" width="503" />
  </figure>
  <p id="zomT">Я заранее подключил камеру к Home Assistant, поэтому ссылка ведет к нему.<br />В качестве результата запроса выбираем ”a binary buffer”.</p>
  <p id="jI4n">Следом добавляем ноду function, где формируем содержимое согласно документации telegram-ноды по отправке изображений. Содержимым снимка будет полученный ранее ответ от ноды HTTP request.</p>
  <p id="uxs2">Далее добавляем telegram-ноду payload. В ней указываем Chat ID и метод отправки. Предполагается, что бог уже заранее настроен.</p>
  <p id="lRGn">Последней я решил добавить telegram-ноду для отображения кнопки получения дополнительного снимка на случай неудачного первого кадра.</p>
  <p id="xlpF">Код этого Node-RED flow представлен ниже:</p>
  <pre id="spod">[{&quot;id&quot;:&quot;9f016b89.edeb18&quot;,&quot;type&quot;:&quot;server-state-changed&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Звонок в дверь&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;exposeToHomeAssistant&quot;:false,&quot;haConfig&quot;:[{&quot;property&quot;:&quot;name&quot;,&quot;value&quot;:&quot;&quot;},{&quot;property&quot;:&quot;icon&quot;,&quot;value&quot;:&quot;&quot;}],&quot;entityidfilter&quot;:&quot;switch.corridor_doorbell_ding&quot;,&quot;entityidfiltertype&quot;:&quot;substring&quot;,&quot;outputinitially&quot;:false,&quot;state_type&quot;:&quot;str&quot;,&quot;haltifstate&quot;:&quot;on&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;outputs&quot;:2,&quot;output_only_on_state_change&quot;:false,&quot;for&quot;:&quot;&quot;,&quot;forType&quot;:&quot;num&quot;,&quot;forUnits&quot;:&quot;minutes&quot;,&quot;ignorePrevStateNull&quot;:false,&quot;ignorePrevStateUnknown&quot;:false,&quot;ignorePrevStateUnavailable&quot;:false,&quot;ignoreCurrentStateUnknown&quot;:false,&quot;ignoreCurrentStateUnavailable&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;eventData&quot;},{&quot;property&quot;:&quot;topic&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;triggerId&quot;}],&quot;x&quot;:140,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;96fbc9f0.88a2e8&quot;],[]]},{&quot;id&quot;:&quot;96fbc9f0.88a2e8&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;rate&quot;,&quot;timeout&quot;:&quot;5&quot;,&quot;timeoutUnits&quot;:&quot;seconds&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;120&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:true,&quot;x&quot;:360,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;65c28ed9.0a8e6&quot;]]},{&quot;id&quot;:&quot;65c28ed9.0a8e6&quot;,&quot;type&quot;:&quot;stoptimer&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;duration&quot;:&quot;1&quot;,&quot;units&quot;:&quot;Second&quot;,&quot;payloadtype&quot;:&quot;str&quot;,&quot;payloadval&quot;:&quot;&quot;,&quot;name&quot;:&quot;Timeout&quot;,&quot;x&quot;:600,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;4a1d76bc.4213b8&quot;],[]]},{&quot;id&quot;:&quot;6a886333.f832cc&quot;,&quot;type&quot;:&quot;telegram event&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Еще снимок&quot;,&quot;bot&quot;:&quot;f6e2842.9c49078&quot;,&quot;event&quot;:&quot;callback_query&quot;,&quot;autoanswer&quot;:true,&quot;x&quot;:510,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;7d5306e4.b68658&quot;]]},{&quot;id&quot;:&quot;7d5306e4.b68658&quot;,&quot;type&quot;:&quot;switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;property&quot;:&quot;payload.content&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;RING MORE PIC&quot;,&quot;vt&quot;:&quot;str&quot;}],&quot;checkall&quot;:&quot;true&quot;,&quot;repair&quot;:false,&quot;outputs&quot;:1,&quot;x&quot;:635,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;4a1d76bc.4213b8&quot;]],&quot;l&quot;:false},{&quot;id&quot;:&quot;4a1d76bc.4213b8&quot;,&quot;type&quot;:&quot;http request&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;method&quot;:&quot;GET&quot;,&quot;ret&quot;:&quot;bin&quot;,&quot;paytoqs&quot;:&quot;ignore&quot;,&quot;url&quot;:&quot;http://192.168.1.51/ISAPI/Streaming/channels/101/picture?snapShotImageType=JPEG&quot;,&quot;tls&quot;:&quot;&quot;,&quot;persist&quot;:false,&quot;proxy&quot;:&quot;&quot;,&quot;authType&quot;:&quot;digest&quot;,&quot;x&quot;:790,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;ff3c4b90.e504a8&quot;]]},{&quot;id&quot;:&quot;ff3c4b90.e504a8&quot;,&quot;type&quot;:&quot;switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;property&quot;:&quot;payload.chat.id&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;9999999&quot;,&quot;vt&quot;:&quot;str&quot;},{&quot;t&quot;:&quot;null&quot;},{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;8888888&quot;,&quot;vt&quot;:&quot;str&quot;}],&quot;checkall&quot;:&quot;true&quot;,&quot;repair&quot;:false,&quot;outputs&quot;:3,&quot;x&quot;:950,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;3edab718.b8c668&quot;],[&quot;3edab718.b8c668&quot;,&quot;4295b732.a42978&quot;],[&quot;4295b732.a42978&quot;]],&quot;outputLabels&quot;:[&quot;Sergey&quot;,&quot;Empty&quot;,null]},{&quot;id&quot;:&quot;3edab718.b8c668&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Chat ID&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;chatId&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;99999999&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:1100,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;d0a52ed6.209b5&quot;]]},{&quot;id&quot;:&quot;d0a52ed6.209b5&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Data&quot;,&quot;func&quot;:&quot;context.global.keyboard = { messageId : msg.payload.messageId };\n\nvar opts = {\n  reply_to_message_id: msg.payload.messageId,\n  reply_markup: JSON.stringify({\n    \&quot;inline_keyboard\&quot;: [[\n                {\n                    \&quot;text\&quot;: \&quot;📷 Eщё снимок\&quot;,\n                    \&quot;callback_data\&quot;: \&quot;RING MORE PIC\&quot;\n                }]\n            ]\n  })\n};\n\nmsg.payload = {\n    chatId: msg.chatId,\n    type: \&quot;photo\&quot;,\n    content: msg.payload,\n    caption: \&quot;🔔 Звонок в дверь\&quot;,\n    options: opts\n};\nreturn msg;\n&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:1250,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;9a15c39c.d532&quot;]]},{&quot;id&quot;:&quot;9a15c39c.d532&quot;,&quot;type&quot;:&quot;telegram sender&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;bot&quot;:&quot;f6e2842.9c49078&quot;,&quot;haserroroutput&quot;:false,&quot;outputs&quot;:1,&quot;x&quot;:1430,&quot;y&quot;:320,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;4295b732.a42978&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Chat ID&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;chatId&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;8888888&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:1100,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;d0a52ed6.209b5&quot;]]}]</pre>
  <p id="eGMH"></p>
  <h3 id="J2gM">Результат</h3>
  <p id="O68y"></p>
  <p id="lpk0">Несмотря на подключение к сети через мобильного оператора, сообщение приходит в течение одной секунды.</p>
  <figure id="YRrQ" class="m_column">
    <img src="https://img3.teletype.in/files/e3/d8/e3d82803-234b-4d11-9f1e-370a689946d3.png" width="1727" />
  </figure>
  <p id="fmL9">А в Node-RED видно момент нажатия кнопки звонка, а также нажатия кнопки получения дополнительного снимка.</p>
  <p id="TZvL"></p>
  <h3 id="pKJe">Kodi</h3>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <figure id="JNVl" class="m_custom">
      <img src="https://img1.teletype.in/files/85/b6/85b689c3-a5e9-47b0-acba-f0be3d6a1dd8.png" width="100" />
    </figure>
  </section>
  <p id="iMut">Позже я обратил внимание на один из компонентов Home Assistant, который умеет слать уведомления в медиацентр Kodi.</p>
  <p id="KxDQ">Настроив его согласно <a href="https://www.home-assistant.io/integrations/kodi/#notifications" target="_blank">документации</a>, я отправился в Node-RED для обновления имеющегося сценария.</p>
  <figure id="dzsK" class="m_column">
    <img src="https://img1.teletype.in/files/c4/f5/c4f52458-4d52-42b6-aa40-b251a6341559.png" width="1060" />
    <figcaption>Итоговый вид сценария претерпел изменения. Код обновлённого flow доступен ниже.</figcaption>
  </figure>
  <p id="8usu">Первый делом добавил ноду call service (Kodi notify) из раздела Home Assistant.</p>
  <p id="KpZF">В параметрах заполнил только поле домен, т. к. остальное легче сформировать в ноде function. Взяв <a href="https://www.home-assistant.io/integrations/kodi/#script-example" target="_blank">этот пример скрипта</a> за основу, я сконвертировал yaml в json и добавил в function-ноду. Затем поменял параметры по своему усмотрению.</p>
  <p id="O7Ja">Код этого Node-RED flow представлен ниже:</p>
  <pre id="5imP">[{&quot;id&quot;:&quot;9f016b89.edeb18&quot;,&quot;type&quot;:&quot;server-state-changed&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Звонок в дверь&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;exposeToHomeAssistant&quot;:false,&quot;haConfig&quot;:[{&quot;property&quot;:&quot;name&quot;,&quot;value&quot;:&quot;&quot;},{&quot;property&quot;:&quot;icon&quot;,&quot;value&quot;:&quot;&quot;}],&quot;entityidfilter&quot;:&quot;switch.corridor_doorbell_ding&quot;,&quot;entityidfiltertype&quot;:&quot;substring&quot;,&quot;outputinitially&quot;:false,&quot;state_type&quot;:&quot;str&quot;,&quot;haltifstate&quot;:&quot;on&quot;,&quot;halt_if_type&quot;:&quot;str&quot;,&quot;halt_if_compare&quot;:&quot;is&quot;,&quot;outputs&quot;:2,&quot;output_only_on_state_change&quot;:false,&quot;for&quot;:&quot;&quot;,&quot;forType&quot;:&quot;num&quot;,&quot;forUnits&quot;:&quot;minutes&quot;,&quot;ignorePrevStateNull&quot;:false,&quot;ignorePrevStateUnknown&quot;:false,&quot;ignorePrevStateUnavailable&quot;:false,&quot;ignoreCurrentStateUnknown&quot;:false,&quot;ignoreCurrentStateUnavailable&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;entityState&quot;},{&quot;property&quot;:&quot;data&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;eventData&quot;},{&quot;property&quot;:&quot;topic&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;triggerId&quot;}],&quot;x&quot;:140,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;96fbc9f0.88a2e8&quot;],[]]},{&quot;id&quot;:&quot;96fbc9f0.88a2e8&quot;,&quot;type&quot;:&quot;delay&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;pauseType&quot;:&quot;rate&quot;,&quot;timeout&quot;:&quot;5&quot;,&quot;timeoutUnits&quot;:&quot;seconds&quot;,&quot;rate&quot;:&quot;1&quot;,&quot;nbRateUnits&quot;:&quot;120&quot;,&quot;rateUnits&quot;:&quot;second&quot;,&quot;randomFirst&quot;:&quot;1&quot;,&quot;randomLast&quot;:&quot;5&quot;,&quot;randomUnits&quot;:&quot;seconds&quot;,&quot;drop&quot;:true,&quot;x&quot;:360,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;65c28ed9.0a8e6&quot;,&quot;2618bb1b.e9dff4&quot;]]},{&quot;id&quot;:&quot;65c28ed9.0a8e6&quot;,&quot;type&quot;:&quot;stoptimer&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;duration&quot;:&quot;1&quot;,&quot;units&quot;:&quot;Second&quot;,&quot;payloadtype&quot;:&quot;str&quot;,&quot;payloadval&quot;:&quot;&quot;,&quot;name&quot;:&quot;Timeout&quot;,&quot;x&quot;:600,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;4a1d76bc.4213b8&quot;],[]]},{&quot;id&quot;:&quot;6a886333.f832cc&quot;,&quot;type&quot;:&quot;telegram event&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Еще снимок&quot;,&quot;bot&quot;:&quot;f6e2842.9c49078&quot;,&quot;event&quot;:&quot;callback_query&quot;,&quot;autoanswer&quot;:true,&quot;x&quot;:510,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;7d5306e4.b68658&quot;]]},{&quot;id&quot;:&quot;7d5306e4.b68658&quot;,&quot;type&quot;:&quot;switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;property&quot;:&quot;payload.content&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;RING MORE PIC&quot;,&quot;vt&quot;:&quot;str&quot;}],&quot;checkall&quot;:&quot;true&quot;,&quot;repair&quot;:false,&quot;outputs&quot;:1,&quot;x&quot;:635,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;4a1d76bc.4213b8&quot;]],&quot;l&quot;:false},{&quot;id&quot;:&quot;4a1d76bc.4213b8&quot;,&quot;type&quot;:&quot;http request&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;method&quot;:&quot;GET&quot;,&quot;ret&quot;:&quot;bin&quot;,&quot;paytoqs&quot;:&quot;ignore&quot;,&quot;url&quot;:&quot;http://192.168.1.51/ISAPI/Streaming/channels/101/picture?snapShotImageType=JPEG&quot;,&quot;tls&quot;:&quot;&quot;,&quot;persist&quot;:false,&quot;proxy&quot;:&quot;&quot;,&quot;authType&quot;:&quot;digest&quot;,&quot;x&quot;:790,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;ff3c4b90.e504a8&quot;]]},{&quot;id&quot;:&quot;ff3c4b90.e504a8&quot;,&quot;type&quot;:&quot;switch&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;property&quot;:&quot;payload.chat.id&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;9999999&quot;,&quot;vt&quot;:&quot;str&quot;},{&quot;t&quot;:&quot;null&quot;},{&quot;t&quot;:&quot;eq&quot;,&quot;v&quot;:&quot;8888888&quot;,&quot;vt&quot;:&quot;str&quot;}],&quot;checkall&quot;:&quot;true&quot;,&quot;repair&quot;:false,&quot;outputs&quot;:3,&quot;x&quot;:950,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;3edab718.b8c668&quot;],[&quot;3edab718.b8c668&quot;,&quot;4295b732.a42978&quot;],[&quot;4295b732.a42978&quot;]],&quot;outputLabels&quot;:[&quot;Sergey&quot;,&quot;Empty&quot;,null]},{&quot;id&quot;:&quot;3edab718.b8c668&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Chat ID&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;chatId&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;99999999&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:1100,&quot;y&quot;:300,&quot;wires&quot;:[[&quot;d0a52ed6.209b5&quot;]]},{&quot;id&quot;:&quot;d0a52ed6.209b5&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Data&quot;,&quot;func&quot;:&quot;context.global.keyboard = { messageId : msg.payload.messageId };\n\nvar opts = {\n  reply_to_message_id: msg.payload.messageId,\n  reply_markup: JSON.stringify({\n    \&quot;inline_keyboard\&quot;: [[\n                {\n                    \&quot;text\&quot;: \&quot;📷 Eщё снимок\&quot;,\n                    \&quot;callback_data\&quot;: \&quot;RING MORE PIC\&quot;\n                }]\n            ]\n  })\n};\n\nmsg.payload = {\n    chatId: msg.chatId,\n    type: \&quot;photo\&quot;,\n    content: msg.payload,\n    caption: \&quot;🔔 Звонок в дверь\&quot;,\n    options: opts\n};\nreturn msg;\n&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:1250,&quot;y&quot;:320,&quot;wires&quot;:[[&quot;9a15c39c.d532&quot;]]},{&quot;id&quot;:&quot;9a15c39c.d532&quot;,&quot;type&quot;:&quot;telegram sender&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;&quot;,&quot;bot&quot;:&quot;f6e2842.9c49078&quot;,&quot;haserroroutput&quot;:false,&quot;outputs&quot;:1,&quot;x&quot;:1430,&quot;y&quot;:320,&quot;wires&quot;:[[]]},{&quot;id&quot;:&quot;4295b732.a42978&quot;,&quot;type&quot;:&quot;change&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Chat ID&quot;,&quot;rules&quot;:[{&quot;t&quot;:&quot;set&quot;,&quot;p&quot;:&quot;chatId&quot;,&quot;pt&quot;:&quot;msg&quot;,&quot;to&quot;:&quot;8888888&quot;,&quot;tot&quot;:&quot;str&quot;}],&quot;action&quot;:&quot;&quot;,&quot;property&quot;:&quot;&quot;,&quot;from&quot;:&quot;&quot;,&quot;to&quot;:&quot;&quot;,&quot;reg&quot;:false,&quot;x&quot;:1100,&quot;y&quot;:340,&quot;wires&quot;:[[&quot;d0a52ed6.209b5&quot;]]},{&quot;id&quot;:&quot;2618bb1b.e9dff4&quot;,&quot;type&quot;:&quot;function&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Ding&quot;,&quot;func&quot;:&quot;msg.payload = {\n    service: \&quot;kodi_livingroom_notifier\&quot;,\n    data: {\n        \&quot;title\&quot;: \&quot;Звонок в дверь\&quot;,\n        \&quot;message\&quot;: \&quot;Звонок в дверь\&quot;,\n        \&quot;data\&quot;: {\n            \&quot;displaytime\&quot;: 10000,\n            \&quot;icon\&quot;: \&quot;http://172.16.1.3:8123/local/images/kodi_ding.png\&quot;\n        }\n    }\n}\nreturn msg;&quot;,&quot;outputs&quot;:1,&quot;noerr&quot;:0,&quot;initialize&quot;:&quot;&quot;,&quot;finalize&quot;:&quot;&quot;,&quot;libs&quot;:[],&quot;x&quot;:550,&quot;y&quot;:420,&quot;wires&quot;:[[&quot;caae558f.e8dac8&quot;]]},{&quot;id&quot;:&quot;caae558f.e8dac8&quot;,&quot;type&quot;:&quot;api-call-service&quot;,&quot;z&quot;:&quot;fd15b534.04ee48&quot;,&quot;name&quot;:&quot;Kodi notify&quot;,&quot;server&quot;:&quot;b9490f48.586ed&quot;,&quot;version&quot;:3,&quot;debugenabled&quot;:false,&quot;service_domain&quot;:&quot;notify&quot;,&quot;service&quot;:&quot;&quot;,&quot;entityId&quot;:&quot;&quot;,&quot;data&quot;:&quot;{}&quot;,&quot;dataType&quot;:&quot;json&quot;,&quot;mergecontext&quot;:&quot;&quot;,&quot;mustacheAltTags&quot;:false,&quot;outputProperties&quot;:[{&quot;property&quot;:&quot;payload&quot;,&quot;propertyType&quot;:&quot;msg&quot;,&quot;value&quot;:&quot;&quot;,&quot;valueType&quot;:&quot;data&quot;}],&quot;queue&quot;:&quot;none&quot;,&quot;x&quot;:710,&quot;y&quot;:420,&quot;wires&quot;:[[]]}]</pre>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Myia">Использованные в сценарии модули Node-RED:<br /><strong>node-red-contrib-time-range-switch<br />node-red-contrib-stoptimer<br />node-red-contrib-telegrambot<br />node-red-contrib-interval</strong></p>
  </section>
  <p id="mxmH"></p>
  <p id="FObu">На выходе я получил дополнительное уведомление для звонка, работающего в беззвучном режиме.</p>
  <figure id="SyaC" class="m_column">
    <img src="https://img4.teletype.in/files/bf/70/bf70f803-c5c0-45cd-ac50-18b01026e3c6.png" width="802" />
  </figure>
  <p id="25Tw"></p>
  <p id="QN7y">Так как для использования в Kodi доступно огромное количество различных плагинов, то следом я настроил отображение видеопотока с камеры одновременно с уведомлением.</p>
  <figure id="XYvS" class="m_column">
    <img src="https://img4.teletype.in/files/b7/e2/b7e27f16-d63c-45e4-8504-a7a853e4ba56.png" width="1918" />
  </figure>
  <p id="pBVW">Но это тема следующих статей, так как она достаточно объемная и затрагивает<br />многие, еще неописанные, вещи.</p>
  <p id="Disq"></p>
  <p id="xUFg">В заключение скажу, что, конечно, есть отличные готовые решения.</p>
  <figure id="Rk3b" class="m_column">
    <img src="https://img4.teletype.in/files/f4/35/f435f9cf-5ef9-42b1-8e2f-e7d8225ccf36.jpeg" width="800" />
  </figure>
  <figure id="ATAV" class="m_column">
    <img src="https://img3.teletype.in/files/26/5d/265ddaf9-3f29-4156-bfbc-f55e948e4bfd.png" width="800" />
  </figure>
  <figure id="TfEL" class="m_column">
    <img src="https://img4.teletype.in/files/bd/e9/bde9055b-df37-4e63-886f-6d3a2f3c158b.jpeg" width="800" />
  </figure>
  <figure id="17FS" class="m_column">
    <img src="https://img4.teletype.in/files/75/64/7564655d-b4ae-4972-9eb1-3987416224d0.jpeg" width="800" />
  </figure>
  <p id="2iyN">В силу специфики своей работы или высокой стоимости они мне не подошли.</p>
  <p id="emEg"></p>
  <hr />
  <p id="hmO8">Все конфигурации, описанные в статье, доступны на <a href="https://github.com/isaenkovpro/configs/tree/master/001%20Doorbell" target="_blank">GitHub</a>.</p>

]]></content:encoded></item></channel></rss>