This commit is contained in:
2026-07-09 14:15:38 +03:00
commit 8127789b08
8 changed files with 368 additions and 0 deletions
+167
View File
@@ -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)