Ejemplo n.º 1
0
    def __init__(self):
        lifx = LifxLAN()
        devices = lifx.get_color_all_lights()
        if len(devices) < 1:
            print('not found...')
            sleep(0.1)
            devices = lifx.get_color_all_lights()

        self.lights = []
        for l in devices:
            if not l.supports_color():
                self.lights.append(l)
Ejemplo n.º 2
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print(
            "\nDiscovery will go much faster if you provide the number of lights on your LAN:"
        )
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    lifx = LifxLAN(num_lights)

    # test power control
    print("Discovering lights...")
    original_powers = lifx.get_power_all_lights()

    print("Turning lights on...")
    lifx.set_power_all_lights("on")

    sleep(0.2)

    print("Toggling power of all lights...")
    toggle_all_lights_power(lifx, 0.2)

    print("Restoring power to all lights...")
    for light, power in original_powers:
        light.set_power(power)

    # test color control
    original_colors = lifx.get_color_all_lights()

    print("Turning lights on...")
    lifx.set_power_all_lights("on")

    sleep(1)

    print("Toggling color of all lights quickly...")
    toggle_all_lights_color(lifx, 0.2)

    print("Toggling color of all lights slowly...")
    toggle_all_lights_color(lifx, 1)

    print("Restoring original color to all lights...")
    for light, color in original_colors:
        light.set_color(color)

    sleep(1)

    print("Restoring original power to all lights...")
    for light, power in original_powers:
        light.set_power(power)
Ejemplo n.º 3
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print(
            "\nDiscovery will go much faster if you provide the number of lights on your LAN:"
        )
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    lifx = LifxLAN(num_lights)
    bulbs = lifx.get_lights()

    # test power control
    print("Discovering lights...")
    original_powers = lifx.get_power_all_lights()
    original_colors = lifx.get_color_all_lights()
    print(original_colors)

    half_period_ms = 2500
    duration_mins = 20
    duration_secs = duration_mins * 60
    print("Breathing...")
    try:
        start_time = time()
        while True:
            for bulb in original_colors:
                color = original_colors[bulb]
                dim = list(copy(color))
                half_bright = int(dim[2] / 2)
                dim[2] = half_bright if half_bright >= 1900 else 1900
                bulb.set_color(dim, half_period_ms, rapid=True)
                sleep(half_period_ms / 1000.0)
            for bulb in original_colors:
                color = original_colors[bulb]
                bulb.set_color(color, half_period_ms, rapid=True)
                sleep(half_period_ms / 1000.0)
            if time() - start_time > duration_secs:
                raise KeyboardInterrupt
    except KeyboardInterrupt:
        print("Restoring original color to all lights...")
        for light in original_colors:
            color = original_colors[light]
            light.set_color(color)

        print("Restoring original power to all lights...")
        for light in original_powers:
            power = original_powers[light]
            light.set_power(power)
Ejemplo n.º 4
0
def main():
    print("Discovering lights...")
    lifx = LifxLAN(num_lights)

    original_colors = lifx.get_color_all_lights()
    original_powers = lifx.get_power_all_lights()

    print("Turning on all lights...")
    lifx.set_power_all_lights(True)
    sleep(1)

    lan.set_color_all_lights(0, 0, True)
Ejemplo n.º 5
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print("\nDiscovery will go much faster if you provide the number of lights on your LAN:")
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    lifx = LifxLAN(num_lights)

    # test power control
    print("Discovering lights...")
    original_powers = lifx.get_power_all_lights()

    print("Turning lights on...")
    lifx.set_power_all_lights("on")

    print("Toggling power of all lights...")
    toggle_all_lights_power(lifx, 0.2)

    print("Restoring power to all lights...")
    for light in original_powers:
        light.set_power(original_powers[light])

    # test color control
    original_colors = lifx.get_color_all_lights()

    print("Turning lights on...")
    lifx.set_power_all_lights("on")

    print("Toggling color of all lights quickly...")
    toggle_all_lights_color(lifx, 0.2)

    print("Toggling color of all lights slowly...")
    toggle_all_lights_color(lifx, 0.5)

    print("Restoring original color to all lights...")
    for light in original_colors:
        light.set_color(original_colors[light])

    sleep(0.2)

    print("Restoring original power to all lights...")
    for light in original_powers:
        light.set_power(original_powers[light])
