matrix_ft.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import socket
  2. class Matrix(object):
  3. '''A Framebuffer display interface that sends a frame via UDP.
  4. see https://github.com/hzeller/flaschen-taschen/blob/master/doc/protocols.md
  5. '''
  6. def __init__(self, host, width, height, layer=1, x_offset=0, y_offset=0, transparent=False, port=1337):
  7. '''
  8. Args:
  9. host: The flaschen taschen server hostname or ip address.
  10. port: The flaschen taschen server port number.
  11. width: The width of the flaschen taschen display in pixels.
  12. height: The height of the flaschen taschen display in pixels.
  13. layer: The layer of the flaschen taschen display to write to. (layer=0 is permanent, layer > 0 decays, see --layer-timeout server opt)
  14. transparent: If true, black(0, 0, 0) will be transparent and show the layer below.
  15. '''
  16. self.width = width
  17. self.height = height
  18. self.layer = layer
  19. self.transparent = transparent
  20. self.x_offset = x_offset
  21. self.y_offset = y_offset
  22. self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  23. self._sock.connect((host, port))
  24. self._init_data()
  25. def _init_data(self):
  26. header = ''.join(["P6\n",
  27. "%d %d\n" % (self.width, self.height),
  28. "255\n"]).encode('utf-8')
  29. footer = ''.join(["%d\n" % self.x_offset,
  30. "%d\n" % self.y_offset,
  31. "%d\n" % self.layer]).encode('utf-8')
  32. self._data = bytearray(self.width * self.height * 3 + len(header) + len(footer))
  33. self._data[0:len(header)] = header
  34. self._data[-1 * len(footer):] = footer
  35. self._header_len = len(header)
  36. def set(self, x, y, color):
  37. '''Set the pixel at the given coordinates to the specified color.
  38. Args:
  39. x: x offset of the pixel to set
  40. y: y offset of the piyel to set
  41. color: A 3 tuple of (r, g, b) color values, 0-255
  42. '''
  43. if x >= self.width or y >= self.height or x < 0 or y < 0:
  44. return
  45. if color == (0, 0, 0) and not self.transparent:
  46. color = (1, 1, 1)
  47. offset = (x + y * self.width) * 3 + self._header_len
  48. self._data[offset] = color[0]
  49. self._data[offset + 1] = color[1]
  50. self._data[offset + 2] = color[2]
  51. def set_offset(self, x, y):
  52. self.x_offset = x
  53. self.y_offset = y
  54. self._init_data()
  55. def send(self):
  56. '''Send the updated pixels to the display.'''
  57. self._sock.send(self._data)
  58. if __name__ == '__main__':
  59. f = Matrix('192.168.178.144', 50, 50)
  60. import time
  61. for j in range(10):
  62. time.sleep(1)
  63. f.set_offset(j*2, j)
  64. for i in range(100):
  65. f.set(i, i, (200, 0, 0))
  66. f.send()