Last active
July 17, 2021 01:49
-
-
Save healeycodes/38c256c747eac46ac4ffc881e93bf095 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# a simple dashboard for the waveshare 2in7b screen | |
# to be ran inside: https://github.com/waveshare/e-Paper/tree/master/RaspberryPi%26JetsonNano/python/examples | |
# 1. install the latest versions of `pyowm` and `requests` | |
# 2. edit `OPEN_WEATHER_KEY`, `LOCATION`, and `NEWS_API_KEY` | |
import sys | |
import os | |
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic') | |
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib') | |
if os.path.exists(libdir): | |
sys.path.append(libdir) | |
import logging | |
from waveshare_epd import epd2in7b | |
import datetime | |
import time | |
import pyowm | |
import requests | |
import textwrap | |
from PIL import Image, ImageDraw, ImageFont | |
logging.basicConfig(level=logging.DEBUG) | |
OPEN_WEATHER_KEY = 'xxx' | |
LOCATION = 'xxx' | |
NEWS_API_KEY = 'xxx' | |
FONT_LARGER = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 19) | |
FONT_SMALLER = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 16) | |
def get_weather(): | |
''' | |
Get the formatted weather description. | |
E.g. `Richmond, GB: Clear sky` | |
''' | |
owm = pyowm.OWM(OPEN_WEATHER_KEY) | |
observation = owm.weather_at_place(LOCATION) | |
w = observation.get_weather() | |
detailed = w.get_detailed_status().capitalize() | |
temp_data = w.get_temperature('celsius') | |
current_temp = str(temp_data["temp"]) | |
min_temp = str(temp_data["temp_min"]) | |
max_temp = str(temp_data["temp_max"]) | |
text = '{}: {}\n{}°C ({}°C - {}°C)' | |
return text.format(LOCATION, detailed, current_temp, min_temp, max_temp) | |
def get_news(limit=3): | |
''' | |
Get some news headlines from the BBC formatted in a list. | |
E.g. `- Acclaimed Swedish author Per Olov Enquist dies | |
- PM's return to work 'a boost for the country' | |
- 'Myth that Sweden has not taken serious steps'` | |
''' | |
url = 'https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey={}'.format(NEWS_API_KEY) | |
resp = requests.get(url=url) | |
data = resp.json() | |
articles = [article['title'] for article in data['articles'][:limit]] | |
wrapper = textwrap.TextWrapper(width=33) | |
text = '' | |
for headline in articles: | |
text += '- {}\n'.format(wrapper.fill(text=headline)) | |
return '{}\n'.format(text) | |
def show_text(epd, top_text='', bottom_text=''): | |
''' | |
Given an EPD instance, and sections of text, render the text. | |
''' | |
HBlackImage = Image.new('1', (epd2in7b.EPD_HEIGHT, epd2in7b.EPD_WIDTH), 255) | |
HRedImage = Image.new('1', (epd2in7b.EPD_HEIGHT, epd2in7b.EPD_WIDTH), 255) | |
# render the black section | |
black_draw = ImageDraw.Draw(HBlackImage) | |
black_draw.text((1, 1), top_text, font=FONT_LARGER, fill=0) | |
# calculate the depth of the black section | |
top_depth = black_draw.textsize(top_text, font=FONT_LARGER)[1] + 5 | |
# render the red section under the black section | |
red_draw = ImageDraw.Draw(HRedImage) | |
red_draw.text((1, top_depth), bottom_text, font=FONT_SMALLER, fill=0) | |
epd.display(epd.getbuffer(HBlackImage), epd.getbuffer(HRedImage)) | |
def main(): | |
try: | |
epd = epd2in7b.EPD() | |
logging.info("Init and Clear") | |
epd.init() | |
epd.Clear() | |
show_text(epd, top_text=get_weather(), bottom_text=get_news()) | |
# leave the dashboard up for half an hour | |
time.sleep(60*30) | |
logging.info("Clear...") | |
epd.init() | |
epd.Clear() | |
except IOError as e: | |
logging.info(e) | |
sys.exit() | |
except KeyboardInterrupt: | |
logging.info("ctrl + c:") | |
epd2in7b.epdconfig.module_exit() | |
sys.exit() | |
while True: | |
t = datetime.datetime.now() | |
# rest the screen outside this range | |
if 7 <= t.hour <= 22: | |
# update the dashboard | |
main() | |
else: | |
time.sleep(30) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment