Compare commits

...

7 Commits

Author SHA1 Message Date
66837ea038 Better calendar size calculations 2025-02-16 20:54:03 +00:00
61eed0d0f9 Formatting 2025-02-16 20:37:42 +00:00
018643dde9 Todo items from HAS 2025-02-16 20:19:55 +00:00
8758248fea Add pip req 2025-02-09 18:58:41 +00:00
26cea15bdf Remove unused import 2025-02-09 18:57:31 +00:00
9c60f7c37b Use HAS for calendar 2025-02-09 18:39:31 +00:00
69eacb4f17 resize top bar 2025-02-06 14:28:48 +00:00
9 changed files with 195 additions and 30 deletions

1
.env.sample Normal file
View File

@@ -0,0 +1 @@
HAS_TOKEN=xxx

5
.gitignore vendored
View File

@@ -175,4 +175,7 @@ cython_debug/
*.bmp
*.png
*.png
credentials.json
.env

BIN
Nunito-Bold.ttf Normal file

Binary file not shown.

18
README.md Normal file
View File

@@ -0,0 +1,18 @@
## Installation
```bash
sudo apt update
sudo apt install python3-pip
git clone https://github.com/pimoroni/inky
cd inky
./install.sh
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
## Todo
- [ ] Accurate temp

View File

@@ -1,7 +1,10 @@
from inky import InkyWHAT
from inky.auto import auto
from dotenv import load_dotenv
from building import draw_image
load_dotenv()
display = auto(verbose = True)
image = draw_image()
display.set_image(image)

View File

@@ -1,27 +1,38 @@
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from datetime import datetime
from datetime import datetime, timedelta
from time import gmtime, strftime
import time
from itertools import groupby
from hasApi import get_calendar_events, get_todo_items
import dateutil.parser
from dotenv import load_dotenv
black = '#000000'
white = '#ffffff'
black = "#000000"
white = "#ffffff"
fontSymbols = ImageFont.truetype("SymbolsNerdFont-Regular.ttf", 18)
fontTitle = ImageFont.truetype("Nunito-SemiBold.ttf", 24)
fontLarge = ImageFont.truetype ("Nunito-ExtraLight.ttf", 18)
fontSmall = ImageFont.truetype ("Nunito-ExtraLight.ttf", 16)
fontTitle = ImageFont.truetype("Nunito-Bold.ttf", 24)
fontLarge = ImageFont.truetype("Nunito-ExtraLight.ttf", 18)
fontLargeBold = ImageFont.truetype("Nunito-SemiBold.ttf", 18)
fontSmall = ImageFont.truetype("Nunito-ExtraLight.ttf", 16)
fontVerySmall = ImageFont.truetype("Nunito-ExtraLight.ttf", 10)
class Space(Exception):
pass
def getsize(font, text):
_, _, right, bottom = font.getbbox(text)
return (right, bottom)
def reflow_quote(quote, width, font):
words = quote.split(" ")
reflowed = ''
reflowed = ""
line_length = 0
for i in range(len(words)):
@@ -39,52 +50,125 @@ def reflow_quote(quote, width, font):
return reflowed
def draw_image():
image = Image.new("P", (400, 300))
draw = ImageDraw.Draw(image)
# Draw the top bar
topbar = 26
draw.rectangle((0, 0, 400, 300), fill=white)
draw.rectangle((0, 0, 400, 40), fill=black)
draw.rectangle((0, 0, 400, topbar), fill=black)
# Add the clock
timeStr = strftime("%H:%M", time.localtime())
draw.text((10, 10), timeStr, white, fontSmall)
draw.text((10, 3), timeStr, white, fontSmall)
# Add indoor tempriture
draw.text((350, 10), "19c", white, fontSmall)
# Add indoor temperature
draw.text((350, 3), "19c", white, fontSmall)
# Add sections
ep = 5
draw.rounded_rectangle((ep, 40+ep, (400/2)-ep, 300-ep), 10, outline=black)
draw.rounded_rectangle(((400/2) + ep, 40+ep, 400-ep, 300-ep), 10, outline=black)
ep = 3
margin = 5
draw.rounded_rectangle(
(margin, topbar + margin, (400 / 2) - margin, 300 - margin),
10,
outline=black,
width=2,
)
draw.rounded_rectangle(
((400 / 2) + margin, topbar + margin, 400 - margin, 300 - margin),
10,
outline=black,
width=2,
)
# Add tasks
draw.text((15, 50), 'Tasks', black, fontTitle)
draw.text((20, topbar + 7), "Tasks", black, fontTitle)
draw.line((margin, 62, 200 - margin, 62), fill=black, width=1)
tasks = [
{'done': False, 'title': 'Something'},
{'done': True, 'title': 'Get the Modus and Audi MOTs organised'},
{'done': False, 'title': 'Something else'},
{'done': False, 'title': 'Call locksmith'},
]
tasks = get_todo_items()
taskStart = 90
taskStart = 70
for task in tasks:
if task['done']:
draw.text((15, taskStart), '󰄵', black, fontSymbols)
if task["status"] == "completed":
continue
draw.text((15, taskStart - 2), "󰄵", black, fontSymbols)
else:
draw.text((15, taskStart), '󰄱', black, fontSymbols)
draw.text((15, taskStart), "󰄱", black, fontSymbols)
reflowedTitle = reflow_quote(task['title'], 170, fontLarge)
reflowedTitle = reflow_quote(task["summary"], 160, fontLarge)
titleSizeW, titleSizeH = getsize(fontLarge, reflowedTitle)
titleSizeH *= (reflowedTitle.count('\n') + 1)
titleSizeH *= reflowedTitle.count("\n") + 1
draw.text((35, taskStart - 3), reflowedTitle, black, fontLarge)
taskStart += titleSizeH + (2*ep)
taskStart += titleSizeH + (2 * ep)
# Add cal
draw.text((220, topbar + 7), "Calendar", black, fontTitle)
draw.line(((400 / 2) + margin, 62, 400 - margin, 62), fill=black, width=1)
events = get_calendar_events()
def get_start_date(x):
start = x["start"]
if "date" in start:
startDate = datetime.strptime(start["date"], "%Y-%m-%d").date()
elif "dateTime" in start:
startDate = datetime.strptime(start["dateTime"][:10], "%Y-%m-%d").date()
else:
print("Error")
print(start)
return None
if startDate < datetime.today().date():
return datetime.today().date()
else:
return startDate
itemStart = 70
for key, group in groupby(events, get_start_date):
dayStart = itemStart
# Calculate
if key == datetime.today().date():
dateStr = "Today"
elif key == (datetime.today() + timedelta(days=1)).date():
dateStr = "Tomorrow"
else:
dateStr = key.strftime("%d %b")
w, h = getsize(fontLarge, "Today")
dayStart += h + (ep)
dayTasks = list(group)
for thing in dayTasks:
reflowedItem = reflow_quote(thing["summary"], 170, fontSmall)
w, h = getsize(fontLarge, "Today")
h *= reflowedItem.count("\n") + 1
dayStart += h + (ep)
dayStart + ep
if dayStart > 280:
print()
break
# Commit if possible
draw.text((215, itemStart), dateStr, black, fontLargeBold)
w, h = getsize(fontLargeBold, dateStr)
itemStart += h + ep
for thing in dayTasks:
reflowedItem = reflow_quote(thing["summary"], 170, fontSmall)
w, h = getsize(fontSmall, thing["summary"])
h *= reflowedItem.count("\n") + 1
draw.text((230, itemStart), reflowedItem, black, fontSmall)
itemStart += h + ep
itemStart += ep
return image
if __name__ == "__main__":
load_dotenv()
img = draw_image()
img.save('built.bmp')
img.save("built.bmp")

5
dev_reqs.txt Normal file
View File

@@ -0,0 +1,5 @@
pillow
imgkit
requests
python-dotenv
python-dateutil

48
hasApi.py Normal file
View File

@@ -0,0 +1,48 @@
import requests
import datetime
from dotenv import load_dotenv
import os
def get_calendar_events():
token = os.getenv("HAS_TOKEN")
if not token:
raise Exception("Missing HAS token")
headers = {"Authorization": f"Bearer {token}"}
payload = {
"start": datetime.datetime.now().strftime("%Y-%m-%d"),
"end": (datetime.datetime.now() + datetime.timedelta(days=14)).strftime(
"%Y-%m-%d"
),
}
response = requests.get(
"https://has.nozzy.online/api/calendars/calendar.romosborne_gmail_com",
headers=headers,
params=payload,
)
return response.json()
def get_todo_items():
token = os.getenv("HAS_TOKEN")
if not token:
raise Exception("Missing HAS token")
headers = {"Authorization": f"Bearer {token}"}
payload = {"entity_id": "todo.todo_2"}
params = {"return_response": "null"}
response = requests.post(
"https://has.nozzy.online/api/services/todo/get_items",
headers=headers,
params=params,
json=payload,
)
data = response.json()
return data["service_response"]["todo.todo_2"]["items"]
if __name__ == "__main__":
load_dotenv()
events = get_todo_items()
for item in events:
print(item["summary"])

View File

@@ -1,3 +1,6 @@
pillow
inky
imgkit
requests
python-dotenv
python-dateutil