import socket class Matrix(object): '''A Framebuffer display interface that sends a frame via UDP. see https://github.com/hzeller/flaschen-taschen/blob/master/doc/protocols.md ''' def __init__(self, host, width, height, layer=1, x_offset=0, y_offset=0, transparent=False, port=1337): ''' Args: host: The flaschen taschen server hostname or ip address. port: The flaschen taschen server port number. width: The width of the flaschen taschen display in pixels. height: The height of the flaschen taschen display in pixels. layer: The layer of the flaschen taschen display to write to. (layer=0 is permanent, layer > 0 decays, see --layer-timeout server opt) transparent: If true, black(0, 0, 0) will be transparent and show the layer below. ''' self.width = width self.height = height self.layer = layer self.transparent = transparent self.x_offset = x_offset self.y_offset = y_offset self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self._sock.connect((host, port)) self._init_data() def _init_data(self): header = ''.join(["P6\n", "%d %d\n" % (self.width, self.height), "255\n"]).encode('utf-8') footer = ''.join(["%d\n" % self.x_offset, "%d\n" % self.y_offset, "%d\n" % self.layer]).encode('utf-8') self._data = bytearray(self.width * self.height * 3 + len(header) + len(footer)) self._data[0:len(header)] = header self._data[-1 * len(footer):] = footer self._header_len = len(header) def set(self, x, y, color): '''Set the pixel at the given coordinates to the specified color. Args: x: x offset of the pixel to set y: y offset of the piyel to set color: A 3 tuple of (r, g, b) color values, 0-255 ''' if x >= self.width or y >= self.height or x < 0 or y < 0: return if color == (0, 0, 0) and not self.transparent: color = (1, 1, 1) offset = (x + y * self.width) * 3 + self._header_len self._data[offset] = color[0] self._data[offset + 1] = color[1] self._data[offset + 2] = color[2] def set_offset(self, x, y): self.x_offset = x self.y_offset = y self._init_data() def send(self): '''Send the updated pixels to the display.''' self._sock.send(self._data) if __name__ == '__main__': f = Matrix('192.168.178.144', 50, 50) import time for j in range(10): time.sleep(1) f.set_offset(j*2, j) for i in range(100): f.set(i, i, (200, 0, 0)) f.send()