Browse Source

added flaschentaschen

cc 4 years ago
parent
commit
38c060f1f3
2 changed files with 81 additions and 0 deletions
  1. 5 0
      jlab/Dockerfile
  2. 76 0
      jlab/matrix_ft.py

+ 5 - 0
jlab/Dockerfile

@@ -19,6 +19,8 @@ RUN pip3 install --upgrade pip
 RUN pip3 install cython
 RUN pip3 install cython
 RUN pip3 install readline ipywidgets jupyter jupyterlab
 RUN pip3 install readline ipywidgets jupyter jupyterlab
 RUN pip3 install numpy
 RUN pip3 install numpy
+RUN pip3 install pillow
+RUN pip3 install pyzmq
 
 
 # needs to build orjson - does not work on armv7
 # needs to build orjson - does not work on armv7
 #~ RUN pip3 install ipycanvas
 #~ RUN pip3 install ipycanvas
@@ -57,3 +59,6 @@ EXPOSE 8888
 
 
 # passwd is "code"
 # passwd is "code"
 CMD ["jupyter", "lab", "--allow-root", "--NotebookApp.token=''", "--NotebookApp.password='argon2:$argon2id$v=19$m=10240,t=10,p=8$GXZHXm2yFviNanoy9hyULw$1YLbN5ymQxuwvwPVN5e0hA'"]
 CMD ["jupyter", "lab", "--allow-root", "--NotebookApp.token=''", "--NotebookApp.password='argon2:$argon2id$v=19$m=10240,t=10,p=8$GXZHXm2yFviNanoy9hyULw$1YLbN5ymQxuwvwPVN5e0hA'"]
+
+# some custom libs for jlab
+COPY ./matrix_ft.py /usr/local/lib/python3.8/site-packages/matrix_ft.py

+ 76 - 0
jlab/matrix_ft.py

@@ -0,0 +1,76 @@
+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=0, 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.
+          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()