Ejemplo n.º 6
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print("\nDiscovery will go much faster if you provide the number of lights on your LAN:")
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    lifx = LifxLAN(num_lights)

    # test power control
    print("Discovering lights...")
    original_powers = lifx.get_power_all_lights()
    original_colors = lifx.get_color_all_lights()

    half_period_ms = 2500
    duration_mins = 20
    duration_secs = duration_mins*60
    print("Breathing...")
    try:
        start_time = time()
        while True:
            for bulb in original_colors:
                color = original_colors[bulb]
                dim = list(copy(color))
                dim[2] = 1900
                bulb.set_color(dim, half_period_ms, rapid=True)
            sleep(half_period_ms/1000.0)
            for bulb in original_colors:
                color = original_colors[bulb]
                bulb.set_color(color, half_period_ms, rapid=True)
            sleep(half_period_ms/1000.0)
            if time() - start_time > duration_secs:
                raise KeyboardInterrupt
    except KeyboardInterrupt:
        print("Restoring original color to all lights...")
        for light in original_colors:
            color = original_colors[light]
            light.set_color(color)

        print("Restoring original power to all lights...")
        for light in original_powers:
            power = original_powers[light]
            light.set_power(power)
Ejemplo n.º 7
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print(
            "\nDiscovery will go much faster if you provide the number of lights on your LAN:"
        )
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    print("Discovering lights...")
    lifx = LifxLAN(num_lights)

    original_colors = lifx.get_color_all_lights()
    original_powers = lifx.get_power_all_lights()

    print("Turning on all lights...")
    lifx.set_power_all_lights(True)
    sleep(1)

    print("Flashy fast rainbow")
    rainbow(lifx, 0.1)

    print("Smooth slow rainbow")
    rainbow(lifx, 1, smooth=True)

    print("Restoring original color to all lights...")
    for light, color in original_colors:
        light.set_color(color)

    sleep(1)

    print("Restoring original power to all lights...")
    for light, power in original_powers:
        light.set_power(power)
Ejemplo n.º 8
0
def scene_two():
    num_lights = None
    if len(sys.argv) != 2:
        print()
    else:
        num_lights = int(sys.argv[1])

    lifx = LifxLAN(num_lights)
    original_colors = lifx.get_color_all_lights()
    original_powers = lifx.get_power_all_lights()
    lifx.set_power_all_lights(True)
    sleep(1)
    earth(lifx, 5, smooth=True)

    #print("Restoring original color to all lights...")
    for light in original_colors:
        light.set_color(original_colors[light])

    sleep(1)

    #print("Restoring original power to all lights...")
    for light in original_powers:
        light.set_power(original_powers[light])
Ejemplo n.º 9
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print("\nDiscovery will go much faster if you provide the number of lights on your LAN:")
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    print("Discovering lights...")
    lifx = LifxLAN(num_lights)

    original_colors = lifx.get_color_all_lights()
    original_powers = lifx.get_power_all_lights()

    print("Turning on all lights...")
    lifx.set_power_all_lights(True)
    sleep(1)

    print("Flashy fast rainbow")
    rainbow(lifx, 0.1)

    print("Smooth slow rainbow")
    rainbow(lifx, 1, smooth=True)

    print("Restoring original color to all lights...")
    for light in original_colors:
        light.set_color(original_colors[light])

    sleep(1)

    print("Restoring original power to all lights...")
    for light in original_powers:
        light.set_power(original_powers[light])
Ejemplo n.º 10
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print(
            "\nDiscovery will go much faster if you provide the number of lights on your LAN:"
        )
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    print("Discovering lights...")
    lifx = LifxLAN(num_lights)

    original_colors = lifx.get_color_all_lights()
    original_powers = lifx.get_power_all_lights()

    print("Turning on all lights...")
    lifx.set_power_all_lights(True)
    sleep(1)
    print("Discovering lights...")

    half_period_ms = 2500
    duration_mins = 20
    duration_secs = duration_mins * 60

    #60000 =red
    for bulb in original_colors:
        color = original_colors[bulb]
        dim = list(copy(color))
        i = 0
        dim[0] = 38000
        bulb.set_color(dim, 0, rapid=True)
        while True:
            text = raw_input("Color = ")
            dim[0] = int(text)
            bulb.set_color(dim, 0, rapid=True)
