Here's an example of the wake-up light in use (for a late riser...)

First enter in the time you want to wake up each day of the week and save the file.

# type in time to get up  each day of the week
default_wake_up = "12:10P"
up_time_monday = default_wake_up
up_time_tuesday = default_wake_up
up_time_wednesday = default_wake_up
up_time_thursday = default_wake_up
up_time_friday = default_wake_up
up_time_saturday = "1:00P"
up_time_sunday = "1:00P"

That's it! The program does the rest of the work for you!

Before wake-up time

Current Time: 11:39AM

Wake-up time: 12:10PM

Light starting at 11:40AM

If the current time is before the "light on" time, the display's backlight should be off unless activated by touch, in which case the backlight comes on for 5 seconds then turns back off.

During wake-up time

Current Time: 11:40AM

Wake-up time: 12:10PM

Light starting at 11:40AM

If the current time = the "light on" time, the strip will turn on and get brighter every minute for 30 minutes until the wake-up time is reached.

After wake-up time

Current Time: 12:11PM

Wake-up time: 12:10PM

Light starting at 11:40AM

After the wake-up time is reached, tap the screen to turn off the strip and the next day's wake-up time will be displayed on the screen.

How it works

The wake-up light does quite a few tricks to deliver light at your wake-up time.

Displaying text

When the backlight is on, we see the current time, wake-up time and light-starting time displayed on the screen.

The fonts, color and locations of these text elements are initialized at the beginning of the program.

# assign fonts
big_font = bitmap_font.load_font(cwd+"/fonts/Nunito-Light-75.bdf")
big_font.load_glyphs(b'0123456789:AP') # pre-load glyphs for fast printing
print('loading fonts...')
info_font = bitmap_font.load_font(cwd+"/fonts/Nunito-Black-17.bdf")
info_font.load_glyphs(b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.:/ ')

time_color = 0xFFFFFF
time_position = (75,130)
time_textarea = Label(big_font, color=time_color,
                      x=time_position[0], y=time_position[1])

wakeup_time_color = 0xFFFFFF
wakeup_time_position = (15,200)
wakeup_time_textarea = Label(info_font, color=wakeup_time_color,
                             x=wakeup_time_position[0], y=wakeup_time_position[1])

light_on_time_color = 0xFFFFFF
light_on_time_position = (15,220)
light_on_time_textarea = Label(info_font, color=light_on_time_color,
                               x=light_on_time_position[0], y=light_on_time_position[1])


Text position

The PyPortal's display is 320 pixels wide and 240 pixels high. In order to refer to those positions on the screen, we use an x/y coordinate system, where x is horizontal and y is vertical.

The origin of this coordinate system is the upper left corner. This means that a pixel placed at the upper left corner would be (0,0) and the lower right corner would be (320, 240).


The fonts used here are bitmap fonts made from the Nunito typeface. You can learn more about converting type in this guide.

Text color

Customize your wake-up light by changing the text colors! You will need to use the hexidecimal value for any color you want to display.

You can use something like to pick your color and then copy the hex value.

Initializing wake-up times

This part of the program converts all the user-entered wake up times into time "objects" that can be easily manipulated later to add / subtract minutes, hours and days to the times!

# parse given time string into hour minute and AM_PM elements
def parseTime(time_before):
    hours_before, minutes_before = time_before.split(":")
    AM_PM_str = minutes_before[-1:]
    minutes_before = int(minutes_before[:-1])
    if (hours_before != '12') and AM_PM_str == 'P':
        hours_before = int(hours_before) + 12
    elif ((hours_before == '12') and (AM_PM_str == 'P')):
        hours_before = int(hours_before)
    elif ((hours_before == '12') and (AM_PM_str == 'A')):
        hours_before = 0
        hours_before = int(hours_before)
    parsed_time = [hours_before, minutes_before]
    return parsed_time

# get time objects for wake up times
val_times = []
parsed_times = []
for i in range(len(wake_up_times)):
    parsed_time_day = parseTime(wake_up_times[i])
    hours, minutes = parsed_time_day[0:2]
    now_day = time.localtime()
    time_obj_mk = time.mktime((now_day[0], now_day[1], now_day[2], hours,
                               minutes, now_day[5], i, now_day[7], now_day[8]))
    time_obj = time.localtime(time_obj_mk)

Main loop

while True:

In the repeating main loop, the following actions are performed:

  1. Declare a variable to reference local time.
  2. Query local time on first run and once an hour after.
  3. Display current time to screen.
  4. Determine which wake-up time to choose based on the current day.
  5. Turn on/off backlight depending on time.
  6. Get the time that is 30 min before the chosen wake-up time.
  7. If current day is same as wake-up day and wake-up time - 30 minutes equals current time, start the strip light.
  8. Increase brightness of light once a min for 30 min until light has reached maximum brightness. Also update the time.
  9. After wake-up time is reached, if user taps screen, turn off strip light.
  10. Delay for 1 second.
while True:
    time_now = time.localtime()
    # only query the online time once per hour (and on first run)
    if (not refresh_time) or (time.monotonic() - refresh_time) > 3600:
            print("Getting time from internet!")
            refresh_time = time.monotonic()
        except RuntimeError as e:
            print("Some error occured, retrying! -", e)
    time_str_text = displayTime()
    # determine which wake up time to choose based on the day
    wake_up_day = whichDay()
    # if time is more than 9 hours after previous day's wake up time,
    # backlight off and can tap to turn on
    # start the light 30 min before wake up time
    start_light_time = subtract30min(wake_up_day)
    # If current day is same as wake up day and 
    # wake up time - 30 minutes equals current time, start the light
    if wake_up_day == time_now[6] and time_str_text == start_light_time:
        print("Starting wake up light")
        # turn on backlight
        for i in range(light_minutes - 1):
            BRIGHTNESS = BRIGHTNESS + (MAX_BRIGHTNESS/light_minutes) # max 0.25, min 0.0
            strip.brightness = BRIGHTNESS
            time.sleep(60) # 60 for once per min
        while not pyportal.touchscreen.touch_point: # turn strip off
        strip.brightness = MIN_BRIGHTNESS
    # update every second so that screen can be tapped to view time

This guide was first published on Aug 07, 2019. It was last updated on Jul 13, 2024.

This page (Using the Wake-Up Light) was last updated on Apr 09, 2024.

Text editor powered by tinymce.