diff --git a/.gitignore b/.gitignore index 2eea525..451fb35 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.env \ No newline at end of file +.env +.idea \ No newline at end of file diff --git a/images.py b/images.py index e71ec45..4d84d5c 100644 --- a/images.py +++ b/images.py @@ -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 - - 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] + 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] + + 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) diff --git a/recharge.py b/recharge.py index f0dd6d9..d0015e9 100644 --- a/recharge.py +++ b/recharge.py @@ -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) diff --git a/recharge2.py b/recharge2.py index 215a3bb..5a5f87a 100644 --- a/recharge2.py +++ b/recharge2.py @@ -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 - - rtn = "\n".rjust(19)+"\n".rjust(19) + if level < 0: + level = 0 + elif level > 12: + level = 12 + + 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" - - return rtn + 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" -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) + 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, 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)