Ejemplo n.º 11
0
def setlightcolor(color):

    print("Discovering lights...")
    lifx = LifxLAN(1)

    devices = lifx.get_lights()
    print(f"Found light: {devices}")

    original_colors = lifx.get_color_all_lights()

    color_up = str(color.upper())

    if color_up == "OFF":
        lifx.set_power_all_lights("off")
        print("Turned off the light..")
        return ()

    color_name = {
        "RED": RED,
        "BLUE": BLUE,
        "CYAN": CYAN,
        "GREEN": GREEN,
        "ORANGE": ORANGE,
        "PURPLE": PURPLE,
        "YELLOW": YELLOW
    }

    print("Turning on the light...")
    lifx.set_power_all_lights("on")

    if color_up in color_name:
        print(f"Setting color to {color_up}")
        lifx.set_color_all_lights(color_name[color_up])
    else:
        print("Color not found, defaulting to pink")
        lifx.set_color_all_lights(PINK)
Ejemplo n.º 12
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print(
            "\nDiscovery will go much faster if you provide the number of lights on your LAN:"
        )
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    lifx = LifxLAN(num_lights)

    # test power control
    print("Discovering lights...")
    original_powers = lifx.get_power_all_lights()
    original_colors = lifx.get_color_all_lights()

    half_period_ms = 2500
    duration_mins = 20
    duration_secs = duration_mins * 60
    print("Breathing...")

    #inititalize lcd display
    lcd_init()
    #GPIO.setup(23,GPIO.OUT)
    #GPIO.setup(12,GPIO.OUT)
    #GPIO.output(12,GPIO.HIGH)
    #GPIO.output(23,GPIO.HIGH)

    GPIO.setup(17, GPIO.OUT)
    #connect headset to Rpi
    headset = mindwave.Headset('/dev/ttyUSB0', 'DB00')
    time.sleep(2)

    headset.connect()
    print "Connecting..."

    while headset.status != 'connected':
        time.sleep(0.5)
        if headset.status == 'standby':
            headset.connect()
            print "Retrying connect..."
    print "Connected."
    time.sleep(1)
    # dims bulb completely at beginning
    # brightness in range [0 - 65535]
    # set_color is [Hue, Saturation, Brightness, Kelvin], duration in ms
    for bulb in original_colors:
        color = original_colors[bulb]
        dim = list(copy(color))
        dim[2] = 65000
        dim[0] = 62000
        #print "changing bulb to %s" % dim[2]
        bulb.set_color(dim, half_period_ms, rapid=True)
    lightswitch = False
    previous = []

    #no idea what this is for lol
    # p = False

    prevAvg = 0
    count = 0
    while True:
        #This is for meditation
        time.sleep(1)
        #Take user input for number of readings per output
        avgSize = 4
        while True:
            question = "Average Size: " + str(avgSize)
            print question
            text = raw_input("Average Size = ")
            if text == "end":
                break
            avgSize = int(text)

        time.sleep(1)
        while True:
            if count < avgSize - 1:
                count += 1
                previous.append(headset.meditation)
                #for x in range(len(previous)):
                #   print previous[x]
            else:
                #p = False
                previous.append(headset.meditation)
                #for x in range(len(previous)):
                #    print previous[x]
                k = 0
                sum = 0
                while k < avgSize:
                    sum += previous[k]
                    k += 1
                Avg = sum / len(previous)
                #print original_colors
                # max brightness of bulb goes from 0 to 65535 based on reverse of Avg. So closer to max meditation means dimmer bulb.
                # brightness in range [0 - 65535]
                # set_color is [Hue, Saturation, Brightness, Kelvin], duration in ms
                for bulb in original_colors:
                    color = original_colors[bulb]
                    dim = list(copy(color))
                    #dim[2] = 655*(100-Avg)
                    dim[0] = 62000 - 200 * Avg
                    #bulb.set_color(dim, 0, rapid=True)
                    #print "changing bulb to %s" % dim[2]
                    bulb.set_color(dim, half_period_ms, rapid=True)
                #time.sleep(half_period_ms/1000.0)
                previous = []
                count = 0
                print "Meditation: %s changing bulb to %s" % (Avg, dim[0])
                #switch light state if avg is more than 50 and prev is less than 50
                if Avg >= 50 and prevAvg < 50:
                    if lightswitch == False:
                        GPIO.output(17, GPIO.HIGH)
                        lightswitch = True
                    else:
                        GPIO.output(17, GPIO.LOW)
                        lightswitch = False
                prevAvg = Avg
            time.sleep(1)
