Bläddra i källkod

added flaschentaschen

cc 4 år sedan
förälder
incheckning
38c060f1f3
2 ändrade filer med 81 tillägg och 0 borttagningar
  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 readline ipywidgets jupyter jupyterlab
 RUN pip3 install numpy
+RUN pip3 install pillow
+RUN pip3 install pyzmq
 
 # needs to build orjson - does not work on armv7
 #~ RUN pip3 install ipycanvas
@@ -57,3 +59,6 @@ EXPOSE 8888
 
 # passwd is "code"
 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()