diff --git a/lw12.py b/lw12.py index 56a408a..5c54d21 100644 --- a/lw12.py +++ b/lw12.py @@ -25,13 +25,14 @@ _LW12_PKT_TAIL = b'\xef' class LW12_MODE(Enum): LIGHT = b'\x04' - COLOR = b'\x05' - DETECT = b'\x07' + EFFECT = b'\x05' + COLOR = b'\x07' IGNORE = b'\xff' -class LW12_DETECT(Enum): - SCAN = b'\x09' +class LW12_CONTROL(Enum): + RGB = b'\x05' + SCAN_CTRL = b'\x09' IGNORE = b'\xff' @@ -40,6 +41,7 @@ class LW12_LIGHT(Enum): FLASH = b'\x02' SET = b'\x03' POWER = b'\x04' + DIM = b'\x05' # Unused: To be used with LW12_MODE.EFFECT IGNORE = b'\xff' @@ -49,7 +51,7 @@ class LW12_POWER(Enum): IGNORE = b'\xff' -class LW12_COLOR_STATIC(Enum): +class LW12_EFFECT_STATIC(Enum): RED = b'\x80' BLUE = b'\x81' GREEN = b'\x82' @@ -59,12 +61,12 @@ class LW12_COLOR_STATIC(Enum): WHITE = b'\x86' -class LW12_COLOR_JUMP(Enum): +class LW12_EFFECT_JUMP(Enum): TRICOLOR = b'\x87' SEVENCOLOR = b'\x88' -class LW12_COLOR_GRADIENT(Enum): +class LW12_EFFECT_GRADIENT(Enum): TRICOLOR = b'\x89' SEVENCOLOR = b'\x8a' RED = b'\x8b' @@ -79,7 +81,7 @@ class LW12_COLOR_GRADIENT(Enum): GREEN_BLUE = b'\x94' -class LW12_COLOR_FLASH(Enum): +class LW12_EFFECT_FLASH(Enum): SEVENCOLOR = b'\x95' RED = b'\x96' GREEN = b'\x97' @@ -90,6 +92,19 @@ class LW12_COLOR_FLASH(Enum): WHITE = b'\x9c' +class Color(object): + + def __init__(self, value): + self._value = value + + @property + def value(self): + return bytes([self._value]) + + def __repr__(self): + return ''.format(self.value) + + LW12_Packet = namedtuple('Packet', 'head data pad tail') LW12_Payload = namedtuple('Payload', 'mode option value r g b') @@ -98,21 +113,21 @@ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) class LW12Controller(object): - def __init__(self, host, port): + def __init__(self, host, port, detect=False): self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.socket_receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.host = host self.port = port - self.socket_receiver.bind(('', 6000)) + self._detect_controllers = detect + if detect: + self.socket_receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.socket_receiver.bind(('', 6000)) def get_remote_socket(self): return (self.host, self.port) def send(self, payload, sock=None): data = self._compile_packet(payload) - if payload.mode == LW12_MODE.DETECT: + if payload.option == LW12_CONTROL.SCAN_CTRL: pad = b'\xff' else: pad = b'\x00' @@ -120,15 +135,14 @@ class LW12Controller(object): if len(packet) != 9: raise Exception('Invalid data length. Packet malformed') try: - from hexdump import hexdump - hexdump(packet) - print(sock or self.get_remote_socket()) return self.socket.sendto(packet, sock or self.get_remote_socket()) except OSError as oserr: if oserr.errno == 101: print('Network is unreachable') def read(self): + if not self._detect_controllers: + return None buffer_, sender = self.socket_receiver.recvfrom(_LW12_PKT_LEN) print(buffer_) print(sender) @@ -159,11 +173,11 @@ class LW12Controller(object): value=LW12_POWER.ON) self.send(payload) - def set_effect_color(self, color): + def set_effect(self, effect): payload = LW12_Payload(r=LW12_LIGHT.SET, g=LW12_LIGHT.IGNORE, b=LW12_LIGHT.IGNORE, mode=LW12_MODE.LIGHT, option=LW12_LIGHT.SET, - value=color) + value=effect) self.send(payload) def set_light_option(self, option, value): @@ -176,11 +190,20 @@ class LW12Controller(object): value=bytes([value])) self.send(payload) + def set_color(self, red, green, blue): + payload = LW12_Payload(r=Color(red), g=Color(green), b=Color(blue), + mode=LW12_MODE.COLOR, + option=LW12_CONTROL.RGB, + value=LW12_LIGHT.SET) + self.send(payload) + def scan(self, broadcast_addr='255.255.255.255', broadcast_port=5000): + if not self._detect_controllers: + return None # Fail safe handling for integers > 100 payload = LW12_Payload(r=LW12_DETECT.IGNORE, g=LW12_DETECT.IGNORE, b=LW12_DETECT.IGNORE, mode=LW12_MODE.DETECT, - option=LW12_DETECT.SCAN, + option=LW12_DETECT.SCAN_CTRL, value=LW12_DETECT.IGNORE) self.send(payload, (broadcast_addr, broadcast_port)) self.read() diff --git a/test.py b/test.py index 67ea447..a49d8ce 100644 --- a/test.py +++ b/test.py @@ -11,35 +11,37 @@ time.sleep(.500) print('[+] LW12 LIGHT ON') lw12.light_on() time.sleep(.500) -# print('[+] LW12_COLOR_STATIC') -# for color in LW12_COLOR_STATIC: -# print(' {}'.format(color)) -# lw12.set_effect_color(color) -# time.sleep(.250) -# print('[+] LW12_LIGHT.BRIGHTNESS') -# for brightness in range(0, 101, 5): -# print(' brightness={}'.format(brightness)) -# lw12.set_light_option(LW12_LIGHT.BRIGHTNESS, brightness) -# time.sleep(.250) -# print('[+] LW12_LIGHT.FLASH') -# print(' speed=100') -# lw12.set_light_option(LW12_LIGHT.FLASH, 100) -# print('[+] LW12_COLOR_JUMP') -# for color in LW12_COLOR_JUMP: -# print(' {}'.format(color)) -# lw12.set_effect_color(color) -# time.sleep(2) -# print('[+] LW12_COLOR_FLASH') -# for color in LW12_COLOR_FLASH: -# print(' {}'.format(color)) -# lw12.set_effect_color(color) -# time.sleep(2) -# print('[+] LW12_COLOR_GRADIENT') -# for color in LW12_COLOR_GRADIENT: -# print(' {}'.format(color)) -# lw12.set_effect_color(color) -# time.sleep(2) -# lw12.set_effect_color(LW12_COLOR_STATIC.PURPLE) -# lw12.set_light_option(LW12_LIGHT.BRIGHTNESS, 10) +print('[+] LW12_EFFECT_STATIC') +for effect in LW12_EFFECT_STATIC: + print(' {}'.format(effect)) + lw12.set_effect(effect) + time.sleep(.250) +print('[+] LW12_LIGHT.BRIGHTNESS') +for brightness in range(0, 101, 5): + print(' brightness={}'.format(brightness)) + lw12.set_light_option(LW12_LIGHT.BRIGHTNESS, brightness) + time.sleep(.250) +print('[+] LW12_LIGHT.FLASH') +print(' speed=100') +lw12.set_light_option(LW12_LIGHT.FLASH, 100) +print('[+] LW12_EFFECT_JUMP') +for effect in LW12_EFFECT_JUMP: + print(' {}'.format(effect)) + lw12.set_effect(effect) + time.sleep(2) +print('[+] LW12_EFFECT_FLASH') +for effect in LW12_EFFECT_FLASH: + print(' {}'.format(effect)) + lw12.set_effect(effect) + time.sleep(2) +print('[+] LW12_EFFECT_GRADIENT') +for effect in LW12_EFFECT_GRADIENT: + print(' {}'.format(effect)) + lw12.set_effect(effect) + time.sleep(2) +lw12.set_effect(LW12_EFFECT_STATIC.PURPLE) +lw12.set_light_option(LW12_LIGHT.BRIGHTNESS, 10) print('[+] LW12 SCAN') lw12.scan() +print('[+] LW12 SET COLOR r=255, g=75, b=216') +lw12.set_color(255, 75, 216)