|
| 1 | +--- |
| 2 | +title: Horus - Blind Controller |
| 3 | +date-published: 2025-04-06 |
| 4 | +type: switch |
| 5 | +standard: global |
| 6 | +board: esp8266 |
| 7 | +difficulty: 1 |
| 8 | +--- |
| 9 | + |
| 10 | +## Description |
| 11 | + |
| 12 | +The Horus Blind Controller allows you to automate and control your blinds using Home Assistant while keeping manual operation via your existing physical switches. It seamlessly integrates with Home Assistant through ESPHome and requires minimal setup. |
| 13 | + |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | +## Features |
| 18 | + |
| 19 | +✅ Works with existing wall switches for manual control |
| 20 | +✅ Remote control via Home Assistant |
| 21 | +✅ Fully pre-flashed with ESPHome — no extra configuration required |
| 22 | +✅ Secure and reliable local communication (no cloud dependency) |
| 23 | +✅ Customizable automation rules |
| 24 | + |
| 25 | +## Wiring Diagram |
| 26 | + |
| 27 | + |
| 28 | + |
| 29 | +## YAML Configuration |
| 30 | + |
| 31 | +```yaml |
| 32 | +substitutions: |
| 33 | + devicename: "horus-blind" |
| 34 | + |
| 35 | +esphome: |
| 36 | + name: ${devicename} |
| 37 | + |
| 38 | +esp8266: |
| 39 | + board: esp01_1m |
| 40 | + |
| 41 | +# Enable logging |
| 42 | +logger: |
| 43 | + |
| 44 | +# Enable Home Assistant API |
| 45 | +api: |
| 46 | + |
| 47 | +ota: |
| 48 | + - platform: esphome |
| 49 | + password: "" |
| 50 | + |
| 51 | +wifi: |
| 52 | + ssid: !secret wifi_ssid |
| 53 | + password: !secret wifi_password |
| 54 | + |
| 55 | + # Enable fallback hotspot (captive portal) in case wifi connection fails |
| 56 | + ap: |
| 57 | + ssid: "Horus-Blind" |
| 58 | + password: "esphomearez" |
| 59 | + |
| 60 | +captive_portal: |
| 61 | + |
| 62 | +#*** Web server optional if you whant check or control over http requests *** |
| 63 | +#web_server: |
| 64 | +# port: 80 |
| 65 | +# version: 3 |
| 66 | +# include_internal: true |
| 67 | +# ota: false |
| 68 | + |
| 69 | +binary_sensor: |
| 70 | +- platform: gpio |
| 71 | + pin: |
| 72 | + number: 4 # --- |
| 73 | + mode: INPUT_PULLUP |
| 74 | + inverted: true |
| 75 | + filters: |
| 76 | + - delayed_on: 50ms |
| 77 | + - delayed_off: 50ms |
| 78 | + id: button_open_1 |
| 79 | + on_press: |
| 80 | + then: |
| 81 | + # logic for cycling through movements: open->stop->close->stop->... |
| 82 | + - lambda: | |
| 83 | + if (id(my_cover_1).current_operation == COVER_OPERATION_IDLE) |
| 84 | + { |
| 85 | + id(my_cover_1).open(); |
| 86 | + id(output_cover_open).turn_on(); |
| 87 | + } |
| 88 | + else |
| 89 | + { |
| 90 | + id(my_cover_1).stop(); // Cover is opening/closing. Stop it |
| 91 | + } |
| 92 | + on_release: |
| 93 | + then: |
| 94 | + - lambda: | |
| 95 | + id(my_cover_1).stop(); // Cover is opening/closing. Stop it |
| 96 | +
|
| 97 | +- platform: gpio |
| 98 | + pin: |
| 99 | + number: 5 # --- |
| 100 | + mode: INPUT_PULLUP |
| 101 | + inverted: true |
| 102 | + filters: |
| 103 | + - delayed_on: 50ms |
| 104 | + - delayed_off: 50ms |
| 105 | + id: button_close_1 |
| 106 | + on_press: |
| 107 | + then: |
| 108 | + # logic for cycling through movements: open->stop->close->stop->... |
| 109 | + - lambda: | |
| 110 | + if (id(my_cover_1).current_operation == COVER_OPERATION_IDLE) |
| 111 | + { |
| 112 | + id(my_cover_1).close(); |
| 113 | + id(output_cover_close).turn_on(); |
| 114 | + } |
| 115 | + else |
| 116 | + { |
| 117 | + id(my_cover_1).stop(); // Cover is opening/closing. Stop it |
| 118 | + } |
| 119 | + on_release: |
| 120 | + then: |
| 121 | + - lambda: | |
| 122 | + id(my_cover_1).stop(); // Cover is opening/closing. Stop it |
| 123 | +
|
| 124 | +switch: |
| 125 | +- platform: gpio |
| 126 | + pin: |
| 127 | + number: 14 |
| 128 | + mode: OUTPUT |
| 129 | + inverted: false |
| 130 | + id: output_cover_open |
| 131 | +- platform: gpio |
| 132 | + pin: |
| 133 | + number: 13 |
| 134 | + mode: OUTPUT |
| 135 | + inverted: false |
| 136 | + id: output_cover_close |
| 137 | + |
| 138 | +cover: |
| 139 | +- platform: time_based |
| 140 | + name: "Blinds" |
| 141 | + id: my_cover_1 |
| 142 | + open_action: |
| 143 | + - switch.turn_on: output_cover_open |
| 144 | + - switch.turn_off: output_cover_close |
| 145 | + open_duration: 23s #Change this value in orther to match the blind open duration |
| 146 | + |
| 147 | + close_action: |
| 148 | + - switch.turn_off: output_cover_open |
| 149 | + - switch.turn_on: output_cover_close |
| 150 | + close_duration: 22s #Change this value in orther to match the blind close duration |
| 151 | + |
| 152 | + stop_action: |
| 153 | + - switch.turn_off: output_cover_open |
| 154 | + - switch.turn_off: output_cover_close |
| 155 | +``` |
| 156 | +
|
| 157 | +## Installation |
| 158 | +
|
| 159 | +1. Connect the device to the existing blind switch following the wiring diagram. |
| 160 | +
|
| 161 | +2. Power on the device—it will automatically create a Wi-Fi hotspot if not connected to your home network. |
| 162 | +
|
| 163 | +3. Connect to the hotspot (SSID: ESPHome-XXXXXX), then configure the Wi-Fi settings. |
| 164 | +
|
| 165 | +4. Add to Home Assistant using the ESPHome integration. |
| 166 | +
|
| 167 | +## Home Assistant Integration |
| 168 | +
|
| 169 | +1. Navigate to Settings → Devices & Services |
| 170 | +
|
| 171 | +2. Click + Add Integration |
| 172 | +
|
| 173 | +3. Select ESPHome and enter the device IP address |
| 174 | +
|
| 175 | +## Automations & Controls |
| 176 | +
|
| 177 | +- Use the physical wall switches for direct control |
| 178 | +
|
| 179 | +- Create automations in Home Assistant to control blinds based on time, weather, or sunlight conditions |
| 180 | +
|
| 181 | +## Support |
| 182 | +
|
| 183 | +For troubleshooting, check the ESPHome logs: |
| 184 | +
|
| 185 | +```sh |
| 186 | +esphome logs smart_blind_controller.yaml |
| 187 | +``` |
0 commit comments