Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Raspberry pi zero w used with an inkyphat e-ink display

Using the raspberry pi zero w with an inkyphat e-ink display



My name's Nikhil. I'm a JavaScript developer who doesn't know any python - I hacked this script together till I got something I liked due to just wanting something that worked, and haven't touched this code since due to having a thing that worked. If you end up improving it, I'd really appreciate a shout.

I've written a post about it here

If you end up making this, or improving this hacky script, I'd love to hear from you. My twitter is @nkhil

The script

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import glob
import time
import argparse
from inky import InkyPHAT
from PIL import Image, ImageDraw, ImageFont
from font_fredoka_one import FredokaOne

    import requests
except ImportError:
    exit("This script requires the requests module\nInstall with: sudo pip install requests")

    import geocoder
except ImportError:
    exit("This script requires the geocoder module\nInstall with: sudo pip install geocoder")

    from bs4 import BeautifulSoup
except ImportError:
    exit("This script requires the bs4 module\nInstall with: sudo pip install beautifulsoup4")

print("""Inky pHAT: Weather

Displays weather information for a given location. The default location is Sheffield-on-Sea.


# Command line arguments to set display colour

# parser = argparse.ArgumentParser()
# parser.add_argument('--colour', '-c', type=str, required=True, choices=["red", "black", "yellow"], help="ePaper display colour")
# args = parser.parse_args()

# Set up the display

colour = "black"
inky_display = InkyPHAT(colour)

# Details to customise your weather display

CITY = "London"

# Convert a city name and country code to latitude and longitude

def get_coords(address):
    g = geocoder.arcgis(address)
    coords = g.latlng
    return coords

# Query Dark Sky ( to scrape current weather data

def get_weather(address):
    coords = get_coords(address)
    weather = {}
    res = requests.get(
        "{}/uk212/en".format(",".join([str(c) for c in coords])))
    if res.status_code == 200:
        soup = BeautifulSoup(res.content, "lxml")
        curr = soup.find_all("span", "currently")
        weather["summary"] = curr[0].img["alt"].split()[0]
        weather["temperature"] = int(curr[0].find(
            "span", "summary").text.split()[0][:-1])
        # press = soup.find_all("div", "pressure")
        # weather["pressure"] = int(press[0].find("span", "num").text)
        return weather
        return weather

def create_mask(source, mask=(inky_display.WHITE, inky_display.BLACK, inky_display.RED)):
    """Create a transparency mask.

    Takes a paletized source image and converts it into a mask
    permitting all the colours supported by Inky pHAT (0, 1, 2)
    or an optional list of allowed colours.

    :param mask: Optional list of Inky pHAT colours to allow.

    mask_image ="1", source.size)
    w, h = source.size
    for x in range(w):
        for y in range(h):
            p = source.getpixel((x, y))
            if p in mask:
                mask_image.putpixel((x, y), 255)

    return mask_image

# Dictionaries to store our icons and icon masks in
icons = {}
masks = {}

# Get the weather data for the given location
location_string = "{city}, {countrycode}".format(
    city=CITY, countrycode=COUNTRYCODE)
weather = get_weather(location_string)

# This maps the weather summary from Dark Sky
# to the appropriate weather icons
icon_map = {
    "snow": ["snow", "sleet"],
    "rain": ["rain"],
    "cloud": ["fog", "cloudy", "partly-cloudy-day", "partly-cloudy-night"],
    "sun": ["clear-day", "clear-night"],
    "storm": [],
    "wind": ["wind"]

# Placeholder variables
pressure = 0
temperature = 0
weather_icon = None

if weather:
    temperature = weather["temperature"]
    # pressure = weather["pressure"]
    summary = weather["summary"]

    for icon in icon_map:
        if summary in icon_map[icon]:
            weather_icon = icon

    print("Warning, no weather information found!")

# Create a new canvas to draw on
# img ="resources/backdrop.png")
img ="P", (inky_display.WIDTH, inky_display.HEIGHT))
draw = ImageDraw.Draw(img)

# Load our icon files and generate masks
for icon in glob.glob("resources/icon-*.png"):
    icon_name = icon.split("icon-")[1].replace(".png", "")
    icon_image =
    icons[icon_name] = icon_image
    masks[icon_name] = create_mask(icon_image)
# Load the FredokaOne font
font = ImageFont.truetype(FredokaOne, 22)

# Draw lines to frame the weather data
# draw.line((69, 36, 69, 81))       # Vertical line
# draw.line((31, 35, 184, 35))      # Horizontal top line
# draw.line((69, 58, 174, 58))      # Horizontal middle line
# draw.line((169, 58, 169, 58), 2)  # Red seaweed pixel :D

# Write text with weather values to the canvas
# datetime = time.strftime("%d/%m %H:%M")

# draw.text((36, 12), datetime, inky_display.WHITE, font=font)

# draw.text((72, 34), "T", inky_display.WHITE, font=font)
draw.text((92, 34), u"{}°".format(temperature), inky_display.WHITE if temperature <
          WARNING_TEMP else inky_display.RED, font=font)

# draw.text((72, 58), "P", inky_display.WHITE, font=font)
# draw.text((92, 58), "{}".format(pressure), inky_display.WHITE, font=font)

# Draw the current weather icon over the backdrop
if weather_icon is not None:
    img.paste(icons[weather_icon], (28, 36), masks[weather_icon])

    draw.text((28, 36), "?", inky_display.RED, font=font)

# Display the weather data on Inky pHAT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.