Building a Magic Mirror
Windows 10 IoT Core, UWP, C#, Raspberry Pi 3
Inspiration
I am certainly not the first one to create a magic mirror, and I will not be the last either. I was inspired by those who are true Innovators…some might say, “I’m standing on the shoulders of giants”. They would probably we right, and I’m okay with that. Earlier this year, I stumbled upon a tweet about someone how created a magic mirror…this is the root of my inspiration.
Yup, it is official -- I want a mirror like this one! https://t.co/MVcM1nca7A
— David Pine (@[email protected]) πΊπ¦ (@davidpine7) February 4, 2016
Before continuing on, allow me to explain what a magic mirror is. A magic mirror is simply a two-way mirror with a monitor positioned behind it that projects through the mirror. The monitor displays the application. The application is running on a small computer, in most cases a Raspberry Pi.
I noticed that a lot of the magic mirrors had greeting messages such as “you look handsome” or “good morning sexy” and other curiously intuitive sayings. I thought “wow” this really is a smart mirror, much to my surprise these were all just static messages (or only dynamic when accounting for the time of day). I was thinking to myself, “I wonder if I could improve upon this”, and that was my motivation!
Open Source
If you want to skip out from reading this post, you can checkout my project up on GitHub Β IEvangelist.Mirror .
Hardware
I was excited when Microsoft started selling the Raspberry Pi 3, Model B - I ordered one immediately.
Specs
Miscellaneous
Below is a semi-comprehensive listing of all the materials and their corresponding cost that I used for building my magic mirror.
Rough Cost | Hardware |
---|---|
$60 | Raspberry Pi 3 Bundle |
$130 | BenQ 27" HDMI LED Monitor |
$90 | Custom-sized Two-way Mirrored Acrylic |
$40 | Microsoft LifeCam |
$25 | Dell USB Wired Soundbar |
$6 | Power Cord Splitter |
$25 | Full HDMI Cable, USB Extension Cables |
$50 | Carpentry Materials |
$50 | Glenlivet 12 Year Old Scotch Whisky (not technically hardware) |
~$480 |
Considering the total investment is still under $500 bucks, that’s not too bad!
OS – Platform
One of my favorite parts about developing the magic mirror was the fact that I could do so from the comfort of Visual Studio using the worlds most powerful programming language today, C#.
Type | Name – Link |
---|---|
OS | |
Platform |
Software
When people throw around the acronym IoT it can mean a lot of different things. For this specific application, it is essential. Using the built-in WIFI on the Pi 3 we can leverage the power of the internet to gather and share information.
Software is simply the movement and manipulation of data. But without context, said data is meaningless.
The magic mirror application strives to provide data that is all of the following:
- Relevant
- Practical
- Convenient
- Timely
Below is the user-interface layout. Let’s have a look at the various components that our application is built on.
Components
From the layout above, it is clear to visualize the key components of the application. Most of these components implement the
IContextSynthesizer
interface. These implementations are indicators that each component is capable of handling voice commands, and providing a message that is consumable
by the UWP speech-synthesizer. More on this later…
Weather – Forecast
The current weather and forecast are retrieved every fifteen minutes from the free
Open Weather API
.
The developer API key and zip code are configurable. Additionally, the unit-of-measure is configurable, where you can specify imperial
or metric
as valid settings.
Clock
The clock is extremely simple. It is just the current date and time. It updates every second, formatting to the hour, minute, and second – additionally displaying the name of the day followed by the month and day number.
Example:
4:20 17
Wednesday, December 21st
Event Calendar / Schedule
My magic mirror is configured to display an aggregation of two calendars. This is entirely configurable, so if you were to
fork my repo
– you would need to setup your desired endpoints. The only requirement is that the URL is an accessible endpoint that returns valid iCal
(*.ics) formatting
.
The events are truncated to fit on the page and ordered by the date of the event.
Music Player
Imagine you have the magic mirror mounted in your bathroom, or bedroom…it would be nice to say, “play a song”, or “play Deftones” for example and music starts playing. That is the idea behind the music player component. The current implementation of the music player is limited. I spent a few long nights trying to figure out how to use the built-in Bluetooth on the Pi 3, while UWP does have some support it is limited. I was able to pair but not stream songs from my iPod for example, which was really frustrating. For the meantime, I simply placed several songs in the Assets
directory as content and I can play these resources. Ideally, I will use a web-based service like Spotify or Pandora.
Voice Commands
The Universal Windows Platform provides two very useful classes, the
SpeechRecognizer
and the
SpeechSynthesizer
. Leveraging this
I have built out the ability to talk to my magic mirror, I can ask it things like “what’s the weather”, “what’s my schedule for Wednesday”, or even tell it commands like “turn
this up”.
Microsoft Cognitive Services
Formally known as “Project Oxford”, Microsoft Cognitive Services offers a ton of programming power and you can start using it today for free. Simply
subscribe
and use your subscription key as the argument to the client .ctor
. The magic mirror makes use of the Emotion API, and corresponding EmotionServiceClient
from the
Microsoft.ProjectOxford.Emotion
package.
Consider the following:
async Task<IEnumerable<RawEmotion>> CaptureEmotionAsync()
{
RawEmotion[] result;
try
{
var photoFile = await _photoService.CreateAsync();
var imageProperties = ImageEncodingProperties.CreateBmp();
await _mediaManager.CapturePhotoToStorageFileAsync(imageProperties, photoFile);
result = await _emotionClient.RecognizeAsync(await photoFile.OpenStreamForReadAsync());
}
finally
{
await _photoService.CleanupAsync();
}
return result.IsNullOrEmpty()
? await TaskCache<IEnumerable<RawEmotion>>.Value(() => Enumerable.Empty<RawEmotion>())
: result;
}
- First our
_photoService
asynchronously creates a photo file - From the
ImageEncodingProperties
class, we create a bitmap encoding property set - Our
_mediaManager
captures a photo, storing it in the photo file with the specified encoding - Finally we invoke the
_emotionClient
passing it the stream from the persisted photo
The result
object contains a Scores
class that looks like the following (from my mugshot):
The service returned a result. The result claims an 81.5% level of confidence that I’m happy based on the given image, what do you think? What you don’t see is that I’m taking a selfie with Jeremy Foster – so, yeah – I was pretty happy!
Construction
I would be lying if I tried taking credit for any of the construction. I’m slightly embarrassed to admit that I opted out of building it, as I lack the carpentry skills needed to do a decent job. Instead, I asked a friend who just so happens to be awesome at carpentry. After persuading him with a bottle of single malt scotch whiskey, I had my magic mirror constructed and the results were amazing! Needless to say, I was excited to try it out.
Share this post
Sponsor
Twitter
Facebook
Reddit
LinkedIn
StumbleUpon
Email