commit 74abec00966236994bcd7b4563f77b02391fe4f5 Author: Stefan Kinzel Date: Fri Dec 23 01:33:23 2016 +0100 initial commit diff --git a/FlipdotSender.py b/FlipdotSender.py new file mode 100644 index 0000000..d44f54c --- /dev/null +++ b/FlipdotSender.py @@ -0,0 +1,104 @@ +from PIL import Image, ImageDraw, ImageFont +import socket +import binascii +import io +import time +import re + +class FlipdotSender(object): + ''' + classdocs + ''' + + C_BLACK = 0 + C_WHITE = 255 + + def __init__(self, udphost, udpport, img_size=(80,16), font_size=11, + font_offset1=(0,-2), font_offset2=(0,6), + font_family='/usr/share/fonts/gnu-free/FreeMono.ttf', + #font_family='/usr/share/fonts/truetype/freefont/FreeMono.ttf', + chars_per_line=11): + ''' + Constructor + ''' + + self._udphost = udphost + if not type(udpport) is int or udpport > 65536: + raise TypeError('port has to be int and > 65536 !!') + self._udpport = udpport + self._img_size = img_size + self._font_size = font_size + self._font_offset1 = font_offset1 + self._font_offset2 = font_offset2 + self._font_family = font_family + self._chars_per_line = chars_per_line + + self._sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + + + def _list2byte(self, l): + byte = 0 + i = 0 + for i in range(8): + byte += 2**(7-i) if l[i] else 0 + return byte + + def _array2packet(self, a): + return [self._list2byte(a[i*8:i*8+8]) for i in range(int(len(a)/8))] + + + def _send(self, image): + imgmap = [] + for pixel in image.getdata(): + r, g, b, a = pixel + if r == FlipdotSender.C_WHITE: + imgmap.append(1) + else: + imgmap.append(0) + + packet = self._array2packet(imgmap) + + self._sock.sendto(bytes(packet), (self._udphost, self._udpport)) + + def send_text(self, text): + image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) + draw = ImageDraw.Draw(image) + draw.fontmode = "1" # No AA + + font = ImageFont.truetype(self._font_family, self._font_size) + + cut = self._chars_per_line + + splitted_text = text.split("|") + + draw.text(self._font_offset1, splitted_text[0], font=font, fill=FlipdotSender.C_WHITE) + if not splitted_text[1] is None: + draw.text(self._font_offset2, splitted_text[1], font=font, fill=FlipdotSender.C_WHITE) + + self._send(image) + + def send_marquee(self, str, speed=3): + offset = self._img_size[0] + font = ImageFont.truetype(self._font_family, self._font_size) + + while offset >= -font.getsize(str)[0]-speed: + image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) + draw = ImageDraw.Draw(image) + draw.fontmode = "1" # No AA + + draw.text((offset,0), str, font=font, fill=FlipdotSender.C_WHITE) + self._send(image) + offset -= speed + time.sleep(0.15) + + def send_img(self, img): + background = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) + stream = io.BytesIO(img) + image = Image.open(stream) + image = image.convert(mode='RGBA') + image = image.resize(self._img_size) + image.save('/tmp/send2.jpeg', 'JPEG') + background.paste(image, box=(0,0), mask=None) + background.save('/tmp/send.jpeg', 'JPEG') + + self._send(background) diff --git a/mqtt-to-flipdot.py b/mqtt-to-flipdot.py new file mode 100644 index 0000000..edc614e --- /dev/null +++ b/mqtt-to-flipdot.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +import time +import paho.mqtt.client as mqtt +from FlipdotSender import FlipdotSender +import time + +def on_connect(client, userdata, flags, rc): + print("Connected with result code " + str(rc)) + client.subscribe("raum2/flipdot/text") + client.subscribe("raum2/flipdot/scroll") + + +def on_message(client, userdata, msg): + print(msg.topic + " " + str(msg.payload.decode("utf-8"))) + + if msg.topic == "raum2/flipdot/scroll": + payload = msg.payload.decode("utf-8") + speed = int(payload[0]) + + flipdot.send_marquee(payload[1:], speed) + if msg.topic == "raum2/flipdot/text": + payload = msg.payload.decode("utf-8") + flipdot.send_text(payload) + + + +flipdot = FlipdotSender("2001:67c:275c:a9::c", 2323) + +client = mqtt.Client() +client.on_connect = on_connect +client.on_message = on_message +client.connect("raum.ctdo.de", 1883, 60) +client.loop_start() + + +while True: + time.sleep(2) + +