console.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. #! /usr/bin/python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. This file is part of LibreLight.
  5. LibreLight is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, version 2 of the License.
  8. LibreLight is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with LibreLight. If not, see <http://www.gnu.org/licenses/>.
  14. (c) 2012 micha@uxsrv.de
  15. """
  16. import sys
  17. rnd_id = ""
  18. rnd_id += " Beta 22.02 "
  19. import subprocess
  20. rnd_id += subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('ascii').strip()
  21. if "__file__" in dir():
  22. sys.stdout.write("\x1b]2;"+str(__file__)+" "+rnd_id+"\x07") # terminal title
  23. else:
  24. sys.stdout.write("\x1b]2;"+str("__file__")+" "+rnd_if+"\x07") # terminal title
  25. import time
  26. import socket
  27. import struct
  28. import sys
  29. import random
  30. import math
  31. from collections import OrderedDict
  32. import lib.chat as chat
  33. import lib.ArtNetNode as ANN
  34. import _thread as thread
  35. #thread.start_new_thread
  36. import lib.motion as motion
  37. #idmx = [0]*512 # incremental dmx
  38. dmx = [0]*512 # absolute dmx data
  39. gcolor = 1
  40. def cprint(*text,color="blue",space=" ",end="\n"):
  41. #return 0 #disable print dbg
  42. if not gcolor:
  43. print(text)
  44. return 0
  45. if color == "green":
  46. txt = '\033[92m'
  47. elif color == "red":
  48. txt = '\033[0;31m\033[1m'
  49. elif color == "yellow":
  50. txt = '\033[93m\033[1m'
  51. elif color == "cyan":
  52. txt = '\033[96m'
  53. else:
  54. txt = '\033[94m'
  55. for t in text:
  56. txt += str(t ) +" "
  57. #HEADER = '\033[95m'
  58. #OKBLUE = '\033[94m'
  59. #OKCYAN = '\033[96m'
  60. #OKGREEN = '\033[92m'
  61. #WARNING = '\033[93m'
  62. #FAIL = '\033[91m'
  63. #ENDC = '\033[0m'
  64. #BOLD = '\033[1m'
  65. #UNDERLINE = '\033[4m'
  66. txt += '\033[0m'
  67. print(txt,end=end)
  68. #return txt
  69. def artnet_loop():
  70. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=12)
  71. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=0)
  72. artnet = ANN.ArtNetNode(to="10.10.10.255",univ=0)
  73. #artnet = ANN.ArtNetNode(to="2.0.0.255",univ=0)
  74. #artnet = ANN.ArtNetNode(to="10.10.10.255",univ=1)
  75. #dmx[205] = 255 #205 BLUE
  76. artnet.dmx= dmx #[0]*512
  77. artnet.send()
  78. while 1:
  79. #artnet._test_frame()
  80. artnet.next()
  81. time.sleep(0.01)
  82. class Main():
  83. def __init__(self):
  84. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=12)
  85. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=0)
  86. #artnet = ANN.ArtNetNode(to="2.0.0.255",univ=0)
  87. #artnet = ANN.ArtNetNode(to="10.10.10.255",univ=1)
  88. self.artnet = {}
  89. #self.artnet["0"] = ANN.ArtNetNode(to="10.10.10.255",univ=0)
  90. #self.artnet["0"].dmx[512-1] = 10
  91. #self.artnet["1"] = ANN.ArtNetNode(to="10.10.10.255",univ=1)
  92. #self.artnet["1"].dmx[512-1] = 11
  93. self.fx = {} # key is dmx address
  94. def loop(self):
  95. #dmx[205] = 255 #205 BLUE
  96. #self.artnet.send()
  97. xx = [0]*512
  98. #artnet = self.artnet["0"]
  99. #artnet.dmx = xx# [:] #dmx #[0]*512
  100. old_univ = -1
  101. while 1:
  102. t = clock.time()
  103. ii = 0
  104. for ii,dmxch in enumerate(Bdmx):
  105. i = ii%512
  106. univ = ii//512
  107. if str(univ) not in self.artnet:
  108. print("add uiv",univ)
  109. self.artnet[str(univ)] = ANN.ArtNetNode(to="10.10.10.255",univ=univ)
  110. self.artnet[str(univ)].dmx[512-1] = 100+univ
  111. if univ != old_univ:
  112. old_univ = univ
  113. #print("UNIV",ii/512)
  114. try:
  115. artnet.next()
  116. except:pass
  117. artnet = self.artnet[str(univ)]
  118. artnet.dmx = xx
  119. v = dmxch.next(t)
  120. if i == 0:
  121. #print(dmxch)
  122. if int(xx[i]*100) != int( v*100):
  123. #print("----v",x[i],v,t)
  124. pass
  125. #print("i:{:0.2f} xx:{:0.2f} v:{:0.2f} {:0.2f}----v {}".format(i,xx[i],v,t+100,dmxch))
  126. #print("i:{:0.2f} xx:{:0.2f} v:{:0.2f} {:0.2f}----v {}".format(i,xx[i],v,t+100,dmxch))
  127. xx[i] = int(v)
  128. try:
  129. artnet.next()
  130. except:pass
  131. time.sleep(0.01)
  132. main = Main()
  133. #thread.start_new_thread(artnet_loop,())
  134. thread.start_new_thread(main.loop,())
  135. class CLOCK():
  136. def __init__(self):
  137. self.__time = 0
  138. self.__start = time.time() # only for debugging
  139. self.__tick = 0.01 # incremental timer drift's on highe cpu load ?
  140. def time(self):
  141. return self.__time
  142. def get_drift(self):
  143. run_time = time.time() - self.__start
  144. tick_time = self.__time # * self.__tick
  145. print( "runtime:{:0.2f} tick_timer:{:0.2f} drift:{:0.2f}".format(run_time,tick_time,run_time-tick_time))
  146. def loop(self):
  147. while 1:
  148. self.__time +=self.__tick
  149. #if int(self.__time*100)/10. % 10 == 0:# self.__time % 2 == 0:
  150. # print( self.get_drift())
  151. #print(self.__time)
  152. #for i in range(10):
  153. time.sleep(self.__tick)
  154. class CLOCK_REAL():
  155. def __init__(self):
  156. self.__time = 0
  157. self.__start = time.time() # only for debugging
  158. self.__tick = 0.01 # incremental timer drift's on highe cpu load ?
  159. def time(self):
  160. self.__time = time.time()
  161. return self.__time
  162. def get_drift(self):
  163. run_time = time.time() - self.__start
  164. tick_time = self.__time # * self.__tick
  165. print( "runtime:{:0.2f} tick_timer:{:0.2f} drift:{:0.2f}".format(run_time,tick_time,run_time-tick_time))
  166. def loop(self):
  167. pass
  168. #clock = CLOCK()
  169. clock = CLOCK_REAL()
  170. thread.start_new_thread(clock.loop,())
  171. class Fade():
  172. def __init__(self,start,target,ftime,clock,delay=0):
  173. #print("init Fade ",start,target,ftime,clock)
  174. if delay < 0:
  175. delay = 0.0001
  176. if ftime <= 0:
  177. ftime = 0.0001
  178. clock += delay
  179. self.__delay = delay
  180. self.__clock = clock
  181. self.__clock_curr = clock
  182. self.__ftime = ftime
  183. self.__start = start
  184. self.__last = start
  185. self.__target = target
  186. self.run = 1
  187. #print("INIT", str(self) )
  188. def __str__(self):
  189. return self.__repr__()
  190. def __repr__(self):
  191. return "<Fade Next:{:0.2f} Start:{:0.2f} Target:{:0.2f} T{:0.2f} Clock:{:0.2f} run:{} delay:{:0.2f}>".format(
  192. self.__last, self.__start,self.__target,self.__ftime,self.__clock_curr,self.run,self.__delay )
  193. def next(self,clock=None):
  194. if self.__ftime <= 0 and self.__delay <= 0:
  195. self.__last = self.__target
  196. self.run = 0
  197. if type(clock) is float or type(clock) is int:#not None:
  198. self.__clock_curr = clock
  199. if self.__target > self.__start:
  200. if self.__last >= self.__target:
  201. self.run = 0
  202. return self.__target
  203. else:
  204. if self.__last <= self.__target:
  205. self.run = 0
  206. return self.__target
  207. current = (self.__clock - self.__clock_curr) / self.__ftime
  208. length = self.__start - self.__target
  209. self.__last = self.__start+ length*current
  210. #if self.__last < 0:
  211. # self.__last = 0
  212. #if self.__last > 255:
  213. # self.__last = 255
  214. self.run = 1
  215. return self.__last
  216. def ctl(self,cmd="",value=None): # if x-fade cmd="%" value=50
  217. # start,stop,fwd,bwd,revers
  218. pass
  219. class MASTER_FX():
  220. def __init__(self):
  221. #cprint(self,"MASTER_FX INIT !",color="green")
  222. self.__data = []
  223. self.__ok = []
  224. self.i=0
  225. self.old_offsets = []
  226. self.offsets = []
  227. self.count = -1
  228. self.init = 10
  229. def add(self,fx):
  230. if fx not in self.__data:
  231. #cprint(self,"ADD TO MASTER !",color="green")
  232. self.__data.append(fx)
  233. info = fx._get_info()
  234. #cprint(self,"ADD" ,info,color="green")
  235. offset = 0
  236. if "offset" in info:
  237. offset = info["offset"]
  238. self.old_offsets.append(offset)
  239. self.offsets.append(offset)
  240. if "xtype" in info:
  241. if info["xtype"] == "rnd":
  242. self._shuffle()
  243. #self.init += 1
  244. def _shuffle(self):
  245. #cprint(self,"REORDER RANDOM !",color="green")
  246. #self.init = 0
  247. #cprint(self.old_offsets)
  248. random.shuffle(self.old_offsets)
  249. #cprint(self.old_offsets)
  250. def _init(self):
  251. self._shuffle()
  252. #self.offsets = []
  253. for i,v in enumerate(self.old_offsets):
  254. offset = self.old_offsets[i]
  255. self.offsets[i] = offset
  256. self.init = 0
  257. def next(self,child):
  258. i = self.__data.index(child)
  259. offset = self.old_offsets[i]
  260. self.offsets[i] = offset
  261. return offset
  262. #for i,v in enumerate(self.old_offsets):
  263. # offset = self.old_offsets[i]
  264. # self.offsets[i] = offset
  265. def get(self,child,count):
  266. offset = 0
  267. if child not in self.__data:
  268. return offset
  269. if self.init:
  270. self._init()
  271. idx = self.__data.index(child)
  272. if (self.count != count and idx == 0 ) or self.init == 0:
  273. self.init = 1
  274. self._shuffle()
  275. #print( count)
  276. self.count=count
  277. idx = self.__data.index(child)
  278. offset = self.offsets[idx]
  279. return offset
  280. class FX():
  281. def __init__(self,xtype="sinus",size=10,speed=10,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None):
  282. self.__xtype=xtype
  283. self.__size = size
  284. self.__start = start
  285. if width > 200:
  286. width = 200
  287. if width <= 0:
  288. width = 1
  289. self.__width = width
  290. self.__invert = invert
  291. self.__base = base
  292. self.__speed = speed
  293. self.__offset = offset
  294. self.__clock = clock
  295. self.__clock_curr = clock
  296. self.out = 0
  297. self.old_v = -1
  298. self.run = 1
  299. self.count = -1
  300. self.__angel = self.__clock_curr*360%360
  301. if master is None:
  302. cprint(master, "MASTER_FX ERR",master,color="red")
  303. self.__master = MASTER_FX()
  304. self.__master.add(self)
  305. else:
  306. #cprint( "MASTER_FX OK",master,color="red")
  307. self.__master = master
  308. self.__master.add(self)
  309. if self.__xtype == "rnd":
  310. self.__offset = self.__master.get(self,-2)
  311. self.__offset = self.__master.next(self)#,count)
  312. self.next()
  313. #print("init FX",self)
  314. def _get_info(self):
  315. print(self.__offset)
  316. return {"offset":self.__offset,"xtype":self.__xtype}
  317. #return self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run
  318. def __str__(self):
  319. return self.__repr__()
  320. def __repr__(self):
  321. return "<FX Next:{:0.2f} xtype:{} Size:{:0.2f} Speed:{:0.2f} ang:{:0.2f} base:{} Clock:{:0.2f} run:{}>".format(
  322. self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run )
  323. def next(self,clock=None):
  324. if type(clock) is float or type(clock) is int:#not None:
  325. self.__clock_curr = clock
  326. t = self.__clock_curr * self.__speed / 60
  327. t += self.__offset / 100 #255 #1024 #255
  328. t += self.__start / 1024 #255
  329. tw = t%1
  330. count = t//1
  331. t = t * (100/self.__width)
  332. if tw > self.__width/100:
  333. t = 1
  334. self.__angel = t%1*360
  335. t = t%1
  336. rad = math.radians(self.__angel)
  337. v=0
  338. out = 0
  339. base = 0
  340. size = self.__size
  341. if self.__base == "+": # add
  342. base = size/2
  343. elif self.__base == "-": # sub
  344. base = size/2*-1
  345. if self.__xtype == "sinus":
  346. v = math.sin( rad )
  347. v/=2
  348. elif self.__xtype == "cosinus":
  349. v = math.cos( rad )
  350. if self.__base == "+": # add
  351. size *= -1
  352. v/=2
  353. elif self.__xtype == "rnd":
  354. #base = 0
  355. if self.__angel > 90 and self.__angel <=270:
  356. v=1
  357. else:
  358. v=0
  359. #if count != self.count and v: # % 2 == 0:#!= self.count:
  360. # #self.__offset = random.randint(0,1024)# /1024
  361. # self.__master._shuffle()
  362. if count != self.count and v == 0: # and v: # % 2 == 0:#!= self.count:
  363. self.__master.next(self)#,count)
  364. #self.__master.next(self)#,count)
  365. self.__offset = self.__master.get(self,count)
  366. base = 0
  367. if self.__base == "-": # sub
  368. if self.__invert:
  369. v = 1-v
  370. #base = -size
  371. size *=-1
  372. v *=-1
  373. elif self.__base == "+": # sub
  374. if self.__invert:
  375. v = v-1
  376. else:
  377. v = (t%1-0.5)
  378. elif self.__xtype == "on":
  379. #base = 0
  380. if self.__angel > 90 and self.__angel <=270:
  381. v=1
  382. else:
  383. v=0
  384. base = 0
  385. if self.__base == "-": # sub
  386. if self.__invert:
  387. v = 1-v
  388. #base = -size
  389. size *=-1
  390. v *=-1
  391. elif self.__base == "+": # sub
  392. if self.__invert:
  393. v = v-1
  394. else:
  395. v = (t%1-0.5)
  396. elif self.__xtype == "ramp" or self.__xtype == "ramp":
  397. v = (t%1)
  398. base = 0
  399. if self.__base == "-": # sub
  400. if self.__invert:
  401. v = 1-v
  402. #base = -size
  403. size *=-1
  404. v *=-1
  405. elif self.__base == "+": # sub
  406. if self.__invert:
  407. v = v-1
  408. else:
  409. v = (t%1-0.5)
  410. elif self.__xtype == "ramp2" or self.__xtype == "bump2":
  411. v = (t%1)
  412. v = 1-v
  413. if v == 1:
  414. v=0
  415. base = 0
  416. if self.__base == "-": # sub
  417. if self.__invert:
  418. v = 1-v
  419. #base = -size
  420. size *=-1
  421. v *=-1
  422. elif self.__base == "+": # sub
  423. if self.__invert:
  424. v = v-1
  425. else:
  426. v = (t%1-0.5)
  427. elif self.__xtype == "fade":
  428. x = t * 2
  429. if x > 1:
  430. x = 2-x
  431. x -= 0.5
  432. v = x*2
  433. #base /= 2
  434. #base *=2
  435. if self.__base == "+": # add
  436. pass#base /= 2
  437. else:
  438. v *= -1
  439. v/=2
  440. if self.__invert:
  441. v *=-1
  442. out = v *size +base
  443. self.out = out
  444. self.count = count
  445. return out
  446. class DMXCH(object):
  447. def __init__(self):
  448. self._base_value = 0
  449. self._fade = None
  450. self._fx = None
  451. self._fx_value = 0
  452. self._flash = None
  453. self._flash_fx = None
  454. self._flash_fx_value = 0
  455. self._last_val = None
  456. def fade(self,target,ftime=0,clock=0,delay=0):
  457. if target != self._base_value:
  458. try:
  459. target = float(target)
  460. self._fade = Fade(self._base_value,target,ftime=ftime,clock=clock,delay=delay)
  461. #self._fade.next()
  462. #self._fade.next()
  463. except Exception as e:
  464. print( "Except:fade",e,target,ftime,clock)
  465. def fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="", clock=0,master=None):
  466. print([self,xtype,size,speed,start,offset,base, clock])
  467. if str(xtype).lower() == "off":
  468. fx_value = self._fx_value
  469. if fx_value != 0:
  470. cprint("???????______ FX OFF AS FADE",fx_value,0,255)
  471. self._fx = Fade(fx_value,0,ftime=0.5,clock=clock)#,delay=delay)
  472. else:
  473. #self._fx = Fade(self._fx_value,target=0,ftime=2,clock=clock)
  474. self._fx = None
  475. self._fx_value = 0
  476. else:
  477. self._fx = FX(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=clock,master=master)
  478. def flash(self,target,ftime=0,clock=0,delay=0):
  479. if str(target).lower() == "off":
  480. self._flash = None
  481. else:#elif target != self._base_value:
  482. try:
  483. target = float(target)
  484. self._flash = Fade(self._last_val,target,ftime=ftime,clock=clock,delay=delay)
  485. except Exception as e:
  486. print( "Except:flash",target,ftime,clock,__name__,e,)
  487. def flash_fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None):
  488. #if self._flash_fx is not None :
  489. # cprint("flash_fx",xtype)
  490. if str(xtype).lower() == "off":
  491. fx_value = self._fx_value
  492. #if fx_value != 0:
  493. # cprint("???????______ FX OFF AS FADE",fx_value,0,255)
  494. # self._flash_fx = Fade(fx_value,0,ftime=0.5,clock=clock)#,delay=delay)
  495. # self._flash_fx = None
  496. #else:
  497. # self._flash_fx = None
  498. # self._flash_fx_value = 0
  499. self._flash_fx = None
  500. self._flash_fx_value = 0
  501. else:
  502. self._flash_fx = FX(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=clock,master=master)
  503. def fx_ctl(self,cmd=""):#start,stop,off
  504. pass
  505. def __str__(self):
  506. return self.__repr__()
  507. def __repr__(self):
  508. return "< DMXCH {:0.2f} > {} {}".format( self._last_val,self._fx,self._fade)
  509. def fade_ctl(self,cmd=""):#start,stop,backw,fwd,bounce
  510. pass
  511. def next(self,clock=0):
  512. value = self._base_value
  513. if self._last_val is None:
  514. self._last_val = value
  515. fx_value = self._fx_value
  516. if self._flash is not None:
  517. value = self._flash.next(clock)
  518. #flicker bug ?!
  519. value = self._flash.next(clock)
  520. fx_value = 0
  521. elif self._fade is not None:#is Fade:# is Fade:
  522. self._base_value = self._fade.next(clock)
  523. #flicker bug ?!
  524. self._base_value = self._fade.next(clock)
  525. value = self._base_value
  526. if self._flash_fx is not None:# is FX:
  527. fx_value = self._flash_fx.next(clock)
  528. elif self._fx is not None and self._flash is None:# is FX:
  529. self._fx_value = self._fx.next(clock)
  530. fx_value = self._fx_value
  531. self._last_val = value+fx_value
  532. return self._last_val
  533. Bdmx = []
  534. for i in range(512*3):
  535. Bdmx.append( DMXCH() )
  536. #print(type(dmx[i]))
  537. def split_cmd(data):
  538. if "cmd" in data:
  539. cmd = data["cmd"]
  540. #print("cmd",cmd)
  541. if "," in cmd:
  542. cmds = cmd.split(",")
  543. else:
  544. cmds = [cmd]
  545. return cmds
  546. import time
  547. import json
  548. import zlib
  549. def JCB(data): #json client input
  550. t_start = time.time()
  551. #jdatas = data["cmd"].split("\x00")
  552. jdatas = [data["cmd"]]
  553. c = clock.time()
  554. c = float(c)
  555. print("JCB",round(c,2))
  556. ftime = 0
  557. delay = 0
  558. for j in jdatas:
  559. master_fx = MASTER_FX()
  560. if not j:
  561. continue
  562. try:
  563. cprint("JCB::")#,j)
  564. jdata = j #jdatas[j]
  565. jtxt = jdata
  566. #jtxt = zlib.decompress(jtxt) #jtxt.decode())
  567. jtxt = str(jtxt,"UTF-8")
  568. cmds = json.loads(jtxt)
  569. for x in cmds:
  570. #cprint(int(clock.time()*1000)/1000,end=" ",color="yellow")#time.time())
  571. #cprint("json", x,type(x),color="yellow")#,cmds[x])
  572. if "DMX" in x:
  573. DMX = int(x["DMX"])
  574. else:continue
  575. if DMX > 0:
  576. DMX -=1
  577. else:continue
  578. if "VALUE" in x:# and x["VALUE"] is not None:
  579. v = x["VALUE"]
  580. else:continue
  581. if "FX" in x:# and x["VALUE"] is not None:
  582. fx = x["FX"]
  583. else:fx=""
  584. if "FX2" in x:# and x["VALUE"] is not None:
  585. fx2 = x["FX2"]
  586. else:fx2={}
  587. if "FADE" in x:
  588. ftime = x["FADE"]
  589. else:ftime=0
  590. if "DELAY" in x:
  591. delay = x["DELAY"]
  592. else:delay=0
  593. if len(Bdmx) < DMX:
  594. continue
  595. if v is not None:
  596. if "FLASH" in x:
  597. #print("FLASH")
  598. Bdmx[DMX].flash(target=v,ftime=ftime, clock=c,delay=delay)
  599. else:
  600. #print("FADE")
  601. Bdmx[DMX].fade(target=v,ftime=ftime, clock=c,delay=delay)
  602. if type(fx2) is dict and fx2:
  603. #cprint("FX2",DMX,fx2,color="green")
  604. xtype="fade"
  605. size = 10
  606. speed = 10
  607. start = 0
  608. offset= 0
  609. width=100
  610. invert=0
  611. base = "-"
  612. if "TYPE" in fx2:
  613. xtype = fx2["TYPE"]
  614. if "SIZE" in fx2:
  615. size = fx2["SIZE"]
  616. if "SPEED" in fx2:
  617. speed = fx2["SPEED"]
  618. if "OFFSET" in fx2:
  619. offset = fx2["OFFSET"]
  620. if "BASE" in fx2:
  621. base = fx2["BASE"]
  622. if "INVERT" in fx2:
  623. invert = fx2["INVERT"]
  624. if "WIDTH" in fx2:
  625. width = fx2["WIDTH"]
  626. if "off" == x["VALUE"]: #fix fx flash off
  627. xtype= "off"
  628. if "alloff" == xtype.lower():
  629. for i in Bdmx:
  630. if i is not None:
  631. i.flash_fx(xtype="off",clock=c)
  632. i.fx(xtype="off",clock=c)
  633. if "FLASH" in x:
  634. 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)
  635. else:
  636. Bdmx[DMX].fx(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=c,master=master_fx)
  637. elif type(fx) is str and fx: # old fx like sinus:200:12:244
  638. ccm = str(DMX+1)+":"+fx
  639. print("fx",ccm)
  640. if "FLASH" in x:
  641. CB({"cmd":"fxf"+ccm})
  642. else:
  643. CB({"cmd":"fx"+ccm})
  644. cprint("{:0.04} sec.".format(time.time()-t_start),color="yellow")
  645. cprint("{:0.04} t.".format(time.time()),color="yellow")
  646. except Exception as e:
  647. cprint("EXCEPTION JCB",e,color="red")
  648. cprint("----",jdata,color="red")
  649. cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
  650. cprint()
  651. cprint("{:0.04} sec.".format(time.time()-t_start),color="yellow")
  652. cprint("{:0.04} t.".format(time.time()),color="yellow")
  653. def CB(data): # raw/text client input
  654. #print("CB",data)
  655. cmds = split_cmd(data)
  656. c = clock.time()
  657. c = float(c)
  658. ftime = 0
  659. delay = 0
  660. for xcmd in cmds:
  661. if xcmd:
  662. cprint("CB",xcmd,end=" ")
  663. pass
  664. else:
  665. continue
  666. if xcmd.startswith("fxf"):
  667. xxcmd=xcmd[3:].split(":")
  668. #print("fxf:",xxcmd)
  669. if "alloff" == xxcmd[1].lower():
  670. for i in Bdmx:
  671. if i is not None:
  672. i.flash_fx(xtype="off",clock=c)
  673. l = xxcmd
  674. try:
  675. xtype=""
  676. size=40
  677. speed=100
  678. start=0
  679. offset=0
  680. base=""
  681. k=int(l[0])-1
  682. xtype=l[1]
  683. if len(l) >= 3:
  684. try:size=int(l[2])
  685. except:pass
  686. if len(l) >= 4:
  687. try:speed=int(l[3])
  688. except:pass
  689. if len(l) >= 5:
  690. try:start=int(l[4])
  691. except:pass
  692. if len(l) >= 6:
  693. try:offset=int(l[5])
  694. except:pass
  695. if len(l) >= 7:
  696. try:base=l[6]
  697. except:pass
  698. if len(Bdmx) > k:
  699. #Bdmx[k].fade(target=v,ftime=t, clock=c)
  700. Bdmx[k].flash_fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
  701. except Exception as e:
  702. print("EXCEPTION IN FX",e)
  703. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  704. elif xcmd.startswith("fx"):
  705. xxcmd=xcmd[2:].split(":")
  706. print("DMX:",xxcmd)
  707. if len(xxcmd) < 2:
  708. print("xxcmd err",xxcmd,xcmd)
  709. continue
  710. if "alloff" == xxcmd[1].lower():
  711. for i in Bdmx:
  712. i.fx(xtype="off",clock=c)
  713. l = xxcmd
  714. try:
  715. xtype=""
  716. size=40
  717. speed=100
  718. start=0
  719. offset=0
  720. base=""
  721. k=int(l[0])-1
  722. xtype=l[1]
  723. if len(l) >= 3:
  724. try:size=int(l[2])
  725. except:pass
  726. if len(l) >= 4:
  727. try:speed=int(l[3])
  728. except:pass
  729. if len(l) >= 5:
  730. try:start=int(l[4])
  731. except:pass
  732. if len(l) >= 6:
  733. try:offset=int(l[5])
  734. except:pass
  735. if len(l) >= 7:
  736. try:base=l[6]
  737. except:pass
  738. if len(Bdmx) > k:
  739. #Bdmx[k].fade(target=v,ftime=t, clock=c)
  740. Bdmx[k].fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
  741. except Exception as e:
  742. print("EXCEPTION IN FX",xcmd,e)
  743. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  744. #jchat = chat.CMD(CB,port=50001) # server listener
  745. #thread.start_new_thread(jchat.poll,())
  746. chat.cmd(JCB) # server listener
  747. #chat.cmd(JCB,port=50001) # server listener
  748. #input("END")