Making a Dumb Lock Smart with DIY Hardware and ESPHome
Welcome to my second post in a series where I document my home automation adventures! You can catch my previous post on hacking cheap smart plugs here.
In this post we'll be taking a look at how I retrofitted my front door dumb-lock and turned it into a smart-lock, complete with automatic locking. I'll also be taking a slight departure from my previous format: rather than being a guide, this will primarily aim to document the process, including all the hurdles I had to jump over to finish the project.
Let's get started!
The Lock
The lock on my apartment front door isn't a traditional deadbolt that I've seen on most doors. From some googling, I guess it's called a "jimmy-proof lock". Here's an example:
It also looks like many of these locks share the same design, which is great because it means my designs may be compatible with other people's locks! I've seen this lock a lot in NYC, and I assume it's popular because landlords can cut installation costs by just drilling this thing into their doors instead of getting a deadbolt, which requires drilling a really big hole in the door and the door frame.
Unfortunately for me, this means that many commercial options like the August smart lock are off the table because they rely on you having a standard deadbolt in your door.
I was going to need to make something myself.
The Electronics
Servo
At this point I had a vague idea of what I wanted to build: an ESP8266 controlling a servo which turned the lock open or closed. Simple enough. Luckily, I had bought this Arduino starter kit months back (I needed a bunch of various components and it seemed like a good option) and that included a servo I never used. So I wired it up to my ESP8266 and it worked just fine.
Now I needed to see if it was strong enough to actually turn the lock. I opened up Blender to design something to attach to the servo that would turn the lock. Here's what I initially came up with:
This fit pretty well on the servo, but unfortunately it was not powerful enough to actuate the lock entirely. I looked around for other servos that might suit the project better (and got drenched on my way back from Micro Center), and eventually settled on this 20kg-rated servo I found on Amazon. Overkill? Maybe. I didn't measure the torque required to actuate the lock. But it was enough!
My original design which used the single mounting point didn't work on this servo, however, so I needed to design a new one that would use two mounting points. After a few iterations and lots of measuring things with a caliper, I eventually got the mount to fit perfectly.
Now all that was left is to see if the new servo was powerful enough to actuate the lock. And it was!
Button
Now that I knew this project was actually possible, I decided to think up the user experience of the lock. I didn't want to lose the convenience of just being able to unlock the door without pulling out my phone, so I also wanted to add a button to this project so I could press it as I was leaving.
Since I'm a nerd, instead of using a normal momentary switch, I went with a Cherry MX Blue switch with one of the blank keycaps I had lying around. I wired this up on a breadboard to make sure it worked as a switch and that I configured the ESP8266 correctly, and it worked like a charm.
I had two functions in mind for the button:
- Short Press: toggle lock/unlock
- Long Press: unlock, wait ten seconds, lock
So, if I was just going out to get my laundry or something I could use the short press but if I was leaving for a while I could use the long press so the door would automatically lock behind me (this actually ended up not being useful later, as you'll see).
Hall Effect Sensor
Later in the project I decided it was a good idea to have a sensor which determined whether the door was opened or closed. My door doesn't actually have a latch separate from the lock, so without being locked the door tends to just drift open, making the lock useless at that point. I wanted to prevent this. It also enabled me to create an automation which automatically locked the door once it was closed.
I used this hall effect sensor from Adafruit and a strong neodymium magnet on the door frame to detect whether the door was closed or not.
The Software
Now that I had all the hardware planned out it was time to figure out the software side of things. I had been using ESPHome for some previous projects and for testing the servo and other components as I was building this. Due to its stellar integration with Home Assistant and amazing flexible YAML configs, I decided to go with it for the final product as well.
You can find the full configuration file here, but I'll go over some of the important bits.
First, I made a section for the servo, which involved two components: a PWM output and the servo itself.
output:
- platform: esp8266_pwm
id: pwm_output
pin: D1
frequency: 50Hz
servo:
- id: lock_servo
min_level: "2%"
max_level: "12.6%"
output: pwm_output
I had to tinker with the min_level
and max_level
values to make sure I got the maximum range the servo provided, which was 270 degrees. Technically I only needed 180 degrees here but I also wanted to make sure the servo was configured correctly.
Next, since ESPHome doesn't have native support for Home Assistant's lock
entity, I created a templated switch which just controlled the servo on state change.
switch:
- platform: template
id: lock_switch
name: "Front Door Lock"
icon: "mdi:lock"
optimistic: true
restore_state: true
turn_on_action:
- servo.write:
id: lock_servo
level: -0.9
turn_off_action:
- servo.write:
id: lock_servo
level: 0.3
Some important notes here:
- Since there is really no way to read the servo's state, I made this component
optimistic
which will eagerly update the state internally with whatever it was last set to. - Those
servo.write
values are pretty arbitrary. I just moved the servo to a position at which the lock was locked, and a position at which it was unlocked, then wrote those down in the config. You will probably need to do the same if you are copying this config.
In Home Assistant, I also added a Template Lock integration which read and writes the state from the switch.
Next, I added the configuration for the button and its two actions.
binary_sensor:
- platform: gpio
id: lock_button
on_click:
- min_length: 50ms
max_length: 1s
then:
- switch.toggle: lock_switch
- min_length: 1s
max_length: 5s
then:
- switch.turn_off: lock_switch
- delay: 10s
- switch.turn_on: lock_switch
pin:
number: D5
inverted: true
mode: INPUT_PULLUP
There isn't much to note here.
And finally, I added the hall effect sensor.
binary_sensor:
# ...
- platform: gpio
id: hall_sensor
name: "Front Door Position"
device_class: door
filters:
- delayed_on_off: 1s
pin:
number: D6
inverted: false
mode: INPUT_PULLUP
Something to note here is the delayed_on_off
filter. I added this in order to make sure the door was actually closed before triggering any automations and avoid any erroneous detection by the sensor. As ESPHome puts it, this filter will "only send an ON or OFF value if the binary sensor has stayed in the same state for at least the specified time period". So, in other terms, only once the door is open or closed for at least one second continuously will the state update.
The Design
With the hardware and software planned out and tested, it was time to put everything together. I needed to design a way to mount the servo to the lock. Luckily, the lock features two screw holes really close to the actual knob. I grabbed my caliper and started measuring.
I went through a couple of iterations, slightly modifying the position or size of the screw holes on the mount.
I eventually ran out of filament so the project was put on hold for a couple of days while I waited to get more. I also had to get some screws that would fit the hole of the lock.
Once I got more filament, I tweaked the design even more, and after printing a few more iterations I eventually was able to fit everything on the lock almost-perfectly! I also re-printed the piece that attaches to the servo with 5 shells to make it extra sturdy so it can handle the stress of the lock.
I also designed a housing for the protoboard I put everything on, as well as a holder for the magnet.
You can find these designs (and the source .blend files) available on Thingiverse here.
Putting It Together
At last, with the hardware, software, and design completed, it was time to put everything together! After screwing things to stuff, putting sticky tape on other things, and applying super glue in other places, here it is!
I set up everything in Home Assistant, as well as the automation to automatically lock the door once it's closed. I also set up integration with HomeKit, so my door could automatically unlock when I got home.
And that's another thing Home Assistant-ized! This was a really really fun project, and I hope you enjoyed reading about this adventure. If you're trying to make your own and have any questions, don't hesitate to reach out! I'll be glad to help you out.