kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Inky Frame: MicroPython Examples.
Co-authored-by: thirdr <ryan@pimoroni.com>pull/445/head
rodzic
e519396876
commit
afea765b71
|
@ -0,0 +1,63 @@
|
|||
# Pico Enviro+ MicroPython Examples <!-- omit in toc -->
|
||||
|
||||
- [PicoGraphics](#picographics)
|
||||
- [Examples](#examples)
|
||||
- [Daily Activity](#daily-activity)
|
||||
- [News](#news)
|
||||
- [PlaceKitten](#placekitten)
|
||||
- [Quote of the Day](#quote-of-the-day)
|
||||
- [Random Joke](#random-joke)
|
||||
- [XKCD Daily](#xkcd-daily)
|
||||
|
||||
## PicoGraphics
|
||||
|
||||
You can draw on Inky Frame using our tiny PicoGraphics display library.
|
||||
- [PicoGraphics MicroPython function reference](../../modules/picographics)
|
||||
|
||||
## Examples
|
||||
|
||||
The examples need `network_manager.py` and `WIFI_CONFIG.py` from the `common` directory to be saved to your Pico W. Open up `WIFI_CONFIG.py` in Thonny to add your wifi details (and save it when you're done).
|
||||
|
||||
You'll also need to install the `micropython-urllib.urequest` library using Thonny's 'Tools' > 'Manage Packages' or `common/lib/urllib` which contains a compiled `.mpy` version that uses less RAM. You should place this directory in `lib` on your Pico W.
|
||||
|
||||
Finally for examples loading images, you'll need `sdcard.mpy` from `common/lib`. You should place this file in `lib` on your Pico W.
|
||||
|
||||
### Daily Activity
|
||||
[inky_frame_daily_activity.py](inky_frame_daily_activity.py)
|
||||
|
||||
### News
|
||||
[inky_frame_news.py](inky_frame_news.py)
|
||||
|
||||
Display headlines from BBC news.
|
||||
|
||||
### PlaceKitten
|
||||
[inky_frame_placekitten.py](inky_frame_placekitten.py)
|
||||
|
||||
Download a random (from a small subset) image from PlaceKitten.
|
||||
|
||||
### Quote of the Day
|
||||
[inky_frame_quote_of_the_day.py](inky_frame_quote_of_the_day.py)
|
||||
|
||||
Load the WikiQuotes Quote of the Day and display it.
|
||||
|
||||
### Random Joke
|
||||
[inky_frame_random_joke.py](inky_frame_random_joke.py)
|
||||
|
||||
Load a random joke from JokeAPI.dev and display it.
|
||||
|
||||
Jokes are rendered into images "offline" by our feed2image service for two reasons:
|
||||
|
||||
1. Saves the Pico W having to process them
|
||||
2. JokeAPI.dev needs TLS1.3 which Pico W does not support!
|
||||
|
||||
For bugs/contributions or to complain about a joke, see: https://github.com/pimoroni/feed2image
|
||||
|
||||
### XKCD Daily
|
||||
[inky_frame_xkcd_daily.py](inky_frame_xkcd_daily.py)
|
||||
|
||||
Download and display the daily webcomic from https://xkcd.com/
|
||||
|
||||
The webcomic is rendered "offline" by our feed2image service since xkcd.com requires TLS1.3!
|
||||
|
||||
For bugs/contributions see: https://github.com/pimoroni/feed2image
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SSID = "YOUR_WIFI_SSID"
|
||||
PSK = "YOUR_WIFI_PASSWORD"
|
||||
COUNTRY = "YOUR_COUNTRY_CODE"
|
|
@ -0,0 +1,138 @@
|
|||
import gc
|
||||
import WIFI_CONFIG
|
||||
from network_manager import NetworkManager
|
||||
import uasyncio
|
||||
import ujson
|
||||
from urllib import urequest
|
||||
from picographics import PicoGraphics, DISPLAY_INKY_FRAME
|
||||
from machine import Pin
|
||||
from pimoroni_i2c import PimoroniI2C
|
||||
from pcf85063a import PCF85063A
|
||||
|
||||
|
||||
I2C_SDA_PIN = 4
|
||||
I2C_SCL_PIN = 5
|
||||
HOLD_VSYS_EN_PIN = 2
|
||||
|
||||
# set up and enable vsys hold so we don't go to sleep
|
||||
hold_vsys_en_pin = Pin(HOLD_VSYS_EN_PIN, Pin.OUT)
|
||||
hold_vsys_en_pin.value(True)
|
||||
|
||||
# intialise the pcf85063a real time clock chip
|
||||
i2c = PimoroniI2C(I2C_SDA_PIN, I2C_SCL_PIN, 100000)
|
||||
rtc = PCF85063A(i2c)
|
||||
|
||||
# Length of time between updates in Seconds.
|
||||
# Frequent updates will reduce battery life!
|
||||
UPDATE_INTERVAL = 60 * 1
|
||||
|
||||
# API URL
|
||||
URL = "https://www.boredapi.com/api/activity"
|
||||
|
||||
|
||||
def status_handler(mode, status, ip):
|
||||
print(mode, status, ip)
|
||||
|
||||
|
||||
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
|
||||
|
||||
gc.collect()
|
||||
graphics = PicoGraphics(DISPLAY_INKY_FRAME)
|
||||
WIDTH, HEIGHT = graphics.get_bounds()
|
||||
graphics.set_font("cursive")
|
||||
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)
|
||||
|
||||
|
||||
rtc.enable_timer_interrupt(True)
|
||||
|
||||
while True:
|
||||
# Connect to WiFi
|
||||
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
|
||||
|
||||
# Clear the screen
|
||||
graphics.set_pen(1)
|
||||
graphics.clear()
|
||||
graphics.set_pen(0)
|
||||
|
||||
# Grab the data
|
||||
socket = urequest.urlopen(URL)
|
||||
j = ujson.load(socket)
|
||||
socket.close()
|
||||
|
||||
text = [j['activity'], j['type'], j['participants']]
|
||||
|
||||
# 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)
|
||||
|
||||
# Page margin
|
||||
graphics.set_pen(4)
|
||||
graphics.line(50, 0, 50, HEIGHT)
|
||||
graphics.set_pen(0)
|
||||
|
||||
# Main text
|
||||
graphics.set_pen(4)
|
||||
graphics.text("Activity Idea", 55, 30, WIDTH - 20, 2)
|
||||
graphics.set_pen(0)
|
||||
graphics.set_font("bitmap8")
|
||||
display_quote(text[0], 55, 170, 5, WIDTH - 20)
|
||||
|
||||
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)
|
||||
|
||||
graphics.update()
|
||||
|
||||
# Time to have a little nap until the next update
|
||||
rtc.set_timer(UPDATE_INTERVAL)
|
||||
hold_vsys_en_pin.init(Pin.IN)
|
|
@ -0,0 +1,188 @@
|
|||
from picographics import PicoGraphics, DISPLAY_INKY_FRAME
|
||||
from network_manager import NetworkManager
|
||||
import uasyncio
|
||||
from urllib import urequest
|
||||
import WIFI_CONFIG
|
||||
import gc
|
||||
import qrcode
|
||||
from machine import Pin
|
||||
from pimoroni_i2c import PimoroniI2C
|
||||
from pcf85063a import PCF85063A
|
||||
|
||||
I2C_SDA_PIN = 4
|
||||
I2C_SCL_PIN = 5
|
||||
HOLD_VSYS_EN_PIN = 2
|
||||
|
||||
# set up and enable vsys hold so we don't go to sleep
|
||||
hold_vsys_en_pin = Pin(HOLD_VSYS_EN_PIN, Pin.OUT)
|
||||
hold_vsys_en_pin.value(True)
|
||||
|
||||
# Uncomment one URL to use (Top Stories, World News and technology)
|
||||
# URL = "http://feeds.bbci.co.uk/news/rss.xml"
|
||||
# URL = "http://feeds.bbci.co.uk/news/world/rss.xml"
|
||||
URL = "http://feeds.bbci.co.uk/news/technology/rss.xml"
|
||||
|
||||
# Length of time between updates in Seconds.
|
||||
# Frequent updates will reduce battery life!
|
||||
UPDATE_INTERVAL = 60 * 1
|
||||
|
||||
graphics = PicoGraphics(DISPLAY_INKY_FRAME)
|
||||
WIDTH, HEIGHT = graphics.get_bounds()
|
||||
graphics.set_font("bitmap8")
|
||||
code = qrcode.QRCode()
|
||||
|
||||
# intialise the pcf85063a real time clock chip
|
||||
i2c = PimoroniI2C(I2C_SDA_PIN, I2C_SCL_PIN, 100000)
|
||||
rtc = PCF85063A(i2c)
|
||||
|
||||
|
||||
def status_handler(mode, status, ip):
|
||||
print(mode, status, ip)
|
||||
|
||||
|
||||
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
|
||||
|
||||
|
||||
def read_until(stream, char):
|
||||
result = b""
|
||||
while True:
|
||||
c = stream.read(1)
|
||||
if c == char:
|
||||
return result
|
||||
result += c
|
||||
|
||||
|
||||
def discard_until(stream, c):
|
||||
while stream.read(1) != c:
|
||||
pass
|
||||
|
||||
|
||||
def parse_xml_stream(s, accept_tags, group_by, max_items=3):
|
||||
tag = []
|
||||
text = b""
|
||||
count = 0
|
||||
current = {}
|
||||
while True:
|
||||
char = s.read(1)
|
||||
if len(char) == 0:
|
||||
break
|
||||
|
||||
if char == b"<":
|
||||
next_char = s.read(1)
|
||||
|
||||
# Discard stuff like <?xml vers...
|
||||
if next_char == b"?":
|
||||
discard_until(s, b">")
|
||||
continue
|
||||
|
||||
# Detect <![CDATA
|
||||
elif next_char == b"!":
|
||||
s.read(1) # Discard [
|
||||
discard_until(s, b"[") # Discard CDATA[
|
||||
text = read_until(s, b"]")
|
||||
discard_until(s, b">") # Discard ]>
|
||||
gc.collect()
|
||||
|
||||
elif next_char == b"/":
|
||||
current_tag = read_until(s, b">")
|
||||
top_tag = tag[-1]
|
||||
|
||||
# Populate our result dict
|
||||
if top_tag in accept_tags:
|
||||
current[top_tag.decode("utf-8")] = text.decode("utf-8")
|
||||
|
||||
# If we've found a group of items, yield the dict
|
||||
elif top_tag == group_by:
|
||||
yield current
|
||||
current = {}
|
||||
count += 1
|
||||
if count == max_items:
|
||||
return
|
||||
tag.pop()
|
||||
text = b""
|
||||
gc.collect()
|
||||
continue
|
||||
|
||||
else:
|
||||
current_tag = read_until(s, b">")
|
||||
tag += [next_char + current_tag.split(b" ")[0]]
|
||||
text = b""
|
||||
gc.collect()
|
||||
|
||||
else:
|
||||
text += char
|
||||
|
||||
|
||||
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 get_rss():
|
||||
try:
|
||||
stream = urequest.urlopen(URL)
|
||||
output = list(parse_xml_stream(stream, [b"title", b"description", b"guid", b"pubDate"], b"item"))
|
||||
return output
|
||||
|
||||
except OSError as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
|
||||
rtc.enable_timer_interrupt(True)
|
||||
|
||||
while True:
|
||||
# Connect to WiFi
|
||||
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
|
||||
|
||||
# Gets Feed Data
|
||||
feed = get_rss()
|
||||
|
||||
# Clear the screen
|
||||
graphics.set_pen(1)
|
||||
graphics.clear()
|
||||
graphics.set_pen(0)
|
||||
|
||||
# Title
|
||||
graphics.text("Headlines from BBC News:", 10, 10, 300, 2)
|
||||
|
||||
# Draws 3 articles from the feed if they're available.
|
||||
if feed:
|
||||
graphics.set_pen(4)
|
||||
graphics.text(feed[0]["title"], 10, 40, WIDTH - 150, 3 if graphics.measure_text(feed[0]["title"]) < 650 else 2)
|
||||
graphics.text(feed[1]["title"], 130, 180, WIDTH - 140, 3 if graphics.measure_text(feed[1]["title"]) < 650 else 2)
|
||||
graphics.text(feed[2]["title"], 10, 320, WIDTH - 150, 3 if graphics.measure_text(feed[2]["title"]) < 650 else 2)
|
||||
|
||||
graphics.set_pen(3)
|
||||
graphics.text(feed[0]["description"], 10, 110 if graphics.measure_text(feed[0]["title"]) < 650 else 90, WIDTH - 150, 2)
|
||||
graphics.text(feed[1]["description"], 130, 250 if graphics.measure_text(feed[1]["title"]) < 650 else 230, WIDTH - 145, 2)
|
||||
graphics.text(feed[2]["description"], 10, 395 if graphics.measure_text(feed[2]["title"]) < 650 else 375, WIDTH - 150, 2)
|
||||
|
||||
code.set_text(feed[0]["guid"])
|
||||
draw_qr_code(490, 40, 100, code)
|
||||
code.set_text(feed[1]["guid"])
|
||||
draw_qr_code(10, 180, 100, code)
|
||||
code.set_text(feed[2]["guid"])
|
||||
draw_qr_code(490, 320, 100, code)
|
||||
|
||||
else:
|
||||
graphics.set_pen(4)
|
||||
graphics.text("Error: Unable to get feed :(", 10, 40, WIDTH - 150, 4)
|
||||
|
||||
graphics.update()
|
||||
|
||||
# Time to have a little nap until the next update
|
||||
rtc.set_timer(UPDATE_INTERVAL)
|
||||
hold_vsys_en_pin.init(Pin.IN)
|
|
@ -0,0 +1,68 @@
|
|||
import gc
|
||||
import uos
|
||||
import random
|
||||
import machine
|
||||
import jpegdec
|
||||
import uasyncio
|
||||
import sdcard
|
||||
import WIFI_CONFIG
|
||||
from urllib import urequest
|
||||
from network_manager import NetworkManager
|
||||
from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY
|
||||
|
||||
"""
|
||||
random placekitten (from a very small set)
|
||||
|
||||
You *must* insert an SD card into Inky Frame!
|
||||
We need somewhere to save the jpg for display.
|
||||
"""
|
||||
|
||||
gc.collect() # We're really gonna need that RAM!
|
||||
|
||||
|
||||
def status_handler(mode, status, ip):
|
||||
print(mode, status, ip)
|
||||
|
||||
|
||||
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
|
||||
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
|
||||
|
||||
|
||||
graphics = PicoGraphics(DISPLAY)
|
||||
|
||||
WIDTH, HEIGHT = graphics.get_bounds()
|
||||
FILENAME = "/sd/placekitten.jpg"
|
||||
ENDPOINT = "http://placekitten.com/{0}/{1}"
|
||||
|
||||
|
||||
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!
|
||||
|
||||
url = ENDPOINT.format(WIDTH, HEIGHT + random.randint(0, 10))
|
||||
|
||||
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!
|
||||
|
||||
|
||||
jpeg = jpegdec.JPEG(graphics)
|
||||
gc.collect() # For good measure...
|
||||
|
||||
graphics.set_pen(1)
|
||||
graphics.clear()
|
||||
|
||||
jpeg.open_file(FILENAME)
|
||||
jpeg.decode()
|
||||
|
||||
graphics.update()
|
|
@ -0,0 +1,169 @@
|
|||
import gc
|
||||
import time
|
||||
import ujson
|
||||
import uasyncio
|
||||
import WIFI_CONFIG
|
||||
from urllib import urequest
|
||||
from network_manager import NetworkManager
|
||||
from picographics import PicoGraphics, DISPLAY_INKY_FRAME
|
||||
|
||||
|
||||
ENDPOINT = "https://en.wikiquote.org/w/api.php?format=json&action=expandtemplates&prop=wikitext&text={{{{Wikiquote:Quote%20of%20the%20day/{3}%20{2},%20{0}}}}}"
|
||||
MONTHNAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
||||
|
||||
|
||||
last_date = ""
|
||||
|
||||
|
||||
def parse_qotd(text):
|
||||
print(text)
|
||||
text = text.split("\n")
|
||||
author = text[8].split("|")[2][5:-4]
|
||||
text = text[6][2:]
|
||||
gc.collect()
|
||||
return text, author
|
||||
|
||||
|
||||
def status_handler(mode, status, ip):
|
||||
print(mode, status, ip)
|
||||
|
||||
|
||||
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
|
||||
|
||||
gc.collect()
|
||||
graphics = PicoGraphics(DISPLAY_INKY_FRAME)
|
||||
WIDTH, HEIGHT = graphics.get_bounds()
|
||||
graphics.set_font("bitmap8")
|
||||
gc.collect()
|
||||
|
||||
|
||||
BADCHARS = {
|
||||
"’": "'",
|
||||
"—": "",
|
||||
"…": "..."
|
||||
}
|
||||
|
||||
|
||||
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 = 9 * scale
|
||||
html_tag = ""
|
||||
word = ""
|
||||
extra_text = ""
|
||||
space_width = graphics.measure_text(" ", scale=scale)
|
||||
x = ox
|
||||
y = oy
|
||||
i = -1
|
||||
while True:
|
||||
if len(extra_text) == 0:
|
||||
i += 1
|
||||
if i >= len(text):
|
||||
break
|
||||
|
||||
if len(extra_text) > 0:
|
||||
char = extra_text[0]
|
||||
extra_text = extra_text[1:]
|
||||
else:
|
||||
char = text[i]
|
||||
|
||||
if char in BADCHARS:
|
||||
word += BADCHARS[char]
|
||||
continue
|
||||
|
||||
# Unpick stuff like [[word]] and [[disambiguation|word]]
|
||||
# and [[w:wikipedia_page|word]]
|
||||
# test cases: July 8th 2022, July 12th 2022
|
||||
if char == "[":
|
||||
if text[i:i + 2] == "[[":
|
||||
link = False
|
||||
if text[i + 2:i + 4] == "w:":
|
||||
link = True
|
||||
i += 2
|
||||
end = text[i:].index("]]")
|
||||
if "|" in text[i + 2:i + end]:
|
||||
parts = text[i + 2:i + end].split("|")
|
||||
word = parts[1]
|
||||
if not link:
|
||||
extra_text = " (" + parts[0] + ")"
|
||||
else:
|
||||
word = text[i + 2:i + end]
|
||||
i += end + 1
|
||||
continue
|
||||
|
||||
if char == "&":
|
||||
if text[i:i + 5] == "&":
|
||||
word += "&"
|
||||
i += 4
|
||||
continue
|
||||
|
||||
if char == "<":
|
||||
j = i + text[i:].index(">")
|
||||
html_tag = text[i + 1:j].replace("/", "").strip()
|
||||
i = j
|
||||
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)
|
||||
|
||||
|
||||
while True:
|
||||
gc.collect()
|
||||
|
||||
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
|
||||
|
||||
date = list(time.localtime())[:3]
|
||||
date.append(MONTHNAMES[date[1] - 1])
|
||||
|
||||
if "{3} {2}, {0}".format(*date) == last_date:
|
||||
time.sleep(60)
|
||||
continue
|
||||
|
||||
url = ENDPOINT.format(*date)
|
||||
print("Requesting URL: {}".format(url))
|
||||
socket = urequest.urlopen(url)
|
||||
j = ujson.load(socket)
|
||||
socket.close()
|
||||
|
||||
text = j['expandtemplates']['wikitext']
|
||||
del j
|
||||
gc.collect()
|
||||
|
||||
text, author = parse_qotd(text)
|
||||
|
||||
print(text)
|
||||
|
||||
graphics.set_pen(1)
|
||||
graphics.clear()
|
||||
graphics.set_pen(0)
|
||||
graphics.text("QoTD - {2} {3} {0:04d}".format(*date), 10, 10, scale=3)
|
||||
|
||||
display_quote(text, 10, 40, 2, wordwrap=WIDTH - 20)
|
||||
|
||||
graphics.text(author, 10, HEIGHT - 20, scale=2)
|
||||
|
||||
graphics.update()
|
||||
gc.collect()
|
||||
|
||||
last_date = "{3} {2}, {0}".format(*date)
|
||||
|
||||
time.sleep(60)
|
|
@ -0,0 +1,88 @@
|
|||
import gc
|
||||
import uos
|
||||
import random
|
||||
import machine
|
||||
import jpegdec
|
||||
import WIFI_CONFIG
|
||||
import uasyncio
|
||||
from network_manager import NetworkManager
|
||||
from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY
|
||||
from urllib import urequest
|
||||
|
||||
|
||||
gc.collect() # We're really gonna need that RAM!
|
||||
|
||||
|
||||
def status_handler(mode, status, ip):
|
||||
print(mode, status, ip)
|
||||
|
||||
|
||||
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
|
||||
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
|
||||
|
||||
|
||||
graphics = PicoGraphics(DISPLAY)
|
||||
|
||||
WIDTH, HEIGHT = graphics.get_bounds()
|
||||
FILENAME = "random-joke.jpg"
|
||||
|
||||
JOKE_IDS = "https://pimoroni.github.io/feed2image/jokeapi-ids.txt"
|
||||
JOKE_IMG = "https://pimoroni.github.io/feed2image/jokeapi-{}-600x448.jpg"
|
||||
|
||||
import sdcard # noqa: E402 - putting this at the top causes an MBEDTLS OOM error!?
|
||||
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!
|
||||
|
||||
# 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
|
||||
|
||||
socket = urequest.urlopen(JOKE_IDS)
|
||||
|
||||
# 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)
|
||||
|
||||
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()
|
||||
del data
|
||||
gc.collect() # We really are tight on RAM!
|
||||
|
||||
|
||||
jpeg = jpegdec.JPEG(graphics)
|
||||
gc.collect() # For good measure...
|
||||
|
||||
graphics.set_pen(1)
|
||||
graphics.clear()
|
||||
|
||||
jpeg.open_file(FILENAME)
|
||||
jpeg.decode()
|
||||
|
||||
graphics.update()
|
|
@ -0,0 +1,74 @@
|
|||
import gc
|
||||
import uos
|
||||
import random
|
||||
import machine
|
||||
import jpegdec
|
||||
import uasyncio
|
||||
import sdcard
|
||||
import WIFI_CONFIG
|
||||
from urllib import urequest
|
||||
from network_manager import NetworkManager
|
||||
from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY
|
||||
|
||||
"""
|
||||
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!
|
||||
"""
|
||||
|
||||
gc.collect() # We're really gonna need that RAM!
|
||||
|
||||
|
||||
def status_handler(mode, status, ip):
|
||||
print(mode, status, ip)
|
||||
|
||||
|
||||
network_manager = NetworkManager("GB", status_handler=status_handler)
|
||||
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
|
||||
|
||||
|
||||
graphics = PicoGraphics(DISPLAY)
|
||||
|
||||
WIDTH, HEIGHT = graphics.get_bounds()
|
||||
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!
|
||||
|
||||
|
||||
url = ENDPOINT.format(WIDTH, HEIGHT + random.randint(0, 10))
|
||||
|
||||
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!
|
||||
|
||||
|
||||
jpeg = jpegdec.JPEG(graphics)
|
||||
gc.collect() # For good measure...
|
||||
|
||||
graphics.set_pen(1)
|
||||
graphics.clear()
|
||||
|
||||
jpeg.open_file(FILENAME)
|
||||
jpeg.decode()
|
||||
|
||||
graphics.update()
|
Ładowanie…
Reference in New Issue