_console.py 31 KB

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