_console.py 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
  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@librelight.de
  15. """
  16. import sys
  17. import time
  18. import json
  19. import zlib
  20. rnd_id = ""
  21. rnd_id += " Beta 22.02 "
  22. import subprocess
  23. import tool.git as git
  24. rnd_id += git.get_all()
  25. if "__file__" in dir():
  26. sys.stdout.write("\x1b]2;"+str(__file__)+" "+rnd_id+"\x07") # terminal title
  27. else:
  28. sys.stdout.write("\x1b]2;"+str("__file__")+" "+rnd_if+"\x07") # terminal title
  29. __run_main = 0
  30. if __name__ == "__main__":
  31. __run_main = 1
  32. else:
  33. import __main__
  34. print(dir())
  35. if "unittest" not in dir(__main__):
  36. __run_main = 1
  37. import time
  38. import socket
  39. import struct
  40. import sys
  41. import random
  42. import math
  43. from collections import OrderedDict
  44. import lib.zchat as chat
  45. import lib.ArtNetNode as ANN
  46. import _thread as thread
  47. #thread.start_new_thread
  48. import lib.motion as motion
  49. #idmx = [0]*512 # incremental dmx
  50. dmx = [0]*512 # absolute dmx data
  51. gcolor = 1
  52. def cprint(*text,color="blue",space=" ",end="\n"):
  53. #return 0 #disable print dbg
  54. if not gcolor:
  55. print(text)
  56. return 0
  57. if color == "green":
  58. txt = '\033[92m'
  59. elif color == "red":
  60. txt = '\033[0;31m\033[1m'
  61. elif color == "yellow":
  62. txt = '\033[93m\033[1m'
  63. elif color == "cyan":
  64. txt = '\033[96m'
  65. else:
  66. txt = '\033[94m'
  67. for t in text:
  68. txt += str(t ) +" "
  69. #HEADER = '\033[95m'
  70. #OKBLUE = '\033[94m'
  71. #OKCYAN = '\033[96m'
  72. #OKGREEN = '\033[92m'
  73. #WARNING = '\033[93m'
  74. #FAIL = '\033[91m'
  75. #ENDC = '\033[0m'
  76. #BOLD = '\033[1m'
  77. #UNDERLINE = '\033[4m'
  78. txt += '\033[0m'
  79. print(txt,end=end)
  80. #return txt
  81. def artnet_loop():
  82. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=12)
  83. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=0)
  84. artnet = ANN.ArtNetNode(to="10.10.10.255",univ=0)
  85. #artnet = ANN.ArtNetNode(to="2.0.0.255",univ=0)
  86. #artnet = ANN.ArtNetNode(to="10.10.10.255",univ=1)
  87. #dmx[205] = 255 #205 BLUE
  88. artnet.dmx= dmx #[0]*512
  89. artnet.send()
  90. while 1:
  91. #artnet._test_frame()
  92. artnet.next()
  93. time.sleep(0.001)
  94. class CLOCK():
  95. def __init__(self):
  96. self.__time = 0
  97. self.__start = time.time() # only for debugging
  98. self.__tick = 0.01 # incremental timer drift's on highe cpu load ?
  99. def time(self):
  100. return self.__time
  101. def get_drift(self):
  102. run_time = time.time() - self.__start
  103. tick_time = self.__time # * self.__tick
  104. print( "runtime:{:0.2f} tick_timer:{:0.2f} drift:{:0.2f}".format(run_time,tick_time,run_time-tick_time))
  105. def loop(self):
  106. while 1:
  107. self.__time +=self.__tick
  108. #if int(self.__time*100)/10. % 10 == 0:# self.__time % 2 == 0:
  109. # print( self.get_drift())
  110. #print(self.__time)
  111. #for i in range(10):
  112. time.sleep(self.__tick)
  113. class CLOCK_REAL():
  114. def __init__(self):
  115. self.__time = 0
  116. self.__start = time.time() # only for debugging
  117. self.__tick = 0.001 # incremental timer drift's on highe cpu load ?
  118. def time(self):
  119. self.__time = time.time()
  120. return self.__time
  121. def get_drift(self):
  122. run_time = time.time() - self.__start
  123. tick_time = self.__time # * self.__tick
  124. print( "runtime:{:0.2f} tick_timer:{:0.2f} drift:{:0.2f}".format(run_time,tick_time,run_time-tick_time))
  125. def loop(self):
  126. pass
  127. #clock = CLOCK()
  128. clock = CLOCK_REAL()
  129. if __run_main:
  130. thread.start_new_thread(clock.loop,())
  131. class Fade():
  132. def __init__(self,start,target,ftime,clock,delay=0):
  133. #print("init Fade ",start,target,ftime,clock)
  134. if delay < 0:
  135. delay = 0.0001
  136. if ftime <= 0:
  137. ftime = 0.0001
  138. clock += delay
  139. self.__delay = delay
  140. self.__clock = clock
  141. self.__clock_curr = clock
  142. self.__ftime = ftime
  143. self.__start = start
  144. self.__last = start
  145. self.__target = target
  146. self.run = 1
  147. #print("INIT", str(self) )
  148. def __str__(self):
  149. return self.__repr__()
  150. def __repr__(self):
  151. return "<FADE Next:{:0.2f} from:{:0.2f} to:{:0.2f} ft:{:0.2f} Clock:{:0.2f} run:{} delay:{:0.2f}>".format(
  152. self.__last, self.__start,self.__target,self.__ftime,self.__clock_curr,self.run,self.__delay )
  153. def next(self,clock=None):
  154. if self.__ftime <= 0 and self.__delay <= 0:
  155. self.__last = self.__target
  156. self.run = 0
  157. if type(clock) is float or type(clock) is int:#not None:
  158. self.__clock_curr = clock
  159. if self.__target > self.__start:
  160. if self.__last >= self.__target:
  161. self.run = 0
  162. return self.__target
  163. else:
  164. if self.__last <= self.__target:
  165. self.run = 0
  166. return self.__target
  167. current = (self.__clock - self.__clock_curr) / self.__ftime
  168. length = self.__start - self.__target
  169. self.__last = self.__start+ length*current
  170. #if self.__last < 0:
  171. # self.__last = 0
  172. #if self.__last > 255:
  173. # self.__last = 255
  174. self.run = 1
  175. return self.__last
  176. def ctl(self,cmd="",value=None): # if x-fade cmd="%" value=50
  177. # start,stop,fwd,bwd,revers
  178. pass
  179. class _MASTER():
  180. def __init__(self,name="None"):
  181. self.__data = {}
  182. self.name = name
  183. def val(self,name,value=None):
  184. _value = 100 #%
  185. name = str(name)
  186. if name not in self.__data:
  187. self.__data[name] = 100
  188. _value = self.__data[name]
  189. if value is not None:
  190. if _value != value:
  191. print(self.name,"CHANGE MASTER:",name,"from:",_value,"to:",value)
  192. self.__data[name] = value
  193. _value = self.__data[name]
  194. return _value /100.
  195. exec_size_master = _MASTER("EXEC-SIZE")
  196. exec_speed_master = _MASTER("EXEC-SPEED")
  197. exec_offset_master = _MASTER("EXEC-OFFSET")
  198. size_master = _MASTER("SIZE")
  199. speed_master = _MASTER("SPEED")
  200. exe_master = []
  201. exe_master.append({"SIZE":100,"SPEED":100,"id":12,"link-ids":[2]})
  202. class MASTER_FX():
  203. def __init__(self):
  204. #cprint(self,"MASTER_FX INIT !",color="green")
  205. self.__data = []
  206. self.__ok = []
  207. self.i=0
  208. self.old_offsets = []
  209. self.offsets = []
  210. self.count = -1
  211. self.init = 10
  212. def add(self,fx):
  213. if fx not in self.__data:
  214. #cprint(self,"ADD TO MASTER !",color="green")
  215. self.__data.append(fx)
  216. info = fx._get_info()
  217. #cprint(self,"ADD" ,info,color="green")
  218. offset = 0
  219. if "offset" in info:
  220. offset = info["offset"]
  221. self.old_offsets.append(offset)
  222. self.offsets.append(offset)
  223. if "xtype" in info:
  224. if info["xtype"] == "rnd":
  225. self._shuffle()
  226. #self.init += 1
  227. def _shuffle(self):
  228. #cprint(self,"REORDER RANDOM !",color="green")
  229. #self.init = 0
  230. #cprint(self.old_offsets)
  231. random.shuffle(self.old_offsets)
  232. #cprint(self.old_offsets)
  233. def _init(self):
  234. self._shuffle()
  235. #self.offsets = []
  236. for i,v in enumerate(self.old_offsets):
  237. offset = self.old_offsets[i]
  238. self.offsets[i] = offset
  239. self.init = 0
  240. def next(self,child):
  241. i = self.__data.index(child)
  242. offset = self.old_offsets[i]
  243. self.offsets[i] = offset
  244. return offset
  245. #for i,v in enumerate(self.old_offsets):
  246. # offset = self.old_offsets[i]
  247. # self.offsets[i] = offset
  248. def get(self,child,count):
  249. offset = 0
  250. if child not in self.__data:
  251. return offset
  252. if self.init:
  253. self._init()
  254. idx = self.__data.index(child)
  255. if (self.count != count and idx == 0 ) or self.init == 0:
  256. self.init = 1
  257. self._shuffle()
  258. #print( count)
  259. self.count=count
  260. idx = self.__data.index(child)
  261. offset = self.offsets[idx]
  262. return offset
  263. class FX():
  264. 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):
  265. self.__xtype=xtype
  266. self.__size = size
  267. self.__start = start
  268. self.__master_id = master_id
  269. if width > 200:
  270. width = 200
  271. if width <= 0:
  272. width = 1
  273. self.__fade_in_master = 0
  274. self.__width = width
  275. self.__invert = invert
  276. self.__base = base
  277. self.__speed = speed
  278. self.__offset = offset
  279. self.__clock = clock
  280. self.__clock_curr = clock
  281. self.__clock_delta = 0
  282. self.__clock_old = self.__clock_curr
  283. self.out = 0
  284. self.old_v = -1
  285. self.run = 1
  286. self.count = -1
  287. self.__angel = self.__clock_curr*360%360
  288. if master is None:
  289. cprint(master, "MASTER_FX ERR",master,color="red")
  290. self.__master = MASTER_FX()
  291. self.__master.add(self)
  292. else:
  293. #cprint( "MASTER_FX OK",master,color="red")
  294. self.__master = master
  295. self.__master.add(self)
  296. if self.__xtype == "rnd":
  297. self.__offset = self.__master.get(self,-2)
  298. self.__offset = self.__master.next(self)#,count)
  299. self._exec_id = None
  300. self.next()
  301. #print("init FX",self)
  302. def exec_id(self,_id=None):
  303. if type(_id) is not type(None):
  304. self._exec_id = str(_id)
  305. return self._exec_id
  306. def _get_info(self):
  307. #print("self.__offset",self.__offset)
  308. return {"offset":self.__offset,"xtype":self.__xtype}
  309. #return self.next(),self.__xtype, self.__size,self.__speed,self.__angel, self.__base,self.__clock_curr,self.run
  310. def __str__(self):
  311. return self.__repr__()
  312. def __repr__(self):
  313. return "<FX Next:{:0.2f} xtype:{} Size:{:0.2f} Speed:{:0.2f} ang:{:0.2f} base:{} Clock:{:0.2f} run:{} EXEC:{}>".format(
  314. self.next(), self.__xtype, self.__size, self.__speed, self.__angel
  315. , self.__base, self.__clock_curr, self.run, self._exec_id )
  316. def next(self,clock=None):
  317. if type(clock) is float or type(clock) is int:#not None:
  318. self.__clock_curr = clock
  319. d = (self.__clock_curr - self.__clock_old)
  320. #print()
  321. #print("A",d)
  322. m1 = ( speed_master.val(self.__master_id)) # global speed-master
  323. #print("B {:0.4}".format(m1))
  324. m2 = ( exec_speed_master.val(self._exec_id)) # exec start by 0
  325. #print("C {:0.4}".format(m2))
  326. shift = 0
  327. m = (m1 * m2) -1
  328. shift += d * m
  329. #print("D",shift)
  330. self.__clock_delta += shift
  331. #print(self.__clock_delta )
  332. self.__clock_old = self.__clock_curr
  333. t = self.__clock_curr
  334. t += self.__clock_delta
  335. t *= self.__speed / 60
  336. offset2 = self.__offset
  337. offset2 *= exec_offset_master.val(self._exec_id)
  338. #t += self.__offset / 100 #255 #1024 #255
  339. t += offset2 / 100
  340. t += self.__start / 1024 #255
  341. #t = t*speed_master.val(self.__master_id)
  342. tw = t%1
  343. count = t//1
  344. t = t * (100/self.__width)
  345. if tw > self.__width/100:
  346. t = 1
  347. self.__angel = t%1*360
  348. t = t%1
  349. rad = math.radians(self.__angel)
  350. v=0
  351. out = 0
  352. base = 0
  353. size = self.__size
  354. if self.__base == "+": # add
  355. base = size/2
  356. elif self.__base == "-": # sub
  357. base = size/2*-1
  358. if self.__xtype == "sinus":
  359. v = math.sin( rad )
  360. v/=2
  361. elif self.__xtype == "cosinus":
  362. v = math.cos( rad )
  363. if self.__base == "+": # add
  364. size *= -1
  365. v/=2
  366. elif self.__xtype == "rnd":
  367. #base = 0
  368. if self.__angel > 90 and self.__angel <=270:
  369. v=1
  370. else:
  371. v=0
  372. #if count != self.count and v: # % 2 == 0:#!= self.count:
  373. # #self.__offset = random.randint(0,1024)# /1024
  374. # self.__master._shuffle()
  375. if count != self.count and v == 0: # and v: # % 2 == 0:#!= self.count:
  376. self.__master.next(self)#,count)
  377. #self.__master.next(self)#,count)
  378. self.__offset = self.__master.get(self,count)
  379. base = 0
  380. if self.__base == "-": # sub
  381. if self.__invert:
  382. v = 1-v
  383. #base = -size
  384. size *=-1
  385. v *=-1
  386. elif self.__base == "+": # sub
  387. if self.__invert:
  388. v = v-1
  389. else:
  390. v = (t%1-0.5)
  391. elif self.__xtype == "on":
  392. #base = 0
  393. if self.__angel > 90 and self.__angel <=270:
  394. v=1
  395. else:
  396. v=0
  397. base = 0
  398. if self.__base == "-": # sub
  399. if self.__invert:
  400. v = 1-v
  401. #base = -size
  402. size *=-1
  403. v *=-1
  404. elif self.__base == "+": # sub
  405. if self.__invert:
  406. v = v-1
  407. else:
  408. v = (t%1-0.5)
  409. elif self.__xtype == "ramp" or self.__xtype == "ramp":
  410. v = (t%1)
  411. base = 0
  412. if self.__base == "-": # sub
  413. if self.__invert:
  414. v = 1-v
  415. #base = -size
  416. size *=-1
  417. v *=-1
  418. elif self.__base == "+": # sub
  419. if self.__invert:
  420. v = v-1
  421. else:
  422. v = (t%1-0.5)
  423. elif self.__xtype == "ramp2" or self.__xtype == "bump2":
  424. v = (t%1)
  425. v = 1-v
  426. if v == 1:
  427. v=0
  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 == "fade":
  441. x = t * 2
  442. if x > 1:
  443. x = 2-x
  444. x -= 0.5
  445. v = x*2
  446. #base /= 2
  447. #base *=2
  448. if self.__base == "+": # add
  449. pass#base /= 2
  450. else:
  451. v *= -1
  452. v/=2
  453. if self.__invert:
  454. v *=-1
  455. #if self.__fade_in_master < 255:
  456. # self.__fade_in_master += v*size
  457. out = v *size +base
  458. self.out = out
  459. self.count = count
  460. out = out * size_master.val(self.__master_id) # master
  461. out = out * exec_size_master.val(self._exec_id) # master
  462. #* (self.__fade_in_master /255.)
  463. return out
  464. class DMXCH(object):
  465. def __init__(self,dmx=-1):
  466. self._base_value = 0
  467. self._fade = None
  468. self._fx = [None,None] # None
  469. self._fx_value = 0
  470. self._dmx = dmx
  471. self._dmx_fine = 0
  472. self._fix_id = 0
  473. self._v_master_id=0
  474. self._flash = None
  475. self._flash_fx = None
  476. self._flash_fx_value = 0
  477. self._last_val = None
  478. self._exec_ids = [None,None,None,None] # go, go-fx, flash, flash-fx
  479. #self.next(clock)
  480. #print("init",self)
  481. def fade(self,target,ftime=0,clock=0,delay=0):
  482. if target != self._base_value:
  483. try:
  484. target = float(target)
  485. self._fade = Fade(self._base_value,target,ftime=ftime,clock=clock,delay=delay)
  486. #self._fade.next()
  487. #self._fade.next()
  488. except Exception as e:
  489. print( "Except:fade",e,target,ftime,clock)
  490. self.next(clock)
  491. #print("init fade",self)
  492. def fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="", clock=0,master=None):
  493. #print("DMXCH.fx",[self,xtype,size,speed,start,offset,base, clock])
  494. self._fx[0] = self._fx[1]
  495. if str(xtype).lower() == "off":
  496. fx_value = self._fx_value
  497. if fx_value != 0:
  498. cprint("???????______ FX OFF AS FADE",fx_value,0,255)
  499. self._fx[1] = Fade(fx_value,0,ftime=0.5,clock=clock)
  500. else:
  501. self._fx[1] = None
  502. self._fx_value = 0
  503. else:
  504. self._fx[1] = FX(xtype=xtype,size=size,speed=speed,invert=invert
  505. ,width=width,start=start,offset=offset,base=base
  506. ,clock=clock,master=master,master_id=1)
  507. self._fx[1].exec_id(self._exec_ids[1])
  508. self.next(clock)
  509. #print("init fx",self)
  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. self.next(clock)
  520. #print("init flush",self)
  521. def flash_fx(self,xtype="sinus",size=40,speed=40,invert=0,width=100,start=0,offset=0,base="",clock=0,master=None):
  522. if str(xtype).lower() == "off":
  523. fx_value = self._fx_value
  524. self._flash_fx = None
  525. self._flash_fx_value = 0
  526. else:
  527. self._flash_fx = FX(xtype=xtype,size=size,speed=speed,invert=invert
  528. ,width=width,start=start,offset=offset,base=base
  529. ,clock=clock,master=master,master_id=0)
  530. self._flash_fx.exec_id(self._exec_ids[3])
  531. self.next(clock)
  532. #print("init flash_fx",self)
  533. def fx_ctl(self,cmd=""): #start,stop,off
  534. pass
  535. def __str__(self):
  536. return self.__repr__()
  537. def exec_ids(self,_id=None):
  538. #if type(_id) is not type(None):
  539. # #self._exec_id = _id
  540. # #print("set exec_id",_id)
  541. return self._exec_ids
  542. def __repr__(self):
  543. v = self._last_val
  544. if type(self._last_val) in [int,float]:
  545. v = round(self._last_val,2)
  546. return "<BUFFER DMX:{} FINE:{} VAL:{} EXEC:{}\n fd:{}\n fx:{}\n fx_flash:{}\n".format(
  547. self._dmx,self._dmx_fine
  548. ,v,str(self._exec_ids)
  549. ,self._fade
  550. ,self._fx
  551. ,self._flash_fx)
  552. def fade_ctl(self,cmd=""): #start,stop,backw,fwd,bounce
  553. pass
  554. def next(self,clock=0):
  555. try:
  556. self._next(clock)
  557. except Exception as e:
  558. cprint("Exception DMXCH.next()" ,e)
  559. out = self._last_val
  560. return out
  561. def _next(self,clock=0):
  562. value = self._base_value
  563. #self._last_val = value
  564. #return value
  565. #if self._dmx == 1024:
  566. # print(self)
  567. if self._last_val is None:
  568. self._last_val = value
  569. fx_value = self._fx_value
  570. if self._flash is not None:
  571. value = self._flash.next(clock)
  572. #flicker bug ?!
  573. value = self._flash.next(clock)
  574. fx_value = 0
  575. elif self._fade is not None:#is Fade:# is Fade:
  576. self._base_value = self._fade.next(clock)
  577. self._base_value = self._fade.next(clock) #flicker bug ?!
  578. value = self._base_value
  579. if self._flash_fx is not None:# is FX:
  580. fx_value = self._flash_fx.next(clock)
  581. else:
  582. self._fx_value = 0
  583. if self._fx[-1] is not None and self._flash is None:# is FX:
  584. self._fx_value += self._fx[-1].next(clock)
  585. fx_value = self._fx_value
  586. self._last_val = value + fx_value
  587. #self._last_val *= v_master.val(self._fix_id)
  588. if self._v_master_id in V_MASTER:
  589. vm = V_MASTER[self._v_master_id].next(clock)
  590. #print("V_MASTER is ", V_MASTER[self._v_master_id])
  591. vm = vm/256
  592. self._last_val *= vm # v_master.val(self._v_master_id)
  593. #out = self._last_val * htp_master.master_by_dmx(self._dmx)
  594. out = self._last_val
  595. return out
  596. V_MASTER = {} #DMXCH
  597. Bdmx = []
  598. for i in range(512*7+1):
  599. Bdmx.append( DMXCH(i) )
  600. #print(type(dmx[i]))
  601. _id = 1
  602. def split_cmd(data):
  603. if "cmd" in data:
  604. cmd = data["cmd"]
  605. #print("cmd",cmd)
  606. if "," in cmd:
  607. cmds = cmd.split(",")
  608. else:
  609. cmds = [cmd]
  610. return cmds
  611. class VDMX():
  612. """functional implementation as class for namespace encapsulation
  613. """
  614. def __init__(self):
  615. self.data = OrderedDict()
  616. self.data[4] = {"DMX":[21,22,23],"VALUE":255, "LIMIT":255} #,"DMXCH":DMXCH("V4")}
  617. for k,v in self.data.items():
  618. pass
  619. #dmxch = v["DMXCH"]
  620. #dmxch.fade(10,0)
  621. #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):
  622. def _list_by_dmx(self,_dmx=0):
  623. data = OrderedDict()
  624. for i,link in self.data.items(): # enumerate(self.data):
  625. if _dmx in link["DMX"]:
  626. #print( "_list_by_dmx",i,link)
  627. data[i] = link
  628. return data
  629. def dmx_by_id(self,_id=0):
  630. #print("dmx by master-id:",_id)
  631. if _id in self.data:
  632. for i,link in self.data[_id].items():
  633. #print("dmx_by_id", i,link)
  634. return (i,link)
  635. return 0,{}
  636. def by_dmx(self,clock,dmx):
  637. #print("master of dmx:",dmx)
  638. val=0
  639. flag = 0
  640. data = self._list_by_dmx(dmx)
  641. for i,row in data.items():
  642. if "DMXCH" not in row:
  643. row["DMXCH"] = DMXCH("V{}".format(i))
  644. row["DMXCH"].fade(255,0)
  645. v = row["DMXCH"].next(clock)
  646. #row["DMXCH"].fade(200,20)
  647. if v >= val:
  648. val = v
  649. flag = 1
  650. out = 1.
  651. if val > 255:
  652. val = 255
  653. if flag:
  654. out = val/255.
  655. else:
  656. out = 1.
  657. return out
  658. vdmx = VDMX()
  659. class HTP_MASTER():
  660. """functional implementation as class for namespace encapsulation
  661. """
  662. def __init__(self):
  663. self.data = OrderedDict()
  664. #self.data[1] = {"DMX":[1,2,3],"VALUE":80, "LIMIT":255}
  665. #self.data[2] = {"DMX":[12,13,22],"VALUE":70, "LIMIT":255}
  666. #self.data[3] = {"DMX":[22,23,24],"VALUE":99, "LIMIT":255}
  667. self.data[4] = {"DMX":[22,23,24],"VALUE":99, "LIMIT":255,"DMXCH":DMXCH(4)}
  668. def _list_by_dmx(self,_dmx=0):
  669. data = OrderedDict()
  670. for i,link in self.data.items(): # enumerate(self.data):
  671. if _dmx in link["DMX"]:
  672. #print( "_list_by_dmx",i,link)
  673. data[i] = link
  674. return data
  675. def dmx_by_id(self,_id=0):
  676. #print("dmx by master-id:",_id)
  677. if _id in self.data:
  678. for i,link in self.data[_id].items():
  679. #print("dmx_by_id", i,link)
  680. return (i,link)
  681. return 0,{}
  682. def val_by_dmx(self,dmx=0):
  683. #print("master of dmx:",dmx)
  684. val=0
  685. flag = 0
  686. data = self._list_by_dmx(dmx)
  687. for i,link in data.items():
  688. #print("master_by_dmx", i,link)
  689. if link["VALUE"] > val:
  690. #print("master_by_dmx", i,link)
  691. val = link["VALUE"]
  692. flag=1
  693. out = 1.
  694. if flag:
  695. out = val/255.
  696. return out
  697. htp_master = HTP_MASTER()
  698. #htp_master.data[_id] = {"DMX":[1,2,3],"VALUE":80, "LIMIT":255,"DMXCH":DMXCH()}
  699. class Main():
  700. def __init__(self):
  701. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=12)
  702. #artnet = ANN.ArtNetNode(to="127.0.0.1",port=6555,univ=0)
  703. #artnet = ANN.ArtNetNode(to="2.0.0.255",univ=0)
  704. #artnet = ANN.ArtNetNode(to="10.10.10.255",univ=1)
  705. self.artnet = {}
  706. #self.artnet["0"] = ANN.ArtNetNode(to="10.10.10.255",univ=0)
  707. #self.artnet["0"].dmx[512-1] = 10
  708. #self.artnet["1"] = ANN.ArtNetNode(to="10.10.10.255",univ=1)
  709. #self.artnet["1"].dmx[512-1] = 11
  710. self.fx = {} # key is dmx address
  711. self.lock = thread.allocate_lock()
  712. def loop(self):
  713. #dmx[205] = 255 #205 BLUE
  714. #self.artnet.send()
  715. xx = [0]*512
  716. #artnet = self.artnet["0"]
  717. #artnet.dmx = xx# [:] #dmx #[0]*512
  718. ii = 0
  719. old_univ = -1
  720. xx = [0]*512
  721. for ii,dmxch in enumerate(Bdmx):
  722. i = ii%512
  723. univ = ii//512
  724. if str(univ) not in self.artnet:
  725. print("add uiv",univ)
  726. self.artnet[str(univ)] = ANN.ArtNetNode(to="10.10.10.255",univ=univ)
  727. #self.artnet[str(univ)].dmx[512-1] = 100+univ
  728. if univ != old_univ:
  729. old_univ = univ
  730. #print("UNIV",ii/512)
  731. try:
  732. artnet.next()
  733. except:pass
  734. artnet = self.artnet[str(univ)]
  735. artnet.dmx = [0]*512
  736. fps_start = time.time()
  737. fps = 0
  738. dbg= 0#1
  739. while 1:
  740. start = time.time()
  741. _t=0
  742. self.lock.acquire_lock()
  743. t = clock.time()
  744. ii = 0
  745. old_univ = -1
  746. xx = [0]*512
  747. for ii,dmxch in enumerate(Bdmx):
  748. i = ii%512
  749. univ = ii//512
  750. s_univ = str(univ)
  751. if s_univ not in self.artnet:
  752. print("add uiv",univ)
  753. self.artnet[s_univ] = ANN.ArtNetNode(to="10.10.10.255",univ=univ)
  754. #self.artnet[str(univ)].dmx[512-1] = 100+univ
  755. #if univ != old_univ:
  756. # old_univ = univ
  757. # #print("UNIV",ii/512)
  758. # try:
  759. # artnet.next()
  760. # except:pass
  761. # artnet = self.artnet[str(univ)]
  762. # #artnet.dmx = xx
  763. #for k,artnet in self.artnet.items():
  764. # artnet.next()
  765. if dbg:
  766. end = time.time()
  767. print(" t",_t,ii,round(end-start,4))
  768. start = time.time()
  769. _t+=1
  770. old_univ = -1
  771. xx = [0]*512
  772. for ii,dmxch in enumerate(Bdmx):
  773. i = ii%512
  774. univ = ii//512
  775. if univ != old_univ:
  776. old_univ = univ
  777. artnet = self.artnet[str(univ)]
  778. xx = artnet.dmx
  779. v = dmxch.next(t)
  780. #vv = vdmx.by_dmx(clock=i,dmx=ii+1)
  781. #try:
  782. # v = v*vv # disable v-master
  783. #except Exception as e:
  784. # cprint("Exception v*vv",[v,vv],e)
  785. # continue
  786. xx[i] = int(v)
  787. if dbg:
  788. end = time.time()
  789. print(" t",_t,ii,round(end-start,4))
  790. start = time.time()
  791. _t+=1
  792. old_univ = -1
  793. xx = [0]*512
  794. for ii,dmxch in enumerate(Bdmx): #fine loop
  795. dmx_fine = dmxch._dmx_fine
  796. if dmx_fine > 0:
  797. i = ii%512
  798. univ = ii//512
  799. if univ != old_univ:
  800. artnet = self.artnet[str(univ)]
  801. xx = artnet.dmx# = xx
  802. v = dmxch.next(t)
  803. vv = vdmx.by_dmx(clock=i,dmx=ii+1)
  804. try:
  805. v = v*vv # disable v-master
  806. except Exception as e:
  807. cprint("Exception v*vv",[v,vv],e)
  808. continue
  809. #xx[i] = int(v)
  810. vf = int(v%1*255)
  811. #print(dmx_fine,end=" ")
  812. dmx_fine = dmx_fine%512
  813. #print(dmx_fine,end=" ")
  814. #print(int(v),end=" ")
  815. #print(vf,end=" ")
  816. #print()
  817. #univ = ii//512
  818. try:
  819. #xx[dmx_fine+1] = 9# int(v%1*255)
  820. if v >= 255:
  821. xx[dmx_fine-1] = 255
  822. elif v < 0:
  823. xx[dmx_fine-1] = 0
  824. else:
  825. xx[dmx_fine-1] = int(v%1*255)
  826. except Exception as e:
  827. print("E dmx_fine",e,dmx_fine)
  828. if dbg:
  829. end = time.time()
  830. print(" t",_t,ii,round(end-start,4))
  831. print()
  832. start = time.time()
  833. _t+=1
  834. self.lock.release_lock()
  835. for k,artnet in self.artnet.items():
  836. artnet.next()
  837. #self.lock.acquire_lock()
  838. #time.sleep(1/35)
  839. fps += 1
  840. stop_fps = 50
  841. time.sleep(1/30)
  842. if fps >= stop_fps:
  843. fps_t = time.time()
  844. #print(int((fps_t-fps_start)*1000),"ms")
  845. print(round(stop_fps/(fps_t-fps_start),2),"core/fps")
  846. fps = 0
  847. fps_start = time.time()
  848. #time.sleep(1/60)
  849. main = Main()
  850. if __run_main:
  851. #thread.start_new_thread(artnet_loop,())
  852. thread.start_new_thread(main.loop,())
  853. def _init_action(row):#Bdmx,out,DMX):
  854. Admx = row["DMXCH"]
  855. if row["fx"]:
  856. x = row["fx"]
  857. Admx.fx(xtype=x["xtype"]
  858. ,size=x["size"]
  859. ,speed=x["speed"]
  860. ,invert=x["invert"]
  861. ,width=x["width"]
  862. ,start=x["start"]
  863. ,offset=x["offset"]
  864. ,base=x["base"]
  865. ,clock=x["clock"]
  866. ,master=x["master"])
  867. if row["flash_fx"]:
  868. x = row["flash_fx"]
  869. Admx.flash_fx(xtype=x["xtype"]
  870. ,size=x["size"]
  871. ,speed=x["speed"]
  872. ,invert=x["invert"]
  873. ,width=x["width"]
  874. ,start=x["start"]
  875. ,offset=x["offset"]
  876. ,base=x["base"]
  877. ,clock=x["clock"]
  878. ,master=x["master"])
  879. if row["flash"]:
  880. x = row["flash"]
  881. Admx.flash(target=x["target"]
  882. ,ftime=x["ftime"]
  883. ,clock=x["clock"]
  884. ,delay=x["delay"])
  885. if row["fade"]:
  886. x = row["fade"]
  887. Admx.fade(target=x["target"]
  888. ,ftime=x["ftime"]
  889. ,clock=x["clock"]
  890. ,delay=x["delay"])
  891. def set_dmx_fine_ch(Admx,dmx_fine_nr):
  892. try:
  893. if int(dmx_fine_nr) > 0:
  894. Admx._dmx_fine = int(dmx_fine_nr)
  895. except Exception as e:
  896. cprint(x,color="red")
  897. cprint("except 3455",e,color="red")
  898. def _parse_cmds(cmds,clock=0,master_fx=None):
  899. c=clock
  900. out = {}
  901. for x in cmds:
  902. Admx = DMXCH() #dummy
  903. _fix_id=0
  904. _attr = ""
  905. if "CMD" in x:
  906. print("CMD:",x)
  907. if "EXEC-SPEED-MASTER" == x["CMD"]:
  908. exec_speed_master.val(x["NR"],x["VALUE"])
  909. if "EXEC-SIZE-MASTER" == x["CMD"]:
  910. exec_size_master.val(x["NR"],x["VALUE"])
  911. if "EXEC-OFFSET-MASTER" == x["CMD"]:
  912. exec_offset_master.val(x["NR"],x["VALUE"])
  913. if "SPEED-MASTER" == x["CMD"]:
  914. speed_master.val(x["NR"],x["VALUE"])
  915. if "SIZE-MASTER" == x["CMD"]:
  916. size_master.val(x["NR"],x["VALUE"])
  917. else:
  918. #print("x",x)
  919. if "DMX" in x:
  920. DMX = int(x["DMX"])
  921. else:
  922. continue
  923. if "VALUE" in x:
  924. v = x["VALUE"]
  925. else:
  926. continue
  927. _inc = 0
  928. _fix_id = 0
  929. _val = -1
  930. _clock = 0
  931. exec_id = None
  932. if "VALUE" in x:
  933. _val = x["VALUE"]
  934. if "INC" in x:
  935. _inc = x["INC"]
  936. if "FIX" in x:
  937. _fix_id = x["FIX"]
  938. if "clock" in x:
  939. _clock=x["clock"]
  940. if "ATTR" in x:
  941. _attr = x["ATTR"]
  942. if DMX <= 0: # VIRTUAL
  943. DMX = "FIX"+str(_fix_id)
  944. ok = 0
  945. if "ATTR" in x:
  946. _attr = x["ATTR"]
  947. if "DIM" == x["ATTR"]:
  948. if _fix_id not in V_MASTER:
  949. V_MASTER[_fix_id] = DMXCH()
  950. #print("_val",_val)
  951. #V_MASTER[_fix_id].fade(_val,ftime=0,clock=0,delay=0)
  952. #print(" V-MASTER",_fix_id,_val,_inc)
  953. ok = 1
  954. if _fix_id in V_MASTER:
  955. Admx = V_MASTER[_fix_id]
  956. if not ok:
  957. continue
  958. else:
  959. if DMX < len(Bdmx):
  960. Admx = Bdmx[DMX-1]
  961. else:
  962. print("DMX ADDRESS too BIG",DMX)
  963. continue
  964. if "DMX-FINE" in x and DMX > 0:
  965. set_dmx_fine_ch(Admx, x["DMX-FINE"])
  966. #print("-")
  967. if "EXEC" in x:
  968. exec_id = x["EXEC"]
  969. if "ATTR" in x:
  970. _attr = x["ATTR"]
  971. if "FIX" in x:
  972. _fix_id = x["FIX"]
  973. fx=""
  974. fx2={}
  975. ftime=0
  976. delay=0
  977. if "FX" in x:
  978. fx = x["FX"]
  979. if "FX2" in x:
  980. fx2 = x["FX2"]
  981. if "FADE" in x:
  982. ftime = x["FADE"]
  983. if "DELAY" in x:
  984. delay = x["DELAY"]
  985. #print("DO",[exec_id],x)
  986. # ids = [401,402,304,103]
  987. # exec-id, exec-fx-id, flush-id, flush-fx-id
  988. if v != "off":
  989. if "FLASH" in x:
  990. ids = Admx.exec_ids()
  991. if type(v) is int:
  992. ids[2] = exec_id
  993. if fx2:
  994. ids[3] = exec_id
  995. #print(" ",[ids, exec_id],"FL")
  996. else: # GO or ON
  997. ids = Admx.exec_ids()
  998. if type(v) is int:
  999. ids[0] = exec_id
  1000. if fx2:
  1001. ids[1] = exec_id
  1002. #print(" ",[ids, exec_id],"GO")
  1003. if v == "off":
  1004. if "FLASH" in x:
  1005. ids = Admx.exec_ids()
  1006. stop = 0
  1007. #print(" ",[ids, exec_id])
  1008. if ids[2] != exec_id:
  1009. stop = 1
  1010. else:
  1011. ids[2] = None
  1012. if fx2:
  1013. if ids[3] != exec_id:
  1014. stop = 1
  1015. else:
  1016. ids[3] = None
  1017. stop = 0
  1018. if stop:
  1019. # this FLASH cmd OFF/RELEASE is not valid anymore
  1020. continue
  1021. #aprint("OK")
  1022. #ids = Admx.exec_ids()
  1023. #print("OK ",[ids, exec_id])
  1024. #Bdmx[DMX].exec_id(exec_id)
  1025. out[DMX] = {"flash":{},"fade":{},"fx":{},"flash_fx":{},"fix_id":_fix_id,"attr":_attr,"DMXCH":Admx}
  1026. if v is not None:
  1027. if "FLASH" in x:
  1028. out[DMX]["flash"] = {"target":v,"ftime":ftime, "clock":c,"delay":delay,"DMXCH":Admx}
  1029. else:
  1030. out[DMX]["fade"] = {"target":v,"ftime":ftime, "clock":c,"delay":delay,"DMXCH":Admx}
  1031. if type(fx2) is dict and fx2:
  1032. xtype="fade"
  1033. size = 10
  1034. speed = 10
  1035. start = 0
  1036. offset= 0
  1037. width=100
  1038. invert=0
  1039. base = "-"
  1040. if "TYPE" in fx2:
  1041. xtype = fx2["TYPE"]
  1042. if "SIZE" in fx2:
  1043. size = fx2["SIZE"]
  1044. if "SPEED" in fx2:
  1045. speed = fx2["SPEED"]
  1046. if "OFFSET" in fx2:
  1047. offset = fx2["OFFSET"]
  1048. if "BASE" in fx2:
  1049. base = fx2["BASE"]
  1050. if "INVERT" in fx2:
  1051. invert = fx2["INVERT"]
  1052. if "WIDTH" in fx2:
  1053. width = fx2["WIDTH"]
  1054. if "off" == x["VALUE"]: #fix fx flash off
  1055. xtype= "off"
  1056. if "alloff" == xtype.lower():
  1057. for dmxch in Bdmx:
  1058. if dmxch is not None:
  1059. dmxch.flash_fx(xtype="off",clock=c)
  1060. dmxch.fx(xtype="off",clock=c)
  1061. for j in V_MASTER:
  1062. dmxch = V_MASTER[j]
  1063. if j is not None:
  1064. dmxch.flash_fx(xtype="off",clock=c)
  1065. dmxch.fx(xtype="off",clock=c)
  1066. if "FLASH" in x:
  1067. out[DMX]["flash_fx"] = {"xtype":xtype,"size":size,"speed":speed,
  1068. "invert":invert,"width":width,"start":start
  1069. ,"offset":offset,"base":base,"clock":c,"master":master_fx}
  1070. else:
  1071. out[DMX]["fx"] = {"xtype":xtype,"size":size,"speed":speed
  1072. ,"invert":invert,"width":width,"start":start
  1073. ,"offset":offset,"base":base,"clock":c,"master":master_fx}
  1074. elif type(fx) is str and fx:
  1075. # old fx like sinus:200:12:244
  1076. ccm = str(DMX+1)+":"+fx
  1077. print("fx",ccm)
  1078. if "FLASH" in x:
  1079. CB({"cmd":"fxf"+ccm})
  1080. else:
  1081. CB({"cmd":"fx"+ccm})
  1082. return out
  1083. import hashlib
  1084. JCB_GLOB_BUF = {}
  1085. def JCB(data,sock=None): #json client input
  1086. t_start = time.time()
  1087. s = time.time()
  1088. e = time.time()
  1089. print("JCB TIME:","{:0.02f}".format(e-s),int(e*100)/100)
  1090. #print("-->-",data)
  1091. jdatas = []
  1092. l2 = 0
  1093. for line in data:
  1094. data2 = json.loads(line)
  1095. l2 += len(data2)
  1096. #print("line:",line)
  1097. jdatas.append(data2) #["CMD"])
  1098. print("INPUT JCB =>",len(data),":",l2)
  1099. c = clock.time()
  1100. c = float(c)
  1101. ftime = 0
  1102. delay = 0
  1103. out = {}
  1104. for cmds in jdatas:
  1105. line = json.dumps(cmds)
  1106. #md5 = hashlib.md5.hexdigest(line)
  1107. master_fx = MASTER_FX()
  1108. if not cmds:
  1109. continue
  1110. try:
  1111. out = _parse_cmds(cmds,clock=c,master_fx=master_fx)
  1112. #cprint("-","{:0.04} sec.".format(time.time()-t_start),color="yellow")
  1113. # ------- ----------------------------------------------------
  1114. except Exception as e:
  1115. cprint("EXCEPTION JCB",e,color="red")
  1116. cprint("----",str(cmds)[:150],"...",color="red")
  1117. cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
  1118. raise e
  1119. if out:
  1120. try:
  1121. try: # second loop to sync-start all dmxch's
  1122. main.lock.acquire_lock()
  1123. for _id in out:
  1124. row = out[_id]
  1125. #print("_id",_id)
  1126. Admx = row["DMXCH"]
  1127. #print("Admx",Admx)
  1128. if row["fix_id"]:
  1129. _fix_id = row["fix_id"]
  1130. Admx._fix_id = _fix_id
  1131. if "attr" in row:
  1132. if row["attr"] in ["RED","GREEN","BLUE","WHITE","AMBER"]: #CYAN,MAGENTA,YELLOW
  1133. Admx._v_master_id = _fix_id
  1134. #print("SET V_MASTER",row)
  1135. _init_action(row)
  1136. e = time.time()
  1137. print(" sub-JCB TIME:","{:0.02f}".format(e-s),int(e*100)/100)
  1138. finally:
  1139. main.lock.release_lock()
  1140. #time.sleep(1/30)
  1141. except Exception as e:
  1142. cprint("EXCEPTION JCB",e,color="red")
  1143. cprint("----",str(cmds)[:150],"...",color="red")
  1144. cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
  1145. raise e
  1146. #cprint(" ","{:0.04} sec.".format(time.time()-t_start),color="yellow")
  1147. e = time.time()
  1148. print("JCB TIME:","{:0.02f}".format(e-s),int(e*100)/100)
  1149. time.sleep(1/60)
  1150. def CB(data): # raw/text client input
  1151. #print("CB",data)
  1152. cmds = split_cmd(data)
  1153. c = clock.time()
  1154. c = float(c)
  1155. ftime = 0
  1156. delay = 0
  1157. for xcmd in cmds:
  1158. if xcmd:
  1159. cprint("CB",xcmd,end=" ")
  1160. pass
  1161. else:
  1162. continue
  1163. if xcmd.startswith("fxf"):
  1164. xxcmd=xcmd[3:].split(":")
  1165. #print("fxf:",xxcmd)
  1166. if "alloff" == xxcmd[1].lower():
  1167. for i in Bdmx:
  1168. if i is not None:
  1169. i.flash_fx(xtype="off",clock=c)
  1170. for i in V_MASTER:
  1171. if i is not None:
  1172. i.flash_fx(xtype="off",clock=c)
  1173. l = xxcmd
  1174. try:
  1175. xtype=""
  1176. size=40
  1177. speed=100
  1178. start=0
  1179. offset=0
  1180. base=""
  1181. k=int(l[0])-1
  1182. xtype=l[1]
  1183. if len(l) >= 3:
  1184. try:size=int(l[2])
  1185. except:pass
  1186. if len(l) >= 4:
  1187. try:speed=int(l[3])
  1188. except:pass
  1189. if len(l) >= 5:
  1190. try:start=int(l[4])
  1191. except:pass
  1192. if len(l) >= 6:
  1193. try:offset=int(l[5])
  1194. except:pass
  1195. if len(l) >= 7:
  1196. try:base=l[6]
  1197. except:pass
  1198. if len(Bdmx) > k:
  1199. #Bdmx[k].fade(target=v,ftime=t, clock=c)
  1200. Bdmx[k].flash_fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
  1201. except Exception as e:
  1202. print("EXCEPTION IN FX",e)
  1203. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  1204. elif xcmd.startswith("fx"):
  1205. xxcmd=xcmd[2:].split(":")
  1206. print("DMX:",xxcmd)
  1207. if len(xxcmd) < 2:
  1208. print("xxcmd err",xxcmd,xcmd)
  1209. continue
  1210. if "alloff" == xxcmd[1].lower():
  1211. for i in Bdmx:
  1212. i.fx(xtype="off",clock=c)
  1213. l = xxcmd
  1214. try:
  1215. xtype=""
  1216. size=40
  1217. speed=100
  1218. start=0
  1219. offset=0
  1220. base=""
  1221. k=int(l[0])-1
  1222. xtype=l[1]
  1223. if len(l) >= 3:
  1224. try:size=int(l[2])
  1225. except:pass
  1226. if len(l) >= 4:
  1227. try:speed=int(l[3])
  1228. except:pass
  1229. if len(l) >= 5:
  1230. try:start=int(l[4])
  1231. except:pass
  1232. if len(l) >= 6:
  1233. try:offset=int(l[5])
  1234. except:pass
  1235. if len(l) >= 7:
  1236. try:base=l[6]
  1237. except:pass
  1238. if len(Bdmx) > k:
  1239. #Bdmx[k].fade(target=v,ftime=t, clock=c)
  1240. Bdmx[k].fx(xtype=xtype,size=size,speed=speed,start=start,offset=offset,base=base,clock=c)
  1241. except Exception as e:
  1242. print("EXCEPTION IN FX",xcmd,e)
  1243. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  1244. if __run_main:
  1245. s = chat.Server(cb=JCB)
  1246. while 1:
  1247. s.poll()
  1248. time.sleep(0.001)