sender.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function, absolute_import, division
  3. import socket
  4. from struct import pack, unpack
  5. from functools import wraps
  6. from collections import namedtuple
  7. DECODER = {}
  8. ENCODER = {}
  9. def decode(data):
  10. format, make = DECODER[ord(data[0])]
  11. args = tuple([e if not isinstance(e, str) else e.decode('utf-8').rstrip('\0') for e in unpack(format, data[1:])])
  12. return make(args)
  13. class Sender(object):
  14. def __init__(self, host, port):
  15. self.host = host
  16. self.port = port
  17. self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  18. def send(encoder):
  19. def _send(*args, **kwargs):
  20. data = encoder(*args, **kwargs)
  21. print('sending %s bytes' % len(data))
  22. self.sock.sendto(data, (self.host, self.port))
  23. return _send
  24. for name, f in ENCODER.iteritems():
  25. setattr(self, name, send(f))
  26. def matrix_api(api_index, format, names):
  27. assert api_index < 256
  28. def wrap(func):
  29. DECODER[api_index] = (format, namedtuple(func.__name__, names)._make)
  30. @wraps(func)
  31. def w(*args, **kwargs):
  32. pack_args = func(*args, **kwargs)
  33. if pack_args is None:
  34. assert not format and not names
  35. return chr(api_index)
  36. else:
  37. if isinstance(pack_args, (basestring, int, float)):
  38. pack_args = (pack_args, )
  39. #~ print(format, pack_args, pack(format, *pack_args))
  40. return chr(api_index) + pack(format, *pack_args)
  41. ENCODER[func.__name__] = w
  42. return w
  43. return wrap
  44. ## API Decls
  45. @matrix_api(1, '255s', 'text')
  46. def print_text(text):
  47. return text.encode('utf-8')
  48. @matrix_api(2, 'sh', 'text loop')
  49. def scroll_text(text, loop=1):
  50. return text.encode('utf-8'), loop
  51. @matrix_api(3, 'shh', 'text width fade')
  52. def fit_text(text, width=0, fade=0):
  53. return text.encode('utf-8'), width, fade
  54. @matrix_api(10, 'hh', 'step total')
  55. def progress(text, step=0, total=0):
  56. return step, total
  57. @matrix_api(255, '', '')
  58. def destroy():
  59. return None
  60. if __name__ == '__main__':
  61. #~ print(repr(print_text(u'Christine ♥')))
  62. print(decode(print_text(u'Christine ♥')).text.encode('utf-8'))
  63. #~ print(decode(print_text('Christine ♥'))._asdict())
  64. #~ print(type(decode(print_text('Christine ♥'))).__name__)
  65. sender = Sender('blaubeere.fritz.box', 10000)
  66. sender.print_text(u'Christine ♥')