Smart Mirror (Mk1)

Introduction

About 12 months ago I had the idea of building my own smart mirror. I liked the idea of doing my hair and seeing a weather report at the same time. I didn't however, like the idea of buying one ready-made off the shelf. This is because, generally they are less customizable, and I want to have the freedom to add more features to it in the future.

I started this project all the way back In August '22, but through a combination of waiting for parts and not having the time, the project was put on hold for quite a while. Fast forward to Christmas '22, and I finally managed to finish the first version of my very own smart mirror (dubbed the Mk1).

For now, its feature set is limited. It can tell you the time and date, along with the current temperature (geo-tagged), and weather details such as humidity, wind speed, and a quick summary of the outside condition (e.g., partially sunny, thick fog, etc).

Compared to my previous project - the smart plant pot - the Mk1 mirror on the face of it seems very simple. It is, after-all, a bunch of salvaged laptop parts, a Raspberry Pi, and a bit of custom software. However, what the Mk1 mirror lacks in complexity now, it provides the foundations for a much more sophisticated system in the future.

Like before, this is not a tutorial on how to make a smart mirror. There are lots of resources on the internet already on how to do that, so it would be pointless me making another (probably half as good) version. Instead, this serves as more of an article on my process, hurdles I encountered and how I solved them.

A test boot of the system
Fig 1. Testing system boot, making sure the hardware was playing ball

Parts and modules

Much like last time, see below a list of the components used in the project. Unlike last time however, there are far fewer.

Components:

  •   Raspbery Pi Model 3B+
  •   Old laptop screen
  •   Laptop Screen Driver
  •   Rechargable battery bank
  •   DC/DC Step-up transformer
  •   Wooden picture frame
  •   2-Way glass mirror

Hardware

The hardware requirements for this project were straightforward; at the heart of the Mk1 mirror there is a Raspberry Pi Model 3B+, along with an old laptop monitor and monitor driver board (MDB), which allows us to run the monitor independently. There is also a small rechargeable battery bank which is connected to a small step-up DC/DC transformer, in turn connected to the MDB. The transformer was necessary as the output voltage of the battery bank wasn't enough to power the MDB, the Raspberry Pi could be powered straight from the battery, however.

Fig 2. Salvaging parts from an old laptop
Fig 2. Salvaging parts from an old laptop

In terms of hardware, that's pretty much it! There is of course, the wooden picture frame that houses everything, the 2-way glass mirror which gives us the nice effect, and some fixtures and fittings; but they don't really seem worth talking about. There was a small amount of modification that needed to be done to the picture frame specifically for this project, which was to drill an inlet hole on the underside of the frame to let the power cable run into the body and connect to the battery.

Software

Now, as far as software goes on the internet, there are already frameworks, applications and libraries available to develop smart mirror products. I didn't want to do any of that. Instead, I wanted to write it all myself.

But why? Why did I want to spend more time and effort than necessary on something that I could hack out in an hour by downloading something online and installing it on the Raspberry Pi? The simple answer, customisation.

Writing the software myself allows me to change the code, add more features, fix (the inevitable) bugs, and so much more. It will also prove as a fun exercise to do and won't be as boring as following an installer guide and ticking a load of checkboxes to end-user license agreements I fully intend on breaking anyway (i'm joking of course...).

My language of choice was Python. This is because, it's easy to write, there are lots of libraries and extensions available, and most importantly, I am very comfortable with it. For the graphics side of things, I settled on Pythons PyGame library. PyGame is Pythons implementation of SDL packaged up as an easy-to-use API, making graphics development extremely easy.

I tried to design the firmware of the mirror with extensibility in mind; I know I'm going to want to extend its functionality in the future, but at the time of developing the Mk1 I didn't know exactly what for. I settled on developing my framework in such a way that it contained generic components (such as image container classes, text containers, and a mini-UI system), making extensions in the future an easier task.


The actual development of the UI was straight forward, essentially the screen just consists of various images and text, making up the different components. The only tricky thing I encountered was the difference in orientation between my development system and the production system - the mirror.

During development, I was using my desktop and a standard PC monitor, orientated horizontally on my desk. In production however, I wanted to hang the mirror vertically on my wall. The only issue with this was, there was no way to re-configure the MDB to run in a vertical setup; it only had the ability to run horizontally.

So, to achieve what I wanted I would need to account for this in the software. To do this, I needed to add a transform (both add rotation and a translation) to every renderable component on the screen. Rotation was required to consider the render space going from a horizontal screen to a vertical screen. The translation was required because the coordinate system of the 'screen space' had now altered, and everything needed to be adjusted accordingly - the horizontal (x-axis) had now become the y-axis, and vice versa. See figure 4 for a visual explination of this.

Fig 3. Comparing Horizontal screenspace to Vertical screen space
Fig 3. A comparision of Horizontal screenspace to Vertical screen space

Open API

One of the most important parts of the project was the data. Afterall, if there wasn't any meaningful data to display, what would be the point of it?

The data was sourced from Openweathermap, which provides (amongst other services) a free weather API. This was super simple to use, and the only thing that was required to get the data into the project was the use of the Python Requests library, which enables you to call http resources in code.

Final result

Below is the final result. As you can see, we have a neat user interface displaying location specific weather information, as well as the date and time. Reflecting on the UI, it could do with a bit of a polish. It was something rough I put together over a weekend just to mark this project as completed. In future revisions of the mirror there will definitely be a major graphical update.

In terms of quality, during the day the mirror element works perfectly. You can easily focus on your reflection and do whatever it is you need to do. With that being said, the UI shines through incredibly well, even in brightly lit rooms. Thanks to the high quality of the 2-way glass lots of light can still travel through the back face of the mirror, meaning even in direct sunlight you can still focus on your reflection and the UI with ease.

Fig 4. Final result
Fig 4. Final result of the smart mirror working

Future work

As I have mentioned throughout this article, the Mk1 mirror is the smart mirror in its simplest form. For now, it does the job, but I have so many ideas I want to implement that I already have designs for the Mk2, Mk3 and even Mk4. I think that's a good sign, but an overwhelming amount of work to do!

I do plan to document these future versions in a similar way to this one, so I don't want to give anything away just yet. I will say though, for the next version, I am planning a complete re-write on the firmware along with some fun additions to the hardware.



Wrapping up

For now, though, I am marking this project as complete. I have some big plans for the smart mirror; so if you found this interesting please do follow London Softworks on all the platforms listed below!

Thank you! -- Chris