In our house we have some big East-facing windows.  When the sun hits those babies, it’s like a magnifying glass. The sun through those windows is strong enough that it has faded the colors of our furniture. And in the summer it gets way hot in that room and we have to crank the Air Conditioning to keep it cool.  My solution is blackout shades. But I only want them to be down when the sun is shining on the windows. That means, they need to be Automated.

The important components of this project are these high torque geared DC motors, this H-bridge motor controller, some push buttons, a D1mini, and of course, Home Assistant. I suppose the actual shades count as important too.  I’m going to use some blackout fabric, some conduit, skateboard bearings, and a few 3D printed parts.

Shove the bearing into one end of the conduit. If it doesn’t quite fit, cut some relief slots in the conduit then smash it in there. Measure out the fabric and secure it to the conduit.  Glue it, tape it, weld it, whatever. I made this little 3D printed part to fit inside the bearing and then fasten to the wall. The other side of the conduit is going to be connected to the motor shaft. This 3D printed part fits on the motor shaft and then into the end of the conduit. I’m also going to drill a hole and put a screw through it to make sure the shaft and the conduit stay secured together.  The motor and other electronic parts are going to live in this cute little 3D printed house. These are 12v motors, and the motor controller has a voltage converter that outputs 5v. We can use that to power the D1mini. So for power we just need to get 12v to the controller. So, I add a 12v power supply to the parts list. We will have to hide the wire, but it’s small, I’m sure no one will see it. The controller, the D1mini, and the buttons fit in the housing like this.

To wire it all up we take 12v from the power supply to the Motor Controller. This motor controller can actually control 2 motors.  You don’t have to use 2 motors, but I’m going to on some of my windows that are close together. The connectors on the sides of the controller go to the motors.

The IN1 and IN2 pins are the control signals for Motor 1. IN3 and IN4 are the control pins for Motor 2.  Here’s a diagram showing the connections to the D1mini.

For the software I’m going to use ESPhome. If you’ve never used ESPhome, or Home Assistant, then here’s a couple video references to get you up to speed. In short, HA is an open source smart home hub. And ESPhome is a way for people with no real programming experience to program wifi based microcontrollers to do all kinds of amazing stuff.  What I love about ESPhome is that it works seamlessly with Home Assistant. Once you’ve written your ESPhome device file and uploaded it, everything you’ve created will almost instantly appear in Home Assistant. No need to edit the HA config file. Also, because ESPhome can communicate directly with HA, you don’t even need to use MQTT. And finally, once you have a basic ESPhome sketch on your microcontroller, you can edit the file and upload the changes over-the-air.  All Hail Ottowinter! Amazing work my friend!

Digiblur – ESPhome install – https://youtu.be/9Yu57vjz7AY

ESPhome install page – https://esphome.io/guides/getting_started_hassio.html

JuanMtech – Hassio install – https://youtu.be/qnCRcGTznXs

In ESPhome, as of right now there isn’t a component for this particular motor controller, but with some fanangaling we can get it to work. Let’s walk through the ESPhome file. This top part is all the setup, wifi connection etc. Then I’m making 4 of the GPIO’s as outputs. If you’re only going to control one motor then you really only need 2 of these. The next part creates switches and assigns each switch to one of the output pins we just set up in that first part.  I’m also giving each switch an ID. That’s so we can include some aspects of the automation inside the ESPhome sketch. We’ll get to that in a minute.

Next we’ll set up a physical button that will control the shade in the rare event that someone wants to control these beautiful smart shades in the old fashion dumb way.  I’m controlling 2 shades so I need an entry for each push button. In ESPhome, buttons like this are binary_sensor entities. The platform is GPIO and we define which pin the button will be connected to. The resting state of these pins is high or On.  I want the resting state to be low or Off. That’s what filters: invert does.

Now we define what happens when we press the button.  This is a super cool part of ESPhome. You can actually include templates and automations right here in the sketch that’ll be loaded on the D1mini.  The best part about that is that automations you define here in the ESPhome sketch, will still work even if your wifi goes down or if Home Assistant isn’t running. That’s cool. In ESPhome a Lambda is where we build our in-sketch automations. I’m going to spend an extra couple minutes explaining how the lambda works because if you really want to unlock the magic of a DIY smart home you’ve got to be able to make automations.

In the lambda for the buttons this is what’s happening. First we say “if” the cover entity (which we haven’t defined yet, but will soon) is in the OPEN state, then it looks at the next if statement, which says, is motor pin 1 On.  If the cover is Open and motor pin 1 is On then the shade is moving, so we send the “Stop” command to that cover. The ‘else’ statement here is what will happen if the first ‘if’ is true, meaning the cover is Open, but the second ‘if’ is not true, meaning the motor pin is low.  That means the shade is open and not moving. In that case we want the shade to close, so a button press in that situation will send the “Close” command. The next ‘else’ statement is what will happen if the first ‘if’ statement is false. That means the cover entity is not in the OPEN state. So if it’s not open, but the motor pin is ‘On’ then it shade is moving, so a button press will send the “Stop” command.  And finally, if the cover is Not OPEN and the motor pin is not On, then a button press will send the “Open” command.

