cc_rider
Major Contributor
- Joined
- Oct 20, 2022
- Messages
- 1,225
This is a slick little device, very much ups the game for displays with embedded controllers. Out of stock at the moment, I'm guessing it was much more popular than they anticipated.
Here's my first attempt at using Micropython code for this device, with the WiiM http API, to monitor the current track and album cover. Nothing fancy, I'll try using asyncio to make it update faster, but for now, "it just works", as has done for at least a week, even though I have my routers reboot every morning. If nothing's playing, it'll display the time and date after a few seconds.
Note that it doesn't have the processing power to resize JPGs or PNGs, so those are being done using an external web service (thanks, Paul Webster!).
I haven't attempted to do anything but display at this point, though it's a touchscreen, so has the possibility to be used as a remote control for the WiiM, as well.
The Presto comes pre-loaded with the necessary binaries, so you just need to load two files (via Thonny or another IDE) to get this working:
main.py
secrets.py:
The secrets.py entries are obvious; in my case, right now in California, time is -8 hours compared to GMT.
Pimoroni Presto - Beta Edition
Hey Presto - meet your new RP2350-powered, connected desktop companion! Presto features a 4" square (480 x 480 pixel) touchscreen, built into an elegant black aluminium stand with bonus RGB backlighting.
shop.pimoroni.com
Here's my first attempt at using Micropython code for this device, with the WiiM http API, to monitor the current track and album cover. Nothing fancy, I'll try using asyncio to make it update faster, but for now, "it just works", as has done for at least a week, even though I have my routers reboot every morning. If nothing's playing, it'll display the time and date after a few seconds.
Note that it doesn't have the processing power to resize JPGs or PNGs, so those are being done using an external web service (thanks, Paul Webster!).
I haven't attempted to do anything but display at this point, though it's a touchscreen, so has the possibility to be used as a remote control for the WiiM, as well.
The Presto comes pre-loaded with the necessary binaries, so you just need to load two files (via Thonny or another IDE) to get this working:
main.py
Python:
from picovector import ANTIALIAS_FAST, PicoVector, Polygon, Transform
import machine
from presto import Presto
import time
import utime
import math
import urequests as requests
import gc
import socket
import jpegdec
import pngdec
import json
import secrets
import ntptime
# Constants
WIIM_IP = secrets.WIIM_IP
TIMEOUT = 15
TIMEZONE_OFFSET = secrets.TIMEZONE_OFFSET * 3600
# Initialize Presto and Display
presto = Presto(ambient_light=False, full_res=True)
presto.set_backlight(0.2)
display = presto.display
WIDTH, HEIGHT = display.get_bounds()
CX, CY = WIDTH // 2, HEIGHT // 2
# Colors
BLACK = display.create_pen(0, 0, 0)
WHITE = display.create_pen(255, 255, 255)
GRAY = display.create_pen(60, 60, 60)
months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
days = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
display.set_pen(BLACK)
display.clear()
# Initialize PicoVector
vector = PicoVector(display)
vector.set_antialiasing(ANTIALIAS_FAST)
vector.set_font("Roboto-Medium.af", 14)
vector.set_font_letter_spacing(100)
vector.set_font_word_spacing(100)
transform = Transform()
#transform.scale(512,512)
vector.set_transform(transform)
# Initialize JPEG Decoder
jpd = jpegdec.JPEG(display)
pnd = pngdec.PNG(display)
def connect_to_wifi():
print("Connecting to WiFi")
status = str(presto.connect())
print("Connection status: "+ status)
# Get current time from NTP server
try:
ntptime.settime()
except:
print('Error updating time from NTP server')
def show_clock():
display.set_pen(BLACK)
display.clear()
timestamp = utime.mktime(utime.localtime()) + TIMEZONE_OFFSET
tm = utime.localtime(timestamp)
# Format date and time
date_str = "{:s} {:02d} {:s} {:d}".format(days[tm[6]], tm[2], months[tm[1]-1], tm[0])
time_str = "{:02d}:{:02d}".format(tm[3], tm[4])
display.set_pen(WHITE)
vector.set_font_size(200)
vector.text(time_str, 20, 240)
vector.set_font_size(60)
vector.text(date_str, 40, 360)
presto.update()
def printtext(x,y,txt):
display.set_pen(WHITE)
vector.set_font_size(20)
vector.text(txt, x, y)
def fetch_album_art(art_url):
gc.collect()
if "size=0" in art_url:
proxy_url = str(art_url[:-1]) + "420X420"
else:
proxy_url = "https://wsrv.nl/?url="+art_url+"&w=420&h=420"
response = requests.get(proxy_url, timeout=TIMEOUT)
if response.status_code == 200:
display.set_pen(BLACK)
display.clear()
album_art = response.content
try:
if ".png" in proxy_url:
pnd.open_RAM(memoryview(album_art))
pnd.decode(30,0)
else:
jpd.open_RAM(memoryview(album_art))
ret = jpd.decode(30, 0, jpegdec.JPEG_SCALE_FULL)
except Exception as e:
print("Fetch Art Error: ",e)
finally:
response.close()
gc.collect()
### Round corners of album cover
try:
rect = Polygon()
display.set_pen(BLACK)
rect.rectangle(20, -10, 440, 440, corners=(15,15,15,15), stroke=10)
vector.draw(rect)
except Exception as e:
print("rect error:",e)
else:
print("Failed to fetch album art")
display.set_pen(BLACK)
display.clear()
def update_display(title, artist):
display.set_pen(BLACK)
display.rectangle(0,420,WIDTH,60)
display.set_pen(WHITE)
vector.set_font_size(30)
vector.text(artist, 30, CY + 205)
vector.set_font_size(20)
vector.text(title, 30, CY + 225)
presto.update()
def main():
# Give enough time to breakout before wdt
#time.sleep(10)
# Reboot when non-responsive
#wdt = WDT(timeout=8388)
#wdt.feed()
connect_to_wifi()
show_clock()
old_album = ""
track = -1
queue = None
trackId = ""
title = ""
Title = ""
artist = ""
art_url = ""
state = ""
count = 0
gc.collect()
print("Free:", gc.mem_free())
while True:
try:
response = requests.get("https://"+WIIM_IP+"/httpapi.asp?command=getPlayerStatus", timeout=TIMEOUT)
if response.status_code == 200:
data = response.json()
if data["status"] == "play":
count = 0
try:
if Title != data["Title"]:
Title = data["Title"]
try:
response = requests.get("https://"+WIIM_IP+"/httpapi.asp?command=getMetaInfo", timeout=TIMEOUT)
data = response.json()["metaData"]
if art_url != data["albumArtURI"]:
art_url = data["albumArtURI"]
fetch_album_art(art_url)
artist = data["artist"]
if artist == "unknow":
artist = data["subtitle"]
title = data["title"]
update_display(artist, title)
except Exception as e:
print("Error getting metadata:",e)
except Exception as e:
print(e)
else:
count +=1
if count > 10:
count = 0
Title = ""
show_clock()
except Exception as e:
print("Connection error:", e)
time.sleep(1)
count += 1
if count > 5:
count = 0
connect_to_wifi()
time.sleep(1)
if __name__ == "__main__":
main()
secrets.py:
Code:
WIFI_SSID = ""
WIFI_PASSWORD = ""
WIIM_IP = "192.168.68.xxx"
TIMEZONE_OFFSET = -8
The secrets.py entries are obvious; in my case, right now in California, time is -8 hours compared to GMT.
Attachments
Last edited: