How To Make a MagicMirror From Scratch
Two issues immediately surfaced up after we moved into our house in Woburn
- The baby room gets either too hot or too cold
- There are so many windows and doors can be left opened
It would be amazing to have a “display” that shows which doors/windows left open and what temperature for each room is, back in 2017, there weren’t many solutions to centralize all the information in one place
So why not make one?
Of course it would be quite easy to make a web page to display all the information if i could find all the endpoints to fetch, and i can just mount a monitor on the wall like those you see in the bank displaying your place in the queue. but that idea got killed immediately by my wife, we are not a bank and practically nobody can see the text clearly once it’s hanging on the wall.
I came across this really cool MagicMirror community a while back and thought it was cool, and i remember seeing some widgets that showing weather info, a slider showing notes etc, so essentially it’s a hub to display information, awesome!!
I googled all the beautiful MagicMirror photos and sent to my wife
Not knowing the final products probably would never look that neat, she green-lighted it.
I separated the project into three chunks:
- Build the mirror frame
- Build the Raspberry Pi that powers the mirror
- Code the modules that display all the information i need.
Building the mirror frame
The woodworking part is quite simple, if you have made a picture frame in the past, this is no different, here are the materials i used: ($236)
Item | Price |
---|---|
Walnut S4S by the Piece, 3/4" X 3" X 48" from Rockler | $30 x 2 |
Clear Framing Grade Glass (optional, you can replace it with IR touch frame for touch support ) | $56 |
SUPREMETECH 24 x 36 x 0.12 Inch Acrylic See-Through Mirror, 30% Transparent | $90 |
Blackout Privacy Window Vinyl Film | $26 |
Selected pine for mounting support. | $10 |
For assembling order, check this diagram:
For my build, here’s what i end up with: Frame -> Glass -> 2-way mirror -> Blackout film for the reflecting part -> Monitor for display
Some pictures from the woodworking part:
Building the Raspberry Pi that powers the mirror
Materials i used: ($76 total)
Item | Price |
---|---|
Raspberry Pi 3 | $40 |
Raspberry Pi Case (for better mounting) | $6 |
Raspberry Pi 3 Model B+ A+ Plus Power Supply Charger AC with Power On/Off Switch | $10 |
Micro USB memory card | Free |
Raspberry Pi Camera Module V2-8 Megapixel,1080p (for gesture control) | $20 |
Steps to build the raspberry pi
Manual Installation
- Install raspbian OS on the RPI, (follow this article)
- Download and install the latest Node.js version, follow this documentation: Linux based distributions
- Clone the repository and check out the master branch: git clone https://github.com/MagicMirrorOrg/MagicMirror
- Enter the repository: cd MagicMirror/
- Install the application: npm run install-mm
- Make a copy of the config sample file: cp config/config.js.sample config/config.js
- Start the application: npm run start
For Server Only use: npm run server . - Create a docker container with Ubuntu 22.04 and repeat the same steps: 2-6.
- Once the MagicMirror runs, push the code to my own github
[Update]:
Since then, there are a few more ways to do this, which simplified the process quite a bit
Automatic Installation Scripts
- Sam (@sdetweil, long time contributor of the MagicMirror² framework) maintains an easy-to-use installation and update script: https://github.com/sdetweil/MagicMirror_scripts
- The MagicMirror Package Manager is a command line interface designed to simplify the installation, removal, and maintenance of MagicMirror modules.
Docker Image
MagicMirror² can be deployed using Docker, head over to this repository for more information.
Code the modules that display all the information i need.
Here’s a architectural diagram of what i did to accomplish this display:
Let's talk about XiaoMi Gateway, it's not the easiest IoT device to pull information from but here are the steps i followed:
// For configurations:
config: {
gatewayIP: '192.168.1.75',
gatewayToken: '[your gateway token, you can get it from miio]',
outsideSensorId: '158d000223f705',
showWindow: true,
celcius: false,
showVentilation: true,
showLights: false,
audioNotifications: false,
showTrend: true,
rooms: [
{
name: 'Outside',
sortOrder: 1,
devices: ['158d000223f705']
},
{
name: 'Master',
sortOrder: 2,
devices: ['158d0001f2abe2']
},
{
name: 'Kayley',
sortOrder: 3,
devices: ['158d00019cbad8']
},
}
Steps to install miio:
pip install python-miio
Alternatively, you can install the latest development version from GitHub:
pip install git+https://github.com/rytilahti/python-miio.git
The miiocli
command allows controlling supported devices from the command line, given that you know their IP addresses and tokens.
The simplest way to acquire the tokens is by using the miiocli cloud
command, which fetches them for you from your cloud account using micloud:
miiocli cloud
Username: example@example.com
Password:
== name of the device (Device offline ) ==
Model: example.device.v1
Token: b1946ac92492d2347c6235b4d2611184
IP: 192.168.xx.xx (mac: ab:cd:ef:12:34:56)
DID: 123456789
Locale: cn
Alternatively, see the docs for other ways to obtain them.
After you have your token, you can start controlling the device. First, you can use info
to get some generic information from any (even yet unsupported) device:
miiocli device --ip <ip> --token <token> info
Model: rockrobo.vacuum.v1
Hardware version: MW300
Firmware version: 1.2.4_16
Supported using: RoborockVacuum
Command: miiocli roborockvacuum --ip 127.0.0.1 --token 00000000000000000000000000000000
Supported by genericmiot: True
To start the mirror:
npm run server
what fascinates me the most is that the mirror system sits on top of Electron, which is a framework to build desktop app that written completely in JS. Sounds horrible right? nope, it turns out to be really cool.
npm start dev
for debugging. Since it's written in JS, you can just step through the code in the browser.
Additional useful information i compiled:
The config.js file is a challenge for new users. It is javascript code and gets included into the MM framework in runtime, meaning it needs to be free of any syntax errors. ( Debugging config.js)
That is quite a challenge, especially if you're using the console or simple text editors to edit config.js.
Fortunately there is an easy-to-understand implemented config check (a so-called js linter).
Run this in the Magic Mirror folder
npm run config:check
It will create an output showing all syntax errors.
Move into the respective line in the config.js and find the error. If you use nano as editor for your console, don't forget the -c flag which includes line numbers
nano -c config/config.js
Here's a video of it i took after i put on the led lights (of course)