reformatted files to be pep8 compliant

updated .gitignore
This commit is contained in:
KS_HTK 2025-08-21 09:51:44 +02:00
parent 666a377e32
commit ef148dbbb6
Signed by: KS_HTK
GPG key ID: A12528D4094FF70C
4 changed files with 285 additions and 270 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
.env .env
.idea

316
images.py
View file

@ -5,195 +5,203 @@ When running this file it will randomly select a transition and a frame to trans
# requires: python-fluepdot, python-dotenv # requires: python-fluepdot, python-dotenv
import os import os
from dotenv import load_dotenv from dotenv import load_dotenv
from src.fluepdot.fluepdot import Fluepdot, Mode from fluepdot import Fluepdot, Mode
from random import choice, sample from random import choice, sample
from itertools import product from itertools import product
from time import sleep from time import sleep
from typing import List from typing import List
DELAY = 5 # hold time for completed animations/frames DELAY = 5 # hold time for completed animations/frames
ANIMATION_DELAY = 0.1 # delay between frames of animations ANIMATION_DELAY = 0.1 # delay between frames of animations
flipdot_logo = [ flipdot_logo = [
" XXXXXX ", " XXXXXX ",
" XX X ", " XX X ",
" X X ", " X X ",
" X X ", " X X ",
" X XX ", " X XX ",
"X X", "X X",
"X X X X", "X X X X",
"X X X X X", "X X X X X",
"X X XXX X", "X X XXX X",
"X XXX X X X", "X XXX X X X",
"X X X X X", "X X X X X",
" X X XXX X ", " X X XXX X ",
" X X ", " X X ",
" X X ", " X X ",
" XX XX ", " XX XX ",
" XXXXXX ", " XXXXXX ",
] ]
fd1 = Fluepdot(f"http://{ip1}")
#fd2 = Fluepdot(f"http://{ip2}", flipped=True)
def checkerboard(len_x: int, len_y: int, invert: bool = False) -> List[List[bool]]: def checkerboard(len_x: int, len_y: int, invert: bool = False) -> List[List[bool]]:
return [[(j+i+invert)%2==0 for i in range(len_x)] for j in range(len_y)] return [[(j + i + invert) % 2 == 0 for i in range(len_x)] for j in range(len_y)]
def droplet(fd: Fluepdot): def droplet(fd: Fluepdot):
max_x, max_y = fd.get_size() max_x, max_y = fd.get_size()
fd.set_mode(Mode.DIFFERENTIAL) fd.set_mode(Mode.DIFFERENTIAL)
frame = [[False for _ in range(max_x)] for _ in range(max_y)] frame = [[False for _ in range(max_x)] for _ in range(max_y)]
cx, cy = max_x//2-.5, max_y//2-.5 cx, cy = max_x // 2 - .5, max_y // 2 - .5
r = 0 r = 0
while r < cx+32: while r < cx + 32:
for y in range(max_y): for y in range(max_y):
for x in range(int(cx-r-2), int(cx+r+3)): for x in range(int(cx - r - 2), int(cx + r + 3)):
if not (0 <= x < max_x and 0 <= y < max_y): if not (0 <= x < max_x and 0 <= y < max_y):
continue continue
frame[y][x] = False frame[y][x] = False
dist = ((x-cx)**2+(y-cy)**2)**.5 dist = ((x - cx) ** 2 + (y - cy) ** 2) ** .5
for l in range(5): for l in range(5):
if r-1-(l**1.4)*4 < dist < r+1-(l**1.4)*4: if r - 1 - (l ** 1.4) * 4 < dist < r + 1 - (l ** 1.4) * 4:
frame[y][x] = True frame[y][x] = True
break break
r+=2 r += 2
if r > 36: if r > 36:
fd_logo_width = len(flipdot_logo[0]) fd_logo_width = len(flipdot_logo[0])
s = int(cx+1 - fd_logo_width//2) s = int(cx + 1 - fd_logo_width // 2)
e = s + fd_logo_width e = s + fd_logo_width
for y in range(max_y): for y in range(max_y):
for x in range(s, e): for x in range(s, e):
frame[y][x] = flipdot_logo[y][x-s] == "X" or frame[y][x] frame[y][x] = flipdot_logo[y][x - s] == "X" or frame[y][x]
sleep(ANIMATION_DELAY)
fd.post_frame(frame)
sleep(ANIMATION_DELAY)
fd.post_frame(frame)
def fd_logo(fd: Fluepdot) -> List[List[bool]]: def fd_logo(fd: Fluepdot) -> List[List[bool]]:
fd.post_text("flipdot e.V.", x=7, y=0, font="fixed_7x14") fd.post_text("flipdot e.V.", x=7, y=0, font="fixed_7x14")
original_frame = fd.get_frame() original_frame = fd.get_frame()
frame = [] frame = []
for lrow, frow in zip(flipdot_logo, original_frame): for lrow, frow in zip(flipdot_logo, original_frame):
new_row = frow[:-(len(lrow)+2)]+lrow+frow[-2:] new_row = frow[:-(len(lrow) + 2)] + lrow + frow[-2:]
frame.append(new_row) frame.append(new_row)
return [[c=="X" for c in row] for row in frame] return [[c == "X" for c in row] for row in frame]
def kurhacken(fd: Fluepdot) -> List[List[bool]]: def kurhacken(fd: Fluepdot) -> List[List[bool]]:
fd.post_text("Kurhecken", x=14, y=-2, font="fixed_10x20") fd.post_text("Kurhecken", x=14, y=-2, font="fixed_10x20")
frame = [[c=="X" for c in row] for row in fd.get_frame()] frame = [[c == "X" for c in row] for row in fd.get_frame()]
fd.set_mode(Mode.DIFFERENTIAL) fd.set_mode(Mode.DIFFERENTIAL)
for x, y in [(56, 4),(57, 4),(60, 4),(61, 4),(56, 3),(57, 3),(60, 3),(61, 3)]: for x, y in [(56, 4), (57, 4), (60, 4), (61, 4), (56, 3), (57, 3), (60, 3), (61, 3)]:
frame[y][x] = True frame[y][x] = True
return frame return frame
def event37c3(fd: Fluepdot) -> List[List[bool]]: def event37c3(fd: Fluepdot) -> List[List[bool]]:
fd.post_text("37c3Unlocked", x=-1, y=-1, font="DejaVuSerif16") fd.post_text("37c3Unlocked", x=-1, y=-1, font="DejaVuSerif16")
frame = [[c=="X" for c in row] for row in fd.get_frame()] frame = [[c == "X" for c in row] for row in fd.get_frame()]
return frame return frame
def event38c3(fd: Fluepdot) -> List[List[bool]]: def event38c3(fd: Fluepdot) -> List[List[bool]]:
fd.post_text("38C3 Illegal Instructions", font="DejaVuSerif16") fd.post_text("38C3 Illegal Instructions", font="DejaVuSerif16")
frame = [[c=="X" for c in row] for row in fd.get_frame()] frame = [[c == "X" for c in row] for row in fd.get_frame()]
return frame return frame
def hackumenta(fd: Fluepdot) -> List[List[bool]]: def hackumenta(fd: Fluepdot) -> List[List[bool]]:
fd.post_text("Hackumenta", x=3, y=-1, font="DejaVuSerif16") fd.post_text("Hackumenta", x=3, y=-1, font="DejaVuSerif16")
frame = [[c=="X" for c in row] for row in fd.get_frame()] frame = [[c == "X" for c in row] for row in fd.get_frame()]
return frame return frame
def wipe_to(fd: Fluepdot, frame: List[List[bool]]): def wipe_to(fd: Fluepdot, frame: List[List[bool]]):
fd.set_mode(Mode.DIFFERENTIAL) fd.set_mode(Mode.DIFFERENTIAL)
current = [[c=="X" for c in row] for row in fd.get_frame()] current = [[c == "X" for c in row] for row in fd.get_frame()]
for i in range(0, len(current[0])): for i in range(0, len(current[0])):
for j in range(len(current)): for j in range(len(current)):
current[j][i] = frame[j][i] current[j][i] = frame[j][i]
if i+1 < len(current[0]): if i + 1 < len(current[0]):
current[j][i+1] = True current[j][i + 1] = True
sleep(ANIMATION_DELAY) sleep(ANIMATION_DELAY)
fd.post_frame(current) fd.post_frame(current)
def dither_to(fd: Fluepdot, frame: List[List[bool]]): def dither_to(fd: Fluepdot, frame: List[List[bool]]):
fd.set_mode(Mode.DIFFERENTIAL) fd.set_mode(Mode.DIFFERENTIAL)
max_x, max_y = fd.get_size() max_x, max_y = fd.get_size()
current = [[c=="X" for c in row] for row in fd.get_frame()] current = [[c == "X" for c in row] for row in fd.get_frame()]
coords = [(x,y) for x, y in product(range(max_x), range(max_y)) if current[y][x] != frame[y][x]] coords = [(x, y) for x, y in product(range(max_x), range(max_y)) if current[y][x] != frame[y][x]]
while coords: while coords:
sleep(ANIMATION_DELAY) sleep(ANIMATION_DELAY)
x, y = choice(coords) x, y = choice(coords)
coords.remove((x, y)) coords.remove((x, y))
if frame[y][x]: if frame[y][x]:
r = fd.set_pixel(x, y) r = fd.set_pixel(x, y)
if r.status_code != 200: if r.status_code != 200:
print(r.text) print(r.text)
else: else:
r = fd.unset_pixel(x, y) r = fd.unset_pixel(x, y)
if r.status_code != 200: if r.status_code != 200:
print(r.text) print(r.text)
def push_to(fd: Fluepdot, frame: List[List[bool]]): def push_to(fd: Fluepdot, frame: List[List[bool]]):
fd.set_mode(Mode.DIFFERENTIAL) fd.set_mode(Mode.DIFFERENTIAL)
current = [[c=="X" for c in row] for row in fd.get_frame()] current = [[c == "X" for c in row] for row in fd.get_frame()]
while True: while True:
sleep(max(ANIMATION_DELAY, 1)) sleep(max(ANIMATION_DELAY, 1))
for crow, frow in zip(current, frame): for crow, frow in zip(current, frame):
for _ in range(3): for _ in range(3):
crow.insert(0, frow.pop(-1)) crow.insert(0, frow.pop(-1))
crow.pop(-1) crow.pop(-1)
if frow: if frow:
continue continue
else: else:
break
else:
fd.post_frame(current)
continue
break break
else:
fd.post_frame(current)
continue
break
def roll_to(fd: Fluepdot, frame: List[List[bool]]): def roll_to(fd: Fluepdot, frame: List[List[bool]]):
fd.set_mode(Mode.DIFFERENTIAL) fd.set_mode(Mode.DIFFERENTIAL)
current = [[c=="X" for c in row] for row in fd.get_frame()] current = [[c == "X" for c in row] for row in fd.get_frame()]
while frame: while frame:
sleep(max(ANIMATION_DELAY, 1.5)) sleep(max(ANIMATION_DELAY, 1.5))
current.insert(0, frame.pop()) current.insert(0, frame.pop())
current.pop() current.pop()
fd.post_frame(current) fd.post_frame(current)
if __name__ == "__main__": if __name__ == "__main__":
load_dotenv() load_dotenv()
hostname = os.getenv("DOTS_HOST") hostname = os.getenv("DOTS_HOST")
fd = Fluepdot(f"http://{hostname}") fd = Fluepdot(f"http://{hostname}")
fd1.clear() fd.clear()
animations = [ animations = [
droplet, droplet,
] ]
transitions = [ transitions = [
wipe_to, wipe_to,
dither_to, dither_to,
push_to, push_to,
roll_to, roll_to,
] ]
stillframes = [ stillframes = [
kurhacken(fd), # Text endpoint kurhacken(fd), # Text endpoint
checkerboard(*fd.get_size(), invert=False), # Frame endpoint checkerboard(*fd.get_size(), invert=False), # Frame endpoint
[[True]*115]*16, [[True] * 115] * 16,
[[False]*115]*16, [[False] * 115] * 16,
#event37c3(fd), # Text endpoint #event37c3(fd), # Text endpoint
event38c3(fd), # Text endpoint event38c3(fd), # Text endpoint
hackumenta(fd), hackumenta(fd),
fd_logo(fd), # Text endpoint fd_logo(fd), # Text endpoint
] ]
#for i, f in enumerate(stillframes): #for i, f in enumerate(stillframes):
# print(i, len(f), [len(g) for g in f]) # print(i, len(f), [len(g) for g in f])
current = stillframes[1] current = stillframes[1]
while True: while True:
sf = sample(stillframes, k=1)[0] sf = sample(stillframes, k=1)[0]
tr = choice(transitions) tr = choice(transitions)
if sf == current: if sf == current:
print("Skipping same frame") print("Skipping same frame")
continue continue
print(tr.__name__) print(tr.__name__)
current = sf current = sf
tr(fd, sf) tr(fd, sf)
sleep(DELAY) sleep(DELAY)

View file

@ -1,7 +1,7 @@
""" """
Script for the flipdot recharge party animation Script for the flipdot recharge party animation
""" """
# requires: python-fluepdot, python_dotenv # requires: python-fluepdot, python_dotenv, pillow
import os import os
from time import sleep from time import sleep
from dotenv import load_dotenv from dotenv import load_dotenv
@ -26,62 +26,65 @@ logo = """
""" """
# convert text to framebuffer format
def textToFramebuffer(text: str, x:int=0, y:int=0, fontname:str="DejaVuSans.ttf", size:int=14) -> str:
from PIL import Image, ImageFont, ImageDraw
font = ImageFont.truetype(fontname, size)
tw, th = font.getsize(text)
while th >= 16:
print(th)
size -= 1
font = ImageFont.truetype(fontname, size)
tw, th = font.getsize(text)
img = Image.new("1", (tw, 16), 0)
draw = ImageDraw.Draw(img)
draw.text((0, 0), text=text, font=font, fill=1)
framebuffer: str = "" # convert text to framebuffer format
for y in range(img.height): def textToFramebuffer(text: str, x: int = 0, y: int = 0, fontname: str = "DejaVuSans.ttf", size: int = 14) -> str:
for x in range(img.width): from PIL import Image, ImageFont, ImageDraw
framebuffer += "X" if img.getpixel((x, y)) == 1 else " " font = ImageFont.truetype(fontname, size)
framebuffer += "\n" _, _, tw, th = font.getbbox(text)
return framebuffer while th >= 16:
print(th)
size -= 1
font = ImageFont.truetype(fontname, size)
_, _, tw, th = font.getbbox(text)
img = Image.new("1", (tw, 16), 0)
draw = ImageDraw.Draw(img)
draw.text((0, 0), text=text, font=font, fill=1)
framebuffer: str = ""
for y in range(img.height):
for x in range(img.width):
framebuffer += "X" if img.getpixel((x, y)) == 1 else " "
framebuffer += "\n"
return framebuffer
def scrl_frm(frame, loop: bool or int = False) -> None: def scrl_frm(frame, loop: bool or int = False) -> None:
def _extend_frame(line: str) -> str: def _extend_frame(line: str) -> str:
return line+(" "*loop)+line[0:115] return line + (" " * loop) + line[0:115]
def _pad_frame(line: str) -> str:
pad = " "*115
return pad+line+pad
frame = frame.split("\n") def _pad_frame(line: str) -> str:
length = len(frame[0])+loop if type(loop) == int else len(frame[0])+115 pad = " " * 115
return pad + line + pad
if type(loop) == int: frame = frame.split("\n")
frame = list(map(_extend_frame, frame)) length = len(frame[0]) + loop if type(loop) == int else len(frame[0]) + 115
else:
frame = list(map(_pad_frame, frame))
_run_once=True if type(loop) == int:
while loop or type(loop)==int or _run_once: frame = list(map(_extend_frame, frame))
_run_once=False else:
for i in range(0, length, 2): frame = list(map(_pad_frame, frame))
print(".\n".join(l[i:i+115] for l in frame))
sleep(.1)
if __name__=="__main__": _run_once = True
load_dotenv() while loop or type(loop) == int or _run_once:
hostname = os.getenv("DOTS_HOST") _run_once = False
frame = textToFramebuffer("recharge! flipdot e.V.", fontname="DejaVuSans.ttf") for i in range(0, length, 2):
fd = Fluepdot(f"http://{hostname}") print(".\n".join(l[i:i + 115] for l in frame))
fd.set_mode(Mode.DIFFERENTIAL) sleep(.1)
logoarr = logo.split("\n")
nframe = "" if __name__ == "__main__":
for y in range(len(logoarr)): load_dotenv()
nframe += logoarr[y] + frame.split("\n")[y]+ "\n" hostname = os.getenv("DOTS_HOST")
nframe = nframe[:-1] frame = textToFramebuffer("recharge! flipdot e.V.", fontname="DejaVuSans.ttf")
print(nframe) fd = Fluepdot(f"http://{hostname}")
fd.post_scroll_frame_raw(nframe, loop=2) fd.set_mode(Mode.DIFFERENTIAL)
#scrl_frm(nframe, loop=2)
logoarr = logo.split("\n")
nframe = ""
for y in range(len(logoarr)):
nframe += logoarr[y] + frame.split("\n")[y] + "\n"
nframe = nframe[:-1]
print(nframe)
fd.post_scroll_frame_raw(nframe, loop=2)
#scrl_frm(nframe, loop=2)

View file

@ -8,74 +8,77 @@ from fluepdot import Fluepdot, Mode
from time import sleep from time import sleep
battery = [ battery = [
" XXXXXXXXXXXX XXXXXXXXXXX ", " XXXXXXXXXXXX XXXXXXXXXXX ",
"XX XX ", "XX XX ",
"X X ", "X X ",
"X X ", "X X ",
"X XX", "X XX",
"X XX", "X XX",
"X X ", "X X ",
"X X ", "X X ",
"XX XX ", "XX XX ",
" XXXXXXXXXXX XXXXXXXXXXXX "] " XXXXXXXXXXX XXXXXXXXXXXX "]
lightning = [" X ",
" XX ",
" XXX ",
" XXX ",
" XXXX ",
"XXXXXXXX "]
lightning=[" X ",
" XX ",
" XXX ",
" XXX ",
" XXXX ",
"XXXXXXXX "]
def get_lightning(level: int) -> str: def get_lightning(level: int) -> str:
if level < 0: if level < 0:
level = 0 level = 0
elif level > 12: elif level > 12:
level = 12 level = 12
rtn = "\n".rjust(19)+"\n".rjust(19) rtn = "\n".rjust(19) + "\n".rjust(19)
for i in range(0, level):
line = lightning[i] if i < len(lightning) else lightning[len(lightning) - i - 1][::-1]
rtn = line.rjust(19) + "\n" + rtn
while rtn.count("\n") < 16:
rtn = "\n".rjust(19) + rtn
return rtn
for i in range(0, level):
line = lightning[i] if i < len(lightning) else lightning[len(lightning)-i-1][::-1]
rtn = line.rjust(19)+"\n"+rtn
while rtn.count("\n") < 16:
rtn="\n".rjust(19)+rtn
return rtn
def get_battery(level: int) -> str: def get_battery(level: int) -> str:
lightning = get_lightning(level).split("\n")[:-1] lightning = get_lightning(level).split("\n")[:-1]
rtn = "" rtn = ""
for ln in range(0, len(lightning)): for ln in range(0, len(lightning)):
if ln < 3: if ln < 3:
rtn+=lightning[ln].ljust(30) rtn += lightning[ln].ljust(30)
elif ln > 2+len(battery): elif ln > 2 + len(battery):
rtn+=lightning[ln].ljust(30) rtn += lightning[ln].ljust(30)
else: else:
for cind in range(0, len(battery[0])): for cind in range(0, len(battery[0])):
try: try:
rtn += "X" if battery[ln-3][cind] == "X" or lightning[ln][cind] == "X" else " " rtn += "X" if battery[ln - 3][cind] == "X" or lightning[ln][cind] == "X" else " "
except IndexError: except IndexError:
rtn += " " rtn += " "
rtn += "\n" rtn += "\n"
return rtn return rtn
if __name__=="__main__":
load_dotenv() if __name__ == "__main__":
hostname = os.getenv("DOTS_HOST") load_dotenv()
fd = Fluepdot(f"http://{hostname}") hostname = os.getenv("DOTS_HOST")
fd.set_mode(Mode.DIFFERENTIAL) fd = Fluepdot(f"http://{hostname}")
l, h = fd.get_size() fd.set_mode(Mode.DIFFERENTIAL)
while True: l, h = fd.get_size()
for i in range(0, 12): while True:
bat = get_battery(i).split("\n")[:-1] for i in range(0, len(lightning) * 2):
bat = list(map(lambda x: x.rjust(l), bat)) bat = get_battery(i).split("\n")[:-1]
bat = "\n".join(bat)+"\n" bat = list(map(lambda x: x.rjust(l), bat))
fd.post_frame_raw(frame=bat) bat = "\n".join(bat) + "\n"
sleep(.5) fd.post_frame_raw(frame=bat)
for i in range(12, 0, -1): sleep(.5)
bat = get_battery(i).split("\n")[:-1] for i in range(len(lightning) * 2, 0, -1):
bat = list(map(lambda x: x.rjust(l), bat)) bat = get_battery(i).split("\n")[:-1]
bat = "\n".join(bat)+"\n" bat = list(map(lambda x: x.rjust(l), bat))
fd.post_frame_raw(frame=bat) bat = "\n".join(bat) + "\n"
sleep(.5) fd.post_frame_raw(frame=bat)
sleep(.5)