Compare commits

..

3 Commits

3 changed files with 97 additions and 54 deletions

View File

@ -11,7 +11,7 @@ class FlipdotSender(object):
''' '''
classdocs classdocs
''' '''
C_BLACK = 0 C_BLACK = 0
C_WHITE = 255 C_WHITE = 255
@ -20,17 +20,17 @@ class FlipdotSender(object):
lastimgmap = [] lastimgmap = []
def __init__(self, udphost, udpport, img_size=(80,16), font_size=9, font_size_scroll=12, def __init__(self, udphost, udpport, img_size=(80,16), font_size=9, font_size_scroll=12,
font_offset1=(0,0), font_offset2=(0,8), font_offset1=(0,0), font_offset2=(0,8),
#font_family='/usr/share/fonts/gnu-free/FreeMono.ttf', #font_family='/usr/share/fonts/gnu-free/FreeMono.ttf',
font_family='/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf', font_family='/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf',
#font_family='/usr/share/fonts/truetype/freefont/FreeMono.ttf', #font_family='/usr/share/fonts/truetype/freefont/FreeMono.ttf',
chars_per_line=11): chars_per_line=11):
''' '''
Constructor Constructor
''' '''
self._udphost = udphost self._udphost = udphost
if not type(udpport) is int or udpport > 65536: if not type(udpport) is int or udpport > 65536:
raise TypeError('port has to be int and > 65536 !!') raise TypeError('port has to be int and > 65536 !!')
@ -42,24 +42,24 @@ class FlipdotSender(object):
self._font_offset2 = font_offset2 self._font_offset2 = font_offset2
self._font_family = font_family self._font_family = font_family
self._chars_per_line = chars_per_line self._chars_per_line = chars_per_line
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def stopAnimation(self): def stopAnimation(self):
global threadrunning global threadrunning
threadrunning=False #tried to stop a running animation threadrunning=False #tried to stop a running animation
def _list2byte(self, l): def _list2byte(self, l):
byte = 0 byte = 0
i = 0 i = 0
for i in range(8): for i in range(8):
byte += 2**(7-i) if l[i] else 0 byte += 2**(7-i) if l[i] else 0
return byte return byte
def _array2packet(self, a): def _array2packet(self, a):
return [self._list2byte(a[i*8:i*8+8]) for i in range(int(len(a)/8))] return [self._list2byte(a[i*8:i*8+8]) for i in range(int(len(a)/8))]
''' '''
def _send(self, image): #old function, backup def _send(self, image): #old function, backup
imgmap = [] imgmap = []
@ -71,14 +71,14 @@ class FlipdotSender(object):
imgmap.append(0) imgmap.append(0)
lastimgmap=imgmap lastimgmap=imgmap
packet = self._array2packet(imgmap) packet = self._array2packet(imgmap)
self._sock.sendto(bytes(packet), (self._udphost, self._udpport))''' self._sock.sendto(bytes(packet), (self._udphost, self._udpport))'''
def _send(self, image,fadespeed=0): #changes slowly 'fadespeed'-pixels at a time def _send(self, image,fadespeed=0): #changes slowly 'fadespeed'-pixels at a time
global threadrunning global threadrunning
#if fadespeed=0 -> change instant. #if fadespeed=0 -> change instant.
#time to change= 1280/25*0.2 #time to change= 1280/25*0.2
imgmap = [] imgmap = []
for pixel in image.getdata(): for pixel in image.getdata():
@ -90,7 +90,7 @@ class FlipdotSender(object):
imgmaptmp=FlipdotSender.lastimgmap imgmaptmp=FlipdotSender.lastimgmap
if fadespeed>0: if fadespeed>0:
threadrunning=True threadrunning=True
#diff=np.sum(np.array(imgmaptmp) != np.array(imgmap)) #different pixels #diff=np.sum(np.array(imgmaptmp) != np.array(imgmap)) #different pixels
@ -111,14 +111,14 @@ class FlipdotSender(object):
threadrunning=False threadrunning=False
else: else:
self.sendPacket(imgmap) #send packet and save last-imagemap self.sendPacket(imgmap) #send packet and save last-imagemap
def sendPacket(self, imgmap): def sendPacket(self, imgmap):
packet = self._array2packet(imgmap) packet = self._array2packet(imgmap)
self._sock.sendto(bytes(packet), (self._udphost, self._udpport)) self._sock.sendto(bytes(packet), (self._udphost, self._udpport))
FlipdotSender.lastimgmap=imgmap FlipdotSender.lastimgmap=imgmap
def send_bytes(self, img): def send_bytes(self, img):
imgmap = [] imgmap = []
for pixel in img: for pixel in img:
@ -134,70 +134,81 @@ class FlipdotSender(object):
self._sock.sendto(bytes(packet), (self._udphost, self._udpport)) self._sock.sendto(bytes(packet), (self._udphost, self._udpport))
def send_binimage(self, data,fadespeed=0): #works like send_bytes, but enables fadeanimation
image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK)
draw = ImageDraw.Draw(image)
draw.fontmode = "1"
for i,d in enumerate(data):
if d=="1":
draw.point((i%self._img_size[0],int(i/self._img_size[0])), fill=FlipdotSender.C_WHITE)
self._send(image,fadespeed)
def send_text(self, text,fadespeed=0): def send_text(self, text,fadespeed=0):
image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK)
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
draw.fontmode = "1" # No AA draw.fontmode = "1" # No AA
font = ImageFont.truetype(self._font_family, self._font_size) font = ImageFont.truetype(self._font_family, self._font_size)
cut = self._chars_per_line cut = self._chars_per_line
splitted_text = text.split("|") splitted_text = text.split("|")
draw.text(self._font_offset1, splitted_text[0], font=font, fill=FlipdotSender.C_WHITE) draw.text(self._font_offset1, splitted_text[0], font=font, fill=FlipdotSender.C_WHITE)
if len(splitted_text)>1: if len(splitted_text)>1:
draw.text(self._font_offset2, splitted_text[1], font=font, fill=FlipdotSender.C_WHITE) draw.text(self._font_offset2, splitted_text[1], font=font, fill=FlipdotSender.C_WHITE)
self._send(image,fadespeed) self._send(image,fadespeed)
def send_textFull(self, text,fadespeed=0): def send_textFull(self, text,fadespeed=0):
image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK)
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
draw.fontmode = "1" # No AA draw.fontmode = "1" # No AA
l=1000 #init very high l=1000 #init very high
splitpoint=40 #very high splitpoint=40 #very high
currentfontsize=12+1 #init with max font size currentfontsize=12+1 #init with max font size
font = ImageFont.truetype(self._font_family, currentfontsize) font = ImageFont.truetype(self._font_family, currentfontsize)
while(l>80): #while text too long and font not too small while(l>80): #while text too long and font not too small
if currentfontsize>8: if currentfontsize>8:
currentfontsize=currentfontsize-1 #reduce size and try if fits currentfontsize=currentfontsize-1 #reduce size and try if fits
else: #if fontsize too small, try cutting sentence (2 lines) else: #if fontsize too small, try cutting sentence (2 lines)
splitpoint=splitpoint-1 splitpoint=splitpoint-1
font = ImageFont.truetype(self._font_family, currentfontsize) font = ImageFont.truetype(self._font_family, currentfontsize)
l=draw.textsize(text[0:splitpoint], font=font)[0] l=draw.textsize(text[0:splitpoint], font=font)[0]
print("Textlength="+str(l)+" split="+str(splitpoint)) print("Textlength="+str(l)+" split="+str(splitpoint))
if splitpoint==40: #not splitted if splitpoint==40: #not splitted
draw.text((0,int((16-currentfontsize)/2) ), text, font=font, fill=FlipdotSender.C_WHITE) draw.text((0,int((16-currentfontsize)/2) ), text, font=font, fill=FlipdotSender.C_WHITE)
else: else:
draw.text((0,-1), text[0:splitpoint], font=font, fill=FlipdotSender.C_WHITE) draw.text((0,-1), text[0:splitpoint], font=font, fill=FlipdotSender.C_WHITE)
draw.text((0,-1+currentfontsize), text[splitpoint:], font=font, fill=FlipdotSender.C_WHITE) draw.text((0,-1+currentfontsize), text[splitpoint:], font=font, fill=FlipdotSender.C_WHITE)
self._send(image,fadespeed) self._send(image,fadespeed)
def send_marquee(self, str, speed=3): def send_marquee(self, str, speed=3):
global threadrunning global threadrunning
threadrunning=True threadrunning=True
offset = self._img_size[0] offset = self._img_size[0]
font = ImageFont.truetype(self._font_family, self._font_size_scroll) font = ImageFont.truetype(self._font_family, self._font_size_scroll)
while offset >= -font.getsize(str)[0]-speed and threadrunning==True: while offset >= -font.getsize(str)[0]-speed and threadrunning==True:
image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK)
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
draw.fontmode = "1" # No AA draw.fontmode = "1" # No AA
draw.text((offset,0), str, font=font, fill=FlipdotSender.C_WHITE) draw.text((offset,0), str, font=font, fill=FlipdotSender.C_WHITE)
self._send(image) self._send(image)
offset -= speed offset -= speed
time.sleep(0.15) time.sleep(0.15)
threadrunning=False threadrunning=False
def send_img(self, img): def send_img(self, img):
background = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) background = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK)
stream = io.BytesIO(img) stream = io.BytesIO(img)
@ -207,5 +218,5 @@ class FlipdotSender(object):
image.save('/tmp/send2.jpeg', 'JPEG') image.save('/tmp/send2.jpeg', 'JPEG')
background.paste(image, box=(0,0), mask=None) background.paste(image, box=(0,0), mask=None)
background.save('/tmp/send.jpeg', 'JPEG') background.save('/tmp/send.jpeg', 'JPEG')
self._send(background) self._send(background)

