reformatted files to be pep8 compliant
updated .gitignore
This commit is contained in:
parent
666a377e32
commit
ef148dbbb6
4 changed files with 285 additions and 270 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
.env
|
.env
|
||||||
|
.idea
|
68
images.py
68
images.py
|
@ -5,7 +5,7 @@ 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
|
||||||
|
@ -34,91 +34,96 @@ flipdot_logo = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
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)
|
sleep(ANIMATION_DELAY)
|
||||||
fd.post_frame(frame)
|
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)
|
||||||
|
@ -132,9 +137,10 @@ def dither_to(fd: Fluepdot, frame: List[List[bool]]):
|
||||||
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):
|
||||||
|
@ -150,20 +156,22 @@ def push_to(fd: Fluepdot, frame: List[List[bool]]):
|
||||||
continue
|
continue
|
||||||
break
|
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,
|
||||||
]
|
]
|
||||||
|
@ -176,8 +184,8 @@ if __name__ == "__main__":
|
||||||
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),
|
||||||
|
|
31
recharge.py
31
recharge.py
|
@ -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,16 +26,17 @@ logo = """
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# convert text to framebuffer format
|
# convert text to framebuffer format
|
||||||
def textToFramebuffer(text: str, x:int=0, y:int=0, fontname:str="DejaVuSans.ttf", size:int=14) -> str:
|
def textToFramebuffer(text: str, x: int = 0, y: int = 0, fontname: str = "DejaVuSans.ttf", size: int = 14) -> str:
|
||||||
from PIL import Image, ImageFont, ImageDraw
|
from PIL import Image, ImageFont, ImageDraw
|
||||||
font = ImageFont.truetype(fontname, size)
|
font = ImageFont.truetype(fontname, size)
|
||||||
tw, th = font.getsize(text)
|
_, _, tw, th = font.getbbox(text)
|
||||||
while th >= 16:
|
while th >= 16:
|
||||||
print(th)
|
print(th)
|
||||||
size -= 1
|
size -= 1
|
||||||
font = ImageFont.truetype(fontname, size)
|
font = ImageFont.truetype(fontname, size)
|
||||||
tw, th = font.getsize(text)
|
_, _, tw, th = font.getbbox(text)
|
||||||
img = Image.new("1", (tw, 16), 0)
|
img = Image.new("1", (tw, 16), 0)
|
||||||
draw = ImageDraw.Draw(img)
|
draw = ImageDraw.Draw(img)
|
||||||
draw.text((0, 0), text=text, font=font, fill=1)
|
draw.text((0, 0), text=text, font=font, fill=1)
|
||||||
|
@ -50,27 +51,29 @@ def textToFramebuffer(text: str, x:int=0, y:int=0, fontname:str="DejaVuSans.ttf"
|
||||||
|
|
||||||
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:
|
def _pad_frame(line: str) -> str:
|
||||||
pad = " "*115
|
pad = " " * 115
|
||||||
return pad+line+pad
|
return pad + line + pad
|
||||||
|
|
||||||
frame = frame.split("\n")
|
frame = frame.split("\n")
|
||||||
length = len(frame[0])+loop if type(loop) == int else len(frame[0])+115
|
length = len(frame[0]) + loop if type(loop) == int else len(frame[0]) + 115
|
||||||
|
|
||||||
if type(loop) == int:
|
if type(loop) == int:
|
||||||
frame = list(map(_extend_frame, frame))
|
frame = list(map(_extend_frame, frame))
|
||||||
else:
|
else:
|
||||||
frame = list(map(_pad_frame, frame))
|
frame = list(map(_pad_frame, frame))
|
||||||
|
|
||||||
_run_once=True
|
_run_once = True
|
||||||
while loop or type(loop)==int or _run_once:
|
while loop or type(loop) == int or _run_once:
|
||||||
_run_once=False
|
_run_once = False
|
||||||
for i in range(0, length, 2):
|
for i in range(0, length, 2):
|
||||||
print(".\n".join(l[i:i+115] for l in frame))
|
print(".\n".join(l[i:i + 115] for l in frame))
|
||||||
sleep(.1)
|
sleep(.1)
|
||||||
|
|
||||||
if __name__=="__main__":
|
|
||||||
|
if __name__ == "__main__":
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
hostname = os.getenv("DOTS_HOST")
|
hostname = os.getenv("DOTS_HOST")
|
||||||
frame = textToFramebuffer("recharge! flipdot e.V.", fontname="DejaVuSans.ttf")
|
frame = textToFramebuffer("recharge! flipdot e.V.", fontname="DejaVuSans.ttf")
|
||||||
|
@ -80,7 +83,7 @@ if __name__=="__main__":
|
||||||
logoarr = logo.split("\n")
|
logoarr = logo.split("\n")
|
||||||
nframe = ""
|
nframe = ""
|
||||||
for y in range(len(logoarr)):
|
for y in range(len(logoarr)):
|
||||||
nframe += logoarr[y] + frame.split("\n")[y]+ "\n"
|
nframe += logoarr[y] + frame.split("\n")[y] + "\n"
|
||||||
nframe = nframe[:-1]
|
nframe = nframe[:-1]
|
||||||
print(nframe)
|
print(nframe)
|
||||||
fd.post_scroll_frame_raw(nframe, loop=2)
|
fd.post_scroll_frame_raw(nframe, loop=2)
|
||||||
|
|
51
recharge2.py
51
recharge2.py
|
@ -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 ",
|
lightning = [" X ",
|
||||||
" XX ",
|
" XX ",
|
||||||
" XXX ",
|
" XXX ",
|
||||||
" XXX ",
|
" XXX ",
|
||||||
" XXXX ",
|
" XXXX ",
|
||||||
"XXXXXXXX "]
|
"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):
|
for i in range(0, level):
|
||||||
line = lightning[i] if i < len(lightning) else lightning[len(lightning)-i-1][::-1]
|
line = lightning[i] if i < len(lightning) else lightning[len(lightning) - i - 1][::-1]
|
||||||
rtn = line.rjust(19)+"\n"+rtn
|
rtn = line.rjust(19) + "\n" + rtn
|
||||||
while rtn.count("\n") < 16:
|
while rtn.count("\n") < 16:
|
||||||
rtn="\n".rjust(19)+rtn
|
rtn = "\n".rjust(19) + rtn
|
||||||
return 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__":
|
|
||||||
|
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}")
|
||||||
fd.set_mode(Mode.DIFFERENTIAL)
|
fd.set_mode(Mode.DIFFERENTIAL)
|
||||||
l, h = fd.get_size()
|
l, h = fd.get_size()
|
||||||
while True:
|
while True:
|
||||||
for i in range(0, 12):
|
for i in range(0, len(lightning) * 2):
|
||||||
bat = get_battery(i).split("\n")[:-1]
|
bat = get_battery(i).split("\n")[:-1]
|
||||||
bat = list(map(lambda x: x.rjust(l), bat))
|
bat = list(map(lambda x: x.rjust(l), bat))
|
||||||
bat = "\n".join(bat)+"\n"
|
bat = "\n".join(bat) + "\n"
|
||||||
fd.post_frame_raw(frame=bat)
|
fd.post_frame_raw(frame=bat)
|
||||||
sleep(.5)
|
sleep(.5)
|
||||||
for i in range(12, 0, -1):
|
for i in range(len(lightning) * 2, 0, -1):
|
||||||
bat = get_battery(i).split("\n")[:-1]
|
bat = get_battery(i).split("\n")[:-1]
|
||||||
bat = list(map(lambda x: x.rjust(l), bat))
|
bat = list(map(lambda x: x.rjust(l), bat))
|
||||||
bat = "\n".join(bat)+"\n"
|
bat = "\n".join(bat) + "\n"
|
||||||
fd.post_frame_raw(frame=bat)
|
fd.post_frame_raw(frame=bat)
|
||||||
sleep(.5)
|
sleep(.5)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue