Skip to content
Snippets Groups Projects
Commit 253bdf6d authored by leo's avatar leo
Browse files

+IpProgPacket

parent d64c6a70
Branches master
No related tags found
No related merge requests found
......@@ -81,11 +81,35 @@ class ArtNetPacket(object):
physical = self.physical,
)
def _split_integer_to_byte(self, p_integer, p_length=2, p_bits=8):
"""
Splits a integer into a bytelist (not bytearray) of the given length.
Every chunk is p_bits bits long
"""
bitmask = (2 ** p_bits) - 1
bytelist = []
for counter in range(p_length - 1, -1, -1):
shifted = p_integer >> counter * (p_bits)
bytelist.append(shifted & bitmask)
return bytelist
def _format_value(self, p_value, p_format):
if type(p_value) is str:
return p_value.encode()
if type(p_value) is int:
length = p_format / 8
return self._split_integer_to_byte(p_value, length)
if type(p_value) is list:
return p_value
raise ValueError("Unknown type: %s" % str(type(p_value)))
def encode(self):
"""
Encodes a package into a bytearray.
"""
fields = []
packet = []
# Iterates through all entries of the schema
for name, fmt in self.schema:
# If there is a function to access the value, the function is called
......@@ -96,12 +120,18 @@ class ArtNetPacket(object):
else:
value = getattr(self, name)
# Store values in array
fields.append([name, fmt, value])
formated = self._format_value(value, fmt)
#fields.append([name, fmt, value])
packet.append(formated)
# Builds a bytearray to send as packet
fmt = ', '.join(['='.join([f,n]) for n,f,v in fields])
data = dict([(n,v) for n,f,v in fields])
return bitstring.pack(fmt, **data).tobytes()
#fmt = ', '.join(['='.join([f,n]) for n,f,v in fields])
#data = dict([(n,v) for n,f,v in fields])
#return bitstring.pack(fmt, **data).tobytes()
return packet
STANDARD_PORT = 6454
......
......@@ -8,9 +8,93 @@ class IpProgPacket(ArtNetPacket):
('header', 'bytes:8'),
('opcode', 'int:16'),
('protocol_version', 'uintbe:16'),
('filler1', 'bytes:8'),
('filler2', 'bytes:8'),
('command', 'bytes:8'),
('filler4', 'bytes:8'),
('filler1', 'int:8'),
('filler2', 'int:8'),
('command', 'int:8'),
('filler4', 'int:8'),
('progiphi', 'uint:8'),
('progip2', 'uint:8'),
('progip1', 'uint:8'),
('progiplo', 'uint:8'),
('progsmhi', 'uint:8'),
('progsm2', 'uint:8'),
('progsm1', 'uint:8'),
('progsmlo', 'uint:8'),
('progporthi', 'int:8'), # Deprecated
('progportlo', 'int:8'), # Deprecated
# Spare
('filler4', 'int:8'), # 1
('filler4', 'int:8'), # 2
('filler4', 'int:8'), # 3
('filler4', 'int:8'), # 4
('filler4', 'int:8'), # 5
('filler4', 'int:8'), # 6
('filler4', 'int:8'), # 7
('filler4', 'int:8'), # 8
)
)
\ No newline at end of file
def __init__(self, p_command=0, p_ip="127.0.0.1", p_netmask="255.255.255.0"):
self.command = p_command
self.ip = p_ip
self.netmask = p_netmask
self.progporthi = 0
self.progportlo = 0
def __setattr__(self, p_name, p_value):
if p_name is "ip":
self.progiphi, self.progip2, self.progip1, self.progiplo = self._split_into_octets(p_value)
if p_name is "netmask":
self.progsmhi, self.progsm2, self.progsm1, self.progsmlo = self._split_into_octets(p_value)
def _split_into_octets(self, p_ip):
"""
Splits a IP-like string into 4 int representing the octets
"""
type_p_ip = type(p_ip)
if type_p_ip is not str:
raise ValueError("String required, %s given" % type_p_ip
splitted = p_ip.split(".")
if len(splitted) is not 4:
raise ValueError("Given IP does not consist of 4 octets: %s " % p_ip)
ip_0 = int(splitted[0])
ip_1 = int(splitted[1])
ip_2 = int(splitted[2])
ip_3 = int(splitted[3])
return (ip_0, ip_1, ip_2, ip_3)
@ArtNetPacket.register
class IpProgReplyPacket(ArtNetPacket):
opcode = OPCODES['OpIpProgReply']
schema = (
('header', 'bytes:8'),
('opcode', 'int:16'),
('protocol_version', 'uintbe:16'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('progiphi', 'uint:8'),
('progip2', 'uint:8'),
('progip1', 'uint:8'),
('progiplo', 'uint:8'),
('progsmhi', 'uint:8'),
('progsm2', 'uint:8'),
('progsm1', 'uint:8'),
('progsmlo', 'uint:8'),
('progporthi', 'int:8'),
('status', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
('filler4', 'int:8'),
)
def __init__(self):
self.progporthi = 0
self.progportlo = 0
\ No newline at end of file
......@@ -21,10 +21,9 @@ class DmxPacket(ArtNetPacket):
super(DmxPacket, self).__init__(**kwargs)
self.frame = frame
#@classmethod
#def parse_framedata(cls, b, fmt):
#from artnet import dmx
#return dmx.Frame([ord(x) for x in b.read('bytes:512')])
@classmethod
def parse_framedata(cls, b, fmt):
return [ord(x) for x in b.read('bytes')]
def format_length(self):
return len(self.frame)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment