execlib.py 13 KB

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