|
|
@@ -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 ♥')
|