I totally understand if your eyes glazed over during that, so here’s a demonstration of how it works.  If the shade is moving a button press will stop it. If the shade is stopped then a button press will move it toward whichever state it was in last. I struggled for a long time trying to figure out how to make this work.  Finally I found a great example in the ESPhome Cookbook page.

https://esphome.io/cookbook/dual-r2-cover

So if you’ve created something cool with ESPhome please contribute to the documentation so others (like me) can benefit from your genius.

https://esphome.io/guides/contributing
esphome:
name: shade
platform: ESP8266
board: d1_mini
wifi:
ssid: !secret wifi
password: !secret wifi_pw
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
output:
- platform: gpio
id: 'shade1'
pin: D1
- platform: gpio
id: 'shade2'
pin: D2
switch:
- platform: output
name: "shade1"
output: 'shade1'
id: shade_s1
- platform: output
name: "shade2"
output: 'shade2'
id: shade_s2
binary_sensor:
- platform: gpio
pin: D3
name: "Button"
filters:
invert:
on_press:
then:
- lambda: |
if (id(kitchen_window).state == cover::COVER_OPEN) {
if (id(shade_s1).state){
// shade is opening
id(kitchen_window).stop();
} else {
// shade is open and not moving
id(kitchen_window).close();
}
} else {
if (id(shade_s2).state){
// shade is closing
id(kitchen_window).stop();
} else {
// shade is closed and not moving
id(kitchen_window).open();
}
}
# END STOP EXAMPLES
# - platform: gpio
# pin: D7
# name: "Kitchen Top Stop"
# filters:
# invert:
# on_press:
# then:
# - switch.turn_off: shade_s1
# - switch.turn_off: shade_s2
# id: kitchen_top_stop
# - platform: gpio
# pin: D8
# name: "Kitchen Top Bottom"
# filters:
# invert:
# on_press:
# then:
# - switch.turn_off: shade_s1
# - switch.turn_off: shade_s2
# id: kitchen_bottom_stop
cover:
- platform: template
name: "Kitchen Window Full"
id: kitchen_window
optimistic: true
open_action:
- switch.turn_off: shade_s2
- switch.turn_on: shade_s1
- delay: 99s
- switch.turn_off: shade_s1
close_action:
- switch.turn_off: shade_s1
- switch.turn_on: shade_s2
- delay: 99s
- switch.turn_off: shade_s2
stop_action:
- switch.turn_off: shade_s1
- switch.turn_off: shade_s2
- platform: template
name: "Kitchen Window Control"
id: kitchen_control
assumed_state: true
# TEMPLATE FOR END STOP SWITCHES
# lambda: |-
# if (id(shade_1_t).state) {
# return cover::COVER_OPEN;
# } else {
# return cover::COVER_CLOSED;
# }
open_action:
- switch.turn_off: shade_s2
- switch.turn_on: shade_s1
close_action:
- switch.turn_off: shade_s1
- switch.turn_on: shade_s2
stop_action:
- switch.turn_off: shade_s1
- switch.turn_off: shade_s2

This controller is an H-Bridge. That means it can reverse the polarity of the power wires to the motor to make it spin in the opposite direction. With pin In1 high (or ON), and pin In2 low (or OFF), the motor spins in one direction.  If you reverse those, making pin In1 Low, and pin In2 High, then the motor spins in the other direction. To control the direction of the motor with ESPhome, I’m going to use the Template Cover component.

I’m going to create 2 Cover entities for this each window because I want to include a timer so it will stop automatically, but I also want the ability to open it partially.  Of course, you have to have your shades installed before you can accurately measure how long it takes for them to fully open. I’m going to take a guess that for my kitchen window it’ll take 1:38.71. It’s a gift.

When you create a Template Cover in ESPhome, you define the platform, the name is what will display on the HA UI, the id is necessary so we can reference this entity in the lambda we created for the pushbutton. The most important parts are the actions. You get to define 3 actions, open, close, and stop. For open I want “in1” High or On, and “in2” Low or Off.  To close the shades those pin states are reversed, and for stop I set them both to off. In the entry without the timer I also want to be able to press either the up or down button anytime. So, to make sure I can always have both up and down buttons available, I’m not including anything that would set the state as open or closed, and I’m using the assumed_state: true option.

On my other cover entry I need to give it a different name and id.  Then I’m adding a delay of 99 seconds to the open and close actions.  After the delay I’m setting whichever pin was on, back to off so the motor will stop turning.  No change for the stop action. I want this entity to track the state of the curtain, that is, are they open or are they closed.  Without something like end-stop switches to verify the state as open or closed, I can set “optimistic: true”. That will change the state when I press one of the directional buttons.  I click open, the state changes to open and the up arrow goes away.

I think that’s it.  It’s Demo time!

This isn’t the end of my battle with the Sun.  I’ve got some blinds torn apart and am still deciding the best way to automate them.  Stepper motor? Servo? Or maybe these geared motors.

Amazon Links:

Fabric – https://amzn.to/2Xy6QQ9

Bearings – https://amzn.to/2EETARa

Conduit – https://www.lowes.com/pd/Common-3-4-in-Actual-75-In-Metallic-Emt-10-ft-Conduit/3129553

H-Bridge – https://amzn.to/2H5BPhE

D1mini – https://amzn.to/2SKRAvK

Geared motor – https://amzn.to/2TC96Xs