Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to send ArtSync message in the Art-Net protocol implementation. #27

Merged
merged 5 commits into from
Mar 16, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions stupidArtnet/StupidArtnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def __init__(self, target_ip='127.0.0.1', universe=0, packet_size=512, fps=30,
self.net = 0
self.packet_size = put_in_range(packet_size, 2, 512, even_packet_size)
self.packet_header = bytearray()
self.artsync_header = bytearray()
self.buffer = bytearray(self.packet_size)

self.make_even = even_packet_size
Expand All @@ -61,13 +62,16 @@ def __init__(self, target_ip='127.0.0.1', universe=0, packet_size=512, fps=30,
self.fps = fps
self.__clock = None

self.make_header()
self.make_artdmx_header()
self.make_artsync_header()


def __del__(self):
"""Graceful shutdown."""
self.stop()
self.close()


def __str__(self):
"""Printable object state."""
state = "===================================\n"
Expand All @@ -82,7 +86,8 @@ def __str__(self):

return state

def make_header(self):

def make_artdmx_header(self):
"""Make packet header."""
# 0 - id (7 x bytes + Null)
self.packet_header = bytearray()
Expand Down Expand Up @@ -125,6 +130,38 @@ def make_header(self):
self.packet_header.append(msb)
self.packet_header.append(lsb)


def make_artsync_header(self):
"""Make ArtSync header"""
self.artsync_header = bytearray() # Initialize as empty bytearray
# ID: Array of 8 characters, the final character is a null termination.
self.artsync_header.extend(bytearray('Art-Net', 'utf8'))
self.artsync_header.append(0x0)
# OpCode: Defines the class of data within this UDP packet. Transmitted low byte first.
self.artsync_header.append(0x00)
self.artsync_header.append(0x52)
# ProtVerHi and ProtVerLo: Art-Net protocol revision number. Current value =14.
# Controllers should ignore communication with nodes using a protocol version lower than =14.
self.artsync_header.append(0x0)
self.artsync_header.append(14)
# Aux1 and Aux2: Should be transmitted as zero.
self.artsync_header.append(0x0)
self.artsync_header.append(0x0)


def send_artsync(self):
"""Send Artsync"""
self.make_artsync_header()
packet = bytearray()
packet.extend(self.artsync_header)
try:
self.socket_client.sendto(packet, (self.target_ip, self.UDP_PORT))
except socket.error as error:
print(f"ERROR: Socket error with exception: {error}")
finally:
self.sequence = (self.sequence + 1) % 256

kacper516 marked this conversation as resolved.
Show resolved Hide resolved

def show(self):
"""Finally send data."""
packet = bytearray()
Expand All @@ -137,6 +174,7 @@ def show(self):
finally:
self.sequence = (self.sequence + 1) % 256


def close(self):
"""Close UDP socket."""
self.socket_client.close()
Expand All @@ -150,6 +188,7 @@ def start(self):
self.__clock.daemon = True
self.__clock.start()


def stop(self):
"""Stops thread clock."""
if self.__clock is not None:
Expand All @@ -169,42 +208,47 @@ def set_universe(self, universe):
self.universe = put_in_range(universe, 0, 255, False)
else:
self.universe = put_in_range(universe, 0, 15, False)
self.make_header()
self.make_artdmx_header()


def set_subnet(self, sub):
"""Setter for subnet address (0 - 15).

Set simplify to false to use
"""
self.subnet = put_in_range(sub, 0, 15, False)
self.make_header()
self.make_artdmx_header()


def set_net(self, net):
"""Setter for net address (0 - 127).

Set simplify to false to use
"""
self.net = put_in_range(net, 0, 127, False)
self.make_header()
self.make_artdmx_header()


def set_packet_size(self, packet_size):
"""Setter for packet size (2 - 512, even only)."""
self.packet_size = put_in_range(packet_size, 2, 512, self.make_even)
self.make_header()
self.make_artdmx_header()

# SETTERS - DATA #

def clear(self):
"""Clear DMX buffer."""
self.buffer = bytearray(self.packet_size)


def set(self, value):
"""Set buffer."""
if len(value) != self.packet_size:
print("ERROR: packet does not match declared packet size")
return
self.buffer = value


def set_16bit(self, address, value, high_first=False):
"""Set single 16bit value in DMX buffer."""
if address > self.packet_size:
Expand All @@ -223,6 +267,7 @@ def set_16bit(self, address, value, high_first=False):
self.buffer[address - 1] = (value) & 0xFF # low
self.buffer[address] = (value >> 8) & 0xFF # high


def set_single_value(self, address, value):
"""Set single value in DMX buffer."""
if address > self.packet_size:
Expand All @@ -233,6 +278,7 @@ def set_single_value(self, address, value):
return
self.buffer[address - 1] = put_in_range(value, 0, 255, False)


def set_single_rem(self, address, value):
"""Set single value while blacking out others."""
if address > self.packet_size:
Expand All @@ -244,6 +290,7 @@ def set_single_rem(self, address, value):
self.clear()
self.buffer[address - 1] = put_in_range(value, 0, 255, False)


def set_rgb(self, address, red, green, blue):
"""Set RGB from start address."""
if address > self.packet_size:
Expand All @@ -268,6 +315,7 @@ def send(self, packet):
self.set(packet)
self.show()


def set_simplified(self, simplify):
"""Builds Header accordingly.

Expand All @@ -279,21 +327,25 @@ def set_simplified(self, simplify):
if simplify == self.is_simplified:
return
self.is_simplified = simplify
self.make_header()
self.make_artdmx_header()


def see_header(self):
"""Show header values."""
print(self.packet_header)


def see_buffer(self):
"""Show buffer values."""
print(self.buffer)


def blackout(self):
"""Sends 0's all across."""
self.clear()
self.show()


def flash_all(self, delay=None):
"""Sends 255's all across."""
self.set([255] * self.packet_size)
Expand Down Expand Up @@ -331,6 +383,10 @@ def flash_all(self, delay=None):
a.show()

print("Values sent")

a.send_artsync()

print("ArtSync sent")

# Cleanup when you are done
del a