The Internet Fridge is a standing joke among technologists. I was writing about them in 2002, and they still haven't appeared!
So I'm going to show you how I built one.
Stop giggling at the back! All I want is for my fridge to notify me if the door has been left over for more than a minute. I'm building this with an Onion Omega2 - but you could just as easily use a Pi Zero or any other board.
This should be simple (as all complicated stories start):
- When the fridge door is closed, a circuit is closed.
- When the fridge door is opened, a circuit is broken.
- If the circuit has been broken for more than 60 seconds, send an alert.
- While the circuit is broken, repeat the alert every 60 seconds.
We need a circuit which will be closed when the fridge is firmly closed, but isn't so strong that it prevents the fridge door closing.
All bodged together with Blue-tack! Perfect for some impromptu Internetting.
You could just use bare wires, but that doesn't look very nice, and they tend to trail around. I'm using a simple spring-loaded button.
Hidden on top of the fridge, the USB wire is long enough to drape around the back. Inconspicuous!
This Python code reads the wire at GPIO 7 every second.
import time import onionGpio # The GPIO port to sense from gpioNum = 7 gpioObj = onionGpio.OnionGpio(gpioNum) # Port set to Input # When a 5V circuit is completed, it will be active status = gpioObj.setInputDirection() # read and print the value once a second loop = 1 while loop == 1: value = gpioObj.getValue() print 'GPIO%d input value: %d'%(gpioNum, int(value)) time.sleep(5)
That will print
0 when the fridge door is open, and
1 when it is closed.
There are two main ways to time how long the door has been open for.
- Once the door is open, sleep for 60 seconds, if the door is still open - send an alert.
- Once the door is open, add up the number of seconds where the door is open - if it reaches 60 (or a multiple of 60), send an alert.
The first solution has a disadvantage - if I open the door for 20 seconds, close it for 10 seconds, then open it for 30 seconds, an alert will be sent. Do I want an alert just because I forgot to take out the cheese for my sandwich?
The second solution is more complex. Complexity scares me. But spending more time with code is better than being annoyed by irrelevant alerts.
I replaced the previous loop with this:
# Set a counter for how many seconds the circuit is open counter = 0 # Read the pin once every second loop = 1 while loop == 1: value = int(gpioObj.getValue()) if 1 == value: # Door is closed, reset the timer. print "Closed. Sleeping" counter = 0 time.sleep(1) elif 0 == value: time.sleep(1) counter += 1 if (counter > 59): if (0 == counter % 60): # Send an alert print "Alert! The door has been open for " + str(counter) + " seconds!"
Hurrah! It works!
OK, I'm not going to be staring at a console the whole day long. How do I get notified that the door is open? A speaker won't be loud enough if I'm out of the room. I could flash my lightbulbs - but I don't have them in every room. I think I'm going to have to push an alert to my phone and my wife's phone.
What's the best way to send push notifications to my phone?
SMS costs money.
WhatsApp has no API.
Telegram bots can't start conversations.
— Terence Eden ⏻ (@edent) December 25, 2016
To be clear, I don't want to install yet-another-bloody-app on my phone and I don't have the patience to develop my own.
Let's see what the peanut-gallery suggests:
I think the Wonderous Mr Whatley might be right. Email. It isn't as glamorous as the others, but it doesn't rely on frequently changing APIs, capricious library developers, flaky 3rd party services, or anything too fragile.
Note - if your Gmail account uses 2FA (and it should!) you will need to create an app-specific password.
import smtplib from_email = "[email protected]" password = "Password123" to_email = "[email protected]" message = "THE FRIDGE IS OPEN" server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(from_email, password) server.sendmail(from_email, to_email, message) server.quit()
Which results in...
Run on start-up
First up, if you're not comfortable with
vi you'll need to install nano
export VISUAL=nano; crontab -e
Then add the following line:
# m h dom mon dow user command @reboot /usr/bin/python /root/fridge.py &
And that's pretty much it!
We always joke about Internet Fridges - usually over-complicated devices which tell you that the potato salad has gone bad and automatically order you more wine. But it doesn't need to be so ambitious.
A basic fridge/freezer is around £200. Even the cheapest appliance should have WiFi connectivity. Not necessarily control or something as dumb as a calendar display - but just a simple, local API for reading information.
Of course, the real barrier isn't cost of the device - it's the cost of service and support. As I repeatedly say, hardware manufacturers are shit at developing software - each frustrated customer ringing a call-centre cuts into the manufacturer's profits. There are huge associated costs for updating software against security threats. That's before we get around to building apps for phones - and then updating them to match newer OS style-guides.
Even on expensive items - like BMW cars - the software experience is just crap! Go to any app store and read the reviews for the apps of "luxury" items, they're uniformly dreadful.
Until manufacturers start taking software seriously, we'll have to augment their offerings with our own home-made bionic implants.