Magic Mirror powered by Home Assistant and TileBoard
https://imgur.com/gallery/L275JQ7
This is my Magic Mirror. It was a project that I wanted to do for a while and completed it about a year ago. It got switched off a few months ago as the UI broke and didn’t have time to get it working.
That brings me to last month where I had time to spend on getting it working again. For this project, I used Home Assistant with TileBoard.
Home Assistant is a big part of my daily routine what with the automations and smart home control.
Parts
The parts are pretty simple. You will need the following:
- An instance of Home Assistant with TileBoard installed
- For this, my Home Assistant instance is on a dedicated server but ** my TileBoard theme is heavily styled** to get the layout I wanted (Read more below)
- A RaspberryPi (with microSD card - 8GB atleast)
- No specific model really, I use a 3B+ but the Pi is only being used for the web browser to render the tiles. Since there will be no user fancy animations, performance isn’t really an issue.
- A spare monitor
- I had an 22" LG monitor spare but you can use any monitor. I would recommend a USB output as this will ensure only 1 power cable is needed for the whole mirror.
- The frame
- I built the frame using wood from a local B&Q (Hardware Store in the UK). The frame is 2.25" deep which allows for the monitor sit along with the brackets to hang on the wall.
- Mirrored Acrylic or Glass
- I went with Acrylic but am shortly changing it out for Glass. The only reason being that the reflection is distored and looks like a funny circus mirror from some angles. You don’t need 2 way glass, don’t but that expensive stuff! Instead, buy a pane of glass (which is much cheaper), and use some 2 way mirror film on it.
- For reference, here is where I bought my acrylic from CutPlasticSheeting’s website.
Tileboard
I am going to ask you nicely to follow the guide on the TileBoard repo. It’s well detailed on how to install it on your Home Assistant instance: https://github.com/resoai/TileBoard
RaspberryPi Prep
The RaspberryPi has a normal instance of Raspbian Buster installed. There are tons of tutorials on how to get this on an SD card but I will glance over it.
First, download the Rasbpian Buster (or newer) image from the RaspberryPi website.
Then, download and install BalenaEtcher from their website.
Next, insert your microSD card into your PC and open BalenaEtcher. The app is easy to use and you just need to select the image, check the right SD card is selected and click “Flash”. Once finished, don’t take the SD card out yet.
I presume that you’re going to use WiFi on this RaspberryPi. We can save some time by pre-configuring WiFi and enabling SSH before we boot the Pi up.
First, with the SD card still in your PC, open Windows Explorer, and navigate to the “Boot” partition of your SD card. In there, you will need to make a blank file named “ssh”. It can be quite tricky to do as Windows moans that you have to use an extension. To solve this, just open Powershell and type the following:
cd E:\ (change the letter E for whatever the letter of the drive is with the "boot" label)
Now type
New-Item ssh
This will have created a blank “ssh” file on the root of E: (or whatever you changed it to).
Now, go back to Windows Explorer and navigate to the root of the “boot” volume again. Make a file called wpa_supplicant.conf
. Open that with a text editor. Put this in the contents of the file
network={
ssid="YOUR_SSID"
psk="YOUR_WIFI_PASSWORD"
key_mgmt=WPA-PSK
}
Save the file and put the SD card in the Pi. Turn on the Pi and wait a few minutes for it to boot for the first time. The red and green LEDs should be doing stuff, but if the green LED isn’t blinking at all for a while, something’s wrong.
RaspberryPi Setup
Now the Pi is ready to go, Go ahead and download Putty. It’s an SSH client that we can use to ssh into the Pi.
Once downloaded, open a connection to the host raspberrypi
port 22
. The username by default is pi
with a password of raspberry
.
We are going to want to install and change a couple of things on the Pi. We need it to first, open the browser on launch, hide the cursor and rotate the screen. Let’s do it!
First, you’ll need to update the Pi to ensure the packages are up to date and secure. Just run sudo apt-get update -y && sudo apt-get upgrade -y
Now lets rotate the display
I am presuming that you know the orientation of which you need the Pi to sit. In my example, my monitor is rotated 90 degrees anti-clockwise, so I had to tell the Pi to rotate the screen. To do this, you will need to edit the systems configuration file. First, open the file for editing: sudo nano /boot/config.txt
Go right to the bottom of the file and add the following lines
avoid_warnings=1
display_rotate=3
avoid_warnings
will be required if you are using the USB power from a monitor or low power outlet. If not set to 1, it will show an undervoltage indicator over the display. It’s really not an issue since we’re not doing anything performance heavy.
display_rotate
is set to 3 for me to suit my setup, but here are some examples of how it can be set
display_rotate=0 Normal
display_rotate=1 90 degrees
display_rotate=2 180 degrees
**NOTE: You can rotate both the image and touch interface 180º by entering lcd_rotate=2 instead**
display_rotate=3 270 degrees
display_rotate=0x10000 horizontal flip
display_rotate=0x20000 vertical flip
To save the file and exit, Press CTRL+X
, then Y
, then ENTER
.
Now reboot with sudo reboot
. When it is booted, take a look at what you’ve done and pat yourself on the back!
Browser
The Pi will need to auto-launch the browser and hide the cursor ready for our viewing pleasure. First we need to install some packages to help with that. Run:
sudo apt-get install unclutter
Next, we need to modify the startup script that the Pi runs on login. So run the following command:
sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart
In that file, paste the following:
point-rpi
@xset s off
@xset -dpms
@xset s noblank
@chromium-browser --incognito --kiosk http://hassio:8123/local/tileboard/index.html
@unclutter -idle 0
It is very important to change the 5th line to the URL of your TileBoard path. If you wanted to use a different UI for the mirror, here is where you would change the URL to go to.
Save that (CTRL+X
, Y
, ENTER
) and reboot. Let it boot and watch your Pi now boot to the TileBoard page
Monitor Power Script
One last thing to do on the Pi is create 3 scripts, “power off”, “power on” and “power status”.
To do this, create these 3 files in the root of /home/pi/scripts/ directory
on.sh
tvservice -p
fbset -accel true
off.sh
fbset -accel false
tvservice -o
state.sh
state=$(tvservice -s | grep '0xa')
if [[ $state == *"state"* ]]
then
echo 'on'
else
echo 'off'
fi
Afterwards, run this command in the scripts folder also. This allows the scripts to be executed.
chmod +x ./*
Now, if you run sh off.sh
it should turn the monitor off. sh on.sh
should turn it on, and sh state.sh
should return true/false depending on the state of the monitor.
Home Assistant Integration
Now, I am not going to go much in depth on the tutorial part of the HA integration but I will provide my configuration for reference.
So the way my mirror power works is by sending a SSH command to the Pi from HA. This runs a script on the RaspberryPi which tells the monitor to turn off via HDMI-CEC. I did this by creating a SSH keypair so that passwords won’t be an issue. There are many great, simple tutorials on how to do that if you check on Google.
Once you can SSH from your HA instance to your Pi, you can remotely trigger the SSH scripts we created earlier.
I then have a custom switch that uses the command line platform like this. This allows HA to query, and control my monitor.
- platform: command_line
switches:
magic_mirror_state:
friendly_name: Magic Mirror Power
command_on: 'ssh [email protected] -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /config/keys/id_rsa "/home/pi/scripts/on.sh"'
command_off: 'ssh [email protected] -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /config/keys/id_rsa "/home/pi/scripts/off.sh"'
command_state: 'ssh [email protected] -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /config/keys/id_rsa "/home/pi/scripts/state.sh"'
value_template: >-
{{ value == 'on' }}