Kaynağa Gözat

more pixel pushing

dirkse 8 yıl önce
ebeveyn
işleme
a665ea3d53
3 değiştirilmiş dosya ile 93 ekleme ve 14 silme
  1. 1 1
      matrix/Dockerfile
  2. 10 13
      matrix/pixelreceiver.py
  3. 82 0
      matrix/sender.py

+ 1 - 1
matrix/Dockerfile

@@ -75,5 +75,5 @@ RUN make -C examples-api-use
 # for python interface
 RUN cd bindings/python && make build-python install-python
 
-COPY pixelreceiver.py /
+COPY *.py /
 CMD python -u /pixelreceiver.py > /pixel/receive.log & jupyter notebook --allow-root

+ 10 - 13
matrix/pixelreceiver.py

@@ -12,6 +12,7 @@ from path import Path
 from rgbmatrix import RGBMatrix, RGBMatrixOptions
 from rgbmatrix import graphics
 from PIL import Image
+from sender import decode
 
 def asc_desc_modulation(x, interval, clamp=0.1):
     sub_idx = x % interval
@@ -163,27 +164,23 @@ try:
             print('waiting to receive message')
             data, address = sock.recvfrom(4096)
 
-            method = ord(data[0])
+            api_call = decode(data)
+
+            # get name of namedtuple
+            method = type(api_call).__name__
             print('received %s bytes from %s [method: %s]' % (len(data), address, method))
 
             r.set_brightness(255)
 
-            data = data[1:]
-
-            if method == 0:
-                r.print_text(data.decode('utf-8'))
-            elif method == 1:
-                r.scroll_text(data.decode('utf-8'))
-            elif method == 2:
-                r.fit_text(data.decode('utf-8'))
-            elif method == 10:
-                r.progress(ord(data[0]), ord(data[1]))
-
-            elif method == 255:
+            if method == 'destroy':
                 # kill SwapOnVSync
                 r.destroy()
                 # XXX: how to re-setup
                 #~ r.setup()
+            else:
+                kwargs = api_call._asdict()
+                getattr(r, method)(**kwargs)
+
         except Exception:
             print(traceback.format_exc())
 

+ 82 - 0
matrix/sender.py

@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import print_function, absolute_import, division
+import socket
+
+from struct import pack, unpack
+from functools import wraps
+from collections import namedtuple
+
+DECODER = {}
+ENCODER = {}
+def decode(data):
+    format, make = DECODER[ord(data[0])]
+    args = tuple([e if not isinstance(e, str) else e.decode('utf-8').rstrip('\0') for e in unpack(format, data[1:])])
+    return make(args)
+
+
+class Sender(object):
+    def __init__(self, host, port):
+        self.host = host
+        self.port = port
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+        def send(encoder):
+            def _send(*args, **kwargs):
+                data = encoder(*args, **kwargs)
+                print('sending %s bytes' % len(data))
+                self.sock.sendto(data, (self.host, self.port))
+            return _send
+        for name, f in ENCODER.iteritems():
+            setattr(self, name, send(f))
+
+def matrix_api(api_index, format, names):
+    assert api_index < 256
+    def wrap(func):
+        DECODER[api_index] = (format, namedtuple(func.__name__, names)._make)
+        @wraps(func)
+        def w(*args, **kwargs):
+            pack_args = func(*args, **kwargs)
+            if pack_args is None:
+                assert not format and not names
+                return chr(api_index)
+            else:
+                if isinstance(pack_args, (basestring, int, float)):
+                    pack_args = (pack_args, )
+                #~ print(format, pack_args, pack(format, *pack_args))
+                return chr(api_index) + pack(format, *pack_args)
+        ENCODER[func.__name__] = w
+        return w
+    return wrap
+
+## API Decls
+
+@matrix_api(1, '255s', 'text')
+def print_text(text):
+    return text.encode('utf-8')
+
+@matrix_api(2, 'sh', 'text loop')
+def scroll_text(text, loop=1):
+    return text.encode('utf-8'), loop
+
+@matrix_api(3, 'shh', 'text width fade')
+def fit_text(text, width=0, fade=0):
+    return text.encode('utf-8'), width, fade
+
+@matrix_api(10, 'hh', 'step total')
+def progress(text, step=0, total=0):
+    return step, total
+
+@matrix_api(255, '', '')
+def destroy():
+    return None
+
+if __name__ == '__main__':
+    #~ print(repr(print_text(u'Christine ♥')))
+    print(decode(print_text(u'Christine ♥')).text.encode('utf-8'))
+    #~ print(decode(print_text('Christine ♥'))._asdict())
+    #~ print(type(decode(print_text('Christine ♥'))).__name__)
+
+
+    sender = Sender('blaubeere.fritz.box', 10000)
+    sender.print_text(u'Christine ♥')