Blog

WiFi Doorbell ā€“ Proof of Concept

Itā€™s been a little while since I posted about my smart home journey because Iā€™ve been pretty busy of late with other things (like my actual job), but rest assured that there has been progress ā€“ albeit slow.

As I mentioned before, Iā€™ll be adding three microcontrollers to our smart home setup in various parts of the house. Each project is going to go through three stages: proof of
concept, prototype, and final product.

Today is our first proof of concept, and itā€™s going to test whether or not I can hook our existing doorbell up to WiFi.

Getting a notification when someone rings the doorbell was the first thing Flo asked for when I mentioned I was going to start making our home smarter, and I quickly set
about figuring out how to do it: happy wife, happy life.

Some initial ideas (adding a relay to the doorbell circuit) were fairly quickly dismissed, and so I came up with a piece of out of the box thinking that Iā€™m actually very proud of.

Iā€™ll be using magnetic switches, also known as reed switches, elsewhere in the house. In fact, we already have them on many of the doors and windows as part of our burglar alarm, and you may well have some in your house too. They work by opening and closing when a magnet is brought into proximity with the switch. My flash of inspiration came when I was thinking about how a doorbell works: an electromagnet pulls a hammer into one chime when the doorbell is pushed, and then a spring pushes it into a second chime when the button is released and the electromagnet turns off. So, if I put a reed switch next to the electromagnet then the switch will flip when the magnet
turns on. Genius!

Happily for me, our doorbell has two chimes: one in the main floor hallway, and one in the basement. I wouldnā€™t want to run cables up the wall to the chime on our main floor, but the basement one is the mechanical room so the aesthetic is really not a consideration.

Using a switch as an input for the NodeMCU is simple. Really the only thing to think about is that the digital input pins are ā€œfloating,ā€ which means that if nothing is connected then the result you get from them is unpredictable. To account for this you use either a ā€œpull upā€ resistor between the input pin and the 3.3v pin, or a ā€œpull downā€ resistor between the input pin and the ground pin. I went for a pull down resistor between the input pin and ground, then put the switch between the input pin and 3.3v.

For the proof of concept I wrote some simple code to display the input pin state over the serial console, taped the reed switch place and, despite some protest from the dog, rang the doorbell a few times.

It works!

Next step: prototype.

Blog

NodeMCU, MQTT, IoT & Other Letters I Find Exciting

If youā€™ve been keeping up with my #SmartHomeĀ series (and if you havenā€™t, why not?) youā€™ll already know that I have plans to make more of my home ā€œsmartā€ using Home
Assistant
as the software that ties everything together, and some DIY NodeMCU-based hardware that Iā€™m going to build myself as a learning opportunity.

Another important piece of the puzzle, but one that I havenā€™t previously mentioned, is MQTT.

MQTT is ā€œa publish-subscribe-based lightweight messaging protocol for use on top of the TCP/IP protocol,ā€ at least according the slightly suspect grammar of the person that wrote the Wikipedia article about it.

image

I learned about MQTT at the same time I learned about Home Assistant, although I didnā€™t initially appreciate its power. Iā€™ve been using it from the start to enable Home Assistant to know where we are: our phones run an app called OwnTracks which publishes
location data to an MQTT ā€œbrokerā€ (server). Home Assistant subscribes to these updates, which means it immediately knows about it when our location changes.

I love this whole solution, not least because itā€™s very easy to run my own MQTT broker (Iā€™m running MosquittoĀ in a Docker container on my home server) and Iā€™m therefore entirely in control of our location data ā€“ itā€™s not being shared with the developer of some app or service I have no insight into.

This publish/subscribe model and the lightweight nature of MQTT makes it perfect for ā€œInternet of Thingsā€ (IoT) devices to communicate with each other, and when you add Home Assistant into the mix it gives me all the tools I need for any sensors I build
to feed their data into my smart home ecosystem, and for my smart home controller to feed commands to any devices.

Indeed, Iā€™ve already built my first little NodeMCU app that leverages the technology.

Iā€™ve ordered almost all the components I need for my upcoming hardware projects from China, and theyā€™re only just starting to arrive. Happily the NodeMCUs themselves were amongst the first shipments to land on my doorstep, so even though the only thing I can really do with them right now is programmatically turn their internal LED on and off, I have still been able to use this to start learning: Iā€™ve made it an internet controlled
LED.

