Add PyPortal Tides code
This commit is contained in:
parent
c36285e79b
commit
b770895718
7 changed files with 46717 additions and 0 deletions
6068
PyPortal_Tides/fonts/Arial-12.bdf
Normal file
6068
PyPortal_Tides/fonts/Arial-12.bdf
Normal file
File diff suppressed because it is too large
Load diff
6506
PyPortal_Tides/fonts/cq-mono-30.bdf
Normal file
6506
PyPortal_Tides/fonts/cq-mono-30.bdf
Normal file
File diff suppressed because it is too large
Load diff
33888
PyPortal_Tides/fonts/mono-bold-8.bdf
Normal file
33888
PyPortal_Tides/fonts/mono-bold-8.bdf
Normal file
File diff suppressed because it is too large
Load diff
103
PyPortal_Tides/pp_tides.py
Normal file
103
PyPortal_Tides/pp_tides.py
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import time
|
||||
import board
|
||||
from adafruit_pyportal import PyPortal
|
||||
from adafruit_bitmap_font import bitmap_font
|
||||
from adafruit_display_text.label import Label
|
||||
|
||||
#--| USER CONFIG |--------------------------
|
||||
STATION_ID = "9447130" # tide location, find yours here: https://tidesandcurrents.noaa.gov/
|
||||
HI_COLOR = 0x00FF00 # high tide times color
|
||||
LO_COLOR = 0x11FFFF # low tide times color
|
||||
DATE_COLOR = 0xFFFFFF # date and time color
|
||||
#-------------------------------------------
|
||||
|
||||
DATA_SOURCE = "https://tidesandcurrents.noaa.gov/api/datagetter?date=today&product=predictions&datum=mllw&interval=hilo&format=json&units=metric&time_zone=lst_ldt&station="+STATION_ID
|
||||
DATA_LOCATION = ["predictions"]
|
||||
|
||||
# determine the current working directory needed so we know where to find files
|
||||
cwd = ("/"+__file__).rsplit('/', 1)[0]
|
||||
pyportal = PyPortal(url=DATA_SOURCE,
|
||||
json_path=DATA_LOCATION,
|
||||
status_neopixel=board.NEOPIXEL,
|
||||
default_bg=cwd+"/tides_bg.bmp")
|
||||
|
||||
# Connect to the internet and get local time
|
||||
pyportal.get_local_time()
|
||||
|
||||
# Setup tide times font
|
||||
tide_font = bitmap_font.load_font(cwd+"/fonts/cq-mono-30.bdf")
|
||||
tide_font.load_glyphs(b'1234567890:')
|
||||
|
||||
# Setup date and time font
|
||||
date_font = bitmap_font.load_font(cwd+"/fonts/Arial-12.bdf")
|
||||
date_font.load_glyphs(b'1234567890-')
|
||||
|
||||
# Labels setup
|
||||
HI_LABELS = [ Label(tide_font, text="00:00", color=HI_COLOR, x= 40, y= 80) ,
|
||||
Label(tide_font, text="00:00", color=HI_COLOR, x= 40, y=165) ]
|
||||
LO_LABELS = [ Label(tide_font, text="00:00", color=LO_COLOR, x=180, y= 80) ,
|
||||
Label(tide_font, text="00:00", color=LO_COLOR, x=180, y=165) ]
|
||||
DATE_LABEL = Label(date_font, text="0000-00-00 00:00:00", color=DATE_COLOR, x=75, y=228)
|
||||
|
||||
# Add all the labels to the display
|
||||
for label in HI_LABELS + LO_LABELS + [DATE_LABEL]:
|
||||
pyportal.splash.append(label)
|
||||
|
||||
def get_tide_info():
|
||||
"""Fetch JSON tide time info and return it."""
|
||||
|
||||
# Get raw JSON data
|
||||
raw_info = pyportal.fetch()
|
||||
|
||||
# Return will be a dictionary of lists containing tide times
|
||||
tide_info = {"H":[], "L":[]}
|
||||
|
||||
# Parse out the tide time info
|
||||
for info in raw_info:
|
||||
tide_type = info["type"]
|
||||
tide_time = info["t"].split(" ")[1]
|
||||
tide_info[tide_type].append(tide_time)
|
||||
|
||||
return tide_info
|
||||
|
||||
def update_display(current_time, update_tides=False):
|
||||
"""Update the display with current info."""
|
||||
|
||||
# Tide time info
|
||||
if update_tides:
|
||||
# out with the old
|
||||
for label in HI_LABELS + LO_LABELS:
|
||||
label.text = ""
|
||||
# in with the new
|
||||
for i, hi_time in enumerate(tide_info["H"]):
|
||||
HI_LABELS[i].text = hi_time
|
||||
for i, lo_time in enumerate(tide_info["L"]):
|
||||
LO_LABELS[i].text = lo_time
|
||||
|
||||
# Date and time
|
||||
DATE_LABEL.text = "{:04}-{:02}-{:02} {:02}:{:02}:{:02}".format(current_time.tm_year,
|
||||
current_time.tm_mon,
|
||||
current_time.tm_mday,
|
||||
current_time.tm_hour,
|
||||
current_time.tm_min,
|
||||
current_time.tm_sec)
|
||||
|
||||
board.DISPLAY.refresh_soon()
|
||||
|
||||
# First run update
|
||||
tide_info = get_tide_info()
|
||||
current_time = time.localtime()
|
||||
update_display(current_time, True)
|
||||
current_yday = current_time.tm_yday
|
||||
|
||||
# Update daily
|
||||
while True:
|
||||
current_time = time.localtime()
|
||||
new_tides = False
|
||||
if current_time.tm_yday != current_yday:
|
||||
# new day, time to update
|
||||
tide_info = get_tide_info()
|
||||
new_tides = True
|
||||
current_yday = current_time.tm_yday
|
||||
update_display(current_time, new_tides)
|
||||
time.sleep(0.5)
|
||||
152
PyPortal_Tides/pp_tides_graphical.py
Normal file
152
PyPortal_Tides/pp_tides_graphical.py
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
import time
|
||||
import board
|
||||
import displayio
|
||||
from adafruit_pyportal import PyPortal
|
||||
from adafruit_bitmap_font import bitmap_font
|
||||
from adafruit_display_text.label import Label
|
||||
|
||||
#--| USER CONFIG |--------------------------
|
||||
STATION_ID = "9447130" # tide location, find yours here: https://tidesandcurrents.noaa.gov/
|
||||
PLOT_SIZE = 2 # tide plot thickness
|
||||
PLOT_COLOR = 0x00FF55 # tide plot color
|
||||
MARK_SIZE = 6 # current time marker size
|
||||
MARK_COLOR = 0xFF0000 # current time marker color
|
||||
DATE_COLOR = 0xE0CD1A # date text color
|
||||
TIME_COLOR = 0xE0CD1A # time text color
|
||||
VSCALE = 20 # vertical plot scale
|
||||
#-------------------------------------------
|
||||
|
||||
DATA_SOURCE = "https://tidesandcurrents.noaa.gov/api/datagetter?date=today&product=predictions&datum=mllw&format=json&units=metric&time_zone=lst_ldt&station="+STATION_ID
|
||||
DATA_LOCATION = ["predictions"]
|
||||
|
||||
WIDTH = board.DISPLAY.width
|
||||
HEIGHT = board.DISPLAY.height
|
||||
|
||||
# determine the current working directory needed so we know where to find files
|
||||
cwd = ("/"+__file__).rsplit('/', 1)[0]
|
||||
pyportal = PyPortal(url=DATA_SOURCE,
|
||||
json_path=DATA_LOCATION,
|
||||
status_neopixel=board.NEOPIXEL,
|
||||
default_bg=cwd+"/tides_bg_graph.bmp")
|
||||
|
||||
# Connect to the internet and get local time
|
||||
pyportal.get_local_time()
|
||||
|
||||
# Setup palette used for plot
|
||||
palette = displayio.Palette(3)
|
||||
palette[0] = 0x0
|
||||
palette[1] = PLOT_COLOR
|
||||
palette[2] = MARK_COLOR
|
||||
palette.make_transparent(0)
|
||||
|
||||
# Setup tide plot bitmap
|
||||
tide_plot = displayio.Bitmap(WIDTH, HEIGHT, 3)
|
||||
pyportal.splash.append(displayio.TileGrid(tide_plot, pixel_shader=palette))
|
||||
|
||||
# Setup font used for date and time
|
||||
date_font = bitmap_font.load_font(cwd+"/fonts/mono-bold-8.bdf")
|
||||
date_font.load_glyphs(b'1234567890-')
|
||||
|
||||
# Setup date label
|
||||
date_label = Label(date_font, text="0000-00-00", color=DATE_COLOR, x=7, y=14)
|
||||
pyportal.splash.append(date_label)
|
||||
|
||||
# Setup time label
|
||||
time_label = Label(date_font, text="00:00:00", color=TIME_COLOR, x=234, y=14)
|
||||
pyportal.splash.append(time_label)
|
||||
|
||||
# Setup current time marker
|
||||
time_marker_bitmap = displayio.Bitmap(MARK_SIZE, MARK_SIZE, 3)
|
||||
for i in range(MARK_SIZE * MARK_SIZE):
|
||||
time_marker_bitmap[i] = 2
|
||||
time_marker = displayio.TileGrid(time_marker_bitmap, pixel_shader=palette, x=-MARK_SIZE, y=-MARK_SIZE)
|
||||
pyportal.splash.append(time_marker)
|
||||
|
||||
def get_tide_data():
|
||||
"""Fetch JSON tide data and return parsed results in a list."""
|
||||
|
||||
# Get raw JSON data
|
||||
raw_data = pyportal.fetch()
|
||||
|
||||
# Results will be stored in a list that is display WIDTH long
|
||||
tide_data = [None]*WIDTH
|
||||
|
||||
# Convert raw data to display coordinates
|
||||
for data in raw_data:
|
||||
d, t = data["t"].split(" ") # date and time
|
||||
h, m = t.split(":") # hours and minutes
|
||||
v = data["v"] # water level
|
||||
x = round( (WIDTH - 1) * (60 * float(h) + float(m)) / 1440 )
|
||||
y = (HEIGHT // 2) - round(VSCALE * float(v))
|
||||
y = 0 if y < 0 else y
|
||||
y = HEIGHT-1 if y >= HEIGHT else y
|
||||
tide_data[x] = y
|
||||
|
||||
return tide_data
|
||||
|
||||
def draw_data_point(x, y, size=PLOT_SIZE, color=1):
|
||||
"""Draw data point on to the tide plot bitmap at (x,y)."""
|
||||
if y is None:
|
||||
return
|
||||
offset = size // 2
|
||||
for xx in range(x-offset, x+offset+1):
|
||||
for yy in range(y-offset, y+offset+1):
|
||||
try:
|
||||
tide_plot[xx, yy] = color
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
def draw_time_marker(current_time):
|
||||
"""Draw a marker on the tide plot for the current time."""
|
||||
h = current_time.tm_hour
|
||||
m = current_time.tm_min
|
||||
x = round( (WIDTH - 1) * (60 * float(h) + float(m)) / 1440 )
|
||||
y = tide_data[x]
|
||||
if y is not None:
|
||||
x -= MARK_SIZE // 2
|
||||
y -= MARK_SIZE // 2
|
||||
time_marker.x = x
|
||||
time_marker.y = y
|
||||
|
||||
def update_display(current_time, update_tides=False):
|
||||
"""Update the display with current info."""
|
||||
|
||||
# Tide data plot
|
||||
if update_tides:
|
||||
# out with the old
|
||||
for i in range(WIDTH * HEIGHT):
|
||||
tide_plot[i] = 0
|
||||
# in with the new
|
||||
for x in range(WIDTH):
|
||||
draw_data_point(x, tide_data[x])
|
||||
|
||||
# Current location marker
|
||||
draw_time_marker(current_time)
|
||||
|
||||
# Date and time
|
||||
date_label.text = "{:04}-{:02}-{:02}".format(current_time.tm_year,
|
||||
current_time.tm_mon,
|
||||
current_time.tm_mday)
|
||||
time_label.text = "{:02}:{:02}:{:02}".format(current_time.tm_hour,
|
||||
current_time.tm_min,
|
||||
current_time.tm_sec)
|
||||
|
||||
board.DISPLAY.refresh_soon()
|
||||
|
||||
# First run update
|
||||
tide_data = get_tide_data()
|
||||
current_time = time.localtime()
|
||||
update_display(current_time, True)
|
||||
current_yday = current_time.tm_yday
|
||||
|
||||
# Run forever
|
||||
while True:
|
||||
current_time = time.localtime()
|
||||
new_tides = False
|
||||
if current_time.tm_yday != current_yday:
|
||||
# new day, time to update
|
||||
tide_data = get_tide_data()
|
||||
new_tides = True
|
||||
current_yday = current_time.tm_yday
|
||||
update_display(current_time, new_tides)
|
||||
time.sleep(0.5)
|
||||
BIN
PyPortal_Tides/tides_bg.bmp
Normal file
BIN
PyPortal_Tides/tides_bg.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 300 KiB |
BIN
PyPortal_Tides/tides_bg_graph.bmp
Normal file
BIN
PyPortal_Tides/tides_bg_graph.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 300 KiB |
Loading…
Reference in a new issue