From 1c84a32b1cb544bb2067e7dd0b84591cdd961a37 Mon Sep 17 00:00:00 2001 From: thirdr Date: Tue, 3 Dec 2024 11:10:31 +0000 Subject: [PATCH] Examples: replaced examples with no longer active API --- examples/inkylauncher/carbon_intensity.py | 120 ++++++++++++++++++++ examples/inkylauncher/daily_activity.py | 127 ---------------------- examples/inkylauncher/daily_xkcd.py | 69 ++++++++++++ examples/inkylauncher/main.py | 8 +- examples/inkylauncher/news_headlines.py | 2 +- examples/inkylauncher/random_joke.py | 121 --------------------- 6 files changed, 194 insertions(+), 253 deletions(-) create mode 100644 examples/inkylauncher/carbon_intensity.py delete mode 100644 examples/inkylauncher/daily_activity.py create mode 100644 examples/inkylauncher/daily_xkcd.py delete mode 100644 examples/inkylauncher/random_joke.py diff --git a/examples/inkylauncher/carbon_intensity.py b/examples/inkylauncher/carbon_intensity.py new file mode 100644 index 0000000..208b4fa --- /dev/null +++ b/examples/inkylauncher/carbon_intensity.py @@ -0,0 +1,120 @@ +""" +This example connects to the Carbon Intensity API to give you a regional +forecast of how your (UK) electricity is being generated and its carbon impact. + +Carbon Intensity API only reports data from the UK National Grid. + +Find out more about what the numbers mean at: +https://carbonintensity.org.uk/ + +Make sure to uncomment the correct size for your display! + +""" + +import urequests +import inky_frame + +graphics = None +WIDTH = None +HEIGHT = None + +# Length of time between updates in minutes. +# Frequent updates will reduce battery life! +UPDATE_INTERVAL = 240 + +# Set (the first half) of your UK postcode here +POSTCODE = "S9" + +URL = "https://api.carbonintensity.org.uk/regional/postcode/" + str(POSTCODE) + + +def update(): + global region, forecast, index, power_list, datetime_to, datetime_from + print(f"Requesting URL: {URL}") + r = urequests.get(URL) + # open the json data + j = r.json() + print("Data obtained!") + print(j) + + # parse the json data + region = j["data"][0]["shortname"] + + forecast = j["data"][0]["data"][0]["intensity"]["forecast"] + index = j["data"][0]["data"][0]["intensity"]["index"] + + power_list = [] + for power in j["data"][0]["data"][0]["generationmix"]: + power_list.append(power['perc']) + + datetime_to = j["data"][0]["data"][0]["to"].split("T") + datetime_from = j["data"][0]["data"][0]["from"].split("T") + + # close the socket + r.close() + + +def draw(): + # we're setting up our PicoGraphics buffer after we've made our RAM intensive https request + w, h = WIDTH, HEIGHT + graphics.set_pen(inky_frame.WHITE) + graphics.clear() + + # draw lines + graphics.set_pen(inky_frame.BLACK) + graphics.line(0, int((h / 100) * 0), w, int((h / 100) * 0)) + graphics.line(0, int((h / 100) * 50), w, int((h / 100) * 50)) + graphics.set_font("bitmap8") + graphics.text('100%', w - 40, 10, scale=2) + graphics.text('50%', w - 40, int((h / 100) * 50 + 10), scale=2) + + # draw bars + bar_colours = [ + inky_frame.ORANGE, + inky_frame.RED, + inky_frame.ORANGE, + inky_frame.RED, + inky_frame.BLUE, + inky_frame.ORANGE, + inky_frame.GREEN, + inky_frame.GREEN, + inky_frame.GREEN + ] + for p in power_list: + graphics.set_pen(bar_colours[power_list.index(p)]) + graphics.rectangle(int(power_list.index(p) * w / 9), int(h - p * (h / 100)), + int(w / 9), int(h / 100 * p)) + + # draw labels + graphics.set_font('sans') + # once in white for a background + graphics.set_pen(inky_frame.WHITE) + labels = ['biomass', 'coal', 'imports', 'gas', 'nuclear', 'other', 'hydro', 'solar', 'wind'] + graphics.set_thickness(4) + for label in labels: + graphics.text(f'{label}', int((labels.index(label) * w / 9) + (w / 9) / 2), h - 10, angle=270, scale=1) + # again in black + graphics.set_pen(inky_frame.BLACK) + labels = ['biomass', 'coal', 'imports', 'gas', 'nuclear', 'other', 'hydro', 'solar', 'wind'] + graphics.set_thickness(2) + for label in labels: + graphics.text(f'{label}', int((labels.index(label) * w / 9) + (w / 9) / 2), h - 10, angle=270, scale=1) + + # draw header + graphics.set_thickness(3) + graphics.set_pen(inky_frame.GREEN) + if index in ['high', 'very high']: + graphics.set_pen(inky_frame.RED) + if index in ['moderate']: + graphics.set_pen(inky_frame.ORANGE) + graphics.set_font("sans") + graphics.text('Carbon Intensity', 10, 35, scale=1.2, angle=0) + + # draw small text + graphics.set_pen(inky_frame.BLACK) + graphics.set_font("bitmap8") + graphics.text(f'Region: {region}', int((w / 2) + 30), 10, scale=2) + graphics.text(f'{forecast} gCO2/kWh ({index})', int((w / 2) + 30), 30, scale=2) + graphics.text(f'{datetime_from[0]} {datetime_from[1]} to {datetime_to[1]}', int((w / 2) + 30), 50, scale=2) + + graphics.update() diff --git a/examples/inkylauncher/daily_activity.py b/examples/inkylauncher/daily_activity.py deleted file mode 100644 index 265c4d4..0000000 --- a/examples/inkylauncher/daily_activity.py +++ /dev/null @@ -1,127 +0,0 @@ -import gc -import ujson -from urllib import urequest - -# Length of time between updates in Seconds. -# Frequent updates will reduce battery life! -UPDATE_INTERVAL = 240 - -# API URL -URL = "https://www.boredapi.com/api/activity" - -graphics = None -text = None - -gc.collect() - - -def display_quote(text, ox, oy, scale, wordwrap): - # Processing text is memory intensive - # so we'll do it one char at a time as we draw to the screen - line_height = 8 * scale - html = False - html_tag = "" - word = "" - space_width = graphics.measure_text(" ", scale=scale) - x = ox - y = oy - for char in text: - if char in "[]": - continue - if char == "<": - html = True - html_tag = "" - continue - if char == ">": - html = False - continue - if html: - if char in "/ ": - continue - html_tag += char - continue - if char in (" ", "\n") or html_tag == "br": - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap or char == "\n" or html_tag == "br": - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - word = "" - html_tag = "" - x += w + space_width - continue - - word += char - - # Last word - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap: - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - - -def update(): - global text - gc.collect() - - try: - # Grab the data - socket = urequest.urlopen(URL) - j = ujson.load(socket) - socket.close() - text = [j['activity'], j['type'], j['participants']] - gc.collect() - except OSError: - pass - - -def draw(): - global text - - WIDTH, HEIGHT = graphics.get_bounds() - - # Clear the screen - graphics.set_pen(1) - graphics.clear() - graphics.set_pen(0) - - # Page lines! - graphics.set_pen(3) - graphics.line(0, 65, WIDTH, 65) - for i in range(2, 13): - graphics.line(0, i * 35, WIDTH, i * 35) - - gc.collect() - - # Page margin - graphics.set_pen(4) - graphics.line(50, 0, 50, HEIGHT) - graphics.set_pen(0) - - # Main text - graphics.set_font("cursive") - graphics.set_pen(4) - graphics.set_font("cursive") - graphics.text("Activity Idea", 55, 30, WIDTH - 20, 2) - graphics.set_pen(0) - graphics.set_font("bitmap8") - - if text: - display_quote(text[0], 55, 170, 5, WIDTH - 20) - gc.collect() - graphics.set_pen(2) - graphics.text("Activity Type: " + text[1], 55, HEIGHT - 45, WIDTH - 20, 2) - graphics.text("Participants: " + str(text[2]), 400, HEIGHT - 45, WIDTH - 20, 2) - else: - graphics.set_pen(4) - graphics.rectangle(0, (HEIGHT // 2) - 20, WIDTH, 40) - graphics.set_pen(1) - graphics.text("Unable to get activity data!", 5, (HEIGHT // 2) - 15, WIDTH, 2) - graphics.text("Check your network settings in secrets.py", 5, (HEIGHT // 2) + 2, WIDTH, 2) - - graphics.update() - - gc.collect() diff --git a/examples/inkylauncher/daily_xkcd.py b/examples/inkylauncher/daily_xkcd.py new file mode 100644 index 0000000..6422290 --- /dev/null +++ b/examples/inkylauncher/daily_xkcd.py @@ -0,0 +1,69 @@ +import gc +import uos +import machine +import jpegdec +import sdcard +from urllib import urequest + +""" +xkcd daily + +You *must* insert an SD card into Inky Frame! +We need somewhere to save the jpg for display. + +Fetches a pre-processed XKCD daily image from: +https://pimoroni.github.io/feed2image/xkcd-daily.jpg + +See https://xkcd.com/ for more webcomics! +""" + +graphics = None +WIDTH = None +HEIGHT = None + +UPDATE_INTERVAL = 240 + +gc.collect() # We're really gonna need that RAM! + +FILENAME = "/sd/xkcd-daily.jpg" +ENDPOINT = "https://pimoroni.github.io/feed2image/xkcd-daily.jpg" + +sd_spi = machine.SPI(0, sck=machine.Pin(18, machine.Pin.OUT), mosi=machine.Pin(19, machine.Pin.OUT), miso=machine.Pin(16, machine.Pin.OUT)) +sd = sdcard.SDCard(sd_spi, machine.Pin(22)) +uos.mount(sd, "/sd") +gc.collect() # Claw back some RAM! + + +def update(): + url = ENDPOINT + + if (WIDTH, HEIGHT) != (600, 448): + url = url.replace("xkcd-", f"xkcd-{WIDTH}x{HEIGHT}-") + + socket = urequest.urlopen(url) + + # Stream the image data from the socket onto disk in 1024 byte chunks + # the 600x448-ish jpeg will be roughly ~24k, we really don't have the RAM! + data = bytearray(1024) + with open(FILENAME, "wb") as f: + while True: + if socket.readinto(data) == 0: + break + f.write(data) + socket.close() + gc.collect() # We really are tight on RAM! + + +def draw(): + + gc.collect() # For good measure... + + jpeg = jpegdec.JPEG(graphics) + + graphics.set_pen(1) + graphics.clear() + + jpeg.open_file(FILENAME) + jpeg.decode() + + graphics.update() diff --git a/examples/inkylauncher/main.py b/examples/inkylauncher/main.py index 6bfcc6f..b7092ad 100644 --- a/examples/inkylauncher/main.py +++ b/examples/inkylauncher/main.py @@ -60,7 +60,7 @@ def launcher(): graphics.set_pen(2) graphics.rectangle(30, HEIGHT - (220 + y_offset), WIDTH - 200, 50) graphics.set_pen(1) - graphics.text("C. Daily Activity", 35, HEIGHT - (205 + y_offset), 600, 3) + graphics.text("C. Daily XKCD", 35, HEIGHT - (205 + y_offset), 600, 3) graphics.set_pen(3) graphics.rectangle(30, HEIGHT - (160 + y_offset), WIDTH - 250, 50) @@ -70,7 +70,7 @@ def launcher(): graphics.set_pen(0) graphics.rectangle(30, HEIGHT - (100 + y_offset), WIDTH - 300, 50) graphics.set_pen(1) - graphics.text("E. Random Joke", 35, HEIGHT - (85 + y_offset), 600, 3) + graphics.text("E. Carbon Intensity", 35, HEIGHT - (85 + y_offset), 600, 3) graphics.set_pen(graphics.create_pen(220, 220, 220)) graphics.rectangle(WIDTH - 100, HEIGHT - (340 + y_offset), 70, 50) @@ -107,7 +107,7 @@ def launcher(): reset() if ih.inky_frame.button_c.read(): ih.inky_frame.button_c.led_on() - ih.update_state("daily_activity") + ih.update_state("daily_xkcd") time.sleep(0.5) reset() if ih.inky_frame.button_d.read(): @@ -117,7 +117,7 @@ def launcher(): reset() if ih.inky_frame.button_e.read(): ih.inky_frame.button_e.led_on() - ih.update_state("random_joke") + ih.update_state("carbon_intensity") time.sleep(0.5) reset() diff --git a/examples/inkylauncher/news_headlines.py b/examples/inkylauncher/news_headlines.py index 6aad9b0..e1cb529 100644 --- a/examples/inkylauncher/news_headlines.py +++ b/examples/inkylauncher/news_headlines.py @@ -148,7 +148,7 @@ def draw(): graphics.set_pen(3) graphics.text(feed[0]["description"], 10, 135 if graphics.measure_text(feed[0]["title"]) < 650 else 90, WIDTH - 150, 2) - graphics.text(feed[1]["description"], 130, 320 if graphics.measure_text(feed[1]["title"]) < 650 else 230, WIDTH - 145, 2) + graphics.text(feed[1]["description"], 130, 320 if graphics.measure_text(feed[1]["title"]) < 650 else 340, WIDTH - 145, 2) graphics.line(10, 215, WIDTH - 10, 215) diff --git a/examples/inkylauncher/random_joke.py b/examples/inkylauncher/random_joke.py deleted file mode 100644 index 86388c1..0000000 --- a/examples/inkylauncher/random_joke.py +++ /dev/null @@ -1,121 +0,0 @@ -import gc -import random -from urllib import urequest -from ujson import load -import qrcode - -gc.collect() # We're really gonna need that RAM! - -graphics = None - -WIDTH = 0 -HEIGHT = 0 - -FILENAME = "random-joke.jpg" - -JOKE_IDS = "https://pimoroni.github.io/feed2image/jokeapi-ids.txt" -JOKE_IMG = "https://pimoroni.github.io/feed2image/jokeapi-{}.json" - -UPDATE_INTERVAL = 60 - -gc.collect() # Claw back some RAM! - -# We don't have the RAM to store the list of Joke IDs in memory. -# the first line of `jokeapi-ids.txt` is a COUNT of IDs. -# Grab it, then pick a random line between 0 and COUNT. -# Seek to that line and ...y'know... there's our totally random joke ID - -joke = [] - - -def measure_qr_code(size, code): - w, h = code.get_size() - module_size = int(size / w) - return module_size * w, module_size - - -def draw_qr_code(ox, oy, size, code): - size, module_size = measure_qr_code(size, code) - graphics.set_pen(1) - graphics.rectangle(ox, oy, size, size) - graphics.set_pen(0) - for x in range(size): - for y in range(size): - if code.get_module(x, y): - graphics.rectangle(ox + x * module_size, oy + y * module_size, module_size, module_size) - - -def update(): - global joke - - try: - socket = urequest.urlopen(JOKE_IDS) - except OSError: - return - - # Get the first line, which is a count of the joke IDs - number_of_lines = int(socket.readline().decode("ascii")) - print("Total jokes {}".format(number_of_lines)) - - # Pick a random joke (by its line number) - line = random.randint(0, number_of_lines) - print("Getting ID from line {}".format(line)) - - for x in range(line): # Throw away lines to get where we need - socket.readline() - - # Read our chosen joke ID! - random_joke_id = int(socket.readline().decode("ascii")) - socket.close() - - print("Random joke ID: {}".format(random_joke_id)) - - url = JOKE_IMG.format(random_joke_id) - - gc.collect() - - # Grab the data - try: - socket = urequest.urlopen(url) - gc.collect() - j = load(socket) - socket.close() - joke = j - del j - gc.collect() - except OSError as e: - print(e) - - -def draw(): - - code = qrcode.QRCode() - graphics.set_pen(1) - graphics.clear() - - if joke: - if joke['type'] == "single": - graphics.set_pen(4) - graphics.text(joke['joke'], 10, 10, WIDTH - 75, 5) - if joke['type'] == "twopart": - graphics.set_pen(4) - graphics.text(joke['setup'], 10, 10, WIDTH - 75, 5) - graphics.set_pen(3) - graphics.text(joke['delivery'], 10, 250, WIDTH - 75, 5) - - graphics.set_pen(0) - # Donate link QR - code.set_text("https://github.com/sponsors/Sv443") - draw_qr_code(WIDTH - 75, HEIGHT - 75, 75, code) - - graphics.text("curated by jokeapi.dev", 10, HEIGHT - 15, WIDTH, 1) - graphics.text("donate <3", WIDTH - 65, HEIGHT - 12, WIDTH, 1) - - else: - graphics.set_pen(4) - graphics.rectangle(0, (HEIGHT // 2) - 20, WIDTH, 40) - graphics.set_pen(1) - graphics.text("Unable to display random joke!", 5, (HEIGHT // 2) - 15, WIDTH, 2) - graphics.text("Check your network settings in secrets.py", 5, (HEIGHT // 2) + 2, WIDTH, 2) - - graphics.update()