View File

@ -48,7 +48,7 @@ class Hangman(object):
self._fo_word2= (15, 7) #(15,7) self._fo_word2= (15, 7) #(15,7)
#self._wordlist="/home/pi/mqtt-to-flipdot/hangman/wordlists/nomenliste_de.txt" #self._wordlist="/home/pi/mqtt-to-flipdot/hangman/wordlists/nomenliste_de.txt"
#self._wordlist="/home/pi/mqtt-to-flipdot/hangman/wordlists/wordsonly.txt" #self._wordlist="/home/pi/mqtt-to-flipdot/hangman/wordlists/wordsonly.txt"
self._wordlist="/root/mqtt-to-flipdot/hangman/wordlists/wordsonly.txt" self._wordlist="/root/mqtt-to-flipdot/hangman/wordlists/wordsonly.txt" #<- on flipdot pi
#self._wordlist="/home/pi/mqtt-to-flipdot/hangman/wordlists/nerdwords.txt" #self._wordlist="/home/pi/mqtt-to-flipdot/hangman/wordlists/nerdwords.txt"
#self._wordlist="./hangman/wordlists/nerdwords.txt" #<- use for local testing #self._wordlist="./hangman/wordlists/nerdwords.txt" #<- use for local testing
@ -58,7 +58,7 @@ class Hangman(object):
self._g_chars="" #used characters self._g_chars="" #used characters
# self._hmdir="/home/pi/mqtt-to-flipdot/hangman/stdhm/" # self._hmdir="/home/pi/mqtt-to-flipdot/hangman/stdhm/"
self._hmdir="/root/mqtt-to-flipdot/hangman/stdhm/" self._hmdir="/root/mqtt-to-flipdot/hangman/stdhm/" #<- on flipdot pi
#self._hmdir="./hangman/stdhm/" #<- use for local testing #self._hmdir="./hangman/stdhm/" #<- use for local testing
self._hmimg=[] self._hmimg=[]

