Smart Mirror

This smart mirror consists of a mirror, a frame, and a display powered by a Raspberry Pi 3. It displays various things, like the weather, time, and news headlines. Eventually, this mirror will also be able to detect motion and sound to determine when it should turn on and off.


Jocelyn L

Areas of Interest

Computer Science


Saratoga High School


Incoming Junior


I learned a lot from building this project, including how to work the raspberry pi and how to navigate through terminal. I learned a lot about linux commands, and I also got a lot more familiar with editing code and downloading/installing files through terminal.

On a more personal note, I learned of how capable I am to build a project from start to finish independently, with only mentors answering my questions. Before Bluestamp, whenever I built a project, I would always have somebody guiding me through this project step by step. This experience showed me that I am capable of building a project by myself, and because of this, motivates me to build more projects in the future.

Second Milestone

In my Second Milestone, I built the frame of my Smart Mirror, and also got the display software working on my Raspberry Pi. I am finished with my base project at this point, and it now looks like an actual Smart Mirror, displaying the weather, time, etc., as well as being a mirror and being reflective.

This is the last milestone of my base project. At this point, I am completely done with my base project, and am now starting to add modifications.

How Weather API Works

Weather API is a function that allows developers to access the forecast of any place, anytime. It takes information of the forecast and allows developers to display them, etc. This occurs by creating a unique weather API token for each use, and then using this token, you can specify where you want the forecast from, and it will get the forecast in a json file, a type of Python file.

I used this in my code by calling the specific elements I wanted from this file by using a specific Python command. Lastly, I then formatted these elements onto my big display screen using some Python formatting code.

Code for Weather API

class WeatherClass(Frame):
def __init__(self, parent, *args, **kwargs):
Frame.__init__(self, parent, bg=’black’)
self.temperature = ”
self.forecast = ”
self.location = ”
self.currently = ”
self.icon = ”
self.degreeFrm = Frame(self, bg=”black”)
self.degreeFrm.pack(side=TOP, anchor=W)
self.temperatureLbl = Label(self.degreeFrm, font=(‘Helvetica’, xlarge_text_size), fg=”white”, bg=”black”)
self.temperatureLbl.pack(side=LEFT, anchor=N)
self.iconLbl = Label(self.degreeFrm, bg=”black”)
self.iconLbl.pack(side=LEFT, anchor=N, padx=20)
self.currentlyLbl = Label(self, font=(‘Helvetica’, medium_text_size), fg=”white”, bg=”black”)
self.currentlyLbl.pack(side=TOP, anchor=W)
self.forecastLbl = Label(self, font=(‘Helvetica’, small_text_size), fg=”white”, bg=”black”)
self.forecastLbl.pack(side=TOP, anchor=W)
self.locationLbl = Label(self, font=(‘Helvetica’, small_text_size), fg=”white”, bg=”black”)
self.locationLbl.pack(side=TOP, anchor=W)

#def get_ip(self):
# try:
# ip_url = “
# req = requests.get(ip_url)
# ip_json = json.loads(req.text)
# return ip_json[‘ip’]
# except Exception as e:
# traceback.print_exc()
# return “Error: %s. Cannot get ip.” % e

def get_weather(self):

if latitude is None and longitude is None:
# get location
location_req_url = “” % self.get_ip()
r = requests.get(location_req_url)
location_obj = json.loads(r.text)

lat = location_obj[‘latitude’]
lon = location_obj[‘longitude’]

location2 = “%s, %s” % (location_obj[‘city’], location_obj[‘region_code’])

# get weather
weather_req_url = “,%s?lang=%s&units=%s” % (weather_api_token, lat,lon,weather_lang,weather_unit)
location2 = “”
# get weather
weather_req_url =”

r = requests.get(weather_req_url)
weather_obj = json.loads(r.text)

degree_sign= u’\N{DEGREE SIGN}’
temperature2 = “%s%s” % (str(int((int(weather_obj[‘main’][‘temp’])-273.15)*1.8+32)), degree_sign)
#print (temperature2)
currently2 = weather_obj[‘weather’][0][‘description’]
#print (currently2)
forecast2 = weather_obj[“wind”][“speed”]
#print (forecast2)

icon_id = weather_obj[‘weather’][0][‘icon’]
#print (icon_id)
icon2 = None

if icon_id in icon_lookup:
icon2 = icon_lookup[icon_id]
#print (icon2)

if icon2 is not None:
if self.icon != icon2:
self.icon = icon2
image =
image = image.resize((100, 100), Image.ANTIALIAS)
image = image.convert(‘RGB’)
#print (image)
photo = ImageTk.PhotoImage(image)
#print (photo)

self.iconLbl.image = photo
else :
# remove image

