Let's make a completely overkill project to automate my skylight and integrate it with HomeAssistant.
Summer is here, and it's bringing the heat with it. My bedroom is on the 1st floor and the 1st floor is where it gets really hot, some people can sleep when it's hot, I, however, can't.
Fortunately, I have a sleep schedule that some people call "messed up" however I prefer "non-traditional", so I can open my window at 23h and close it when I go to sleep at 02h30 and have my room relatively cool.
However, by the time I wake up, it's already much too hot, and I don't like it. I could leave the window open, but light wakes me up easily, and I want to avoid being woken up by the sun at 5h30
So instead of remembering to open the window every day, my maker mind went to the obvious solution, which was: let's start yet another completely overkill project to automate this thing to open and close automatically.
As I said, my room is on the first floor and our house have a slanted roof, so I have a velux (skylight) that pivots on the top, like that:
So, I foolishly bought a 40 cm linear actuator, thinking that I could fit it so that I would have a big range, that was a stupid idea, the damn thing wouldn't fit at all. Therefore, I returned it and bought a 20 cm one, which barely fit.
After this was installed, I started working on the controller, this was a bit tricky. The linear actuator has end stops that prevent it from going too far in or out. This is very useful to avoid the system breaking itself. But for me, it's even more useful because it helps to determine the state of the window. If I supply power to the actuator input, and it doesn't move, it means that it's either open or closed, which gives us this table:
Motor supply | Motor running | Outcome |
---|---|---|
+12v | No | Open |
+12v | Yes | Opening |
-12v | Yes | Closing |
-12v | No | Closed |
No | Stopped | |
Yes | Problem 🤣 |
Now, how can we detect if the motor is running? The first thing I thought of was to use a current sensor and as a bonus, I would be able to test if the motor stalls, there are, however, multiple issues with this:
The next thing I thought of is to use a similar approach to my previous controller, using two optocouplers to detect in which direction is the motor running. The issue with that is that, as I said before, the actuator doesn't have connection directly to the motor, but only via a switch. So, I opened the very greasy gearbox and spliced the wires to get a direct connection to the motors.As I didn't have a 3 wire cable big and flexible enough, I used two speaker wires and added multiple layers of heat shrink. While the heath shrink was still hot, I pressed on the cover to create something that look good enough and has some strain relief. It's not the prettiest thing, but it works and will barely ever be seen.
As this project is very similar to my previously done garage door controller, I based a lot of the design from it.
I went with a basic circuit with a DC-DC convert to reduce 12v to 5v. Also added some decoupling caps, a power LED and a jumper for disconnecting the 12v input
Next is the detection of the motor direction, same design as my garage door controller, one optocoupler works when opening and the other one when closing.
I could have used a traditional H-Bridge (like a L293) but as I don't need speed control, so I simply used two SPDT relays that I had on hand. Depending which one I turn on, the motor will spin in the according direction.
To still be able to use this thing without a phone, I added 3 buttons to control the motor (open, close, and stop). I also tied the stop button to GPIO0, which is the boot pin for the esp8266.
For the mcu, I choose a simple esp8266 with both a d1 mini footprint and an esp12 footprint (with an ams1117 to get 3.3v):
Subsequently, I did a very crude prototype:
And everything worked, so I designed a pcb:
Once again, PCBWay stepped in and offered to manufacture the PCB
After waiting for one week, I received the PCBs
After looking at the PCBs, they were pretty good, nothing wrong with the 5 boards.
A quick test later, I concluded that the board worked just fine.
As this isn't a massive project, I did all the software development under the Arduino IDE.
In short, the esp8266 connects to my home Wi-Fi network and then connect to the MQTT server running on my home automation VM. It then listens for command and periodically reports the window status, over the serial port, mqtt.
Almost all the functions use two structs, one for reading the state of the window and another one for sending commands:
|
|
As you can see in the window_status_t
struct, I added some edge cases that I actually didn't implement in hardware (such as the handle sensor or the overcurrent sensor). I might add the handle sensor in the future because that motor will rip that thing out without any question if it starts opening with it closed.
The main function responsible to move the window is this one:
|
|
It works like this:
You can see here are the message the board transmits via mqtt:
I then hit the same issue that I had with my garage door controller. HomeAssistant doesn't support a mqtt cover with a status "partially_opened". So, I need to transmit two window_status messages the first one is "normal" and the second topic treats the partially_opened
state as open
You can also see a fan sub-topic, on the pcb, I added a fan output in case I want to add a fan in the future.
Here is the HomeAssistant configuration:
|
|
The result is a nice entity showing up on the dashboard:
Now let's do some automation, I couldn't do an automation easily with the UI, so I went full YAML mode and wrote this:
|
|
Basically, it has two triggers with a corresponding ID, I can then use this ID as a template in the action part of the automation.
After adding the open/close time helpers and adding everything to the UI, I have a very nice interface to control the thingI could have used the sun rise time as a way to schedule the closing time of the window, but I prefer being able to manually set it.
I spent a bit of time on SolidWorks designing a button box that's not completely stupid to stick on my wall:
This was originally intended to match the angle of the roof and put the button parallel to the wall, but instead it fitted just perfectly to the top of my mosquito net, so I put it there instead.
I then spent more time designing a case for the controller:As you can see, I also added light pipes to the cover. These light pipes will be filled with hot glue and painted black (when I'll get the time to do it).
And here is a little demo video of the whole system:
Here are some things that I learned the hard way on this project:
Arduino's code / 3D files / schematic / PCB: https://github.com/TheStaticTurtle/TiltWindowController
Again, thanks to pcbway for letting me try out their PCB manufacturing for this project, and if you would like to chat about it or other projects, please join my discord here:
Want to chat about this article? Just post a message down here. Chat is powered by giscus and all discussions can be found here: TheStaticTurtle/blog-comments