Управляем дюймовыми жалюзи дешево

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



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



    Результат работы моего проекта по автоматизации жалюзи из Leroy Merlin


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


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



    Автоматизированные жалюзи на окне офиса


    1. Выбор двигателя и управляющего микроконтроллера


    Сначала непонятно было с чего вообще начинать. Для автоматизации, в других проектах часто использовали шаговый двигатель 28BYJ-48 за примерно 130 руб за штуку (в Китае). С управляющим контроллером у меня вопрос не стоял, поскольку практически везде использую LOLIN (WEMOS) D1 mini.



    Переделанные и стандартные жалюзи: вид сверху


    2. Прошивка для микроконтроллера ESP8266 китайского производителя Espressif Systems


    На следующем шаге — прошивке мне не хотелось заморачиваться со сложным кодингом, а привычная Tasmota не выдавала готовых вариантов. Тогда я познакомился с ESPHome — прошивкой которая нативно и без MQTT поддерживается Home Assistant.



    Переделанные и стандартные жалюзи: вид сбоку


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



    Переделанные жалюзи: вид сбоку


    Поскольку я использую Hass.io, то для компиляции прошивок использовал самый простой для этого вариант — ESPHome Hass.io Add-On.
    На окне три жалюзи и получилось три микроконтроллера. Вот получившиеся прошивки:
    После тестов обнаружил что, для корректного открытия/закрытия жалюзи необходимо задавать разное число шагов для каждой жалюзи.



    window_1.yaml
    substitutions:
      devicename: window_1
      upper_devicename: Window 1
    
    esphome:
      name: $devicename
      platform: ESP8266
      board: d1_mini
    
    wifi:
      ssid: "xxx"
      password: "xxx"
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Window 1 Fallback Hotspot"
        password: "xxx"
    
    captive_portal:
    
    # web_server:
    #   port: 80
    #   css_url: http://192.168.15.10:8123/local/webserver-v1.min.css
    #   js_url: http://192.168.15.10:8123/local/webserver-v1.min.js
    
    # Enable Home Assistant API
    api:
      services:
        - service: control_stepper
          variables:
            target: int
          then:
            - stepper.set_target:
                id: my_stepper
                target: !lambda 'return target;'
    
    # Enable OTA Access
    ota:
    
    # Enable verbose logging over serial
    logger:
    
    # physical connection
    stepper:
      - platform: uln2003
        id: my_stepper
        pin_a: D0
        pin_b: D5
        pin_c: D6
        pin_d: D7
        max_speed: 250 steps/s
        sleep_when_done: true    
        acceleration: inf
        deceleration: inf
    
    i2c:
    
    cover:
      - platform: template
        name: "Zhaliuzi 1"
        id: window1
        device_class: blind
    
        open_action:
          - stepper.report_position:
              id: my_stepper
              position: 0
          - stepper.set_target:
              id: my_stepper
              target: -1550
    
        close_action:
          - stepper.report_position:
              id: my_stepper
              position: 0
          - stepper.set_target:
              id: my_stepper
              target: 1550
    
        stop_action:
          - stepper.set_target:
              id: my_stepper
              target: !lambda return id(my_stepper).current_position;      
        optimistic: true  
        assumed_state: true
    
    sensor:
      - platform: bh1750
        name: "Osveshchennost u okna"
        address: 0x23
        update_interval: 40s
    
    # General device data
      - platform: uptime
        id: uptime_sec
      - platform: wifi_signal
        name: ${upper_devicename} WiFi Signal
        id: wifis_signal
        update_interval: 900s
    
    text_sensor:
      - platform: template
        name: ${upper_devicename} Uptime
        lambda: |-
          int seconds = (id(uptime_sec).state);
          int days = seconds / (24 * 3600);
          seconds = seconds % (24 * 3600);
          int hours = seconds / 3600;
          seconds = seconds % 3600;
          int minutes = seconds /  60;
          seconds = seconds % 60;
          return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
        icon: mdi:clock-start
        update_interval: 113s
      - platform: template
        name: ${upper_devicename} Wifi Strength
        icon: "mdi:wifi"
        lambda: |-
          if (id(wifis_signal).state > -50 ) {
            return {"Excellent"};
          } else if (id(wifis_signal).state > -60) {
            return {"Good"};
          } else if (id(wifis_signal).state > -70) {
            return {"Fair"};
          } else if (id(wifis_signal).state < -70) {
            return {"Weak"};
          } else {
            return {"None"};
          }
        update_interval: 900s
      - platform: version
        name: ${upper_devicename} Version
      - platform: template
        name: ${upper_devicename} MAC Address
        lambda: 'return {WiFi.macAddress().c_str()};'
        icon: mdi:fingerprint
        update_interval: 1d
    
    switch:
      - platform: restart
        name: ${upper_devicename} Restart

    window_2.yaml
    substitutions:
      devicename: window_2
      upper_devicename: Window 2
    
    esphome:
      name: $devicename
      platform: ESP8266
      board: d1_mini
    
    wifi:
      ssid: "xxx"
      password: "xxx"
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Window 2 Fallback Hotspot"
        password: "xxx"
    
    captive_portal:
    
    # web_server:
    #   port: 80
    #   css_url: http://192.168.15.10:8123/local/webserver-v1.min.css
    #   js_url: http://192.168.15.10:8123/local/webserver-v1.min.js
    
    # Enable Home Assistant API
    api:
      services:
        - service: control_stepper
          variables:
            target: int
          then:
            - stepper.set_target:
                id: my_stepper
                target: !lambda 'return target;'
    
    # Enable OTA Access
    ota:
    
    # Enable verbose logging over serial
    logger:
    
    # physical connection
    stepper:
      - platform: uln2003
        id: my_stepper
        pin_a: D0
        pin_b: D5
        pin_c: D6
        pin_d: D7
        max_speed: 250 steps/s
        sleep_when_done: true    
        acceleration: inf
        deceleration: inf
    
    cover:
      - platform: template
        name: "Zhaliuzi 2"
        id: window2
        device_class: blind
    
        open_action:
          - stepper.report_position:
              id: my_stepper
              position: 0
          - stepper.set_target:
              id: my_stepper
              target: -1800
    
        close_action:
          - stepper.report_position:
              id: my_stepper
              position: 0
          - stepper.set_target:
              id: my_stepper
              target: 1800
    
        stop_action:
          - stepper.set_target:
              id: my_stepper
              target: !lambda return id(my_stepper).current_position;      
        optimistic: true  
        assumed_state: true
    
    # General device data
    sensor:
      - platform: uptime
        id: uptime_sec
      - platform: wifi_signal
        name: ${upper_devicename} WiFi Signal
        id: wifis_signal
        update_interval: 900s
    
    text_sensor:
      - platform: template
        name: ${upper_devicename} Uptime
        lambda: |-
          int seconds = (id(uptime_sec).state);
          int days = seconds / (24 * 3600);
          seconds = seconds % (24 * 3600);
          int hours = seconds / 3600;
          seconds = seconds % 3600;
          int minutes = seconds /  60;
          seconds = seconds % 60;
          return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
        icon: mdi:clock-start
        update_interval: 113s
      - platform: template
        name: ${upper_devicename} Wifi Strength
        icon: "mdi:wifi"
        lambda: |-
          if (id(wifis_signal).state > -50 ) {
            return {"Excellent"};
          } else if (id(wifis_signal).state > -60) {
            return {"Good"};
          } else if (id(wifis_signal).state > -70) {
            return {"Fair"};
          } else if (id(wifis_signal).state < -70) {
            return {"Weak"};
          } else {
            return {"None"};
          }
        update_interval: 900s
      - platform: version
        name: ${upper_devicename} Version
      - platform: template
        name: ${upper_devicename} MAC Address
        lambda: 'return {WiFi.macAddress().c_str()};'
        icon: mdi:fingerprint
        update_interval: 1d
    
    switch:
      - platform: restart
        name: ${upper_devicename} Restart

    window_3.yaml
    substitutions:
      devicename: window_3
      upper_devicename: Window 3
    
    esphome:
      name: $devicename
      platform: ESP8266
      board: d1_mini
    
    wifi:
      ssid: "xxx"
      password: "xxx"
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Window 3 Fallback Hotspot"
        password: "xxx"
    
    captive_portal:
    
    # web_server:
    #   port: 80
    #   css_url: http://192.168.15.10:8123/local/webserver-v1.min.css
    #   js_url: http://192.168.15.10:8123/local/webserver-v1.min.js
    
    # Enable Home Assistant API
    api:
      services:
        - service: control_stepper
          variables:
            target: int
          then:
            - stepper.set_target:
                id: my_stepper
                target: !lambda 'return target;'
    
    # Enable OTA Access
    ota:
    
    # Enable verbose logging over serial
    logger:
    
    # physical connection
    stepper:
      - platform: uln2003
        id: my_stepper
        pin_a: D0
        pin_b: D5
        pin_c: D6
        pin_d: D7
        max_speed: 250 steps/s
        sleep_when_done: true    
        acceleration: inf
        deceleration: inf
    
    cover:
      - platform: template
        name: "Zhaliuzi 3"
        id: window3
        device_class: blind
    
        open_action:
          - stepper.report_position:
              id: my_stepper
              position: 0
          - stepper.set_target:
              id: my_stepper
              target: -1600
    
        close_action:
          - stepper.report_position:
              id: my_stepper
              position: 0
          - stepper.set_target:
              id: my_stepper
              target: 1600
    
        stop_action:
          - stepper.set_target:
              id: my_stepper
              target: !lambda return id(my_stepper).current_position;      
        optimistic: true  
        assumed_state: true
    
    # General device data
    sensor:
      - platform: uptime
        id: uptime_sec
      - platform: wifi_signal
        name: ${upper_devicename} WiFi Signal
        id: wifis_signal
        update_interval: 900s
    
    text_sensor:
      - platform: template
        name: ${upper_devicename} Uptime
        lambda: |-
          int seconds = (id(uptime_sec).state);
          int days = seconds / (24 * 3600);
          seconds = seconds % (24 * 3600);
          int hours = seconds / 3600;
          seconds = seconds % 3600;
          int minutes = seconds /  60;
          seconds = seconds % 60;
          return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
        icon: mdi:clock-start
        update_interval: 113s
      - platform: template
        name: ${upper_devicename} Wifi Strength
        icon: "mdi:wifi"
        lambda: |-
          if (id(wifis_signal).state > -50 ) {
            return {"Excellent"};
          } else if (id(wifis_signal).state > -60) {
            return {"Good"};
          } else if (id(wifis_signal).state > -70) {
            return {"Fair"};
          } else if (id(wifis_signal).state < -70) {
            return {"Weak"};
          } else {
            return {"None"};
          }
        update_interval: 900s
      - platform: version
        name: ${upper_devicename} Version
      - platform: template
        name: ${upper_devicename} MAC Address
        lambda: 'return {WiFi.macAddress().c_str()};'
        icon: mdi:fingerprint
        update_interval: 1d
    
    switch:
      - platform: restart
        name: ${upper_devicename} Restart

    3. Установка привода в жалюзи


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



    Установленные на окне жалюзи из Леруа Мерлен с электроприводом


    4. Установка конструкции на окне


    Поскольку жалюзи уже были установлены строителями мне оставалось только установить коробку с микроконтроллерами и блоком питания рядом с окном. Блок питания не самый мощный, поскольку шаговые двигатели включаются последовательно — сначала первый, потом второй, потом третий. Общее время работы около 20 секунд.



    Коробка с тремя ESP8266 и блоком питания на стене офиса


    5. Правила для автоматизации закрытия жалюзи из Home Assistant


    При превышении определенного порога жалюзи поворачиваются на 90 градусов и потом соответственно обратно .


    automations.yaml
    - alias: Covers OPEN
      trigger:
        - platform: numeric_state
          entity_id: sensor.osveshchennost_u_okna
          above: 0
          below: 2500
      condition:
        - condition: state
          entity_id: cover.zhaliuzi_3
          state: 'closed'
        - condition: state
          entity_id: cover.zhaliuzi_2
          state: 'closed'
        - condition: state
          entity_id: cover.zhaliuzi_1
          state: 'closed'
      action:
        - service: cover.open_cover
          data:
            entity_id: cover.zhaliuzi_3
        - delay: '00:00:06'
        - service: cover.open_cover
          data:
            entity_id: cover.zhaliuzi_2
        - delay: '00:00:06'
        - service: cover.open_cover
          data:
            entity_id: cover.zhaliuzi_1
    
    - alias: Covers CLOSE
      trigger:
        - platform: numeric_state
          entity_id: sensor.osveshchennost_u_okna
          above: 2501
          below: 50000
      condition:
        - condition: state
          entity_id: cover.zhaliuzi_3
          state: 'open'
        - condition: state
          entity_id: cover.zhaliuzi_2
          state: 'open'
        - condition: state
          entity_id: cover.zhaliuzi_1
          state: 'open'
      action:
        - service: cover.close_cover
          data:
            entity_id: cover.zhaliuzi_3
        - delay: '00:00:06'
        - service: cover.close_cover
          data:
            entity_id: cover.zhaliuzi_2
        - delay: '00:00:06'
        - service: cover.close_cover
          data:
            entity_id: cover.zhaliuzi_1

    Итог


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


    P.S. Уже после окончания работы мне подсказали, что есть специальные соединительные втулки, которые позволят жестко соединить вал двигателя и вал жалюзи. Это позволит избежать прокручивания, которое может возникнуть в моем текущем случае из-за недостаточного закрепления соединительной трубки.

    Дополнительные подробности можно найти на GitHub.


    Автор: Михаил Шардин,
    17 декабря 2019 г.

    Only registered users can participate in poll. Log in, please.

    Ваши жалюзи/шторы автоматизированы?

    • 2.8%Да6
    • 94.0%Нет204
    • 3.2%Где-то да, где-то нет7
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 17

      +1
      Хочу на балконе, после ремонта, римские шторы прикрутить автоматические. Тоже сам делать буду, ибо готовые стоят каких-то конских денег.
        0

        Как вариант присмотритесь к марке Dooya в Китае — у меня в другом месте на шторе в жилой комнате стоят — недорого и надежно.

          +1
          На mysku есть пару вариантов, например — mysku.ru/blog/diy/62110.html
          image
            0
            Ну да, примерно так.
          +3
          Идея отличная. Думаю, многие (я в том числе) задумывались над подобным…
          Но вид всего этого накрученного в коробке меня немного поверг в ужас! Я, конечно, понимаю, что ничего случиться не должно, но там же еще и бескорпусный блок питания на 220!
            0

            Хорошее замечание, но БП там в толстой термоусадке.

              +1
              Не заметил. Увидел «муть», подумал что вообще термопистолетом залито.
              0
              захотелось туда прям банку силикона двухкомпонентного залить :)
              0
              а esp2866 одна всеми тремя моторами управлять не может? или для простоты мультиплицировали?
                +1

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

                0
                А есть что-то условно-бюджетное, но надёжное для более серьёзных нагрузок (типа откатных ворот, тепловых ставен и т.д.)?
                  0
                  В данном случае проще брать обычные полноценные глупые решения для ворот и уже на сухие контакты закреплять умный модуль.
                    +1

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

                    0
                    Я правильно понимаю что для закрытия/открытия нужен один оборот? Тогда можно заюзать не шаговик. а серву. Ну или на худой конец присобачить на вал проходной потенциометр типа ru.aliexpress.com/i/33016106140.html?spm=a2g0v.12057483.0.0.5a92580a000QtA, тоже будет почти серва.
                      0

                      Спасибо, для закрытия/открытия примерно половина оборота.

                        0
                        А вал, который крутит шаговый мотор вращается, когда руками крутишь жалюзи?
                          0

                          руками невозможно прокрутить

                    Only users with full accounts can post comments. Log in, please.