165 lines
4.4 KiB
Python
Executable file
165 lines
4.4 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 = Cue list 1 = 1x flash (on, off)
|
|
1 = Cue list 2 = 2x flashes (on, off, on, off)
|
|
2 = Cue list 3 = 3x flashes (on, off, on, off, on, off)
|
|
...and so on...
|
|
8 = Cue list 9 = 9x flashes
|
|
9 = Cue list 10 = 10x flashes
|
|
|
|
The basic timing for 1x flash is:
|
|
|
|
- Flash on over 0s
|
|
- Hold on for 0.2s
|
|
- Flash off over 0s
|
|
- Hold off for 0.2s
|
|
|
|
'''
|
|
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
|
|
|
|
|
|
# avoid overload and turn light on with a fade
|
|
def fade_to(sender, start, end, duration, channels=16, universe=1, lights=[]):
|
|
distance = end - start
|
|
steps = int(duration * 10)
|
|
if not steps:
|
|
steps = 2
|
|
step = duration/steps
|
|
delta = distance/steps
|
|
current = start
|
|
value = current
|
|
switch = 0
|
|
while steps:
|
|
switch += 1
|
|
value += delta
|
|
n = int(round(value))
|
|
if n != current:
|
|
current = n
|
|
old = sender[1].dmx_data[:channels]
|
|
target = [n] * channels
|
|
if switch % 2:
|
|
a = target
|
|
b = old
|
|
else:
|
|
a = old
|
|
b = target
|
|
channel_data = [a[x] if x % 2 else b[x] for x in range(channels)]
|
|
sender[universe].dmx_data = channel_data + lights[channels:]
|
|
time.sleep(step)
|
|
steps -= 1
|
|
channel_data = [end] * channels
|
|
sender[universe].dmx_data = channel_data + lights[channels:]
|
|
|
|
def dmx_base(letter):
|
|
lights = [0] * 512
|
|
letter_offset = 101 - 1
|
|
for offset in range(letter_offset, letter_offset+27):
|
|
lights[offset] = config.letter_base_light
|
|
if letter:
|
|
lights[letter_offset + string.ascii_lowercase.index(letter.lower())] = 255
|
|
lights[letter_offset + 26] = 255
|
|
return lights
|
|
|
|
|
|
def flash(sender, universe, flashes, letter):
|
|
step = 0.2
|
|
flash_duration = 0.02
|
|
base = 0
|
|
brightness = config.lights_brightness
|
|
channels = config.led_lights
|
|
|
|
sender[universe].dmx_data = [0] * channels
|
|
while flashes:
|
|
lights = dmx_base(letter)
|
|
fade_to(sender, base, brightness, flash_duration, channels, universe, lights)
|
|
time.sleep(step)
|
|
lights = dmx_base(None)
|
|
channel_data = [0] * channels
|
|
sender[universe].dmx_data = channel_data + lights[channels:]
|
|
time.sleep(step)
|
|
flashes -= 1
|
|
lights = dmx_base(None)
|
|
channel_data = [0] * channels
|
|
sender[universe].dmx_data = channel_data + lights[channels:]
|
|
time.sleep(step)
|
|
|
|
|
|
def switch(state, seq):
|
|
import lanbox
|
|
lb = lanbox.Lanbox()
|
|
lb.layerGo(state)
|
|
|
|
|
|
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:
|
|
if config.lanbox:
|
|
letter_offset = 11 + string.ascii_lowercase.index(letter) * 10
|
|
if not config.lanbox:
|
|
universe = 1
|
|
sender = sacn.sACNsender()
|
|
sender.start()
|
|
sender.activate_output(universe)
|
|
sender[universe].multicast = True
|
|
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)
|
|
if config.lanbox:
|
|
switch(light + letter_offset, seq)
|
|
else:
|
|
flash(sender, universe, light + 1, letter)
|
|
pos += sleep
|
|
if not config.lanbox:
|
|
sender.stop()
|