cdosea-play/cdoseaplay/lights.py

140 lines
3.6 KiB
Python
Executable File

#!/usr/bin/python3
import os
import string
import subprocess
import sys
import time
import ox
import sacn
from .pi import random
from . import config
# Screen 1-5, Control, 6,7
'''
> _*10 patterns / cues that correspond to 10 digit:*_
> 0 = Screen LED @ 100% fade time = 9s (cue list 1)
> 1 = LED Control @ 10% fade time = 8s (cue list 2)
> 2 = LED Control @ 20% fade time = 7s (cue list 3)
> 3 = LED Control @ 30% fade time = 6s (cue list 4)
> 4 = LED Control @ 40% fade time = 5s (cue list 5)
> 5 = LED Control @ 50% fade time = 4s (cue List 6)
> 6 = LED Control @ 60% fade time = 3s (cue list 7)
> 7 = LED Control @ 70% fade time = 2s (cue list 8)
> 8 = LED Control @ 80% fade time = 1s (cue list 9)
> 9 = LED Control @ 90% fade time = 0s (cue list 10)
'''
def channels(screen, control):
screen = int(screen * 255)
control = int(control * 255)
return {'1': screen, '2': screen, '3': screen, '4': screen, '5': screen, '6': control, '7': control}
LIGHTS = {
0: (channels(1, 0.0), 9),
1: (channels(0, 0.1), 8),
2: (channels(0, 0.2), 7),
3: (channels(0, 0.3), 6),
4: (channels(0, 0.4), 5),
5: (channels(0, 0.5), 4),
6: (channels(0, 0.6), 3),
7: (channels(0, 0.7), 2),
8: (channels(0, 0.8), 1),
9: (channels(0, 0.9), 0.1),
}
CURRENT_STATE = [0] * 16
def send(state):
sender = sacn.sACNsender()
sender.start()
universe = 1
sender.activate_output(universe)
sender[1].multicast = True
n = 16
while n:
sender[1].dmx_data = [value] * n
time.sleep(1)
n -= 1
sender[1].dmx_data = [0]
time.sleep(10) # send the data for 10 seconds
def fade_to(target, duration):
global CURRENT_STATE
sender = sacn.sACNsender()
sender.start()
universe = 1
sender.activate_output(universe)
sender[1].multicast = True
current = CURRENT_STATE[0]
distance = target - current
steps = int(duration * 10)
step = duration/steps
delta = distance/steps
value = current
switch = 0
while steps:
switch += 1
value += delta
n = int(round(value))
if n != current:
current = n
old = sender[1].dmx_data[:16]
target = [n] * 16
if switch % 2:
a = target
b = old
else:
a = old
b = target
sender[1].dmx_data = [a[x] if x % 2 else b[x] for x in range(16)]
CURRENT_STATE = sender[1].dmx_data[:16]
time.sleep(step)
steps -= 1
sender[1].dmx_data = [0] * 16
CURRENT_STATE = [0] * 16
time.sleep(0.1)
sender.stop()
def switch(state):
if config.lanbox:
import lanbox
lb = lanbox.Lanbox()
lb.layerGo(state)
else:
lights, duration = LIGHTS[state]
brightness = lights['7']
fade_to(brightness, duration)
if __name__ == '__main__':
path = sys.argv[1]
no_sleep = len(sys.argv) > 2 and sys.argv[2] == "no-sleep"
n = int(os.path.getctime(path) - 1495280000) % 1000
info = ox.avinfo(path)
duration = info.get('duration', 0)
seq = random(n * 100)
pos = 0
lights = []
letter_offset = 0
letter = path.split('/')[-1][0].lower()
if config.letter_offset:
letter_offset = 11 + string.ascii_lowercase.index(letter) * 10
while pos < duration - 15:
sleep = seq() + 15
light = seq()
if pos + sleep > duration:
break
if not no_sleep:
time.sleep(sleep)
print("letter", letter, "offset", letter_offset, "light", light, "cue", letter_offset + light)
switch(light + letter_offset)
pos += sleep