Magic Mirror – the architecture

The progress of MagicMirror development is still in the early state. It is mostly a set of proofs of concept than a working solution. I’m still waiting for a .NET Core ARM release, so I spend my time on preparing architecture and infrastructure for my project.

The thing that needs to be said is how I want to build the mirror. Essentially I take a Venetian mirror or a normal glass with an additional layer that will make the same effect. On the backside, I’ll install a simple LCD display connected to Raspberry Pi 3 computer. At the same time, I’ll connect to it a small camera, microphone and a speaker. In the future, we can use GPIO port to install additional devices (like a boiler, central heating system or anything else).

System architecture and stack

Magic Mirror architecture

This picture needs a clarification, so let’s start with user communication with the system.

Electron application

The responsibility of this component is dual. In the first place, it will display view the main desktop, so a set of widgets and a dashboard. Secondly, it will send a camera view every couple of seconds to a server, and if something interesting is happening in the front of a mirror it will start streaming the view to the server. Optionally it will be a proxy for voice transmission.

Essentially, the electron architecture introduces two processes types: main process and rendering process. It’s forced by the main component used by Electron – Chromium. There is always one main process and multiple rendering processes. Rendering processes are independent of each other and as a renderer process, we can only make a call to the main process using IPC. If you use Chrome browser, you should know that each tab is a separated renderer process.

Chromium process architecture

A renderer process does not necessarily display an HTML page – it can only be processing something in the background. My idea is to have the first renderer process for displaying a dashboard, the second for sending periodical camera captures or streaming, the third one voice and the fourth one for handling incoming messages. The main process will be rather playing a role of an orchestrator.

GPIO Port

This component is an interface for all additional devices which can be connected to the system. In the first stage, it will not be even a part of a project, but I need to be prepared for connecting additional devices, like a boiler, central heating or GSM module. This is basically the universal port in Raspberry Pi (GPIO – General Purpose Input/Output). More about this port you can read here.

Admin Web

The purpose of the whole project is to get a simple tool to be an assistant. It will be the powerful system, though, so we need to be able to configure it. This component is a simple web page which basically allows a user to edit the configuration using a browser.

IoT Service

This component is a web service that is going to be responsible for handling and managing all devices available on the platform. For instance, if you connect an intelligent kettle to your system, this service will handle the communication with this device so you can run it using a mirror during morning teeth brushing.

Users

This service is going to work with users, so it plays a role of Authorization and Authentication service. What’s interesting, it will recognise a user using his/her face. Exposed API gets a video stream and recognises a user standing in front of a mirror.

Components & Widgets

Magic Mirror has a misleading name, that suggests that it’s only a mirror. In a fact, it’s a whole extendable platform. This service is going to keep available components and widgets. For example, it will connect to your Gmail account and read last emails.

Configuration service

The MagicMirror might indeed become a system with complex logic. Maybe it will manage your whole intelligent house in the future. The configuration component has a purpose to enable or disable components, change language or local time zone. There are plenty of possible configurations that might be implemented, but you probably have an idea what is it for.

Global infrastructure

I decided to use MongoDB as a data bank for all services. It is universal and fast. If a MagicMirror is a successful project I might move it to a central server and introduce Redis working on a client side. The scalability of Mongo will be a useful feature then. What’s more, I can imagine that using structured data will force joining tables all the time, so a database is an obvious bottleneck.

I’ll use Nginx as a web server. It is super easy to configure and it supports load balancing out of the box. It is also pretty fast, so it should handle a big load of requests in the future.

All services are orchestrated with Docker. It’s much easier to develop a solution for completely different platform. I can use my Windows development machine and run it on Raspberry Pi 3.

In the next post I’ll try to describe you my solution structure, so look forward updates!