if self.currently != currently2:
self.currently = currently2
if self.forecast != forecast2:
self.forecast = forecast2
if self.temperature != temperature2:
self.temperature = temperature2
if self.location != location2:
if location2 == “, “:
self.location = “Cannot Pinpoint Location”
self.locationLbl.config(text=”Cannot Pinpoint Location”)
self.location = location2

except Exception as e:
print (“Error: %s. Cannot get weather.”) % e

self.after(600000, self.get_weather)

def convert_kelvin_to_fahrenheit(kelvin_temp):
return 1.8 * (kelvin_temp – 273) + 32

HDMI Display Issues

Throughout the process to get my Smart Mirror base built, I encountered many HDMI Display issues with the Raspberry Pi 3 and my HDMI Display. Listed below are many of the problems I encountered, and how I fixed them.

Code of Config.txt

# For more options and information see
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default “safe” mode

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border

# uncomment to force a console size. By default it will be display’s size minus
# overscan.

# uncomment if hdmi display is not detected and composite is being output

# uncomment to force a specific HDMI mode (this will force VGA)

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display

# uncomment for composite PAL

#uncomment to overclock the arm. 700 MHz is the default.

# Uncomment some or all of these to enable the optional hardware interfaces

# Uncomment this to enable infrared communication.

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)

# Enable DRM VC4 V3D driver on top of the dispmanx display stack




Specific HDMI Problems

Background: After getting my Raspberry Pi 3 set up with the original HDMI Display working, I realized I had to get my display replaced with a bigger one because a bigger display was more practical for building my project, a Smart Mirror. After getting my new display(10.1 inches!), the problems started rolling in.

First problem: After receiving my bigger display, I tried hooking up the Raspberry Pi 3 to this new display. However, initially, it did not work and displayed No Signal. I was very puzzled, and then proceeded to try and hook up the Raspberry Pi to my TV, a different HDMI display. The Raspberry Pi worked on the TV, but again, when I tried to do it on my 10.1 inch display, it did not work. As a result, I initially thought the issue had something to do with the power source, since the 10.1 inch display and the Raspberry Pi 3 were getting power from the same source, while the TV got power from a different source. However, after some research, I found out that it was not a power issue because if it was, the Raspberry Pi’s red light would blink, and it was not blinking. This made me very confused because I did not know what was causing this No Signal issue. However, after some playing with the display, I realized the issue was that I was not on the right channel the entire time, and after switching to the display’s HDMI channel, it worked.

Second Problem: All seemed to go well, until again I encountered another No Signal. After checking that I was on the right channel, I decided to fix this by editing config.txt in the Raspberry Pi. I uncommented the comment that said hdmi_safe=1. After this, my display started working again.

Second Problem Part 2: However, I encountered another issue from this. My display had a black border around it, and it seemed to be squishing the Smart Mirror Screen together so that it was very small. Initially, I tried to disable overscan, because that was what all sources told me to do. However, I realized that the Raspberry Pi was not letting me disable overscan for some odd reason. After fiddling around, I noticed that my display was outputting the Raspberry Pi in 640×480 resolution, not the display’s actual resolution. I tried changing the resolution, but it did not let me change the resolution as well. I then realized that this was because hdmi_safe=1 was putting my Raspberry Pi into safe mode, which could only operate on one specific set of settings that wouldn’t let me change the resolution. After this, I researched what hdmi_safe did, and realized that I could replace hdmi_safe with multiple lines of code which would imitate what hdmi_safe does, except without the restrictions of the same resolution. After replacing these lines of code, I was able to change the resolution, the black border disappeared, and the Smart Mirror Screen was working great again.

First Milestone

My First Milestone was to get my Raspberry Pi 3 working and hooked up to my HDMI display. The Raspberry Pi is basically a mini computer; it allows you to access web browsers, play games, edit code, and do much more. To get my Raspberry Pi 3 started, I had to download the OS to an SD card, then insert this SD card into the Raspberry Pi, which I then connected to a power source. After this, I just connected the HDMI display to the Raspberry Pi, and I also connected a mouse and keyboard to it.

Technical Difficulties Encountered In Setup

The Raspberry Pi 3 booted up fine, but my challenges started when I tried to connect it to my HDMI display. At first, when I plugged in the HDMI cable, my display was displaying ‘No Signal’, with a blue screen. Because of this, to troubleshoot this, I first re-wrote the OS onto my SD card. Then, I tried again, but it was still displaying no signal. After this, I attempted to use a different HDMI display(and in the process, changed the power source), but it still displayed ‘No Signal’ on this new HDMI display.

After trying with the new HDMI display, I just connected my Raspberry Pi back to my original power source and re-connected it with my original HDMI display, then it started working, and I was able to go through the initial configuration settings. I do not know exactly why this fixed itself, but have a few guesses, one being that it may have been related to the power source. This is because now, when I plug my Raspberry Pi into another power source, the display will show ‘No Signal’, but when I plug it into my original power source, the display will work.

Start typing and press Enter to search

Bluestamp Engineering