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

от автора

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

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

Результат работы моего проекта по автоматизации жалюзи из 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 г.


ссылка на оригинал статьи https://habr.com/ru/post/480690/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *