I finally figured it out. I had been trying to find an ESPhome project to copy for a while the would allow me to create my own automated shades. I wanted to use the cheap spring-loaded cut-to-fit shades you can buy for about $10 a piece. Without a complete step-by-step tutorial online, I figured why not piece together parts of other projects. So i did.
I took the basic physical design from this Instrctables post: https://www.instructables.com/DIY-Motorized-WiFi-Roller-Blind-ESP8266-Blynk/ . The ESPhome code I used and modified was from:
DIY Motorised Smart Blinds .
Each of these projects used a D1 mini to control one window covering. Blinds in the case of everythingsmarthome and shades in the instructables post but I wanted to controlled two windows, two shades with one D1. So I did, and I gave them manual controls. I also made it battery powered and give it a LUX sensor to detect the level of light outside. The batteries are 18650s and I’m charging them with a solar panel suction-cupped to the window.
Don’t get me wrong it has its issues. The batteries only last three days, so I ordered a 30 watt solar panel to take the place of my 1.5 watt panel. Hopefully that will help when it eventually gets here.
I’m using almost every pin of this D1. If anyone wants my ESPhome code or more information let me know. I’m even toying with the idea of creating my own custom PCB for the project.
Edit ESPhome code below:
esphome:
name: living-room-shades
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key:
ota:
password:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid:
password:
captive_portal:
cover:
- platform: template
name: "My Blind 0"
id: my_blind0
device_class: blind
open_action:
- stepper.set_target:
id: my_stepper0
target: 60000
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).target_position;
close_action:
- stepper.set_target:
id: my_stepper0
target: 0
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).target_position;
stop_action:
- stepper.set_target:
id: my_stepper0
target: !lambda return id(my_stepper0).current_position;
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).current_position;
optimistic: true
assumed_state: true
- platform: template
name: "My Blind 1"
id: my_blind1
device_class: blind
open_action:
- stepper.set_target:
id: my_stepper1
target: -60000
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).target_position;
close_action:
- stepper.set_target:
id: my_stepper1
target: 0
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).target_position;
stop_action:
- stepper.set_target:
id: my_stepper1
target: !lambda return id(my_stepper1).current_position;
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).current_position;
optimistic: true
assumed_state: true
sensor:
- platform: template
name: "My Blind 0 Position"
id: position0
- platform: template
name: "My Blind 1 Position"
id: position1
- platform: adc
pin: VCC
id: "VCC"
internal: true
- platform: template
name: "battery_level"
unit_of_measurement: '%'
update_interval: 60s
lambda: |-
return ((id(VCC).state /3.30) * 100.00);
- platform: adc
pin: A0
name: "LUX Sensor"
update_interval: 60s
unit_of_measurement: lux
filters:
- lambda: |-
return (x / 10000.0) * 2000000.0;
binary_sensor:
- platform: gpio
pin: TX
id: "Open_Button"
on_press:
then:
- stepper.set_target:
id: my_stepper0
target: !lambda return id(my_stepper0).current_position;
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).current_position;
- stepper.set_target:
id: my_stepper1
target: !lambda return id(my_stepper1).current_position;
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).current_position;
on_release:
then:
- stepper.set_target:
id: my_stepper0
target: 60000
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).target_position;
- stepper.set_target:
id: my_stepper1
target: -60000
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).target_position;
on_double_click:
min_length: 50ms
max_length: 350ms
then:
- stepper.set_target:
id: my_stepper0
target: 60000
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).target_position;
- stepper.set_target:
id: my_stepper1
target: -60000
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).target_position;
- platform: gpio
pin: RX
id: "Close_Button"
on_press:
then:
- stepper.set_target:
id: my_stepper0
target: !lambda return id(my_stepper0).current_position;
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).current_position;
- stepper.set_target:
id: my_stepper1
target: !lambda return id(my_stepper1).current_position;
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).current_position;
on_release:
then:
- stepper.set_target:
id: my_stepper0
target: 0
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).target_position;
- stepper.set_target:
id: my_stepper1
target: 0
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).target_position;
on_double_click:
min_length: 50ms
max_length: 350ms
then:
- stepper.set_target:
id: my_stepper0
target: 0
- sensor.template.publish:
id: position0
state: !lambda return id(my_stepper0).target_position;
- stepper.set_target:
id: my_stepper1
target: 0
- sensor.template.publish:
id: position1
state: !lambda return id(my_stepper1).target_position;
stepper:
- platform: uln2003
id: my_stepper0
pin_a: D1
pin_b: D2
pin_c: D3
pin_d: D4
max_speed: 725 steps/s
sleep_when_done: True
acceleration: inf
deceleration: inf
- platform: uln2003
id: my_stepper1
pin_a: D5
pin_b: D6
pin_c: D7
pin_d: TX
max_speed: 725 steps/s
sleep_when_done: True
acceleration: inf
deceleration: inf