initial
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
import numpy as np
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from time import sleep
|
||||
from datetime import datetime
|
||||
import logging
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from requests import RequestException
|
||||
|
||||
|
||||
from lib.image.rgb565 import convert_rgb_to_rgb565_numpy
|
||||
from lib.terminal import disable_cursor, enable_cursor, restore_screen, was_key_pressed
|
||||
from lib.lifedata import get_status_data
|
||||
|
||||
SCREEN_WIDTH_PIXELS = 900
|
||||
SCREEN_HEIGHT_PIXELS = 1440
|
||||
MARGIN_PIXELS = 15
|
||||
|
||||
CLOCK_SIZE_MULTIPLIER = (900 - 2 * MARGIN_PIXELS) / 243
|
||||
STATUS_SIZE_MULTIPLIER = 2
|
||||
|
||||
CLOCK_WIDTH_PIXELS = 243
|
||||
CLOCK_HEIGHT_PIXELS = 70
|
||||
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
logging.info('You pressed Ctrl+C!')
|
||||
restore_screen('/dev/tty1')
|
||||
enable_cursor('/dev/tty1')
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
#capture also ctrl+c
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
disable_cursor('/dev/tty1')
|
||||
|
||||
img = Image.new('RGB', (SCREEN_WIDTH_PIXELS,SCREEN_HEIGHT_PIXELS))
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
|
||||
def draw_label(label, x, y):
|
||||
label_font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', CLOCK_HEIGHT_PIXELS // 2)
|
||||
label_text_color = (0, 255//2, 0)
|
||||
draw.text((x,y), label, font=label_font, fill=label_text_color, anchor='rb')
|
||||
|
||||
|
||||
def draw_clock_digits(x, y, size ,hours, minutes, blink_second, color=(0, 255, 0)):
|
||||
"""
|
||||
Draws clock digits at the specified position.
|
||||
"""
|
||||
current_time = f'{hours}:{minutes}'
|
||||
# Blink logic
|
||||
if ':' in current_time and datetime.now().second % 2 == blink_second:
|
||||
current_time = current_time.replace(":", " ")
|
||||
|
||||
draw_digits(x, y, size, current_time, color)
|
||||
|
||||
def draw_digits(x, y, size, digits, color=(0, 255, 0)):
|
||||
"""
|
||||
Draws clock digits at the specified position.
|
||||
"""
|
||||
font_path = "/usr/share/fonts/truetype/dseg/DSEG14Classic-BoldItalic.ttf"
|
||||
font = ImageFont.truetype(font_path, int(CLOCK_HEIGHT_PIXELS * size))
|
||||
|
||||
draw.text((x, y), digits, font=font, fill=color)
|
||||
|
||||
def draw_clock():
|
||||
x = SCREEN_WIDTH_PIXELS - CLOCK_WIDTH_PIXELS * CLOCK_SIZE_MULTIPLIER - MARGIN_PIXELS
|
||||
y = MARGIN_PIXELS
|
||||
now = datetime.now()
|
||||
hours = now.strftime("%H")
|
||||
minutes = now.strftime("%M")
|
||||
|
||||
draw_clock_digits(x, y, CLOCK_SIZE_MULTIPLIER, hours, minutes, 0)
|
||||
#draw_label('Time:', x - MARGIN_PIXELS, y + CLOCK_HEIGHT_PIXELS)
|
||||
|
||||
|
||||
def draw_death_clock():
|
||||
x = SCREEN_WIDTH_PIXELS - CLOCK_WIDTH_PIXELS * STATUS_SIZE_MULTIPLIER - MARGIN_PIXELS
|
||||
y = MARGIN_PIXELS + CLOCK_HEIGHT_PIXELS * CLOCK_SIZE_MULTIPLIER + 2 * MARGIN_PIXELS
|
||||
|
||||
death_date = datetime.strptime("08/23/2026", "%m/%d/%Y").date()
|
||||
today = datetime.today().date()
|
||||
days_until_death = (death_date - today).days
|
||||
|
||||
color = (0, 255, 0)
|
||||
|
||||
draw_digits(x, y, STATUS_SIZE_MULTIPLIER, f'{days_until_death:4}', color)
|
||||
draw_label('death:', x - MARGIN_PIXELS, y + CLOCK_HEIGHT_PIXELS * STATUS_SIZE_MULTIPLIER)
|
||||
|
||||
def draw_journal_minutes(status):
|
||||
x = SCREEN_WIDTH_PIXELS - CLOCK_WIDTH_PIXELS * STATUS_SIZE_MULTIPLIER - MARGIN_PIXELS
|
||||
y = MARGIN_PIXELS + CLOCK_HEIGHT_PIXELS * CLOCK_SIZE_MULTIPLIER + CLOCK_HEIGHT_PIXELS * STATUS_SIZE_MULTIPLIER + 4 * MARGIN_PIXELS
|
||||
|
||||
elapsed_minutes = status['journal_updated_minutes']
|
||||
|
||||
hours = elapsed_minutes // 60
|
||||
minutes = elapsed_minutes % 60
|
||||
|
||||
if elapsed_minutes <=15:
|
||||
color = (0, 255, 0)
|
||||
elif elapsed_minutes <= 20:
|
||||
color = (255, 255, 0)
|
||||
else:
|
||||
color = (255, 0, 0)
|
||||
|
||||
draw_clock_digits(x, y, STATUS_SIZE_MULTIPLIER, f'{hours:02}', f'{minutes:02}', 1, color)
|
||||
draw_label('Journal:', x - MARGIN_PIXELS, y + CLOCK_HEIGHT_PIXELS * STATUS_SIZE_MULTIPLIER)
|
||||
|
||||
|
||||
def draw_fasting(status):
|
||||
x = SCREEN_WIDTH_PIXELS - CLOCK_WIDTH_PIXELS * STATUS_SIZE_MULTIPLIER - MARGIN_PIXELS
|
||||
y = MARGIN_PIXELS + CLOCK_HEIGHT_PIXELS * CLOCK_SIZE_MULTIPLIER + CLOCK_HEIGHT_PIXELS * STATUS_SIZE_MULTIPLIER * 2 + 6 * MARGIN_PIXELS
|
||||
|
||||
if 'fasting' in status and status['fasting']:
|
||||
label = 'Breakfast'
|
||||
date = datetime.strptime(status['fast']['projected_end'], "%Y-%m-%d %H:%M:%S")
|
||||
delta = date - datetime.now()
|
||||
hours = delta.seconds // 3600
|
||||
minutes = (delta.seconds // 60) % 60
|
||||
color = (0, 255, 0)
|
||||
else:
|
||||
label = 'Fasting'
|
||||
date = datetime.now().replace(hour=16, minute=0, second=0, microsecond=0)
|
||||
if date > datetime.now():
|
||||
delta = date - datetime.now()
|
||||
color = (0, 255, 0)
|
||||
else:
|
||||
delta = datetime.now() - date
|
||||
color = (255, 0, 0)
|
||||
|
||||
hours = delta.seconds // 3600
|
||||
minutes = (delta.seconds // 60) % 60
|
||||
|
||||
draw_clock_digits(x, y, STATUS_SIZE_MULTIPLIER, f'{hours:02}', f'{minutes:02}', 1, color)
|
||||
draw_label(f'{label}:', x - MARGIN_PIXELS, y + CLOCK_HEIGHT_PIXELS * STATUS_SIZE_MULTIPLIER)
|
||||
|
||||
def clear_status_area():
|
||||
x = 0
|
||||
y = MARGIN_PIXELS + CLOCK_HEIGHT_PIXELS * CLOCK_SIZE_MULTIPLIER + 2 * MARGIN_PIXELS
|
||||
draw.rectangle([x, y, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS], fill=(0, 0, 0))
|
||||
|
||||
|
||||
while True:
|
||||
draw_clock()
|
||||
draw_death_clock()
|
||||
try:
|
||||
status = get_status_data()
|
||||
|
||||
draw_journal_minutes(status)
|
||||
# draw_fasting(status)
|
||||
|
||||
except RequestException as e:
|
||||
logging.error(f'Error fetching status data: {e}')
|
||||
clear_status_area()
|
||||
|
||||
|
||||
rotated_img = img.rotate(90, expand=True)
|
||||
img_rgb565 = convert_rgb_to_rgb565_numpy(rotated_img)
|
||||
with open('/dev/fb0', 'wb') as fb:
|
||||
fb.write(img_rgb565)
|
||||
img = Image.new('RGB', (SCREEN_WIDTH_PIXELS,SCREEN_HEIGHT_PIXELS))
|
||||
draw = ImageDraw.Draw(img)
|
||||
sleep(1)
|
||||
Reference in New Issue
Block a user