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

View file

@ -1,7 +1,7 @@
"""
Script for the flipdot recharge party animation
"""
# requires: python-fluepdot, python_dotenv
# requires: python-fluepdot, python_dotenv, pillow
import os
from time import sleep
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 = ""
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
# 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.getbbox(text)
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 _extend_frame(line: str) -> str:
return line+(" "*loop)+line[0:115]
def _pad_frame(line: str) -> str:
pad = " "*115
return pad+line+pad
def _extend_frame(line: str) -> str:
return line + (" " * loop) + line[0:115]
frame = frame.split("\n")
length = len(frame[0])+loop if type(loop) == int else len(frame[0])+115
def _pad_frame(line: str) -> str:
pad = " " * 115
return pad + line + pad
if type(loop) == int:
frame = list(map(_extend_frame, frame))
else:
frame = list(map(_pad_frame, frame))
frame = frame.split("\n")
length = len(frame[0]) + loop if type(loop) == int else len(frame[0]) + 115
_run_once=True
while loop or type(loop)==int or _run_once:
_run_once=False
for i in range(0, length, 2):
print(".\n".join(l[i:i+115] for l in frame))
sleep(.1)
if type(loop) == int:
frame = list(map(_extend_frame, frame))
else:
frame = list(map(_pad_frame, frame))
if __name__=="__main__":
load_dotenv()
hostname = os.getenv("DOTS_HOST")
frame = textToFramebuffer("recharge! flipdot e.V.", fontname="DejaVuSans.ttf")
fd = Fluepdot(f"http://{hostname}")
fd.set_mode(Mode.DIFFERENTIAL)
_run_once = True
while loop or type(loop) == int or _run_once:
_run_once = False
for i in range(0, length, 2):
print(".\n".join(l[i:i + 115] for l in frame))
sleep(.1)
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)
if __name__ == "__main__":
load_dotenv()
hostname = os.getenv("DOTS_HOST")
frame = textToFramebuffer("recharge! flipdot e.V.", fontname="DejaVuSans.ttf")
fd = Fluepdot(f"http://{hostname}")
fd.set_mode(Mode.DIFFERENTIAL)
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
battery = [
" XXXXXXXXXXXX XXXXXXXXXXX ",
"XX XX ",
"X X ",
"X X ",
"X XX",
"X XX",
"X X ",
"X X ",
"XX XX ",
" XXXXXXXXXXX XXXXXXXXXXXX "]
" XXXXXXXXXXXX XXXXXXXXXXX ",
"XX XX ",
"X X ",
"X X ",
"X XX",
"X XX",
"X X ",
"X X ",
"XX XX ",
" XXXXXXXXXXX XXXXXXXXXXXX "]
lightning = [" X ",
" XX ",
" XXX ",
" XXX ",
" XXXX ",
"XXXXXXXX "]
lightning=[" X ",
" XX ",
" XXX ",
" XXX ",
" XXXX ",
"XXXXXXXX "]
def get_lightning(level: int) -> str:
if level < 0:
level = 0
elif level > 12:
level = 12
if level < 0:
level = 0
elif 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:
lightning = get_lightning(level).split("\n")[:-1]
lightning = get_lightning(level).split("\n")[:-1]
rtn = ""
for ln in range(0, len(lightning)):
if ln < 3:
rtn+=lightning[ln].ljust(30)
elif ln > 2+len(battery):
rtn+=lightning[ln].ljust(30)
else:
for cind in range(0, len(battery[0])):
try:
rtn += "X" if battery[ln-3][cind] == "X" or lightning[ln][cind] == "X" else " "
except IndexError:
rtn += " "
rtn += "\n"
rtn = ""
for ln in range(0, len(lightning)):
if ln < 3:
rtn += lightning[ln].ljust(30)
elif ln > 2 + len(battery):
rtn += lightning[ln].ljust(30)
else:
for cind in range(0, len(battery[0])):
try:
rtn += "X" if battery[ln - 3][cind] == "X" or lightning[ln][cind] == "X" else " "
except IndexError:
rtn += " "
rtn += "\n"
return rtn
return rtn
if __name__=="__main__":
load_dotenv()
hostname = os.getenv("DOTS_HOST")
fd = Fluepdot(f"http://{hostname}")
fd.set_mode(Mode.DIFFERENTIAL)
l, h = fd.get_size()
while True:
for i in range(0, 12):
bat = get_battery(i).split("\n")[:-1]
bat = list(map(lambda x: x.rjust(l), bat))
bat = "\n".join(bat)+"\n"
fd.post_frame_raw(frame=bat)
sleep(.5)
for i in range(12, 0, -1):
bat = get_battery(i).split("\n")[:-1]
bat = list(map(lambda x: x.rjust(l), bat))
bat = "\n".join(bat)+"\n"
fd.post_frame_raw(frame=bat)
sleep(.5)
if __name__ == "__main__":
load_dotenv()
hostname = os.getenv("DOTS_HOST")
fd = Fluepdot(f"http://{hostname}")
fd.set_mode(Mode.DIFFERENTIAL)
l, h = fd.get_size()
while True:
for i in range(0, len(lightning) * 2):
bat = get_battery(i).split("\n")[:-1]
bat = list(map(lambda x: x.rjust(l), bat))
bat = "\n".join(bat) + "\n"
fd.post_frame_raw(frame=bat)
sleep(.5)
for i in range(len(lightning) * 2, 0, -1):
bat = get_battery(i).split("\n")[:-1]
bat = list(map(lambda x: x.rjust(l), bat))
bat = "\n".join(bat) + "\n"
fd.post_frame_raw(frame=bat)
sleep(.5)