238 lines
8.0 KiB
Python
238 lines
8.0 KiB
Python
import sys, struct, time, serial
|
|
|
|
'connects to a fnordlicht'
|
|
""" http://github.com/fd0/fnordlicht/blob/master/doc/PROTOCOL """
|
|
|
|
class Fnordlicht:
|
|
|
|
tty = ''
|
|
verbose = False
|
|
|
|
def __init__(self, tty, verbose = False, addr = 255):
|
|
self.tty = tty
|
|
self.addr = addr
|
|
if verbose:
|
|
self.verbose = True
|
|
print 'using tty "%s", address "%s"' % (self.tty, self.addr)
|
|
|
|
def __send(self, data):
|
|
if self.verbose:
|
|
print 'sending package:',data
|
|
# pad data package with 0-characters
|
|
for i in range(15 - len(data)):
|
|
data.append(0)
|
|
try:
|
|
# open serial port at '19200,8N1', 1s timeout
|
|
ser = serial.Serial(self.tty, 19200, timeout=1)
|
|
for i in range(15):
|
|
ser.write(chr(data[i]))
|
|
ser.flush()
|
|
ser.close()
|
|
except:
|
|
print 'unable to send string on %s: %s' % (self.tty, sys.exc_info()[0])
|
|
|
|
def sync(self):
|
|
if self.verbose:
|
|
print 'sync()'
|
|
data = []
|
|
for i in range(14):
|
|
data.append(0x1b)
|
|
data.append(self.addr)
|
|
self.__send(data)
|
|
|
|
def fade_rgb(self, r, g, b, step, delay):
|
|
if self.verbose:
|
|
print 'fade_rgb(%d, %d, %d, %d, %d)' % (r, g, b, step, delay)
|
|
data = [self.addr, 0x01]
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(r)
|
|
data.append(g)
|
|
data.append(b)
|
|
self.__send(data)
|
|
|
|
def fade_hsv(self, h, s, v, step, delay):
|
|
if self.verbose:
|
|
print 'fade_hsv(%d, %d, %d, %d, %d)' % (h, s, v, step, delay)
|
|
data = [self.addr, 0x02]
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(ord(struct.pack('<h', h)[0]))
|
|
data.append(ord(struct.pack('<h', h)[1]))
|
|
data.append(s)
|
|
data.append(v)
|
|
self.__send(data)
|
|
|
|
def save_rgb(self, slot, r, g, b, step, delay, pause):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'save_rgb(%d, %d, %d, %d, %d, %d, %d)' % (slot, r, g, b, step, delay, pause)
|
|
data = [self.addr, 0x03]
|
|
data.append(slot)
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(ord(struct.pack('<H', pause)[0]))
|
|
data.append(ord(struct.pack('<H', pause)[1]))
|
|
data.append(r)
|
|
data.append(g)
|
|
data.append(b)
|
|
self.__send(data)
|
|
|
|
def save_hsv(self, slot, h, s, v, step, delay, pause):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'save_hsv(%d, %d, %d, %d, %d, %d, %d)' % (slot, h, s, v, step, delay, pause)
|
|
data = [self.addr, 0x04]
|
|
data.append(slot)
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(ord(struct.pack('<H', pause)[0]))
|
|
data.append(ord(struct.pack('<H', pause)[1]))
|
|
data.append(ord(struct.pack('<h', h)[0]))
|
|
data.append(ord(struct.pack('<h', h)[1]))
|
|
data.append(s)
|
|
data.append(v)
|
|
self.__send(data)
|
|
|
|
def save_current(self, slot, step, delay, pause):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'save_current(%d, %d, %d, %d)' % (slot, step, delay, pause)
|
|
data = [self.addr, 0x05]
|
|
data.append(slot)
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(ord(struct.pack('<H', pause)[0]))
|
|
data.append(ord(struct.pack('<H', pause)[1]))
|
|
self.__send(data)
|
|
|
|
def config_offsets(self, step, delay, h, s, v):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'config_offsets(%d, %d, %d, %d, %d)' % (step, delay, h, s, v)
|
|
data = [self.addr, 0x06]
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(ord(struct.pack('<h', h)[0]))
|
|
data.append(ord(struct.pack('<h', h)[1]))
|
|
data.append(s)
|
|
data.append(v)
|
|
self.__send(data)
|
|
|
|
def __start_program(self, program, params):
|
|
if self.verbose:
|
|
print 'start_program(%d, %s)' % (program, params)
|
|
data = [self.addr, 0x07]
|
|
data.append(program)
|
|
data.extend(params)
|
|
self.__send(data)
|
|
|
|
def program_colorwheel(self, fade_step, fade_delay, fade_sleep, hue_start, hue_step, add_addr, saturation, value):
|
|
if self.verbose:
|
|
print 'program_colorwheel(%d, %d, %d, %d, %d, %d, %d, %d)' % (fade_step, fade_delay, fade_sleep, hue_start, hue_step, add_addr, saturation, value)
|
|
data = [fade_step, fade_delay, fade_sleep]
|
|
data.append(ord(struct.pack('<H', hue_start)[0]))
|
|
data.append(ord(struct.pack('<H', hue_start)[1]))
|
|
data.append(ord(struct.pack('<h', hue_step)[0]))
|
|
data.append(ord(struct.pack('<h', hue_step)[1]))
|
|
data.append(add_addr)
|
|
data.append(saturation)
|
|
data.append(value)
|
|
self.__start_program(0, data)
|
|
|
|
def program_random(self, seed, flags, fade_step, fade_delay, fade_sleep, saturation, value, min_distance):
|
|
if self.verbose:
|
|
print 'program_random(%d, %d, %d, %d, %d, %d, %d, %d)' % (seed, flags, fade_step, fade_delay, fade_sleep, saturation, value, min_distance)
|
|
data = []
|
|
data.append(ord(struct.pack('<H', seed)[0]))
|
|
data.append(ord(struct.pack('<H', seed)[1]))
|
|
data.append(flags)
|
|
data.append(fade_step)
|
|
data.append(fade_delay)
|
|
data.append(ord(struct.pack('<H', fade_sleep)[0]))
|
|
data.append(ord(struct.pack('<H', fade_sleep)[1]))
|
|
data.append(saturation)
|
|
data.append(value)
|
|
data.append(min_distance)
|
|
self.__start_program(1, data)
|
|
|
|
def stop(self, fading = 1):
|
|
if self.verbose:
|
|
print 'stop(%d)' % (fading)
|
|
data = [self.addr, 0x08]
|
|
data.append(fading)
|
|
self.__send(data)
|
|
|
|
def modify_current(self, step, delay, r, g, b, h, s, v):
|
|
if self.verbose:
|
|
print 'modify_current(%d, %d, %d, %d, %d, %d, %d, %d)' % (step, delay, r, g, b, h, s, v)
|
|
data = [self.addr, 0x09]
|
|
data.append(step)
|
|
data.append(delay)
|
|
data.append(ord(struct.pack('<b', r)))
|
|
data.append(ord(struct.pack('<b', g)))
|
|
data.append(ord(struct.pack('<b', b)))
|
|
data.append(ord(struct.pack('<h', h)[0]))
|
|
data.append(ord(struct.pack('<h', h)[1]))
|
|
data.append(ord(struct.pack('<b', s)))
|
|
data.append(ord(struct.pack('<b', v)))
|
|
self.__send(data)
|
|
|
|
def pull_int(self, delay):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'pull_int(%d)' % (delay)
|
|
data = [self.addr, 0x0a]
|
|
data.append(delay)
|
|
self.__send(data)
|
|
|
|
def config_startup_nothing(self):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'config_startup_nothing()'
|
|
data = [self.addr, 0x0b]
|
|
data.append(0)
|
|
self.__send(data)
|
|
|
|
def config_startup_program(self, program, params):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'config_startup_program(%d, %s)' % (program, params)
|
|
data = [self.addr, 0x0b]
|
|
data.append(1)
|
|
data.append(program)
|
|
data.extend(params)
|
|
self.__send(data)
|
|
|
|
def powerdown(self):
|
|
# TODO untested
|
|
if self.verbose:
|
|
print 'powerdown()'
|
|
data = [self.addr, 0x0c]
|
|
self.__send(data)
|
|
|
|
# secondary functions
|
|
|
|
def fade_updown_rgb(self, r, g, b, step, delay, sleep_time):
|
|
self.fade_rgb(r, g, b, step, delay)
|
|
time.sleep(sleep_time)
|
|
self.fade_rgb(0, 0, 0, step, delay)
|
|
time.sleep(sleep_time)
|
|
|
|
def fade_updown_hsv(self, h, s, v, step, delay, sleep_time):
|
|
self.fade_hsv(h, s, v, step, delay)
|
|
time.sleep(sleep_time)
|
|
self.fade_hsv(h, s, 0, step, delay)
|
|
time.sleep(sleep_time)
|
|
|
|
|
|
#fnordlicht = Fnordlicht('/dev/ttyUSB0', verbose = True)
|
|
#fnordlicht.sync()
|
|
#fnordlicht.fade_rgb(255, 0, 0, 100, 1)
|
|
#fnordlicht.fade_hsv(300, 255, 255, 100, 1)
|
|
#fnordlicht.start_program(0, [1, 1, 1, 0, 0, 60, 0, 255, 255, 255]) # colorwheel
|
|
#fnordlicht.stop(fading = 1)
|
|
#fnordlicht.modify_current(1, 1, 0, 0, 0, 100, 100, 100)
|
|
#fnordlicht.fade_updown_rgb(255, 0, 0, 10, 1, 1)
|
|
#fnordlicht.program_random(23, 3, 1, 5, 1, 255, 255, 90)
|