[youtube https://www.youtube.com/watch?v=JLETpLMicYs?feature=oembed&enablejsapi=1&origin=https://safe.txmblr.com&wmode=opaque&w=540&h=304]

As promised, Iā€™m going to be sharing both the hardware and the software as I take this DIY Smart Home journey. There is no DIY hardware here, just the NodeMCU itself, but Iā€™ve published both the Arduino sketch and Home Assistant configuration Iā€™ve used for the video.

Enjoy!

Blog

[wpvideo Tkoe72i4]

I have begun to learn how to program my NodeMCU.

Granted, all itā€™s doing here is running the example ā€œBlinkā€ program that comes with the Arduino IDE, but the important point is that the little light is turning on and off because I uploaded some code that tells it to.

Itā€™s not connected to a computer here. The USB cable is simply plugged into a power outlet.

Blog

[wpvideo Tkoe72i4]

I have begun to learn how to program my NodeMCU.

Granted, all itā€™s doing here is running the example ā€œBlinkā€ program that comes with the Arduino IDE, but the important point is that the little light is turning on and off because I uploaded some code that tells it to.

Itā€™s not connected to a computer here. The USB cable is simply plugged into a power outlet.

Blog

Smart Home Adventures

Ever since I bought my own home nearly a year ago, Iā€™ve
become increasingly interested in making it smart.

Right off the bat, I feel like I should clarify what that
means to me. The ability to turn some lights on or off with an app is not
smart, in my opinion ā€“ the smart way of controlling lights is by flicking a
switch conveniently located in the room you wish to illuminate.

A smart home needs to be much more intelligent. Itā€™s about
automation. Itā€™s about the home being able to notify me if something is
happening that I need to know about. Itā€™s about being able to accomplish things
with minimal difficulty, not adding complexity and more steps.

Thatā€™s where off the shelf ā€œsmart homeā€ solutions really
started to fall down for me. I could spend hundreds or maybe even thousands of
dollars, for what? The ability to turn on my living room lights while Iā€™m still
at the office? Why would I ever need to do that?

Nevertheless, the lack (in my opinion) of a pre-packaged,
useful, holistic solution that accomplished my vision of what a ā€œsmart homeā€
should be didnā€™t deter me from tackling things bit by bit. It started with our
burglar alarm. It has internet connectivity which sends me alerts in the event
that something unexpected is happening, and lets me arm or disarm the system
from my phone ā€“ which I actually do find useful.

Next up was our thermostat. The one that was installed when
we bought the house was an old-fashioned one with a simple mercury switch
inside. You set the temperature, and that was it. We replaced that about a
month ago with something programmable (it doesnā€™t need to be as warm in here at
night as it does during the day; it doesnā€™t need to be as warm if nobodyā€™s
home), and I took the opportunity to get one with WiFi so I can set the
temperature remotely. Thatā€™s not useful in and of itself, but if you take that
functionality and look at it in the context of my wider vision then the
thermostat is certainly something Iā€™d like to be able to programmatically
control.

It was around this same time that I discovered home assistant, and now my dream is
starting to come alive.

image

Home Assistant is an open-source project that runs on a
variety of hardware (I was originally running it on a Raspberry Pi, and Iā€™ve
since switched to running it in a Docker
container on our home
server
). It has a ton of plugins
(ā€œcomponentsā€) that enable it to support a variety of products ā€“ including our
existing alarm, thermostat, streaming media players, and others (including,
somewhat ironically, the colour-changing lightbulbs we have in our family
room). It includes the ability to create scripts and automations, it uses our
cellphones to know our locations, and can send us push notifications.

My initial setup was all about notifications. If we both
leave the house but the burglar alarm isnā€™t set then it tells us (and provides
an easy way to fix the issue). If we leave one of the exterior doors open for
more than five minutes, it notifies us (or just one of us, if the other is
out). I also created a dashboard (that you may have seen in my last post) to display some of this stuff on a monitor in my office.

Since installing the thermostat Iā€™ve added more automation.
The time we go to bed isnā€™t always predictable, but when we do go to bed we set
the alarm. So, if itā€™s after 7pm and the alarm goes from disarmed to armed, the
thermostat gets put into night mode. If nobody is home then the temperature
gets gradually turned down based on how far away we are.

If nobody is home at dusk then it turns on some lights and
streams talk radio through the family room speakers to give the impression that
someone is.

This stuff meets my definition of smart, and Iā€™m barely
scratching the surface. The open nature of the platform not only means that Iā€™m
not tied to a particular vendor or technology, but also means that I can add on
to the system in a DIY way.

Which is exactly what Iā€™m going to do. Iā€™ve bought some NodeMCU microcontrollers which are
WiFi enabled, Arduino IDE-compatible
development boards designed to the basis for DIY electronics projects.

Watch this space, because over the coming months Iā€™ll be
connecting our doorbell, garage door and laundry appliances to Home Assistant.
Iā€™ll be learning as I go, and Iā€™ll share the hardware and software.

Blog

Smart Home Dashboard

[youtube https://www.youtube.com/watch?v=8N087dKoKno?feature=oembed&enablejsapi=1&origin=https://safe.txmblr.com&wmode=opaque&w=540&h=304]

Recently, I have been all about turning our home into a smart home. Thatā€™s mostly because Iā€™ve discovered Home Assistant: a little piece of software that runs (in my case) on a Raspberry Pi and pulls together data from all the sensors and smart devices you own.

Apart from a new WiFi thermostat that I was going to buy anyway I havenā€™t yet spent any money at all in my quest for this – Iā€™ve merely connected together the devices we already owned (Chromecasts; family room lights; our burglar alarm), added in some data available through various APIs (weather; internet speed; server status) and pulled location information from our phones using an app that publishes the information to my own server.

Anyway, now that I have all this information in one place I wanted an attractive way to display it in my office. Happily Iā€™d already bought a monitor with a built-in powered USB hub from a surplus equipment sale a while back, with this kind of project in mind.

So, my Friday afternoon project today became hooking up another Raspberry Pi to this monitor and crafting a HTML dashboard for it to display. Not everything works yet, but I think itā€™s pretty good for an afternoonā€™s work.

(Since I didnā€™t remove the clock from the frame when I shot the video, I canā€™t pretend this thing is quick to boot. I may have manipulated the video speed at a couple of points. But anyway).

Oh, and watch this space for some home-brew smart home devices, coming soon!

Blog

There is only one way to avoid criticism:
do nothing, say nothing, and be nothing.

Aristotle (via forbes)
Blog

Using JavaScript to Identify Whether a Server Exists

Recently, for reasons Iā€™m sure Iā€™ll write about in the
future, I needed to find a way to use JavaScript to test if either of two
web-locations are accessible ā€“ my home intranet (which would mean the user is on
my network), or the corporate intranet of the company for which I work (which
would mean the user is on my organizationā€™s network). The page doing this test
is on the public web.

My solution for doing this test was simple. Since neither
resource is accessible publicly I put a small JavaScript file on each, then I
use AJAX and jQuery to try and fetch it. If
thatā€™s successful, I know the user has access to whichever intranet site served
the request and my page can react accordingly.

If neither request is successful I donā€™t have to do
anything, but the user doesnā€™t see any errors unless they choose to take a look
in the browser console.

This all worked wonderfully until I enabled SSL on the page
that needs to run these tests, then it immediately fell apart.

Both requests fail, because a page served over HTTPS is
blocked from asynchronously fetching content over an insecure connection. Which
makes sense, but really throws a spanner into the works for me: neither my home
nor corporate intranet sites are available outside the confines of their safe
networks, so neither support HTTPS.

My first attempt at getting around this was to simply change
the URL prefix for each from http:// to https:// and see what happened. Neither
site supports that protocol, but is the error that comes back different for a
site which exists but canā€™t respond, vs. a site which doesnā€™t exist? It appears
so!

Sadly, my joy at having solved the problem was extremely
short lived. The browser can tell the difference and reports as much in the
console, but JavaScript doesnā€™t have access to the error reported in the
console. As far as my code was concerned, both scenario was still identical
with a HTTP response code of 0 and the status description worryingly generic ā€œerror.ā€

We are getting closer to the solution I landed on, however.
The next thing I tried was specifying the port in the URL. I used the https://
prefix to avoid the ā€œmixed contentā€ error, but appended :80 after the hostname
to specify a port that the server was actually listening on.

This was what I was looking for. Neither server is capable
of responding to a HTTPS request on port 80, but the server that doesnā€™t exist
immediately returns an error (with a status code of 0 and the generic ā€œerrorā€
as the descriptive text), but the server that is accessible simply doesnā€™t
respond. Eventually the request times out with a status code of 0 but a status
description, crucially, of ā€œtimeout.ā€

From that, I built my imperfect but somewhat workable
solution. I fire a request off to each address, both of which are going to
fail. One fails immediately which indicates the server doesnā€™t exist, and the
other times-out (which I can check for in my JavaScript), indicating that the
server exists and I can react accordingly.

Itā€™s not a perfect solution. I set the timeout limit in my
code to five seconds, which means a ā€œsuccessfulā€ result canā€™t possibly come
back in less time than that. Iā€™d like to reduce that time, but when I
originally had it set at 2.5 seconds I was occasionally getting a
false-positive on my corporate network caused by, yā€™know, an actual timeout
from a request that took longer than that to return in an error state.

Nevertheless if you have a use-case like mine and you need
to test whether a server exists from the client perspective (i.e. the response
from doing the check server-side is irrelevant), I know of no other way. As for
me, Iā€™m still on the lookout for a more elegant design. Iā€™m next going to try
and figure out a reliable way to identify if the user is connected to my home
or corporate network based on their IP address. That way I can do a quick
server-side check and return an immediate result.

Itā€™s good to have this to fall back on, though, and for now
at least it appears to be working.