Source code for bibliopixel.util.artnet_message

import ctypes, functools
from . import log

DMX_LENGTH = 512
ARTNET_DMX = 0x5000
ARTNET_VERSION = 14
NAME = b'Art-Net\x00'
MAX_NET = 0xFF
MAX_SUBNET = 0xF
MAX_UNIVERSE = 0xF
UDP_PORT = 0x1936  # 6454


[docs]@functools.lru_cache(maxsize=DMX_LENGTH) def MessageClass(length=DMX_LENGTH): assert 0 <= length <= DMX_LENGTH assert length % 2 == 0, 'artnet only takes messages of even length' Char, Int8, Int16 = ctypes.c_char, ctypes.c_ubyte, ctypes.c_ushort class DMXMessage(ctypes.Structure): # http://artisticlicence.com/WebSiteMaster/User%20Guides/art-net.pdf p47 _fields_ = [ ('id', Char * 8), ('opCode', Int16), ('protVerHi', Int8), ('protVerLo', Int8), ('sequence', Int8), ('physical', Int8), ('subUni', Int8), ('net', Int8), ('lengthHi', Int8), ('length', Int8), ('data', Int8 * length), # At position 18 ] return DMXMessage
[docs]def dmx_message( length=None, net=0, subnet=0, universe=0, sequence=1, data=None): if length is None: length = DMX_LENGTH if (data is None) else len(data) elif data is not None: assert len(data) == length Message = MessageClass(length) assert 0 <= sequence <= DMX_LENGTH assert 0 <= net <= MAX_NET assert 0 <= subnet <= MAX_SUBNET assert 0 <= universe <= MAX_UNIVERSE # http://artisticlicence.com/WebSiteMaster/User%20Guides/art-net.pdf p5 subUni = (subnet << 4) + universe hi, lo = divmod(length, 256) msg = Message( id=NAME, opCode=ARTNET_DMX, protVerLo=ARTNET_VERSION, sequence=sequence, net=net, subUni=subUni, lengthHi=hi, length=lo) if data is not None: msg.data[:] = data return msg
DMXMessage = MessageClass() EMPTY_MESSAGE_SIZE = ctypes.sizeof(MessageClass(0))
[docs]def bytes_to_message(b): if not isinstance(b, bytearray): b = bytearray(b) length = len(b) - EMPTY_MESSAGE_SIZE assert 0 <= length <= DMX_LENGTH result = MessageClass(length).from_buffer(b) if result.id == NAME[:-1]: return result # For some reason, ctypes throws away that trailing \0 character # when converting back to bytes(). log.error('Expected name %s but got name %s', NAME[:-1], result.id)