_console.py 27 KB

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