#! /usr/bin/python3
# -*- coding: utf-8 -*-
"""
This file is part of LibreLight.
LibreLight is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 2 of the License.
LibreLight is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LibreLight. If not, see .
(c) 2012 micha@uxsrv.de
"""
import sys
import time
import json
import zlib
rnd_id = ""
rnd_id += " Beta 22.02 "
import subprocess
rnd_id += subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('ascii').strip()
if "__file__" in dir():
sys.stdout.write("\x1b]2;"+str(__file__)+" "+rnd_id+"\x07") # terminal title
else:
sys.stdout.write("\x1b]2;"+str("__file__")+" "+rnd_if+"\x07") # terminal title
__run_main = 0
if __name__ == "__main__":
__run_main = 1
else:
import __main__
print(dir())
if "unittest" not in dir(__main__):
__run_main = 1
import time
import socket
import struct
import sys
import random
import math
from collections import OrderedDict
import lib.zchat as chat
import lib.ArtNetNode as ANN
import _thread as thread
#thread.start_new_thread
import lib.motion as motion
#idmx = [0]*512 # incremental dmx
dmx = [0]*512 # absolute dmx data
gcolor = 1
def cprint(*text,color="blue",space=" ",end="\n"):
#return 0 #disable print dbg
if not gcolor:
print(text)
return 0
if color == "green":
txt = '\033[92m'
elif color == "red":
txt = '\033[0;31m\033[1m'
elif color == "yellow":
txt = '\033[93m\033[1m'
elif color == "cyan":
txt = '\033[96m'
else:
txt = '\033[94m'
for t in text:
txt += str(t ) +" "
#HEADER = '\033[95m'
#OKBLUE = '\033[94m'
#OKCYAN = '\033[96m'
#OKGREEN = '\033[92m'
#WARNING = '\033[93m'
#FAIL = '\033[91m'
#ENDC = '\033[0m'
#BOLD = '\033[1m'
#UNDERLINE = '\033[4m'
txt += '\033[0m'
print(txt,end=end)
#return txt
def artnet_loop():
#artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=12)
#artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=0)
artnet = ANN.ArtNetNode(to="10.10.10.255",univ=0)
#artnet = ANN.ArtNetNode(to="2.0.0.255",univ=0)
#artnet = ANN.ArtNetNode(to="10.10.10.255",univ=1)
#dmx[205] = 255 #205 BLUE
artnet.dmx= dmx #[0]*512
artnet.send()
while 1:
#artnet._test_frame()
artnet.next()
time.sleep(0.01)
class CLOCK():
def __init__(self):
self.__time = 0
self.__start = time.time() # only for debugging
self.__tick = 0.01 # incremental timer drift's on highe cpu load ?
def time(self):
return self.__time
def get_drift(self):
run_time = time.time() - self.__start
tick_time = self.__time # * self.__tick
print( "runtime:{:0.2f} tick_timer:{:0.2f} drift:{:0.2f}".format(run_time,tick_time,run_time-tick_time))
def loop(self):
while 1:
self.__time +=self.__tick
#if int(self.__time*100)/10. % 10 == 0:# self.__time % 2 == 0:
# print( self.get_drift())
#print(self.__time)
#for i in range(10):
time.sleep(self.__tick)
class CLOCK_REAL():
def __init__(self):
self.__time = 0
self.__start = time.time() # only for debugging
self.__tick = 0.01 # incremental timer drift's on highe cpu load ?
def time(self):
self.__time = time.time()
return self.__time
def get_drift(self):
run_time = time.time() - self.__start
tick_time = self.__time # * self.__tick
print( "runtime:{:0.2f} tick_timer:{:0.2f} drift:{:0.2f}".format(run_time,tick_time,run_time-tick_time))
def loop(self):
pass
#clock = CLOCK()
clock = CLOCK_REAL()
if __run_main:
thread.start_new_thread(clock.loop,())
class Fade():
def __init__(self,start,target,ftime,clock,delay=0):
#print("init Fade ",start,target,ftime,clock)
if delay < 0:
delay = 0.0001
if ftime <= 0:
ftime = 0.0001
clock += delay
self.__delay = delay
self.__clock = clock
self.__clock_curr = clock
self.__ftime = ftime
self.__start = start
self.__last = start
self.__target = target
self.run = 1
#print("INIT", str(self) )
def __str__(self):
return self.__repr__()
def __repr__(self):
return "".format(
self.__last, self.__start,self.__target,self.__ftime,self.__clock_curr,self.run,self.__delay )
def next(self,clock=None):
if self.__ftime <= 0 and self.__delay <= 0:
self.__last = self.__target
self.run = 0
if type(clock) is float or type(clock) is int:#not None:
self.__clock_curr = clock
if self.__target > self.__start:
if self.__last >= self.__target:
self.run = 0
return self.__target
else:
if self.__last <= self.__target:
self.run = 0
return self.__target
current = (self.__clock - self.__clock_curr) / self.__ftime
length = self.__start - self.__target
self.__last = self.__start+ length*current
#if self.__last < 0:
# self.__last = 0
#if self.__last > 255:
# self.__last = 255
self.run = 1
return self.__last
def ctl(self,cmd="",value=None): # if x-fade cmd="%" value=50
# start,stop,fwd,bwd,revers
pass
class _MASTER():
def __init__(self,name="None"):
self.__data = {}
self.name = name
def val(self,name,value=None):
_value = 100 #%
name = str(name)
if name not in self.__data:
self.__data[name] = 100
_value = self.__data[name]
if value is not None:
if _value != value:
print(self.name,"CHANGE MASTER:",name,"from:",_value,"to:",value)
self.__data[name] = value
_value = self.__data[name]
return _value /100.
exec_size_master = _MASTER("EXEC-SIZE")
exec_speed_master = _MASTER("EXEC-SPEED")
exec_offset_master = _MASTER("EXEC-OFFSET")
size_master = _MASTER("SIZE")
speed_master = _MASTER("SPEED")
exe_master = []
exe_master.append({"SIZE":100,"SPEED":100,"id":12,"link-ids":[2]})
class MASTER_FX():
def __init__(self):
#cprint(self,"MASTER_FX INIT !",color="green")
self.__data = []
self.__ok = []
self.i=0
self.old_offsets = []
self.offsets = []
self.count = -1
self.init = 10
def add(self,fx):
if fx not in self.__data:
#cprint(self,"ADD TO MASTER !",color="green")
self.__data.append(fx)
info = fx._get_info()
#cprint(self,"ADD" ,info,color="green")
offset = 0
if "offset" in info:
offset = info["offset"]
self.old_offsets.append(offset)
self.offsets.append(offset)
if "xtype" in info:
if info["xtype"] == "rnd":
self._shuffle()
#self.init += 1
def _shuffle(self):
#cprint(self,"REORDER RANDOM !",color="green")
#self.init = 0
#cprint(self.old_offsets)
random.shuffle(self.old_offsets)
#cprint(self.old_offsets)
def _init(self):
self._shuffle()
#self.offsets = []
for i,v in enumerate(self.old_offsets):
offset = self.old_offsets[i]
self.offsets[i] = offset
self.init = 0
def next(self,child):
i = self.__data.index(child)
offset = self.old_offsets[i]
self.offsets[i] = offset
return offset
#for i,v in enumerate(self.old_offsets):
# offset = self.old_offsets[i]
# self.offsets[i] = offset
def get(self,child,count):
offset = 0
if child not in self.__data:
return offset
if self.init:
self._init()
idx = self.__data.index(child)
if (self.count != count and idx == 0 ) or self.init == 0:
self.init = 1
self._shuffle()
#print( count)
self.count=count
idx = self.__data.index(child)
offset = self.offsets[idx]
return offset
class FX():
def __init__(self,xtype="sinus",size=10,speed=10,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None,master_id=0):
self.__xtype=xtype
self.__size = size
self.__start = start
self.__master_id = master_id
if width > 200:
width = 200
if width <= 0:
width = 1
self.__fade_in_master = 0
self.__width = width
self.__invert = invert
self.__base = base
self.__speed = speed
self.__offset = offset
self.__clock = clock
self.__clock_curr = clock
self.__clock_delta = 0
self.__clock_old = self.__clock_curr
self.out = 0
self.old_v = -1
self.run = 1
self.count = -1
self.__angel = self.__clock_curr*360%360
if master is None:
cprint(master, "MASTER_FX ERR",master,color="red")
self.__master = MASTER_FX()
self.__master.add(self)
else:
#cprint( "MASTER_FX OK",master,color="red")
self.__master = master
self.__master.add(self)
if self.__xtype == "rnd":
self.__offset = self.__master.get(self,-2)
self.__offset = self.__master.next(self)#,count)
self._exec_id = None
self.next()
#print("init FX",self)
def exec_id(self,_id=None):
if type(_id) is not type(None):
self._exec_id = str(_id)
return self._exec_id
def _get_info(self):
print(self.__offset)
return {"offset":self.__offset,"xtype":self.__xtype}
#return self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run
def __str__(self):
return self.__repr__()
def __repr__(self):
return "".format(
self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run,self._exec_id )
def next(self,clock=None):
if type(clock) is float or type(clock) is int:#not None:
self.__clock_curr = clock
d = (self.__clock_curr - self.__clock_old)
#print()
#print("A",d)
m1 = ( speed_master.val(self.__master_id)) # global speed-master
#print("B {:0.4}".format(m1))
m2 = ( exec_speed_master.val(self._exec_id)) # exec start by 0
#print("C {:0.4}".format(m2))
shift = 0
m = (m1 * m2) -1
shift += d * m
#print("D",shift)
self.__clock_delta += shift
#print(self.__clock_delta )
self.__clock_old = self.__clock_curr
t = self.__clock_curr
t += self.__clock_delta
t *= self.__speed / 60
offset2 = self.__offset
offset2 *= exec_offset_master.val(self._exec_id)
#t += self.__offset / 100 #255 #1024 #255
t += offset2 / 100
t += self.__start / 1024 #255
#t = t*speed_master.val(self.__master_id)
tw = t%1
count = t//1
t = t * (100/self.__width)
if tw > self.__width/100:
t = 1
self.__angel = t%1*360
t = t%1
rad = math.radians(self.__angel)
v=0
out = 0
base = 0
size = self.__size
if self.__base == "+": # add
base = size/2
elif self.__base == "-": # sub
base = size/2*-1
if self.__xtype == "sinus":
v = math.sin( rad )
v/=2
elif self.__xtype == "cosinus":
v = math.cos( rad )
if self.__base == "+": # add
size *= -1
v/=2
elif self.__xtype == "rnd":
#base = 0
if self.__angel > 90 and self.__angel <=270:
v=1
else:
v=0
#if count != self.count and v: # % 2 == 0:#!= self.count:
# #self.__offset = random.randint(0,1024)# /1024
# self.__master._shuffle()
if count != self.count and v == 0: # and v: # % 2 == 0:#!= self.count:
self.__master.next(self)#,count)
#self.__master.next(self)#,count)
self.__offset = self.__master.get(self,count)
base = 0
if self.__base == "-": # sub
if self.__invert:
v = 1-v
#base = -size
size *=-1
v *=-1
elif self.__base == "+": # sub
if self.__invert:
v = v-1
else:
v = (t%1-0.5)
elif self.__xtype == "on":
#base = 0
if self.__angel > 90 and self.__angel <=270:
v=1
else:
v=0
base = 0
if self.__base == "-": # sub
if self.__invert:
v = 1-v
#base = -size
size *=-1
v *=-1
elif self.__base == "+": # sub
if self.__invert:
v = v-1
else:
v = (t%1-0.5)
elif self.__xtype == "ramp" or self.__xtype == "ramp":
v = (t%1)
base = 0
if self.__base == "-": # sub
if self.__invert:
v = 1-v
#base = -size
size *=-1
v *=-1
elif self.__base == "+": # sub
if self.__invert:
v = v-1
else:
v = (t%1-0.5)
elif self.__xtype == "ramp2" or self.__xtype == "bump2":
v = (t%1)
v = 1-v
if v == 1:
v=0
base = 0
if self.__base == "-": # sub
if self.__invert:
v = 1-v
#base = -size
size *=-1
v *=-1
elif self.__base == "+": # sub
if self.__invert:
v = v-1
else:
v = (t%1-0.5)
elif self.__xtype == "fade":
x = t * 2
if x > 1:
x = 2-x
x -= 0.5
v = x*2
#base /= 2
#base *=2
if self.__base == "+": # add
pass#base /= 2
else:
v *= -1
v/=2
if self.__invert:
v *=-1
#if self.__fade_in_master < 255:
# self.__fade_in_master += v*size
out = v *size +base
self.out = out
self.count = count
out = out * size_master.val(self.__master_id) # master
out = out * exec_size_master.val(self._exec_id) # master
#* (self.__fade_in_master /255.)
return out
class DMXCH(object):
def __init__(self,dmx=-1):
self._base_value = 0
self._fade = None
self._fx = [None,None] # None
self._fx_value = 0
self._dmx = dmx
self._flash = None
self._flash_fx = None
self._flash_fx_value = 0
self._last_val = None
self._exec_id = None
#self.next(clock)
#print("init",self)
def fade(self,target,ftime=0,clock=0,delay=0):
if target != self._base_value:
try:
target = float(target)
self._fade = Fade(self._base_value,target,ftime=ftime,clock=clock,delay=delay)
#self._fade.next()
#self._fade.next()
except Exception as e:
print( "Except:fade",e,target,ftime,clock)
self.next(clock)
print("init",self)
def fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="", clock=0,master=None):
print([self,xtype,size,speed,start,offset,base, clock])
self._fx[0] = self._fx[1]
if str(xtype).lower() == "off":
fx_value = self._fx_value
if fx_value != 0:
cprint("???????______ FX OFF AS FADE",fx_value,0,255)
self._fx[1] = Fade(fx_value,0,ftime=0.5,clock=clock)
else:
self._fx[1] = None
self._fx_value = 0
else:
self._fx[1] = FX(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=clock,master=master,master_id=1)
self._fx[1].exec_id(self._exec_id)
self.next(clock)
print("init",self)
def flash(self,target,ftime=0,clock=0,delay=0):
if str(target).lower() == "off":
self._flash = None
else:#elif target != self._base_value:
try:
target = float(target)
self._flash = Fade(self._last_val,target,ftime=ftime,clock=clock,delay=delay)
except Exception as e:
print( "Except:flash",target,ftime,clock,__name__,e,)
self.next(clock)
print("init",self)
def flash_fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None):
if str(xtype).lower() == "off":
fx_value = self._fx_value
self._flash_fx = None
self._flash_fx_value = 0
else:
self._flash_fx = FX(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=clock,master=master,master_id=0)
self._flash_fx.exec_id(self._exec_id)
self.next(clock)
print("init",self)
def fx_ctl(self,cmd=""): #start,stop,off
pass
def __str__(self):
return self.__repr__()
def exec_id(self,_id=None):
if type(id) is not type(None):
self._exec_id = _id
return self._exec_id
def __repr__(self):
return " fx:[{}] fd:{}".format(self._dmx, self._last_val,self._exec_id,self._fx,self._fade)
def fade_ctl(self,cmd=""): #start,stop,backw,fwd,bounce
pass
def next(self,clock=0):
value = self._base_value
if self._last_val is None:
self._last_val = value
fx_value = self._fx_value
if self._flash is not None:
value = self._flash.next(clock)
#flicker bug ?!
value = self._flash.next(clock)
fx_value = 0
elif self._fade is not None:#is Fade:# is Fade:
self._base_value = self._fade.next(clock)
self._base_value = self._fade.next(clock) #flicker bug ?!
value = self._base_value
if self._flash_fx is not None:# is FX:
fx_value = self._flash_fx.next(clock)
else:
self._fx_value = 0
if self._fx[-1] is not None and self._flash is None:# is FX:
self._fx_value += self._fx[-1].next(clock)
fx_value = self._fx_value
self._last_val = value + fx_value
#out = self._last_val * htp_master.master_by_dmx(self._dmx)
out = self._last_val
return out
Bdmx = []
for i in range(512*3):
Bdmx.append( DMXCH(i) )
#print(type(dmx[i]))
_id = 1
def split_cmd(data):
if "cmd" in data:
cmd = data["cmd"]
#print("cmd",cmd)
if "," in cmd:
cmds = cmd.split(",")
else:
cmds = [cmd]
return cmds
class VDMX():
"""functional implementation as class for namespace encapsulation
"""
def __init__(self):
self.data = OrderedDict()
self.data[4] = {"DMX":[21,22,23],"VALUE":255, "LIMIT":255} #,"DMXCH":DMXCH("V4")}
for k,v in self.data.items():
pass
#dmxch = v["DMXCH"]
#dmxch.fade(10,0)
#dmxch.fx(size=200,speed=200,base="-") #self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="", clock=0,master=None):
def _list_by_dmx(self,_dmx=0):
data = OrderedDict()
for i,link in self.data.items(): # enumerate(self.data):
if _dmx in link["DMX"]:
#print( "_list_by_dmx",i,link)
data[i] = link
return data
def dmx_by_id(self,_id=0):
#print("dmx by master-id:",_id)
if _id in self.data:
for i,link in self.data[_id].items():
#print("dmx_by_id", i,link)
return (i,link)
return 0,{}
def by_dmx(self,clock,dmx):
#print("master of dmx:",dmx)
val=0
flag = 0
data = self._list_by_dmx(dmx)
for i,row in data.items():
if "DMXCH" not in row:
row["DMXCH"] = DMXCH("V{}".format(i))
row["DMXCH"].fade(255,0)
v = row["DMXCH"].next(clock)
#row["DMXCH"].fade(200,20)
if v >= val:
val = v
flag = 1
out = 1.
if val > 255:
val = 255
if flag:
out = val/255.
else:
out = 1.
return out
vdmx = VDMX()
class HTP_MASTER():
"""functional implementation as class for namespace encapsulation
"""
def __init__(self):
self.data = OrderedDict()
#self.data[1] = {"DMX":[1,2,3],"VALUE":80, "LIMIT":255}
#self.data[2] = {"DMX":[12,13,22],"VALUE":70, "LIMIT":255}
#self.data[3] = {"DMX":[22,23,24],"VALUE":99, "LIMIT":255}
self.data[4] = {"DMX":[22,23,24],"VALUE":99, "LIMIT":255,"DMXCH":DMXCH(4)}
def _list_by_dmx(self,_dmx=0):
data = OrderedDict()
for i,link in self.data.items(): # enumerate(self.data):
if _dmx in link["DMX"]:
#print( "_list_by_dmx",i,link)
data[i] = link
return data
def dmx_by_id(self,_id=0):
#print("dmx by master-id:",_id)
if _id in self.data:
for i,link in self.data[_id].items():
#print("dmx_by_id", i,link)
return (i,link)
return 0,{}
def val_by_dmx(self,dmx=0):
#print("master of dmx:",dmx)
val=0
flag = 0
data = self._list_by_dmx(dmx)
for i,link in data.items():
#print("master_by_dmx", i,link)
if link["VALUE"] > val:
#print("master_by_dmx", i,link)
val = link["VALUE"]
flag=1
out = 1.
if flag:
out = val/255.
return out
htp_master = HTP_MASTER()
#htp_master.data[_id] = {"DMX":[1,2,3],"VALUE":80, "LIMIT":255,"DMXCH":DMXCH()}
class Main():
def __init__(self):
#artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=12)
#artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=0)
#artnet = ANN.ArtNetNode(to="2.0.0.255",univ=0)
#artnet = ANN.ArtNetNode(to="10.10.10.255",univ=1)
self.artnet = {}
#self.artnet["0"] = ANN.ArtNetNode(to="10.10.10.255",univ=0)
#self.artnet["0"].dmx[512-1] = 10
#self.artnet["1"] = ANN.ArtNetNode(to="10.10.10.255",univ=1)
#self.artnet["1"].dmx[512-1] = 11
self.fx = {} # key is dmx address
def loop(self):
#dmx[205] = 255 #205 BLUE
#self.artnet.send()
xx = [0]*512
#artnet = self.artnet["0"]
#artnet.dmx = xx# [:] #dmx #[0]*512
old_univ = -1
while 1:
t = clock.time()
ii = 0
for ii,dmxch in enumerate(Bdmx):
i = ii%512
univ = ii//512
if str(univ) not in self.artnet:
print("add uiv",univ)
self.artnet[str(univ)] = ANN.ArtNetNode(to="10.10.10.255",univ=univ)
self.artnet[str(univ)].dmx[512-1] = 100+univ
if univ != old_univ:
old_univ = univ
#print("UNIV",ii/512)
try:
artnet.next()
except:pass
artnet = self.artnet[str(univ)]
artnet.dmx = xx
v = dmxch.next(t)
vv = vdmx.by_dmx(clock=i,dmx=ii+1)
v = v*vv # disable v-master
xx[i] = int(v)
try:
artnet.next()
except:pass
time.sleep(0.01)
main = Main()
if __run_main:
#thread.start_new_thread(artnet_loop,())
thread.start_new_thread(main.loop,())
def JCB(data): #json client input
t_start = time.time()
#jdatas = data["cmd"].split("\x00")
jdatas = [data["cmd"]]
c = clock.time()
c = float(c)
print("JCB",round(c,2))
ftime = 0
delay = 0
for j in jdatas:
master_fx = MASTER_FX()
if not j:
continue
try:
cprint("JCB::")#,j)
jdata = j #jdatas[j]
jtxt = jdata
#jtxt = zlib.decompress(jtxt) #jtxt.decode())
jtxt = str(jtxt,"UTF-8")
cmds = json.loads(jtxt)
for x in cmds:
#cprint(int(clock.time()*1000)/1000,end=" ",color="yellow")#time.time())
#cprint("json", x,type(x),color="yellow")#,cmds[x])
if "CMD" in x:
print("CMD:",x)
if "EXEC-SPEED-MASTER" == x["CMD"]:
exec_speed_master.val(x["NR"],x["VALUE"])
if "EXEC-SIZE-MASTER" == x["CMD"]:
exec_size_master.val(x["NR"],x["VALUE"])
if "EXEC-OFFSET-MASTER" == x["CMD"]:
exec_offset_master.val(x["NR"],x["VALUE"])
if "SPEED-MASTER" == x["CMD"]:
speed_master.val(x["NR"],x["VALUE"])
if x["NR"] == 2:
pass
#vdmx.data[4]["DMXCH"].fade(x["VALUE"],3)#,clock=clock.time())
if x["NR"] == 3:
pass
#vdmx.data[4]["DMXCH"].fx(size=255,speed=x["VALUE"],base="-",offset=0)#xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=c,master=master_fx)
if "SIZE-MASTER" == x["CMD"]:
size_master.val(x["NR"],x["VALUE"])
else:
if "DMX" in x:
DMX = int(x["DMX"])
else:continue
if DMX > 0:
DMX -=1
else:continue
exec_id = None
if "EXEC" in x:
exec_id = x["EXEC"]
if "VALUE" in x:# and x["VALUE"] is not None:
v = x["VALUE"]
else:continue
if "FX" in x:# and x["VALUE"] is not None:
fx = x["FX"]
else:fx=""
if "FX2" in x:# and x["VALUE"] is not None:
fx2 = x["FX2"]
else:fx2={}
if "FADE" in x:
ftime = x["FADE"]
else:ftime=0
if "DELAY" in x:
delay = x["DELAY"]
else:delay=0
if len(Bdmx) < DMX:
continue
Bdmx[DMX].exec_id(exec_id)
if v is not None:
if "FLASH" in x:
#print("FLASH")
Bdmx[DMX].flash(target=v,ftime=ftime, clock=c,delay=delay)
else:
#print("FADE")
Bdmx[DMX].fade(target=v,ftime=ftime, clock=c,delay=delay)
if type(fx2) is dict and fx2:
#cprint("FX2",DMX,fx2,color="green")
xtype="fade"
size = 10
speed = 10
start = 0
offset= 0
width=100
invert=0
base = "-"
if "TYPE" in fx2:
xtype = fx2["TYPE"]
if "SIZE" in fx2:
size = fx2["SIZE"]
if "SPEED" in fx2:
speed = fx2["SPEED"]
if "OFFSET" in fx2:
offset = fx2["OFFSET"]
if "BASE" in fx2:
base = fx2["BASE"]
if "INVERT" in fx2:
invert = fx2["INVERT"]
if "WIDTH" in fx2:
width = fx2["WIDTH"]
if "off" == x["VALUE"]: #fix fx flash off
xtype= "off"
if "alloff" == xtype.lower():
for i in Bdmx:
if i is not None:
i.flash_fx(xtype="off",clock=c)
i.fx(xtype="off",clock=c)
if "FLASH" in x:
Bdmx[DMX].flash_fx(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=c,master=master_fx)
else:
Bdmx[DMX].fx(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=c,master=master_fx)
elif type(fx) is str and fx: # old fx like sinus:200:12:244
ccm = str(DMX+1)+":"+fx
print("fx",ccm)
if "FLASH" in x:
CB({"cmd":"fxf"+ccm})
else:
CB({"cmd":"fx"+ccm})
cprint("{:0.04} sec.".format(time.time()-t_start),color="yellow")
cprint("{:0.04} t.".format(time.time()),color="yellow")
except Exception as e:
cprint("EXCEPTION JCB",e,color="red")
cprint("----",str(jdata)[:150],"...",color="red")
cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
cprint()
cprint("{:0.04} sec.".format(time.time()-t_start),color="yellow")
cprint("{:0.04} t.".format(time.time()),color="yellow")
def CB(data): # raw/text client input
#print("CB",data)
cmds = split_cmd(data)
c = clock.time()
c = float(c)
ftime = 0
delay = 0
for xcmd in cmds:
if xcmd:
cprint("CB",xcmd,end=" ")
pass
else:
continue
if xcmd.startswith("fxf"):
xxcmd=xcmd[3:].split(":")
#print("fxf:",xxcmd)
if "alloff" == xxcmd[1].lower():
for i in Bdmx:
if i is not None:
i.flash_fx(xtype="off",clock=c)
l = xxcmd
try:
xtype=""
size=40
speed=100
start=0
offset=0
base=""
k=int(l[0])-1
xtype=l[1]
if len(l) >= 3:
try:size=int(l[2])
except:pass
if len(l) >= 4:
try:speed=int(l[3])
except:pass
if len(l) >= 5:
try:start=int(l[4])
except:pass
if len(l) >= 6:
try:offset=int(l[5])
except:pass
if len(l) >= 7:
try:base=l[6]
except:pass
if len(Bdmx) > k:
#Bdmx[k].fade(target=v,ftime=t, clock=c)
Bdmx[k].flash_fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
except Exception as e:
print("EXCEPTION IN FX",e)
print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
elif xcmd.startswith("fx"):
xxcmd=xcmd[2:].split(":")
print("DMX:",xxcmd)
if len(xxcmd) < 2:
print("xxcmd err",xxcmd,xcmd)
continue
if "alloff" == xxcmd[1].lower():
for i in Bdmx:
i.fx(xtype="off",clock=c)
l = xxcmd
try:
xtype=""
size=40
speed=100
start=0
offset=0
base=""
k=int(l[0])-1
xtype=l[1]
if len(l) >= 3:
try:size=int(l[2])
except:pass
if len(l) >= 4:
try:speed=int(l[3])
except:pass
if len(l) >= 5:
try:start=int(l[4])
except:pass
if len(l) >= 6:
try:offset=int(l[5])
except:pass
if len(l) >= 7:
try:base=l[6]
except:pass
if len(Bdmx) > k:
#Bdmx[k].fade(target=v,ftime=t, clock=c)
Bdmx[k].fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
except Exception as e:
print("EXCEPTION IN FX",xcmd,e)
print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
if __run_main:
#jchat = chat.CMD(CB,port=50001) # server listener
#thread.start_new_thread(jchat.poll,())
chat.cmd(JCB) # server listener
#chat.cmd(JCB,port=50001) # server listener
#input("END")