Simplify and caption
This commit is contained in:
parent
cd70c4cdca
commit
2c8d78b397
1 changed files with 551 additions and 596 deletions
188
src/display.py
188
src/display.py
|
|
@ -1,95 +1,93 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import fcntl
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
sys.path.append(str(Path(__file__).parent / "lib"))
|
||||
from waveshare_epd import epd7in3e
|
||||
from immich import ImmichClient, get_random_photo_of_people, get_random_photo_from_album
|
||||
from homeassistant import HomeAssistantClient
|
||||
|
||||
LOCK_FILE = "/tmp/frame.lock"
|
||||
|
||||
IMMICH_URL = os.environ.get("IMMICH_URL", "https://immich.schmelczer.dev")
|
||||
IMMICH_API_KEY = os.environ.get("IMMICH_API_KEY", "6crxVS1JLTJxsfGlzVhN2kefdL4EP7HPkkoMk9L6ZOE")
|
||||
|
||||
HA_URL = os.environ.get("HA_URL", "https://homeassistant.schmelczer.dev")
|
||||
HA_TOKEN = os.environ.get("HA_TOKEN", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmZjk3OTNmOWMzOWU0YjdmYmRjYTc5YmJkMTUyODcyNSIsImlhdCI6MTc2OTIwMjg1NCwiZXhwIjoyMDg0NTYyODU0fQ.IiL_1vTrGMlOoPMksN6lAopE0aInlY_wRnL4Jc-CeBs")
|
||||
HA_PRESENCE_ENTITIES = ["person.andras", "person.ruby"]
|
||||
|
||||
DEFAULT_SATURATION = 1.3
|
||||
DEFAULT_CONTRAST = 1.05
|
||||
DEFAULT_GAMMA = 0.90
|
||||
|
||||
def display_image(image_path: Path, orientation: int, saturation: float,
|
||||
contrast: float, gamma: float, enhance: bool) -> None:
|
||||
epd = epd7in3e.EPD()
|
||||
try:
|
||||
epd.init()
|
||||
img = Image.open(image_path).convert("RGB")
|
||||
if orientation:
|
||||
img = img.rotate(orientation, expand=True)
|
||||
buf = epd.getbuffer(img, saturation=saturation, contrast=contrast,
|
||||
gamma=gamma, enhance=enhance)
|
||||
epd.display(buf)
|
||||
finally:
|
||||
epd.sleep()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Display image on e-ink frame")
|
||||
parser.add_argument("--people", default="Me,Ruby",
|
||||
help="Comma-separated names for Immich search")
|
||||
parser.add_argument("--album", help="Fetch from album (overrides --people)")
|
||||
parser.add_argument("-o", "--orientation", type=int, choices=[0, 90, 180, 270],
|
||||
default=0, help="Rotation in degrees")
|
||||
parser.add_argument("--saturation", type=float, default=DEFAULT_SATURATION)
|
||||
parser.add_argument("--contrast", type=float, default=DEFAULT_CONTRAST)
|
||||
parser.add_argument("--gamma", type=float, default=DEFAULT_GAMMA)
|
||||
parser.add_argument("--no-enhance", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
lock_fd = open(LOCK_FILE, "w")
|
||||
try:
|
||||
fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except BlockingIOError:
|
||||
print("Another instance running, skipping")
|
||||
sys.exit(0)
|
||||
|
||||
now = datetime.now()
|
||||
print(f"Time: {now.strftime('%H:%M')}")
|
||||
|
||||
if 0 <= now.hour < 7:
|
||||
print("Night time, skipping")
|
||||
sys.exit(0)
|
||||
|
||||
ha = HomeAssistantClient(HA_URL, HA_TOKEN)
|
||||
home = [e.split(".")[-1].title() for e in HA_PRESENCE_ENTITIES if ha.is_person_home(e)]
|
||||
if not home:
|
||||
print("No one home, skipping")
|
||||
sys.exit(0)
|
||||
print(f"Home: {', '.join(home)}")
|
||||
|
||||
client = ImmichClient(IMMICH_URL, IMMICH_API_KEY)
|
||||
if args.album:
|
||||
image_path = get_random_photo_from_album(client, args.album, args.orientation)
|
||||
print(f"Album: {args.album}")
|
||||
else:
|
||||
names = [n.strip() for n in args.people.split(",")]
|
||||
image_path = get_random_photo_of_people(client, names, args.orientation)
|
||||
print(f"People: {', '.join(names)}")
|
||||
|
||||
try:
|
||||
display_image(image_path, args.orientation, args.saturation,
|
||||
args.contrast, args.gamma, not args.no_enhance)
|
||||
finally:
|
||||
image_path.unlink(missing_ok=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import fcntl
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
sys.path.append(str(Path(__file__).parent / "lib"))
|
||||
from immich import ImmichClient, get_random_photo_of_people, get_random_photo_from_album
|
||||
from homeassistant import HomeAssistantClient
|
||||
from overlay import format_age, format_location
|
||||
# waveshare_epd is imported lazily after the lock — its epdconfig claims
|
||||
# GPIO pins at import time, so two overlapping invocations would both crash
|
||||
# on "GPIO busy" before reaching the flock below.
|
||||
|
||||
IMMICH_URL = os.environ.get("IMMICH_URL", "https://immich.schmelczer.dev")
|
||||
IMMICH_API_KEY = os.environ.get("IMMICH_API_KEY", "6crxVS1JLTJxsfGlzVhN2kefdL4EP7HPkkoMk9L6ZOE")
|
||||
|
||||
HA_URL = os.environ.get("HA_URL", "https://homeassistant.schmelczer.dev")
|
||||
HA_TOKEN = os.environ.get("HA_TOKEN", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmZjk3OTNmOWMzOWU0YjdmYmRjYTc5YmJkMTUyODcyNSIsImlhdCI6MTc2OTIwMjg1NCwiZXhwIjoyMDg0NTYyODU0fQ.IiL_1vTrGMlOoPMksN6lAopE0aInlY_wRnL4Jc-CeBs")
|
||||
HA_PRESENCE_ENTITIES = ["person.andras", "person.ruby"]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Display image on e-ink frame")
|
||||
parser.add_argument("--people", default="Me,Ruby",
|
||||
help="Comma-separated names for Immich search")
|
||||
parser.add_argument("--album", help="Fetch from album (overrides --people)")
|
||||
parser.add_argument("-o", "--orientation", type=int, choices=[0, 90, 180, 270],
|
||||
default=0, help="Rotation in degrees")
|
||||
parser.add_argument("--saturation", type=float, default=1.3)
|
||||
parser.add_argument("--contrast", type=float, default=1.05)
|
||||
parser.add_argument("--gamma", type=float, default=0.90)
|
||||
args = parser.parse_args()
|
||||
|
||||
lock_fd = open("/tmp/frame.lock", "w")
|
||||
try:
|
||||
fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except BlockingIOError:
|
||||
print("Another instance running, skipping")
|
||||
sys.exit(0)
|
||||
|
||||
from waveshare_epd import epd7in3e
|
||||
|
||||
now = datetime.now()
|
||||
print(f"Time: {now.strftime('%H:%M')}")
|
||||
if 0 <= now.hour < 7:
|
||||
print("Night time, skipping")
|
||||
sys.exit(0)
|
||||
|
||||
ha = HomeAssistantClient(HA_URL, HA_TOKEN)
|
||||
home = [e.split(".")[-1].title() for e in HA_PRESENCE_ENTITIES if ha.is_person_home(e)]
|
||||
if not home:
|
||||
print("No one home, skipping")
|
||||
sys.exit(0)
|
||||
print(f"Home: {', '.join(home)}")
|
||||
|
||||
client = ImmichClient(IMMICH_URL, IMMICH_API_KEY)
|
||||
if args.album:
|
||||
image_path, asset = get_random_photo_from_album(client, args.album, args.orientation)
|
||||
print(f"Album: {args.album}")
|
||||
else:
|
||||
names = [n.strip() for n in args.people.split(",")]
|
||||
image_path, asset = get_random_photo_of_people(client, names, args.orientation)
|
||||
print(f"People: {', '.join(names)}")
|
||||
|
||||
left_text = format_age(asset)
|
||||
right_text = format_location(asset)
|
||||
if left_text or right_text:
|
||||
print(f"Overlay: {left_text or '-'} | {right_text or '-'}")
|
||||
|
||||
try:
|
||||
epd = epd7in3e.EPD()
|
||||
try:
|
||||
epd.init()
|
||||
img = Image.open(image_path).convert("RGB")
|
||||
if args.orientation:
|
||||
img = img.rotate(args.orientation, expand=True)
|
||||
buf = epd.getbuffer(img, saturation=args.saturation, contrast=args.contrast,
|
||||
gamma=args.gamma, left_text=left_text, right_text=right_text,
|
||||
orientation=args.orientation)
|
||||
epd.display(buf)
|
||||
finally:
|
||||
epd.sleep()
|
||||
finally:
|
||||
image_path.unlink(missing_ok=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
Loading…
Reference in a new issue