_console.py 31 KB

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