The software for this project can be thought of in two parts. Both are important.
At the heart of this project is an Elixir/Phoenix application. Essentially, what is being displayed is one web page running from a local webserver.
The design is up to you, but you will want to make sure the background is black. Black will allow the mirror to reflect better. For the text to be visible in different lighting conditions I strongly recommend using bright white. In my case, as the weather forecast is further out the text is slightly more grey (to indicate some level of importance.) Making things bolder and bigger and with more contrast will serve you better.
You can see the entire application on GitHub. But I do want to show some of the highlights.
The application uses Phoenix 1.4 and LiveView 0.4.1. A previous iteration used Phoenix channels, which worked great also, but requires a bit more code.
The html view is very simple. Just 2 `live_render/2` calls.
And here are each of the liveview components:
It’s important to note the views are designed to refresh themselves on intervals. For the weather it is every 15 minutes. Obviously the clock needs to be updated more frequently. In this case I am showing hours:minutes:seconds, so it is updating every second.
Step 1 is to download an operating system onto your Raspberry Pi. The most common OS, and the one I used is Raspian.
Next, you will need to burn the OS image to your memory card. To do this, download Etcher by Resio.io. It is available for MacOS, Windows, and Linux.
Since this project requires internet access to get weather forecasts, next you will need to setup the Wifi on your Raspberry Pi. You can find detailed instructions on raspberrypi.org, but it is pretty simple.
The quickest way to enable wireless networking is to use the command line raspi-config tool.
sudo raspi-config
Select the Network Options item from the menu, then the Wi-fi option. On a fresh install, for regulatory purposes, you will need to specify the country in which the device is being used. Then set the SSID of the network, and the passphrase for the network.
Next, you will want to set the system time on your Raspberry Pi. From the Raspian desktop, select Menu > Preferences > Raspberry Pi Configuration > Localisation
Since this project will be running in a full screen web browser, we’ll need to download Chromium. To get started, update the package manager and packages with: sudo apt-get update && sudo apt-get upgrade -y
Once that has completed, install chromium and xserver utils; sudo apt-get install chromium-browser x11-xserver-utils
You will also want to install unclutter
and git
(if you want to pull code changes down.)
And then get erlang and elixir installed. There are very succinct instructions available on elixir-lang.org. Erlang Solutions also has very thorough instructions on building a beam server on a Raspberry Pi (or any other ARM processor computer.)
Now we will setup SSH. You can find detailed instructions on raspberrypi.org. In Terminal type: ifconfig
. Make note of the IP next to the line that starts wlan0
Now you should be able to access your Pi via SSH. From another computer, type: ssh pi@<IP-ADDRESS-HERE>
The default password is: raspberrypi
Almost done.
On the Pi terminal, type: raspi-config
and activate the option for “wait for network”. While you are there, this is a good opportunity to change your password from the default to something a little more secure.
The last step is to change some config files on the Raspberry Pi.
There are some special files used by the Raspberry Pi OS to startup the machine and put into a proper kiosk mode.
Type:sudo nano /etc/lightdm/lightdm.conf
Look for the line that starts with xserver-command
and change it to:
This will tell the Pi not to go to sleep and not show a cursor.
Type: sudo nano ~/.config/lxsession/LXDE-pi/autostart
. Depending on which version of Raspian you are using, this file may or may not already exist. The file should contain the following code:
This tells the Pi to call the kiosk.sh script on startup.
Now, create that file: sudo nano ~/kiosk.sh.
It should contain this code:
This file call unclutter, which hides the cursor after 0.5 seconds of inactivity. It also makes sure Chromium will not show pop-up warnings in the case of not shutting down properly. Finally, it loads the environment variables it needs from a file named .env
and it starts up a server using mix.
There are different ways to run a webserver. Mix is the most basic, but also the easiest. Since there will only be 1 client connected at any point I didn’t see a need for anything fancier.
I hope this inspires you to build your own smart mirror. Projects like these are a fun way to spend a weekend and let you spread your wings a little with new ideas. If you do build one, I’d love to hear about it!
Twitter: @sprsmpl