View File

@ -33,14 +33,14 @@ def on_message(client, userdata, msg):
mode="inuse" mode="inuse"
updateTimeout() updateTimeout()
payload = msg.payload.decode("utf-8") payload = msg.payload.decode("utf-8")
if len(payload)>0 and (payload[0]).isdigit(): if len(payload)>0 and (payload[0]).isdigit():
speed = int(payload[0]) speed = int(payload[0])
text = payload[1:] text = payload[1:]
else: else:
speed = 3 speed = 3
text = payload text = payload
#flipdot.send_marquee(text, speed) #flipdot.send_marquee(text, speed)
if flipthread is not None and flipthread.isAlive(): if flipthread is not None and flipthread.isAlive():
flipdot.stopAnimation() flipdot.stopAnimation()
@ -48,7 +48,7 @@ def on_message(client, userdata, msg):
flipdot.stopAnimation() #try to stop animation flipdot.stopAnimation() #try to stop animation
time.sleep(0.1) time.sleep(0.1)
flipthread.join() #wait for thread to finish flipthread.join() #wait for thread to finish
flipthread=Thread(target=flipdot.send_marquee, args=(text,speed)) flipthread=Thread(target=flipdot.send_marquee, args=(text,speed))
flipthread.start() flipthread.start()
@ -72,21 +72,55 @@ def on_message(client, userdata, msg):
flipthread.start() flipthread.start()
if msg.topic == "raum2/flipdot/textFull/set": #scale/break text automatically if mode!="inuse" and msg.topic == "raum2/flipdot/textFull/set": #scale/break text automatically
mode="inuse" #mode="inuse"
updateTimeout() #updateTimeout()
payload = msg.payload.decode("utf-8") payload = msg.payload.decode("utf-8")
if flipthread is not None and flipthread.isAlive():
flipdot.stopAnimation()
while flipthread.isAlive():
flipdot.stopAnimation() #try to stop animation
time.sleep(0.1)
flipthread.join()
if len(payload)>0 and payload[0]=='~': if len(payload)>0 and payload[0]=='~':
payload=payload[1:] payload=payload[1:]
flipdot.send_textFull(payload,50) #flipdot.send_textFull(payload,50)
flipdot.send_textFull(payload) flipthread=Thread(target=flipdot.send_textFull, args=(payload,64))
else:
#flipdot.send_textFull(payload)
flipthread=Thread(target=flipdot.send_textFull, args=(payload,))
flipthread.start()
if msg.topic == "raum2/flipdot/image/set": if msg.topic == "raum2/flipdot/image/set":
'''
mode="inuse" mode="inuse"
updateTimeout() updateTimeout()
payload = msg.payload.decode("utf-8") payload = msg.payload.decode("utf-8")
print(payload) print(payload)
flipdot.send_bytes(payload) flipdot.send_bytes(payload)
'''
payload = msg.payload.decode("utf-8")
if flipthread is not None and flipthread.isAlive():
flipdot.stopAnimation()
while flipthread.isAlive():
flipdot.stopAnimation() #try to stop animation
time.sleep(0.1)
flipthread.join()
if len(payload)>0 and payload[0]=='~':
payload=payload[1:]
#flipdot.send_textFull(payload,50)
flipthread=Thread(target=flipdot.send_binimage, args=(payload,64))
else:
#flipdot.send_textFull(payload)
flipthread=Thread(target=flipdot.send_binimage, args=(payload,))
flipthread.start()
@ -98,7 +132,7 @@ def on_message(client, userdata, msg):
updateTimeout() updateTimeout()
client.publish("raum2/flipdot/hangman","started") client.publish("raum2/flipdot/hangman","started")
mode="hangman" mode="hangman"
elif (mode=="hangman") and (len(payload)>0): #try entered character elif (mode=="hangman") and (len(payload)>0): #try entered character
updateTimeout() updateTimeout()
trychar=payload[-1] trychar=payload[-1]
@ -112,16 +146,16 @@ def on_message(client, userdata, msg):
client.publish("raum2/flipdot/hangman","won") client.publish("raum2/flipdot/hangman","won")
elif gamestatus==0: #ended in another way elif gamestatus==0: #ended in another way
client.publish("raum2/flipdot/hangman","ended") client.publish("raum2/flipdot/hangman","ended")
if payload=="#stop": if payload=="#stop":
mode="standby" mode="standby"
client.publish("raum2/flipdot/hangman","ended") client.publish("raum2/flipdot/hangman","ended")
def updateTimeout(): def updateTimeout():
global timeout global timeout
timeout=int(round(time.time() * 1000)) timeout=int(round(time.time() * 1000))
#flipdot = FlipdotSender("2001:67c:275c:a9::c", 2323) #flipdot = FlipdotSender("2001:67c:275c:a9::c", 2323)
flipdot = FlipdotSender("localhost", 2323) flipdot = FlipdotSender("localhost", 2323)
@ -133,7 +167,7 @@ hangman= Hangman("localhost", 2323,flipdot)
client = mqtt.Client() client = mqtt.Client()
client.on_connect = on_connect client.on_connect = on_connect
client.on_message = on_message client.on_message = on_message
client.connect("raum.ctdo.de", 1883, 60) client.connect("mqtt.ctdo.de", 1883, 60)
client.loop_start() client.loop_start()
@ -150,5 +184,3 @@ while True:
timeout=0 timeout=0
time.sleep(2) time.sleep(2)