Ejemplo n.º 13
0
def main():
    num_lights = None
    if len(sys.argv) != 2:
        print("\nDiscovery will go much faster if you provide the number of lights on your LAN:")
        print("  python {} <number of lights on LAN>\n".format(sys.argv[0]))
    else:
        num_lights = int(sys.argv[1])

    # instantiate LifxLAN client, num_lights may be None (unknown).
    # In fact, you don't need to provide LifxLAN with the number of bulbs at all.
    # lifx = LifxLAN() works just as well. Knowing the number of bulbs in advance
    # simply makes initial bulb discovery faster.
    lifx = LifxLAN(num_lights)

    # test power control
    print("Discovering lights...")
    original_powers = lifx.get_power_all_lights()
    original_colors = lifx.get_color_all_lights()

    half_period_ms = 2500
    duration_mins = 20
    duration_secs = duration_mins*60
    print("Breathing...")
    
    #inititalize lcd display
    lcd_init()
    #GPIO.setup(23,GPIO.OUT)
    #GPIO.setup(12,GPIO.OUT)
    #GPIO.output(12,GPIO.HIGH)
    #GPIO.output(23,GPIO.HIGH)


    GPIO.setup(17,GPIO.OUT)
    #connect headset to Rpi
    headset = mindwave.Headset('/dev/ttyUSB0', 'DB00')
    time.sleep(2)

    headset.connect()
    print "Connecting..."

    while headset.status != 'connected':
        time.sleep(0.5)
        if headset.status == 'standby':
            headset.connect()
            print "Retrying connect..."
    print "Connected."
    time.sleep(1)
    # dims bulb completely at beginning
    # brightness in range [0 - 65535]
    # set_color is [Hue, Saturation, Brightness, Kelvin], duration in ms
    for bulb in original_colors:
        color = original_colors[bulb]
        dim = list(copy(color))
        dim[2] = 65000
        dim[0]=62000
        #print "changing bulb to %s" % dim[2]
        bulb.set_color(dim, half_period_ms, rapid=True)    
    previous = 0   
    #selecting options from menu  
    arr = ['Attention', 'Meditation', 'Blink']
    i = 0
    j = 1
    lcd_byte(LCD_LINE_1, LCD_CMD)
    lcd_string('Select option',2)
    lcd_byte(LCD_LINE_2, LCD_CMD)
    lcd_string('Press any Button' ,2)
    while GPIO.input(14)==GPIO.LOW and GPIO.input(15)==GPIO.LOW:
        pass
    time.sleep(1)
    lcd_byte(LCD_LINE_1, LCD_CMD)
    lcd_string("-->" + arr[i],2)
    lcd_byte(LCD_LINE_2, LCD_CMD)
    lcd_string(arr[j],2)
    while True:
        #print "Attention: %s, Meditation: %s, previous: %s" % (headset.attention, headset.meditation,previous)
        #scroll through options on the menu
        if GPIO.input(15)== GPIO.HIGH:
            print('Scrolling--------')
            
            i = (i+1)%3
            j = (j+1)%3
            lcd_byte(LCD_LINE_1, LCD_CMD)
            lcd_string("-->" + arr[i],2)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            lcd_string(arr[j],2)
            while GPIO.input(15)== GPIO.HIGH:
                pass
    ##      lcd.GPIO.cleanup()
        #select option
        if GPIO.input(14)== GPIO.HIGH:
            
            selected = arr[i]
            print ("Selected " + selected)
            lightswitch = False
            previous = []
            p = False
            prevAvg=0
            count = 0
            #if attention is selected
            if i==0:
                time.sleep(1)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                lcd_string("Type end to Cont",2)
                #Take user input for number of readings per output
                avgSize =4
                while True:
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    question = "Average Size: "+str(avgSize)
                    lcd_string(question,2)
                    text = raw_input("Average Size = ")
                    if text == "end":
                        break
                    avgSize = int(text)
                    
                    
                    

                lcd_byte(LCD_LINE_1, LCD_CMD)
                lcd_string("Sel. Attention ",2)
                time.sleep(1)
                while True:                    
                    if GPIO.input(14)==GPIO.HIGH:
                        break
                    if count < avgSize-1:
                        count+=1
                        previous.append(headset.attention)
                        #for x in range(len(previous)): 
                         #   print previous[x]
                    else:
                        #p = False
                        previous.append(headset.attention)
                        #for x in range(len(previous)): 
                        #    print previous[x]
                        k = 0
                        sum = 0
                        while k < avgSize:
                            sum += previous[k]
                            k+=1
                        Avg = sum/len(previous)
                        previous = []
                        count = 0
                        print "Attention: %s" % Avg
                        #switch light state if avg is more than 50 and prev is less than 50
                        if Avg >= 50 and prevAvg < 50:
                            if lightswitch == False :
                                GPIO.output(17,GPIO.HIGH)
                                lightswitch = True
                            else:
                                GPIO.output(17,GPIO.LOW)
                                lightswitch = False
                        prevAvg = Avg
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        lcd_string(str(Avg),2)                      
                    time.sleep(1)
            #if meditation is selected
            if i ==1:
                time.sleep(1)                
                lcd_byte(LCD_LINE_2, LCD_CMD)
                lcd_string("Type end to Cont",2)
                #Take user input for number of readings per output
                avgSize =4
                while True:
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    question = "Average Size: "+str(avgSize)
                    lcd_string(question,2)
                    text = raw_input("Average Size = ")
                    if text == "end":
                        break
                    avgSize = int(text)

                lcd_byte(LCD_LINE_1, LCD_CMD)
                lcd_string("Sel. Meditation ",2)
                time.sleep(1)
                while True:                    
                    if GPIO.input(14)==GPIO.HIGH:
                        break
                    if count < avgSize-1:
                        count+=1
                        previous.append(headset.meditation)
                        #for x in range(len(previous)): 
                         #   print previous[x]
                    else:
                        #p = False
                        previous.append(headset.meditation)
                        #for x in range(len(previous)): 
                        #    print previous[x]
                        k = 0
                        sum = 0
                        while k < avgSize:
                            sum += previous[k]
                            k+=1
                        Avg = sum/len(previous)
                        #print original_colors
                        # max brightness of bulb goes from 0 to 65535 based on reverse of Avg. So closer to max meditation means dimmer bulb.
                        # brightness in range [0 - 65535]
                        # set_color is [Hue, Saturation, Brightness, Kelvin], duration in ms
                        for bulb in original_colors:
                            color = original_colors[bulb]
                            dim = list(copy(color))
                            #dim[2] = 655*(100-Avg)
                            dim[0] = 62000-200*Avg
                            #bulb.set_color(dim, 0, rapid=True)
                            #print "changing bulb to %s" % dim[2]
                            bulb.set_color(dim, half_period_ms, rapid=True)
                        #time.sleep(half_period_ms/1000.0)
                        previous = []
                        count = 0
                        print "Meditation: %s changing bulb to %s" % (Avg,dim[0])
                        #switch light state if avg is more than 50 and prev is less than 50
                        if Avg >= 50 and prevAvg < 50:
                            if lightswitch == False :
                                GPIO.output(17,GPIO.HIGH)
                                lightswitch = True
                            else:
                                GPIO.output(17,GPIO.LOW)
                                lightswitch = False
                        prevAvg = Avg
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        lcd_string(str(Avg),2)                      
                    time.sleep(1)
            #if blink is selected
            #blink doesnt work yet
            if i == 2:
                print('WORK IN PROGRESS')
            lcd_byte(LCD_LINE_1, LCD_CMD)
            lcd_string("-->" + arr[i],2)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            lcd_string(arr[j],2)
            GPIO.output(17,GPIO.LOW)
            while GPIO.input(14)== GPIO.HIGH:
                pass
Ejemplo n.º 14
0
override_max_bright_total_rgb = 200 * 3
max_bright_override = 1.0

########### END CONFIG SETTINGS ###########

channels_per_light = 3  # Red, Green, Blue
scale_up = 65535  # This value will change what's concidered max brightness. minimum is 1 maximum is 65535
max_rgb_per_color = 255
max_rgb_total = max_rgb_per_color * 3
override_scaling = 1 / (max_rgb_total - override_max_bright_total_rgb)
# test power control
print("Discovering lights...")
lifx = LifxLAN(numb_lights)
lights = lifx.get_lights()
original_powers = lifx.get_power_all_lights()
original_colors = lifx.get_color_all_lights()


def dmx_channels(idx):
    start = first_channel + idx * channels_per_light
    end = start + channels_per_light
    return start, end


lights.sort(key=lambda l: l.get_label())
for i, l in enumerate(lights):
    startChannel, endChannel = dmx_channels(i)
    print(
        f"{l.label} is assigned to DMX channels {startChannel + 1} to {endChannel}"
    )