_console.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  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.zchat 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():
  230. def __init__(self):
  231. self.__data = {}
  232. def val(self,name,value=None):
  233. value = 100 #%
  234. if name in self.__data:
  235. if value is not None:
  236. self.__data[name] = value
  237. else:
  238. value = self.__data[name]
  239. return value
  240. class SPEED_MASTER(_MASTER):
  241. def __init__(self):
  242. super().__init__()
  243. class SIZE_MASTER(_MASTER):
  244. def __init__(self):
  245. super().__init__()
  246. size_master = SIZE_MASTER()
  247. speed_master = SPEED_MASTER()
  248. class MASTER_FX():
  249. def __init__(self):
  250. #cprint(self,"MASTER_FX INIT !",color="green")
  251. self.__data = []
  252. self.__ok = []
  253. self.i=0
  254. self.old_offsets = []
  255. self.offsets = []
  256. self.count = -1
  257. self.init = 10
  258. def add(self,fx):
  259. if fx not in self.__data:
  260. #cprint(self,"ADD TO MASTER !",color="green")
  261. self.__data.append(fx)
  262. info = fx._get_info()
  263. #cprint(self,"ADD" ,info,color="green")
  264. offset = 0
  265. if "offset" in info:
  266. offset = info["offset"]
  267. self.old_offsets.append(offset)
  268. self.offsets.append(offset)
  269. if "xtype" in info:
  270. if info["xtype"] == "rnd":
  271. self._shuffle()
  272. #self.init += 1
  273. def _shuffle(self):
  274. #cprint(self,"REORDER RANDOM !",color="green")
  275. #self.init = 0
  276. #cprint(self.old_offsets)
  277. random.shuffle(self.old_offsets)
  278. #cprint(self.old_offsets)
  279. def _init(self):
  280. self._shuffle()
  281. #self.offsets = []
  282. for i,v in enumerate(self.old_offsets):
  283. offset = self.old_offsets[i]
  284. self.offsets[i] = offset
  285. self.init = 0
  286. def next(self,child):
  287. i = self.__data.index(child)
  288. offset = self.old_offsets[i]
  289. self.offsets[i] = offset
  290. return offset
  291. #for i,v in enumerate(self.old_offsets):
  292. # offset = self.old_offsets[i]
  293. # self.offsets[i] = offset
  294. def get(self,child,count):
  295. offset = 0
  296. if child not in self.__data:
  297. return offset
  298. if self.init:
  299. self._init()
  300. idx = self.__data.index(child)
  301. if (self.count != count and idx == 0 ) or self.init == 0:
  302. self.init = 1
  303. self._shuffle()
  304. #print( count)
  305. self.count=count
  306. idx = self.__data.index(child)
  307. offset = self.offsets[idx]
  308. return offset
  309. class FX():
  310. def __init__(self,xtype="sinus",size=10,speed=10,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None):
  311. self.__xtype=xtype
  312. self.__size = size
  313. self.__start = start
  314. if width > 200:
  315. width = 200
  316. if width <= 0:
  317. width = 1
  318. self.__fade_in_master = 0
  319. self.__width = width
  320. self.__invert = invert
  321. self.__base = base
  322. self.__speed = speed
  323. self.__offset = offset
  324. self.__clock = clock
  325. self.__clock_curr = clock
  326. self.out = 0
  327. self.old_v = -1
  328. self.run = 1
  329. self.count = -1
  330. self.__angel = self.__clock_curr*360%360
  331. if master is None:
  332. cprint(master, "MASTER_FX ERR",master,color="red")
  333. self.__master = MASTER_FX()
  334. self.__master.add(self)
  335. else:
  336. #cprint( "MASTER_FX OK",master,color="red")
  337. self.__master = master
  338. self.__master.add(self)
  339. if self.__xtype == "rnd":
  340. self.__offset = self.__master.get(self,-2)
  341. self.__offset = self.__master.next(self)#,count)
  342. self.next()
  343. #print("init FX",self)
  344. def _get_info(self):
  345. print(self.__offset)
  346. return {"offset":self.__offset,"xtype":self.__xtype}
  347. #return self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run
  348. def __str__(self):
  349. return self.__repr__()
  350. def __repr__(self):
  351. return "<FX Next:{:0.2f} xtype:{} Size:{:0.2f} Speed:{:0.2f} ang:{:0.2f} base:{} Clock:{:0.2f} run:{}>".format(
  352. self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run )
  353. def next(self,clock=None):
  354. if type(clock) is float or type(clock) is int:#not None:
  355. self.__clock_curr = clock
  356. t = self.__clock_curr * self.__speed / 60
  357. t += self.__offset / 100 #255 #1024 #255
  358. t += self.__start / 1024 #255
  359. tw = t%1
  360. count = t//1
  361. t = t * (100/self.__width)
  362. if tw > self.__width/100:
  363. t = 1
  364. self.__angel = t%1*360
  365. t = t%1
  366. rad = math.radians(self.__angel)
  367. v=0
  368. out = 0
  369. base = 0
  370. size = self.__size
  371. if self.__base == "+": # add
  372. base = size/2
  373. elif self.__base == "-": # sub
  374. base = size/2*-1
  375. if self.__xtype == "sinus":
  376. v = math.sin( rad )
  377. v/=2
  378. elif self.__xtype == "cosinus":
  379. v = math.cos( rad )
  380. if self.__base == "+": # add
  381. size *= -1
  382. v/=2
  383. elif self.__xtype == "rnd":
  384. #base = 0
  385. if self.__angel > 90 and self.__angel <=270:
  386. v=1
  387. else:
  388. v=0
  389. #if count != self.count and v: # % 2 == 0:#!= self.count:
  390. # #self.__offset = random.randint(0,1024)# /1024
  391. # self.__master._shuffle()
  392. if count != self.count and v == 0: # and v: # % 2 == 0:#!= self.count:
  393. self.__master.next(self)#,count)
  394. #self.__master.next(self)#,count)
  395. self.__offset = self.__master.get(self,count)
  396. base = 0
  397. if self.__base == "-": # sub
  398. if self.__invert:
  399. v = 1-v
  400. #base = -size
  401. size *=-1
  402. v *=-1
  403. elif self.__base == "+": # sub
  404. if self.__invert:
  405. v = v-1
  406. else:
  407. v = (t%1-0.5)
  408. elif self.__xtype == "on":
  409. #base = 0
  410. if self.__angel > 90 and self.__angel <=270:
  411. v=1
  412. else:
  413. v=0
  414. base = 0
  415. if self.__base == "-": # sub
  416. if self.__invert:
  417. v = 1-v
  418. #base = -size
  419. size *=-1
  420. v *=-1
  421. elif self.__base == "+": # sub
  422. if self.__invert:
  423. v = v-1
  424. else:
  425. v = (t%1-0.5)
  426. elif self.__xtype == "ramp" or self.__xtype == "ramp":
  427. v = (t%1)
  428. base = 0
  429. if self.__base == "-": # sub
  430. if self.__invert:
  431. v = 1-v
  432. #base = -size
  433. size *=-1
  434. v *=-1
  435. elif self.__base == "+": # sub
  436. if self.__invert:
  437. v = v-1
  438. else:
  439. v = (t%1-0.5)
  440. elif self.__xtype == "ramp2" or self.__xtype == "bump2":
  441. v = (t%1)
  442. v = 1-v
  443. if v == 1:
  444. v=0
  445. base = 0
  446. if self.__base == "-": # sub
  447. if self.__invert:
  448. v = 1-v
  449. #base = -size
  450. size *=-1
  451. v *=-1
  452. elif self.__base == "+": # sub
  453. if self.__invert:
  454. v = v-1
  455. else:
  456. v = (t%1-0.5)
  457. elif self.__xtype == "fade":
  458. x = t * 2
  459. if x > 1:
  460. x = 2-x
  461. x -= 0.5
  462. v = x*2
  463. #base /= 2
  464. #base *=2
  465. if self.__base == "+": # add
  466. pass#base /= 2
  467. else:
  468. v *= -1
  469. v/=2
  470. if self.__invert:
  471. v *=-1
  472. #if self.__fade_in_master < 255:
  473. # self.__fade_in_master += v*size
  474. out = v *size +base
  475. self.out = out
  476. self.count = count
  477. return out #* (self.__fade_in_master /255.)
  478. class DMXCH(object):
  479. def __init__(self):
  480. self._base_value = 0
  481. self._fade = None
  482. self._fx = [None,None] # None
  483. self._fx_value = 0
  484. self._flash = None
  485. self._flash_fx = None
  486. self._flash_fx_value = 0
  487. self._last_val = None
  488. def fade(self,target,ftime=0,clock=0,delay=0):
  489. if target != self._base_value:
  490. try:
  491. target = float(target)
  492. self._fade = Fade(self._base_value,target,ftime=ftime,clock=clock,delay=delay)
  493. #self._fade.next()
  494. #self._fade.next()
  495. except Exception as e:
  496. print( "Except:fade",e,target,ftime,clock)
  497. def fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="", clock=0,master=None):
  498. print([self,xtype,size,speed,start,offset,base, clock])
  499. self._fx[0] = self._fx[1]
  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._fx[1] = Fade(fx_value,0,ftime=0.5,clock=clock)
  505. else:
  506. self._fx[1] = None
  507. self._fx_value = 0
  508. else:
  509. self._fx[1] = FX(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=clock,master=master)
  510. def flash(self,target,ftime=0,clock=0,delay=0):
  511. if str(target).lower() == "off":
  512. self._flash = None
  513. else:#elif target != self._base_value:
  514. try:
  515. target = float(target)
  516. self._flash = Fade(self._last_val,target,ftime=ftime,clock=clock,delay=delay)
  517. except Exception as e:
  518. print( "Except:flash",target,ftime,clock,__name__,e,)
  519. def flash_fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None):
  520. #if self._flash_fx is not None :
  521. # cprint("flash_fx",xtype)
  522. if str(xtype).lower() == "off":
  523. fx_value = self._fx_value
  524. #if fx_value != 0:
  525. # cprint("???????______ FX OFF AS FADE",fx_value,0,255)
  526. # self._flash_fx = Fade(fx_value,0,ftime=0.5,clock=clock)#,delay=delay)
  527. # self._flash_fx = None
  528. #else:
  529. # self._flash_fx = None
  530. # self._flash_fx_value = 0
  531. self._flash_fx = None
  532. self._flash_fx_value = 0
  533. else:
  534. self._flash_fx = FX(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=clock,master=master)
  535. def fx_ctl(self,cmd=""):#start,stop,off
  536. pass
  537. def __str__(self):
  538. return self.__repr__()
  539. def __repr__(self):
  540. return "< DMXCH {:0.2f} > {} {}".format( self._last_val,self._fx,self._fade)
  541. def fade_ctl(self,cmd=""):#start,stop,backw,fwd,bounce
  542. pass
  543. def next(self,clock=0):
  544. value = self._base_value
  545. if self._last_val is None:
  546. self._last_val = value
  547. fx_value = self._fx_value
  548. if self._flash is not None:
  549. value = self._flash.next(clock)
  550. #flicker bug ?!
  551. value = self._flash.next(clock)
  552. fx_value = 0
  553. elif self._fade is not None:#is Fade:# is Fade:
  554. self._base_value = self._fade.next(clock)
  555. #flicker bug ?!
  556. self._base_value = self._fade.next(clock)
  557. value = self._base_value
  558. if self._flash_fx is not None:# is FX:
  559. fx_value = self._flash_fx.next(clock)
  560. else:
  561. self._fx_value = 0
  562. if self._fx[-1] is not None and self._flash is None:# is FX:
  563. self._fx_value += self._fx[-1].next(clock)
  564. #if self._fx[0] is not None and self._flash is None:# is FX:
  565. # self._fx_value += self._fx[0].next(clock)
  566. fx_value = self._fx_value
  567. self._last_val = value + fx_value
  568. return self._last_val
  569. Bdmx = []
  570. for i in range(512*3):
  571. Bdmx.append( DMXCH() )
  572. #print(type(dmx[i]))
  573. def split_cmd(data):
  574. if "cmd" in data:
  575. cmd = data["cmd"]
  576. #print("cmd",cmd)
  577. if "," in cmd:
  578. cmds = cmd.split(",")
  579. else:
  580. cmds = [cmd]
  581. return cmds
  582. import time
  583. import json
  584. import zlib
  585. def JCB(data): #json client input
  586. t_start = time.time()
  587. #jdatas = data["cmd"].split("\x00")
  588. jdatas = [data["cmd"]]
  589. c = clock.time()
  590. c = float(c)
  591. print("JCB",round(c,2))
  592. ftime = 0
  593. delay = 0
  594. for j in jdatas:
  595. master_fx = MASTER_FX()
  596. if not j:
  597. continue
  598. try:
  599. cprint("JCB::")#,j)
  600. jdata = j #jdatas[j]
  601. jtxt = jdata
  602. #jtxt = zlib.decompress(jtxt) #jtxt.decode())
  603. jtxt = str(jtxt,"UTF-8")
  604. cmds = json.loads(jtxt)
  605. for x in cmds:
  606. #cprint(int(clock.time()*1000)/1000,end=" ",color="yellow")#time.time())
  607. #cprint("json", x,type(x),color="yellow")#,cmds[x])
  608. if "CMD" in x:
  609. print("CMD:",x)
  610. if "SPEED-MASTER" == x["CMD"]:
  611. speed_master.val("SPEED-{}".format(x["NR"]),x["VALUE"])
  612. if "SIZE-MASTER" == x["CMD"]:
  613. size_master.val("SIZE-{}".format(x["NR"]),x["VALUE"])
  614. else:
  615. if "DMX" in x:
  616. DMX = int(x["DMX"])
  617. else:continue
  618. if DMX > 0:
  619. DMX -=1
  620. else:continue
  621. if "VALUE" in x:# and x["VALUE"] is not None:
  622. v = x["VALUE"]
  623. else:continue
  624. if "FX" in x:# and x["VALUE"] is not None:
  625. fx = x["FX"]
  626. else:fx=""
  627. if "FX2" in x:# and x["VALUE"] is not None:
  628. fx2 = x["FX2"]
  629. else:fx2={}
  630. if "FADE" in x:
  631. ftime = x["FADE"]
  632. else:ftime=0
  633. if "DELAY" in x:
  634. delay = x["DELAY"]
  635. else:delay=0
  636. if len(Bdmx) < DMX:
  637. continue
  638. if v is not None:
  639. if "FLASH" in x:
  640. #print("FLASH")
  641. Bdmx[DMX].flash(target=v,ftime=ftime, clock=c,delay=delay)
  642. else:
  643. #print("FADE")
  644. Bdmx[DMX].fade(target=v,ftime=ftime, clock=c,delay=delay)
  645. if type(fx2) is dict and fx2:
  646. #cprint("FX2",DMX,fx2,color="green")
  647. xtype="fade"
  648. size = 10
  649. speed = 10
  650. start = 0
  651. offset= 0
  652. width=100
  653. invert=0
  654. base = "-"
  655. if "TYPE" in fx2:
  656. xtype = fx2["TYPE"]
  657. if "SIZE" in fx2:
  658. size = fx2["SIZE"]
  659. if "SPEED" in fx2:
  660. speed = fx2["SPEED"]
  661. if "OFFSET" in fx2:
  662. offset = fx2["OFFSET"]
  663. if "BASE" in fx2:
  664. base = fx2["BASE"]
  665. if "INVERT" in fx2:
  666. invert = fx2["INVERT"]
  667. if "WIDTH" in fx2:
  668. width = fx2["WIDTH"]
  669. if "off" == x["VALUE"]: #fix fx flash off
  670. xtype= "off"
  671. if "alloff" == xtype.lower():
  672. for i in Bdmx:
  673. if i is not None:
  674. i.flash_fx(xtype="off",clock=c)
  675. i.fx(xtype="off",clock=c)
  676. if "FLASH" in x:
  677. 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)
  678. else:
  679. Bdmx[DMX].fx(xtype=xtype,size=size,speed=speed,invert=invert,width=width,start=start,offset=offset,base=base,clock=c,master=master_fx)
  680. elif type(fx) is str and fx: # old fx like sinus:200:12:244
  681. ccm = str(DMX+1)+":"+fx
  682. print("fx",ccm)
  683. if "FLASH" in x:
  684. CB({"cmd":"fxf"+ccm})
  685. else:
  686. CB({"cmd":"fx"+ccm})
  687. cprint("{:0.04} sec.".format(time.time()-t_start),color="yellow")
  688. cprint("{:0.04} t.".format(time.time()),color="yellow")
  689. except Exception as e:
  690. cprint("EXCEPTION JCB",e,color="red")
  691. cprint("----",str(jdata)[:150],"...",color="red")
  692. cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
  693. cprint()
  694. cprint("{:0.04} sec.".format(time.time()-t_start),color="yellow")
  695. cprint("{:0.04} t.".format(time.time()),color="yellow")
  696. def CB(data): # raw/text client input
  697. #print("CB",data)
  698. cmds = split_cmd(data)
  699. c = clock.time()
  700. c = float(c)
  701. ftime = 0
  702. delay = 0
  703. for xcmd in cmds:
  704. if xcmd:
  705. cprint("CB",xcmd,end=" ")
  706. pass
  707. else:
  708. continue
  709. if xcmd.startswith("fxf"):
  710. xxcmd=xcmd[3:].split(":")
  711. #print("fxf:",xxcmd)
  712. if "alloff" == xxcmd[1].lower():
  713. for i in Bdmx:
  714. if i is not None:
  715. i.flash_fx(xtype="off",clock=c)
  716. l = xxcmd
  717. try:
  718. xtype=""
  719. size=40
  720. speed=100
  721. start=0
  722. offset=0
  723. base=""
  724. k=int(l[0])-1
  725. xtype=l[1]
  726. if len(l) >= 3:
  727. try:size=int(l[2])
  728. except:pass
  729. if len(l) >= 4:
  730. try:speed=int(l[3])
  731. except:pass
  732. if len(l) >= 5:
  733. try:start=int(l[4])
  734. except:pass
  735. if len(l) >= 6:
  736. try:offset=int(l[5])
  737. except:pass
  738. if len(l) >= 7:
  739. try:base=l[6]
  740. except:pass
  741. if len(Bdmx) > k:
  742. #Bdmx[k].fade(target=v,ftime=t, clock=c)
  743. Bdmx[k].flash_fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
  744. except Exception as e:
  745. print("EXCEPTION IN FX",e)
  746. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  747. elif xcmd.startswith("fx"):
  748. xxcmd=xcmd[2:].split(":")
  749. print("DMX:",xxcmd)
  750. if len(xxcmd) < 2:
  751. print("xxcmd err",xxcmd,xcmd)
  752. continue
  753. if "alloff" == xxcmd[1].lower():
  754. for i in Bdmx:
  755. i.fx(xtype="off",clock=c)
  756. l = xxcmd
  757. try:
  758. xtype=""
  759. size=40
  760. speed=100
  761. start=0
  762. offset=0
  763. base=""
  764. k=int(l[0])-1
  765. xtype=l[1]
  766. if len(l) >= 3:
  767. try:size=int(l[2])
  768. except:pass
  769. if len(l) >= 4:
  770. try:speed=int(l[3])
  771. except:pass
  772. if len(l) >= 5:
  773. try:start=int(l[4])
  774. except:pass
  775. if len(l) >= 6:
  776. try:offset=int(l[5])
  777. except:pass
  778. if len(l) >= 7:
  779. try:base=l[6]
  780. except:pass
  781. if len(Bdmx) > k:
  782. #Bdmx[k].fade(target=v,ftime=t, clock=c)
  783. Bdmx[k].fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
  784. except Exception as e:
  785. print("EXCEPTION IN FX",xcmd,e)
  786. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  787. if __run_main:
  788. #jchat = chat.CMD(CB,port=50001) # server listener
  789. #thread.start_new_thread(jchat.poll,())
  790. chat.cmd(JCB) # server listener
  791. #chat.cmd(JCB,port=50001) # server listener
  792. #input("END")