execlib.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. #/usr/bin/python3
  2. import copy
  3. import __main__ as MAIN
  4. from lib.cprint import cprint
  5. from collections import OrderedDict
  6. import json
  7. try:
  8. import memcache
  9. mc = memcache.Client(['127.0.0.1:11211'], debug=0)
  10. except:
  11. mc = None
  12. def reshape_exec(data ,value=None,xfade=0,flash=0,ptfade=0,DELAY=None):
  13. f=0 #fade
  14. out = []
  15. delay=0
  16. if DELAY is not None:
  17. if DELAY < 0:
  18. delay = (DELAY*-1)*len(data)
  19. delay += DELAY
  20. print("-"*20+" DELAY is MINUS !!!",DELAY,delay)
  21. for row in data:
  22. #cprint("reshape_exec in:",row)
  23. line = {}
  24. line["DELAY"]=round(delay,3)
  25. if type(value) is float:
  26. line["VALUE"] = value #round(value,3)
  27. else:
  28. line["VALUE"] = value
  29. if "FX" not in row:
  30. cprint("698 FX not in row...",row,color="red")
  31. row["FX"] = ""
  32. else:
  33. if type(row["FX"]) is not str:
  34. cprint("702 FX is not str...",row,color="red")
  35. row["FX"] = ""
  36. if value is not None:
  37. line["FX"] = row["FX"].split(":",1)[-1]
  38. else:
  39. line["FX"] = row["FX"]
  40. if row["FX2"]:
  41. line["FX2"] = row["FX2"]
  42. if row["FIX"]:
  43. line["FIX"] = row["FIX"]
  44. if row["ATTR"]:
  45. line["ATTR"] = row["ATTR"]
  46. if row["VALUE"] is not None:
  47. if value is None:
  48. v=row["VALUE"]
  49. if type(v) is float:
  50. line["VALUE"] = v #round(v,3)
  51. else:
  52. line["VALUE"] = v
  53. if row["ATTR"] in ["PAN","TILT"]:
  54. f = ptfade
  55. for a in ["DIM","ZOOM","FOCUS","RED","GREEN","BLUE","WHITE","AMBER","IRIS","BLADE"]:
  56. #FADE ATTRIBUTES
  57. if a in row["ATTR"]:
  58. f = xfade
  59. break
  60. if flash:
  61. xfade = 0
  62. if type( f ) is float:
  63. line["FADE"] = round(f,4)
  64. else:
  65. line["FADE"] = f
  66. if 0:
  67. cprint("reshape_exec j",line,color="red")
  68. #cprint("reshape_exec out:",line)
  69. out.append(line)
  70. if DELAY is not None:
  71. delay+=DELAY #0.02
  72. #for j in out: # info
  73. # print("reshape_exec",j)
  74. return out
  75. def calc_align_delay(meta,xdelay,vcmd):
  76. for i in vcmd:
  77. i["DELAY"] = round(0,3)
  78. # ALIGN-DELAY
  79. _xd = 0
  80. if type(xdelay) in [int,float]:
  81. _align = meta.ALIGN.val()
  82. _len = len(vcmd)
  83. _len_h = int(len(vcmd)/2)
  84. if _align == ">":
  85. for i in vcmd:
  86. i["DELAY"] = round(_xd,3)
  87. _xd += xdelay
  88. elif _align == "<":
  89. for i in vcmd[::-1]:
  90. i["DELAY"] = round(_xd,3)
  91. _xd += xdelay
  92. elif _align == "><":
  93. xdelay *= 2
  94. for i in vcmd[:_len_h]:
  95. i["DELAY"] = round(_xd,3)
  96. _xd += xdelay
  97. _xd = 0
  98. for i in vcmd[:_len_h-1:-1]:
  99. i["DELAY"] = round(_xd,3)
  100. _xd += xdelay
  101. elif _align == "<>":
  102. xdelay *= 2
  103. for i in vcmd[:_len_h-1][::-1]:
  104. i["DELAY"] = round(_xd,3)
  105. _xd += xdelay
  106. _xd = 0
  107. for i in vcmd[:_len_h:-1][::-1]:
  108. i["DELAY"] = round(_xd,3)
  109. _xd += xdelay
  110. elif _align == "rnd":
  111. _rnd = list(range(len(vcmd)))
  112. import random
  113. random.shuffle(_rnd)
  114. for j in _rnd:
  115. i = vcmd[j]
  116. i["DELAY"] = round(_xd,3)
  117. _xd += xdelay
  118. for i in vcmd:
  119. print("1-->",i)
  120. import lib.showlib as showlib
  121. def EXEC_CFG_CHECKER(sdata):
  122. "repair CFG "
  123. ok = 0
  124. if "CFG" not in sdata:
  125. sdata["CFG"] = OrderedDict()
  126. ok += 1
  127. if "FADE" not in sdata["CFG"]:
  128. sdata["CFG"]["FADE"] = 4
  129. ok += 1
  130. if "HAVE-FX" not in sdata["CFG"]:
  131. sdata["CFG"]["HAVE-FX"] = 0
  132. if "HAVE-VAL" not in sdata["CFG"]:
  133. sdata["CFG"]["HAVE-VAL"] = 0
  134. if "FIX-COUNT" not in sdata["CFG"]:
  135. sdata["CFG"]["FIX-COUNT"] = 0
  136. if "DEALY" in sdata["CFG"]: # REMOVE TYPO !
  137. del sdata["CFG"]["DEALY"]
  138. if "DELAY" not in sdata["CFG"]:
  139. sdata["CFG"]["DELAY"] = 0
  140. ok += 1
  141. if "BUTTON" not in sdata["CFG"]:
  142. sdata["CFG"]["BUTTON"] = "GO"
  143. ok += 1
  144. if "HTP-MASTER" not in sdata["CFG"]:
  145. sdata["CFG"]["HTP-MASTER"] = 100 #%
  146. ok += 1
  147. if "SIZE-MASTER" not in sdata["CFG"]:
  148. sdata["CFG"]["SIZE-MASTER"] = 100 #%
  149. ok += 1
  150. if "SPEED-MASTER" not in sdata["CFG"]:
  151. sdata["CFG"]["SPEED-MASTER"] = 100 #%
  152. ok += 1
  153. if "OFFSET-MASTER" not in sdata["CFG"]:
  154. sdata["CFG"]["OFFSET-MASTER"] = 100 #%
  155. ok += 1
  156. if "HAVE-FX" not in sdata["CFG"]:
  157. sdata["CFG"]["HAVE-FX"] = 0 # yes/no
  158. ok += 1
  159. if "HAVE-VAL" not in sdata["CFG"]:
  160. sdata["CFG"]["HAVE-VAL"] = 0 # yes/no
  161. ok += 1
  162. if "FIX-COUNT" not in sdata["CFG"]:
  163. sdata["CFG"]["FIX-COUNT"] = 0 # yes/no
  164. ok += 1
  165. #try:del sdata["CFG"]["SPEED-MASTER"] #= 100 #%
  166. #except:pass
  167. return ok
  168. import time
  169. def exec_set_mc(excec_labels,exec_data):
  170. l = excec_labels
  171. d = exec_data
  172. if not mc:
  173. #cprint("MC not connected !")
  174. return
  175. index=[]
  176. for i,k in enumerate(l):
  177. nr = i
  178. data = d[k]
  179. label=l[nr]
  180. exec_set_mc_single(nr,label,data)
  181. #print("--------------exec_set_mc-------EXEC-META---------------------")
  182. def exec_set_mc_single(nr,label,data):
  183. #data = d[v]
  184. key="EXEC-"+str(nr)
  185. mc.set(key,json.dumps(data))
  186. key2="EXEC-META-"+str(nr)
  187. cfg = {'FADE': 2.0, 'DELAY': 0, 'BUTTON': 'GO', 'HTP-MASTER': 100
  188. ,'SIZE-MASTER': 100, 'SPEED-MASTER': 100, 'OFFSET-MASTER': 100, 'OUT-FADE': 10.0
  189. ,'HAVE-FX': 0, 'HAVE-VAL': 0, 'FIX-COUNT': 11
  190. }
  191. if "CFG" in data:
  192. cfg.update(data["CFG"])
  193. mc.set(key2,json.dumps({"LABEL":label,"CFG":cfg}) )
  194. class EXEC(): #Presets():
  195. def __init__(self):
  196. self.base = showlib.Base()
  197. self._last_copy = None
  198. self._last_move = None
  199. self.fx_buffer = {}
  200. def load_exec(self):
  201. filename="exec"
  202. filename="presets" # preset.sav
  203. d,l = self.base._load(filename)
  204. for i in d:
  205. sdata = d[i]
  206. ok = EXEC_CFG_CHECKER(sdata)
  207. start = time.time()
  208. self.val_exec = d
  209. self.label_exec = l
  210. exec_set_mc(self.label_exec,self.val_exec)
  211. def check_cfg(self,nr=None):
  212. #cprint("EXEC.check_cfg()",nr)#,color="red")
  213. ok = 0
  214. if nr is not None:
  215. if nr in self.val_exec:
  216. sdata = self.val_exec[nr]
  217. ok += self._check_cfg(sdata)
  218. else:
  219. cprint("nr not in data ",nr,color="red")
  220. else:
  221. for nr in self.val_exec:
  222. sdata = self.val_exec[nr]
  223. ok += self._check_cfg(sdata)
  224. return ok
  225. def _check_cfg(self,sdata):
  226. #cprint("EXEC._check_cfg()")#,color="red")
  227. ok = EXEC_CFG_CHECKER(sdata)
  228. if ok:
  229. pass#cprint("REPAIR CFG's",ok,"count:",sdata["CFG"],color="red")
  230. return ok
  231. def backup_exec(self,save_as="",new=0):
  232. filename = "exec" # new
  233. filename = "presets" # preset.sav
  234. data = self.val_exec
  235. labels = self.label_exec
  236. if new:
  237. data = [] #*512
  238. labls = [""]*512
  239. r=self.base._backup(filename,data,labels,save_as)
  240. return r
  241. def get_cfg(self,nr):
  242. #cprint("EXEC.get_cfg()",nr)
  243. self.check_cfg(nr)
  244. if nr not in self.val_exec:
  245. cprint("get_cfg",self,"error get_cfg no nr:",nr,color="red")
  246. return {}
  247. if "CFG" in self.val_exec[nr]:
  248. return self.val_exec[nr]["CFG"]
  249. def set_cfg(self,nr,sdata):
  250. cprint("EXEC.set_cfg()",nr,color="yellow")
  251. cprint(" ",sdata,color="yellow")
  252. #self.check_cfg(nr)
  253. if nr < 0:
  254. return {}
  255. if nr not in self.val_exec:
  256. cprint(" get_cfg",self,"error get_cfg no nr:",nr,color="red")
  257. return {}
  258. if "CFG" in self.val_exec[nr]:
  259. print(" ",self.val_exec[nr]["CFG"] )
  260. print(" ",sdata)
  261. # OrderedDict([('FADE', 4), ('HAVE-FX', 0), ('HAVE-VAL', 0), ('FIX-COUNT', 0), ('DELAY', 0),
  262. #('BUTTON', 'GO'), ('HTP-MASTER', 100), ('SIZE-MASTER', 100), ('SPEED-MASTER', 100), ('OFFSET-MASTER', 100)])
  263. r=EXEC_CFG_CHECKER(sdata)
  264. print(" ",sdata)
  265. self.val_exec[nr]["CFG"] = sdata
  266. if "Label" in sdata:
  267. self.label_exec[nr] = sdata["Label"]
  268. def clean(self,nr):
  269. if nr not in self.val_exec:
  270. self.val_exec[nr] = OrderedDict()
  271. #self.val_exec[nr]["VALUE"] = 0
  272. #self.val_exec[nr]["FX"] = ""
  273. sdata = self.val_exec[nr]
  274. for fix in sdata:
  275. #print("exec.clear()",nr,fix,sdata[fix])
  276. for attr in sdata[fix]:
  277. row = sdata[fix][attr]
  278. if fix == "CFG":
  279. continue
  280. if "VALUE" not in row:
  281. row["VALUE"] = None
  282. if "FX" not in row:
  283. row["FX"] = ""
  284. if "FX2" not in row:
  285. row["FX2"] = OrderedDict()
  286. elif row["FX2"]:
  287. for k in ["SIZE","SPEED","START","OFFSET"]:
  288. row["FX2"][k] = int( row["FX2"][k] )
  289. row["FX"] = ""
  290. if "FX" in row and row["FX"] and not row["FX2"]: # rebuild old FX to Dict-FX2
  291. #"off:0:0:0:16909:-:"
  292. x = row["FX"].split(":")
  293. cprint("-fx",x,len(x))
  294. #'FX2': {'TYPE': 'sinus', 'SIZE': 200, 'SPEED': 30, 'START': 0, 'OFFSET': 2805, 'BASE': '-'}}
  295. if len(x) >= 6:
  296. row["FX2"]["TYPE"] = x[0]
  297. row["FX2"]["SIZE"] = int(x[1])
  298. row["FX2"]["SPEED"] = int(x[2])
  299. row["FX2"]["START"] = int(x[3])
  300. row["FX2"]["OFFSET"] = int(x[4])
  301. row["FX2"]["BASE"] = x[5]
  302. row["FXOLD"] = row["FX"]
  303. row["FX"] = ""
  304. #cprint("exec.clear()",nr,fix,row)
  305. def get_raw_map(self,nr):
  306. self.clean(nr)
  307. #cprint("EXEC.get_raw_map",nr)
  308. sdata = self.val_exec[nr]
  309. cmd = ""
  310. out = []
  311. dmx=-1
  312. for fix in sdata:
  313. if fix == "CFG":
  314. #print("CFG",nr,sdata[fix])
  315. continue
  316. for attr in sdata[fix]:
  317. x = {}
  318. #print("RAW",attr)
  319. x["FIX"] = fix
  320. x["ATTR"] = attr
  321. x["VALUE"] = sdata[fix][attr]["VALUE"]
  322. x["FX"] = sdata[fix][attr]["FX"]
  323. x["FX2"] = sdata[fix][attr]["FX2"]
  324. #x["DMX"] = sdata[fix][attr]["NR"]
  325. out.append(x)
  326. return out
  327. def get_btn_txt(self,nr):
  328. sdata=self.val_exec[nr]
  329. BTN="go"
  330. if "CFG" in sdata:
  331. if "BUTTON" in sdata["CFG"]:
  332. BTN = sdata["CFG"]["BUTTON"]
  333. _label = self.label_exec[nr] # = label
  334. #txt=str(nr+1)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+_label
  335. #txt=str(nr+1)+" "+str(BTN)+" "+str(len(sdata)-1)+"\n"+_label
  336. txt="{} {} {}\n{}".format(nr+1,BTN,len(sdata)-1,_label)
  337. cprint("get_btn_txt",nr,[txt])
  338. return txt
  339. def _btn_cfg(self,nr,txt=None):
  340. if nr not in self.val_exec:
  341. return ""
  342. if "CFG" not in self.val_exec[nr]:
  343. self.val_exec[nr]["CFG"] = OrderedDict()
  344. return self.val_exec[nr]["CFG"]
  345. def btn_cfg(self,nr,txt=None):
  346. if nr not in self.val_exec:
  347. return ""
  348. if "CFG" not in self.val_exec[nr]:
  349. self.val_exec[nr]["CFG"] = OrderedDict()
  350. if "BUTTON" not in self.val_exec[nr]["CFG"]:
  351. self.val_exec[nr]["CFG"]["BUTTON"] = ""
  352. if type(txt) is str:
  353. self.val_exec[nr]["CFG"]["BUTTON"] = txt
  354. if self.val_exec[nr]["CFG"]["BUTTON"] is None:
  355. self.val_exec[nr]["CFG"]["BUTTON"] = ""
  356. MAIN.master._refresh_exec(nr=nr)
  357. cprint("EEE", self.val_exec[nr]["CFG"]["BUTTON"] )
  358. return self.val_exec[nr]["CFG"]["BUTTON"]
  359. def label(self,nr,txt=None):
  360. if nr not in self.label_exec:
  361. return ""
  362. if type(txt) is str:
  363. self.label_exec[nr] = txt
  364. cprint("set label",nr,[txt])
  365. cprint("??? ?? set label",nr,[txt])
  366. return self.label_exec[nr]
  367. def clear_move(self):
  368. cprint("EXEC.clear_move()",end=" ")
  369. self.clear_copy()
  370. def clear_copy(self):
  371. cprint("EXEC.clear_copy()",end=" ")
  372. if self._last_copy is not None:
  373. cprint("=OK=",color="red")
  374. self._last_copy = None
  375. else:
  376. cprint("=NONE=",color="green")
  377. def copy(self,nr,overwrite=1):
  378. cprint("EXEC._copy",nr,"last",self._last_copy)
  379. if nr >= 0:
  380. if self._last_copy is not None:
  381. if MAIN.modes.val("COPY"):
  382. MAIN.modes.val("COPY",3)
  383. ok = self._copy(self._last_copy,nr,overwrite=overwrite)
  384. return ok #ok
  385. else:
  386. if MAIN.modes.val("COPY"):
  387. MAIN.modes.val("COPY",2)
  388. self._last_copy = nr
  389. cprint("EXEC.copy START ",color="red")
  390. return 0
  391. return 1 # on error reset move
  392. def _copy(self,nr_from,nr_to,overwrite=1):
  393. cprint("EXEC._copy",nr_from,"to",nr_to)
  394. self.check_cfg(nr_from)
  395. if type(self._last_copy) is None:
  396. cprint("EXEC._copy last nr is None",color="red")
  397. return 0
  398. cprint("------ EXEC._copy", nr_from in self.val_exec , nr_to in self.val_exec)
  399. if nr_from in self.val_exec and nr_to in self.val_exec:
  400. fdata = self.val_exec[nr_from]
  401. tdata = self.val_exec[nr_to]
  402. #cprint(fdata)
  403. flabel = self.label_exec[nr_from]
  404. tlabel = self.label_exec[nr_to]
  405. self.val_exec[nr_to] = copy.deepcopy(fdata)
  406. self.label_exec[nr_to] = flabel
  407. if not overwrite: #default
  408. cprint("overwrite",overwrite)
  409. self.val_exec[nr_from] = copy.deepcopy(tdata)
  410. self.label_exec[nr_from] = tlabel
  411. #self.label_exec[nr_from] = "MOVE"
  412. self.clear_copy()
  413. cprint("EXEC.copy OK",color="green")
  414. return 1
  415. def move(self,nr):
  416. cprint("EXEC.move",self._last_copy,"to",nr)
  417. if nr >= 0:
  418. last = self._last_copy
  419. if MAIN.modes.val("MOVE"):
  420. MAIN.modes.val("MOVE",2)
  421. ok= self.copy(nr,overwrite=0)
  422. if ok and last >= 0:
  423. if MAIN.modes.val("MOVE"):
  424. MAIN.modes.val("MOVE",3)
  425. cprint("EXEC.move OK",color="red")
  426. #self.delete(last)
  427. return ok,nr,last #ok
  428. return 0,nr,last # on error reset move
  429. def delete(self,nr):
  430. cprint("EXEC.delete",nr)
  431. ok=0
  432. if nr in self.val_exec:
  433. self.val_exec[nr] = OrderedDict()
  434. self.label_exec[nr] = "-"
  435. ok = 1
  436. self.check_cfg(nr)
  437. return ok
  438. def rec(self,nr,data,arg=""):
  439. cprint("rec",self,"rec()",len(data),arg,color="red")
  440. self.check_cfg(nr)
  441. self._check_cfg(data) #by ref
  442. odata=self.val_exec[nr]
  443. #print("odata",odata)
  444. if "CFG" in odata:
  445. if "BUTTON" in odata["CFG"]:
  446. data["CFG"]["BUTTON"] = odata["CFG"]["BUTTON"]
  447. self.val_exec[nr] = data
  448. return 1