Linux

After seeing a critical mass of Magic Mirror builds online, I caved and built one as a Christmas gift for my girlfriend – I made a few innovations on top of the other builds I’ve seen, so I’ve documented them here.  I drew much of the inspiration from Dylan Pierce in particular, so be sure to check out his build log as well!  Here’s the finished product, before wall-mounting:

 

mirror2

Build Process:

As I did not have the patience to spec out my own LCD panel, I decided to purchase a used victim TV, and worked from there.  The first step was to pop the bezel off and take a few measurements:

 

20161221_002223

 

With measurements of the LCD panel itself, I was able to mount the LCD panel in a basic 2×4 frame:

20161222_203728

The LCD Panel did not have any usable mounting holes that could mate with the 2×4, so I held it in place with some small angle brackets.

20161222_210831

After installing the brackets, I realized the single-screw mounting hole would be prone to rotation – some flank screws made for a quick fix.  Also pictured: speed holes

 

20161222_211047

I eventually added small metal mending plates to sandwich the LCD bezel in the frame (not pictured)

The TV I had cannibalised did not support HDMI/CEC control via the raspi, so I patched in to the power button with an opto-isolator (Sharp PC817).  By using an opto-isolator, the raspi only “sees” an LED as the load, allowing for safe coupling between the raspi and the TV circuitry.  The pin spacing on the PC817 was conducive to patching in directly to the tactile switches.  I also replaced the TV’s “off” LED with an opto-isolator connected in the opposite direction – this lets the raspi know if the TV is on or not.  This is important, because the power button is of the on/off toggle type; the raspi wouldn’t be able to know if it was turning it “on” or “off” otherwise, it would only know that it is changing the state.

 

20161222_213606

 

Originally, I was going to power the TV on and off via cron job, until a coworker suggested putting a sensor in to turn the mirror on when someone is in front of it.  I just happened to have a spare ultrasonic sensor around, so I mounted it into the frame and wired it up via GPIO pins on the rpi:

20161224_172106

With all the electronics connected + working, I glued the fancy mirror-glass in place (Actually, it’s acrylic), and added a nice aesthetic touch with some faux-oak molding and iron-on veneer (ran out of veneer, so the bottom got the thin piece).  I measured the mirror piece to have a 0.5″ margin beyond the viewable LCD portion so that I could affix it to the LCD bezel for a tight fit.  Mirror glass was the same used by Dylan Pierce available at TAP Plastics:

20161224_231110

The notch is in place to accommodate a power cable while wall-mounted.  Also pictured: speed holes

 

The ultrasonic sensors were a bit tricky; I drilled holes in the moulding and adjusted them with a dremel.  They are by no means perfect…

20161224_231134

 

And here’s a view of the rear/electronics – the intention is that this will be wall-mounted, so I didn’t bother with a protective cover.  Zip ties were applied liberally.

20161224_231116

 

Schematic

mirror_schem

Note: The optoisolator / ultrasonic sensor circuitry was soldered onto a piece of perfboard that mated with the RPi’s GPIO header

Software

The base software installation uses raspbian jessie and MagicMirror², and raspbian packages python-gpiozero and wiringpi (i.e. install via sudo apt-get install _____).  All GPIO control code is below.

Note: all .sh and .py files live in /home/pi, the .service files live in /etc/systemd/system/, enable via:

  • cd /etc/systemd/system
  • sudo systemctl enable detect_person.service
  • sudo systemctl enable tv.service

This allows for control via, e.g. sudo service tv [start|stop].  The tv.service serves to turn on the tv during the boot process (as well as for general debugging), while the detect_person service performs the ongoing operation for person detection.   Note that the particulars in detect_person.py need to be tuned to the environment that the mirror is installed in!

I also had to play with some settings /boot/config.txt to get the right screen orientation, see the comments in that file for details.

 

 

 

In some cases, you need to connect to a VPN to do remote work. Typically this sets the VPN interface to be the default gateway – and so, all your web traffic/etc will route through your VPN connection. This becomes troublesome if your VPN endpoint wont route out to the web.

For example, I’m ssh-ed into some work servers right now, and need the internet to write this awesome blog post. My VPN endpoint at the office does not route any traffic to the web, by design.

To get around this, first add a static route for the subnet associated with your VPN interface

sudo route add -net 10.0.0.0 netmask 255.0.0.0 gw 10.0.0.1

Then, remove the default route that is trying to shove all your http traffic onto the VPN

sudo route del default

Finally, re-create your default interface to specifically route out your LAN’s gateway

sudo route add default gw 192.168.0.0.1

There are probably better ways to configure this – likely, there exists a way to keep the VPN interface from becoming the default gateway – but this is quick and easy 🙂

This is more for my own records than anything else – this is how you mount a CD (or .iso image) from the command line:


mount -t iso9660 /dev/sr0 /mnt #mount a CD/DVD from optical drive
mount -t iso9660 /path/to/file.iso /mnt #mount an .iso file

that is all! Depending on your system, you’ll likely need to use sudo/be root.

Edit: On some distributions (Ubuntu 12.04 server for example), the cdrom device is known as /dev/cdrom instead of /dev/sr0

What do you do with a busted laptop?  Many people are quick to throw them away.  Others turn them into FreeNAS boxes, or other useful servers.  For the machine I inherited today, I decided to turn it into an all-in-one style desktop PC.  The screen still worked, it was able to boot windows – the only trouble being that it was in physically rough shape.

 

100_1217

Ouch…

Basically, the screen had become detached from the rest of the machine – but all the cables were still in place for it to function.  After some light tweaking, I was able to get the screen to flip around the body of the laptop and sit flat on the reverse side:

100_1221

But how to keep it in place?  Being impatient and lazy (usually a dangerous combination), I tried my lucking using an entire roll of electrical tape to keep it all together.  Because why not?

100_1225

Partway through the taping

Being that this thing is going to mount against something on the reverse, I removed the keyboard as well.  So it’s not bumping its keys into stuff all the time.

As luck would have it, I had an old monitor stand kicking around – works as a nice little kickstand. Not perfectly stable, but still more solid than I was expecting:

100_1230

Starting to take form…

Now all that’s left is to wipe the old Vista install and put on a fresh OS…

100_1232

Tape starting to lift in the top-right corner, this was later fixed. The answer, of course, was more tape.

A few hours of tinkering, an old laptop, some electrical tape, and a fresh Xubuntu install made for a perfectly good bedroom workstation.  Not bad for one night!

A very quick hack that I’ve found very useful over the years – an alias lets you rename a command, a set of commands, etc.

For example, the ALSA command-line volume control interface, alsamixer, is much more memorable as salsamixer:

alias salsamixer='alsamixer'

Just stick that in your ~/.bashrc file, run a source ~/.bashrc (or log out and back in) and you can run the command salsamixer.  Neat, no?

 

Another super handy one for debian/ubuntu/mint users:

alias sagi='sudo apt-get install'

Again, append that to your ~/.bashrc file.  Now, you can install software with 16 less keystrokes:

sagi python-mysqldb

 

Neat, hey?