moved variables to global config
parent
a5dbf46e29
commit
020e879810
|
@ -0,0 +1,21 @@
|
||||||
|
# this is just python syntax.
|
||||||
|
# Edit this file and enter the network name for your Wifi in SSID
|
||||||
|
# Enter the password for your Wifi network in the PSK
|
||||||
|
# Set the COUNTRY to the country code of your local country (yes, this matters!)
|
||||||
|
|
||||||
|
SSID = "Example_Network"
|
||||||
|
PSK = "Example_Password"
|
||||||
|
COUNTRY = "US" # Change to your local two-letter ISO 3166-1 country code
|
||||||
|
|
||||||
|
# URL that has the image
|
||||||
|
IMG_URL = "http://home.example.com:8123/local/image.png"
|
||||||
|
|
||||||
|
# Length of time between updates in minutes.
|
||||||
|
# Frequent updates will reduce battery life!
|
||||||
|
UPDATE_INTERVAL = 60
|
||||||
|
|
||||||
|
# Filename on the SD card for the image. Probably doesn't need changing.
|
||||||
|
FILENAME = "/sd/frame.png"
|
||||||
|
|
||||||
|
# tz_offset is hours from GMT. E.g., US PST is -7 (UTC-07:00) and CEST (Paris) is 1 (UTC+01:00)
|
||||||
|
TZ_OFFSET = -5
|
|
@ -0,0 +1,8 @@
|
||||||
|
# this is just python syntax.
|
||||||
|
# Edit this file and enter the network name for your Wifi in SSID
|
||||||
|
# Enter the password for your Wifi network in the PSK
|
||||||
|
# Set the COUNTRY to the country code of your local country (yes, this matters!)
|
||||||
|
|
||||||
|
SSID = "Example_Network"
|
||||||
|
PSK = "Example_Password"
|
||||||
|
COUNTRY = "US" # Change to your local two-letter ISO 3166-1 country code
|
|
@ -0,0 +1,187 @@
|
||||||
|
# inky-lovelace.py: Fetch a lovelace dashboard and display it on an inky-frame.
|
||||||
|
# Copyright (C) 2023 Paco Hope <github@filter.paco.to>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copy a PNG into the root of the pico from a known URL
|
||||||
|
|
||||||
|
Display it.
|
||||||
|
|
||||||
|
Sleep
|
||||||
|
"""
|
||||||
|
|
||||||
|
from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7"
|
||||||
|
from urllib import urequest
|
||||||
|
from machine import Pin, SPI
|
||||||
|
from network_manager import NetworkManager
|
||||||
|
import time
|
||||||
|
import inky_frame
|
||||||
|
import pngdec
|
||||||
|
import gc
|
||||||
|
import sdcard
|
||||||
|
import os
|
||||||
|
import CONFIG
|
||||||
|
import inky_frame
|
||||||
|
import uasyncio
|
||||||
|
global graphics
|
||||||
|
|
||||||
|
def display_image(j, CONFIG.FILENAME):
|
||||||
|
# Open the PNG file
|
||||||
|
j.open_file(CONFIG.FILENAME)
|
||||||
|
# Decode the PNG
|
||||||
|
j.decode()
|
||||||
|
|
||||||
|
# write the date/time at the top
|
||||||
|
year, month, day, hour, minute, second, dow, _ = time.localtime(time.time())
|
||||||
|
graphics.set_pen(0)
|
||||||
|
graphics.set_font('sans')
|
||||||
|
# display.text(text, x, y, wordwrap, scale, angle, spacing)
|
||||||
|
graphics.text(f"{hour:02}:{minute:02} {year}-{month}-{day}", 230, 10, scale=0.5)
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
|
def show_error(text,y):
|
||||||
|
WIDTH = 600
|
||||||
|
HEIGHT = 0 + 20 * y
|
||||||
|
|
||||||
|
graphics.set_pen(4)
|
||||||
|
graphics.rectangle(0, HEIGHT, WIDTH, 35)
|
||||||
|
graphics.set_pen(1)
|
||||||
|
graphics.text(text, 5, 16 + HEIGHT, 400, 2)
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
|
def fetch(url):
|
||||||
|
""" Fetch the image, store it onboard.
|
||||||
|
Returns False at first error.
|
||||||
|
Returns True only if everything succeeds.
|
||||||
|
"""
|
||||||
|
|
||||||
|
inky_frame.button_b.led_on()
|
||||||
|
network_manager = NetworkManager(CONFIG.COUNTRY, status_handler=status_handler, client_timeout=60)
|
||||||
|
try:
|
||||||
|
uasyncio.get_event_loop().run_until_complete(network_manager.client(CONFIG.SSID, CONFIG.PSK))
|
||||||
|
except RuntimeError:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print("join network failed")
|
||||||
|
print(e)
|
||||||
|
inky_frame.button_b.led_off()
|
||||||
|
return False
|
||||||
|
inky_frame.button_b.led_off()
|
||||||
|
|
||||||
|
year, month, day, hour, minute, second, dow, _ = time.localtime(time.time())
|
||||||
|
print(f"{hour:02}:{minute:02} {year}-{month}-{day}")
|
||||||
|
|
||||||
|
if year < 2023:
|
||||||
|
# blink b when we are setting the time
|
||||||
|
inky_frame.button_b.led_on()
|
||||||
|
inky_frame.set_time() # set time from network
|
||||||
|
inky_frame.button_b.led_off()
|
||||||
|
|
||||||
|
tz_seconds = (CONFIG.TZ_OFFSET * 3600)
|
||||||
|
year, month, day, hour, minute, second, dow, _ = time.localtime(time.time() + tz_seconds)
|
||||||
|
|
||||||
|
# don't bother updating before 06:00 or after 23:00
|
||||||
|
if hour < 5 or hour > 22:
|
||||||
|
print("no need to fetch")
|
||||||
|
return False
|
||||||
|
del year, month, day, hour, minute, second, tz_seconds
|
||||||
|
print( "fetching " + url )
|
||||||
|
inky_frame.button_c.led_on()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Grab the image
|
||||||
|
socket = urequest.urlopen(url)
|
||||||
|
gc.collect()
|
||||||
|
except OSError as e:
|
||||||
|
print("Unable open URL. OSErr: ")
|
||||||
|
print(e)
|
||||||
|
except Exception as e:
|
||||||
|
print("other exception")
|
||||||
|
print(e)
|
||||||
|
return False
|
||||||
|
os.remove(CONFIG.FILENAME)
|
||||||
|
inky_frame.button_c.led_off()
|
||||||
|
inky_frame.button_d.led_on()
|
||||||
|
try:
|
||||||
|
data = bytearray(1024)
|
||||||
|
with open(CONFIG.FILENAME, "wb+") as f:
|
||||||
|
while True:
|
||||||
|
if socket.readinto(data) == 0:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(".", end="" )
|
||||||
|
f.write(data)
|
||||||
|
socket.close()
|
||||||
|
del data
|
||||||
|
except Exception as e:
|
||||||
|
print("Unable to write file")
|
||||||
|
print(e)
|
||||||
|
return False
|
||||||
|
del socket
|
||||||
|
inky_frame.button_d.led_off()
|
||||||
|
gc.collect()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def status_handler(mode, status, ip):
|
||||||
|
print(mode, status, ip)
|
||||||
|
|
||||||
|
def mount_sd():
|
||||||
|
# set up the SD card
|
||||||
|
try:
|
||||||
|
sd_spi = SPI(0, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.OUT))
|
||||||
|
sd = sdcard.SDCard(sd_spi, Pin(22))
|
||||||
|
os.mount(sd, "/sd")
|
||||||
|
except Exception as e:
|
||||||
|
print("mounting SD card")
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
files = os.listdir("/sd")
|
||||||
|
if len(files) == 0:
|
||||||
|
show_error("SD didn't mount?", 5)
|
||||||
|
del files
|
||||||
|
|
||||||
|
while True:
|
||||||
|
graphics = None
|
||||||
|
gc.collect()
|
||||||
|
inky_frame.led_busy.off()
|
||||||
|
inky_frame.button_a.led_off()
|
||||||
|
inky_frame.button_b.led_off()
|
||||||
|
inky_frame.button_c.led_off()
|
||||||
|
inky_frame.button_d.led_off()
|
||||||
|
inky_frame.button_e.led_off()
|
||||||
|
inky_frame.led_busy.on()
|
||||||
|
|
||||||
|
inky_frame.button_a.led_on()
|
||||||
|
mount_sd()
|
||||||
|
gc.collect()
|
||||||
|
inky_frame.button_a.led_off()
|
||||||
|
if fetch(CONFIG.IMG_URL):
|
||||||
|
gc.collect()
|
||||||
|
inky_frame.button_e.led_on()
|
||||||
|
|
||||||
|
# set up the display
|
||||||
|
graphics = PicoGraphics(DISPLAY)
|
||||||
|
|
||||||
|
# Create a new PNG decoder for our PicoGraphics
|
||||||
|
j = pngdec.PNG(graphics)
|
||||||
|
|
||||||
|
display_image(j, CONFIG.FILENAME)
|
||||||
|
# Display the result
|
||||||
|
graphics.update()
|
||||||
|
|
||||||
|
inky_frame.button_e.led_off()
|
||||||
|
inky_frame.led_busy.off()
|
||||||
|
# Go to sleep if on battery power
|
||||||
|
inky_frame.button_a.led_off()
|
||||||
|
inky_frame.button_b.led_off()
|
||||||
|
inky_frame.button_c.led_off()
|
||||||
|
inky_frame.button_d.led_off()
|
||||||
|
inky_frame.button_e.led_off()
|
||||||
|
inky_frame.sleep_for(CONFIG.UPDATE_INTERVAL)
|
||||||
|
|
Loading…
Reference in New Issue