Smart Mirror?A Smart Mirror is basically a computer attached to a monitor on a wall. It's used as an information radiator. The mirror part is about having a semi-transparent mirror in front of the monitor, so that dark parts of the computer screen acts as a mirror, albeit somewhat darker than normal.
|The Smart Mirror is hanging on the wall...|
This doesn't take much computing power, so a good computer for this purpose would be a cheap and tiny Raspberry Pi and any old flat screen monitor you have left over. The most difficult part of this is to make it look good enough to be acceptable on a wall in a home.
Warning!Unless you really know what you are doing, building or installing a device like this could cause fire, electrocution, network security breaches, or a divorce, so don't try unless you understand the legal and practical consequences for the safety of yourself and others who might be affected. This text will not teach you any of the skills you need. It will only help you with some practical tips, assuming that you alreaady have sufficient training and skills in building electrical devices, carpentry, linux and network security.
I'm not going to tell you to unplug cables before tearing things apart, or to change default passwords. Unless such things are obvious, wait for consumer versions of smart mirrors to appear on the market. They will be cheaper and easier to use anyway... Be patient!
PartsYour milage may vary, but this is the material I used:
- An old 19" VGA monitor
- Semi-transparent mirror 40 cm * 30 cm
- A VESA wall mount and suitable screws for the wall
- Raspberry Pi 3 Model B
- Micro SD card as "hard drive"
- USB charger providing at least 1.5A
- Long enough micro USB cable to power Pi
- Gert VGA666 adapter
- Spacers, nuts and screws to attach Pi to back of monitor. Use M2.5! I used M3s which are too big.
- VGA cable
- Power cable for monitor
- Solid oak millwork for front and side of frame
- Metal Corner Brackets
- Wood glue
- Wood oil
Besides these parts, you obviously need suitable tools and materials, but if you passed the criteria in the warning section, you already know that...
If you have a suitable monitor with a HDMI connector, life will be easier for you, since the Raspberry Pi has an HDMI connector. Then you can skip the Gert VGA666 passive VGA adapter.
You could also use glass and semitransparent mirror film instead of the acrylic mirror I used.
You could also use glass and semitransparent mirror film instead of the acrylic mirror I used.
The VGA MonitorBefore you start, you should probably think about the layout on the back of the monitor:
- Is there a suitable space for the Raspberry? How should it be directed to make it convenient to attach power, monitor, possible USB devices and to swap micro SD card if you need to do that.
- How are the connectors you need to use located? Will cables protrude in an inconvenient way?
- In what direction from the mirror do you expect the cables to go?
- If you plan to make the mirror vertical, should you rotate left or right?
|Once upon a time, the monitor looked like this...|
Be careful about the monitor adjustment buttons. In my case, it was a piece of PCB on a ribbon cable, and I attached it on the backside of the monitor with double sided tape in such a way that I can reach the buttons with my fingertips if I need to.
Another consideration is that screws for the wall mount will no longer go through the layer of plastic you removed. This might cause supplied screws to extend further into the monitor interior than intended. That could possibly lead to damage, so beware!
The Raspberry PiI used a Raspberry Pi 3B, but the software I use, Magic Mirror 2, supports both Pi 2 and Pi 3.
|Raspberry Pi 3B|
|The mirror from behind. The left side goes up, so the Raspberry Pi in the lower right corner will also be in the lower right corner when the mirror is in place.|
I found a good place in a corner of my monitor for the Pi, and used M3 screws, nuts and 5 mm brass spacers to attach it to a piece of the monitor which could be screwed loose and drilled in. I suspect a glue gun would work. It obviously depends on what stress the Pi is exposed to, mainly from cables attacted to the connectors. M3 is really a bit big for the holes in the Raspberry Pi. The right size is M2.5.
The MirrorI used a ready made acrylic one-way mirror from Slöjddetaljer. I think my screen area inside the metal frame was 30.5 cm * 38 cm, so their 30 cm * 40 cm model was a very convenient size. The disadvantage with acrylic is that it scratches very easily, so be very careful cleaning spots. You will obviously place the reflective layer back, so front side scratches won't destroy the reflection, and you can polish them away with special polish for acrylic surfaces.
To cut off the excess piece, I scratched the mirror on both sides with a sharp knife along a metal ruler, and broke off the piece I didn't want. It's not completely trivial to break 2 cm * 30 cm in one piece. Remember to be careful not to make scratches or marks in the mirror.
The more scratch resistant approach is obviously to get a pane of 3 mm glass cut to the right size, and mount one-way mirror film on the back side.
Whether you have a glass or acrylic mirror, you want to make sure that the reflective side is on the back, and I think that the mirror should lie directly on the LED screen. You don't want refelctons to go back and forth between the mirror and the screen.
The way I cut the mirror, it fit entirely inside the metal framing which surrounds the LED display, and thus lies flush to the LED. It's kept in place by the oak frame. I simply taped it to the screen with masking tape.
|The mirror without frame, attached to the monitor with masking tape.|
The FrameSince the Monitor and the Computer hangs on the VESA wall mount, the frame only needs to be strong enough to carry its own weight, and stop the thin mirror from falling off the computer screen. The frame hangs on the "picture", in contrast to a traditional picture, which hangs in its frame.
You could imagine using a frame from an old painting or mirror, and just saw it to size, but there is a problem with that. Depth! A mirror glass is just a few millimeters. The minimal depth of an old painting it determined by the wood frame which the canvas is streched on. That's tiny compared to a computer monitor plus a wall mount.
|Mirror without frame from side|
With the wood I selected, I have 8 mm of oak in front of the mirror, and 47 mm of oak behind the top 8 mm, streching back towards the wall. The monitor and wall mount are thicker than that. I measure 19 mm from the wall to the back of the frame. That's big enough to allow for ventilation (I hope), but small enough to hide most of the ugly technology. It's 73 mm from the wall to the front of the frame. That's a 73 - 19 = 54 mm thick frame. 47 + 8 = 55, so I have sanded down 1 mm when I worked with this, which brings us to the carpentry part...
The front part is a 27 mm * 8 mm "foglist", which means that the corners closest to one of the wide sides are rounded. This is the front of the frame. The frame sides are from 47 mm * 10 mm "planhyvlad list". While the bigger side pieces are untreated, the foglist was varnished, so I had to sand those down first so that they would work with wood glue and wood oil.
Gluing the front and side in angle with the outsides flush, the front will provide a 27 - 10 = 17 mm cover. We want to cover four things:
- Sideways gap between oak frame and metal frame of sceen.
- Metal frame besides screen.
- Gap between metal frame and mirror pane.
- Tape keeping the mirror in place.
17 mm should be fine for this. There was also 21 mm wide foglist, but 11 mm would have been too little, and it would have made the proportions of the frame worse. Running the Raspberry in console (non GUI) mode, I notice that the frame completely covers the top and bottom rows of text, and the first and last columns. Considering this, it's possible that I should have made the frame a bit bigger, and used shims to keep the monitor in the middle. It's no problem while running the magicmirror2 app though. The app is made with consideration to custom frames...
|Frame from behind. Hole for Raspberry power in near left corner. Piece of wood to keep frame in place on inside of top side. Stains from rejected experiment with antique wax also visible on inside.|
This is what I did in order:
- Sand off the varnish from the foglist.
- Cut foglist and planhyvlad list in four pieces each which are long enough to fit on each side with some margin.
- Match the pieces, decide which sides look better, glue them and clamp them.
- Remove excess glue and sand the L-shaped pieces so that they are straight and smooth.
- Saw the ends to right length in 45 degree angle and sand edges.
- Glue and clamp into the final shape.
- Remove excess glue and sand corners slightly.
- Measure where the hole for the power USB for the Raspberry should go, and drill that.
- Glue a piece of wood on the inside of the top side of the frame, to keep the frame in place when it's hanging on the monitor.
- Oil the frame twice with a night in between.
- Mount the decorative (?) metal brackets for the corners. (I didn't want to hammer nails into the frame without pilot holes, and I was reluctant to drill freehand with thinner drills than 2 mm, so I used super glue to make sure that the thin nails for the corner brackets stuck in their holes.)
Software and Configuration
During installation, I had a USB keyboard and mouse attaced to the mirror. Once I had set up remote access via VNC, that was no-longer needed. It also took some work to get the VGA666 drivers to work, so initially I had another monitor attached on the HDMI port.
The Raspberry Pi is running Raspbian installed on a micro SD card.
The main piece of software is available at https://magicmirror.builders/
Installation and configuration is described in the GitHub repo.
The application is configured in config/config.js, and third party modules are installed with git clone in the modules subdirectory. I'n used these modules:
Display Rotation and VGA666
If yu are using a digital monitor via the HDMI connector, this is not an issue, but since the VGA666 adapter uses GPIO ports which are by default reserved for other use, you might have some things to deal with if you use a VGA monitor.
All the details you need to know are in the Raspberry Pi Forum. As I said above, you might need an HDMI monitor until you get this to work.
I added this to /boot/config.txt
# VGA 666
Starting MagicMirror2 on boot
I had to fiddle with Electron to get the app to run at boot, but I hope that's now set up with the default install.
Not blanking the screen...
By default, the Raspberry turns of the screen after a few minutes of inactivity. You don't want that...
Add in /etc/lightdm/lightdm.conf:xserver-command=X -s 0 -dpms
The easy ways to get remote access to a Raspberry Pi is to enable either ssh or vnc in raspi-config, interfacing options. I used vnc.
MaintenanceTo update MagicMirror2, run git pull && npm install. You might need to do the same for each module. For Raspbian, it's the usual sudo apt update followed by sudo apt upgrade.
Placing the MirrorThe main consideration regarding placement compared to a normal mirror, is that you need somewhere to connect your power cords, so that you don't stumble on them.
Otherwise, besides the fact that you want a mirror placed so that you can look straight into it, it should of course be located in a place where it makes sense to see the information you radiate. For instance, weather information might be conventient where you decide whether to wear boots or loafers...
Future WorkThere are some things left to do...
Assume that you have settings so that you see yourself nicely in the mirror in the daylight, and you can see the text on the screen. Assuming that the settings are fixed, things will appear very differently at night. Without daylight, with much less light in the room, the thing that used to be a mirror, is now a black screen with very bright text that's hurting your eyes (well, almost).
There are two parts in this problem:
- How do we determine how bright the screen should be?
- How do we change the brightness of the screen once we know what we want?
Regarding part 1, I assume there are two fundamental approaches. A) time based solution, and B) light based solution. Since I don't have a camera connected to the Pi, and the VGA666 uses up the entire GPIO bus where I could possibly have attached a light meter, I think I'll go for the time based solution. It's also a much simpler solution, so it's a good first attempt anyway.
I guess there are basically two fundamental approaches for part 2 too. We either change system brightness settings in the drivers or in X, or we change something in the magicmirror2 application (which covers the entire screen anyway).
There are a number of ways you could adjust brightness for the HDMI output in a Raspberry Pi, e.g. xbacklight or xcontrast, but they don't seem to work with the VGA666 driver. There is no such thing as an assumption of a LED backlight in a VGA connection, even though it exists in the acual device when it's a LED screen.
The best way forward might be to cover the entire window in magicmirror2 with a black top layer with varying transparency in CSS, or something similar...
Infrastructure As Code
As is now, I've installed the application, and done all the needed configuration by hand. something happens, e.g. the SD card break (which sometimes happens with these devices after power losses), I'll have to do it all over again.
It would be nice to e.g. have a git repo with an Ansible playbook containing everything needed to get us from a fresh Raspbian install to a working system.