Editor3.py 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. #! /usr/bin/python
  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, either version 2 of the License, or
  8. (at your option) any later version.
  9. librelight is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with librelight. If not, see <http://www.gnu.org/licenses/>.
  15. (c) 2012 micha.rathfelder@gmail.com
  16. """
  17. import json
  18. import time
  19. import sys
  20. import _thread as thread
  21. import tkinter
  22. import tkinter as tk
  23. from tkinter import font
  24. import lib.chat as chat
  25. import lib.motion as motion
  26. Xroot = tk.Tk()
  27. Xroot["bg"] = "black" #white
  28. Xroot.title( __file__)
  29. root = tk.Frame(Xroot,bg="black",width="100px")
  30. root.pack(fill=tk.BOTH, side=tk.LEFT)
  31. root3 = tk.Frame(Xroot,bg="black",width="20px")
  32. root3.pack(fill=tk.BOTH, side=tk.LEFT)
  33. root2 = tk.Frame(Xroot,bg="black",width="1px")
  34. root2.pack(fill=tk.BOTH, side=tk.LEFT)
  35. #default_font = font.Font(family='Helvetica', size=12, weight='bold')
  36. Font = font.Font(family='Helvetica', size=9, weight='normal')
  37. FontBold = font.Font(family='Helvetica', size=10, weight='bold')
  38. #default_font.configure(size=9)
  39. Xroot.option_add("*Font", FontBold)
  40. from collections import OrderedDict
  41. show_name = "GloryCamp2021"
  42. show_name = "GloryCamp2021"
  43. CUES = OrderedDict()
  44. groups = OrderedDict()
  45. BLIND = 0
  46. STORE = 0
  47. FLASH = 0
  48. STONY_FX = 0
  49. LABEL = 0
  50. POS = ["PAN","TILT","MOTION"]
  51. COLOR = ["RED","GREEN","BLUE","COLOR"]
  52. BEAM = ["GOBO","G-ROT","PRISMA","P-ROT","FOCUS","SPEED"]
  53. INT = ["DIM","SHUTTER","STROBE","FUNC"]
  54. client = chat.tcp_sender()
  55. fade = 5 #2 #0.1 #1.13
  56. def build_cmd(dmx,val,args=[fade],flash=0,xpfx="",attr=""):
  57. cmd=""
  58. if xpfx:
  59. pfx=xpfx
  60. elif flash:
  61. pfx ="df"
  62. else:
  63. pfx ="d"
  64. if type(val) is float or type(val) is int:
  65. cmd += ",{}{}:{:0.4f}".format(pfx,dmx,val)
  66. else:
  67. cmd += ",{}{}:{}".format(pfx,dmx,val)
  68. if flash:
  69. cmd += ":0:0"#.format(val)
  70. else:
  71. for val in args:
  72. if type(val) is float or type(val) is int:
  73. cmd += ":{:0.4f}".format(val)
  74. else:
  75. cmd += ":{}".format(val)
  76. if attr:
  77. cmd += ":"+str(attr)
  78. return cmd
  79. def update_dmx(attr,data,value=None,args=[fade],flash=0,pfx=""):
  80. global BLIND
  81. dmx = data["DMX"]
  82. val = None
  83. cmd=""
  84. if attr == "VDIM":
  85. for attr in data["ATTRIBUT"]:
  86. dmx = data["DMX"]
  87. if data["ATTRIBUT"][attr]["NR"] < 0:
  88. continue
  89. dmx += data["ATTRIBUT"][attr]["NR"]
  90. #print(attr)
  91. val = data["ATTRIBUT"][attr]["VALUE"]
  92. if data["ATTRIBUT"][attr]["MASTER"]:
  93. val = val * (data["ATTRIBUT"]["VDIM"]["VALUE"] / 255.)
  94. if val is not None:
  95. #cmd += ",d{}:{:0.4f}".format(dmx,int(val))
  96. if value is not None:
  97. val = value
  98. cmd += build_cmd(dmx,val,args=args,flash=flash,xpfx=pfx,attr=attr)
  99. #print("cmd",cmd)
  100. elif data["ATTRIBUT"][attr]["NR"] >= 0:
  101. dmx += data["ATTRIBUT"][attr]["NR"]
  102. val = data["ATTRIBUT"][attr]["VALUE"]
  103. if data["ATTRIBUT"][attr]["MASTER"]:
  104. if "VDIM" in data["ATTRIBUT"]:
  105. val = val * (data["ATTRIBUT"]["VDIM"]["VALUE"] / 255.)
  106. if val is not None:
  107. #cmd += ",d{}:{}".format(dmx,int(val))
  108. if value is not None:
  109. val = value
  110. cmd += build_cmd(dmx,val,args=args,flash=flash,xpfx=pfx,attr=attr)
  111. #print("cmd",cmd)
  112. if not BLIND:
  113. #client.send(cmd )
  114. pass
  115. else:
  116. cmd=""
  117. return cmd
  118. class Xevent():
  119. def __init__(self,fix,elem,attr=None,data=None,mode=None):
  120. self.data=data
  121. self.attr = attr
  122. self.elem = elem
  123. self.mode = mode
  124. def encoder(self,fix,attr,data,elem,action=""):
  125. if action == "click":
  126. if self.data["ATTRIBUT"][attr]["ACTIVE"]:
  127. self.data["ATTRIBUT"][attr]["ACTIVE"] = 0
  128. self.elem["bg"] = "grey"
  129. else:
  130. self.data["ATTRIBUT"][attr]["ACTIVE"] = 1
  131. self.elem["bg"] = "yellow"
  132. return 1
  133. v2=data["ATTRIBUT"][attr]["VALUE"]
  134. change=0
  135. increment = 4.11
  136. if action == "+":
  137. v2+= increment
  138. v = "+{:0.4f}".format( increment ) #) #4.11"
  139. change=1
  140. elif action == "-":
  141. v2-= 4.11
  142. v = "-{:0.4f}".format( increment ) #) #4.11"
  143. change=1
  144. if v2 < 0:
  145. v2=0
  146. elif v2 > 256:
  147. v2=256
  148. if change:
  149. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  150. elem["bg"] = "yellow"
  151. #v2 = v
  152. #v = data["ATTRIBUT"][attr]["VALUE"]
  153. data["ATTRIBUT"][attr]["VALUE"] = v2
  154. elem["text"] = "{} {:0.2f}".format(attr,v2)
  155. #worker.fade_dmx(fix,attr,data,v,v2,ft=0)
  156. cmd=update_dmx(attr=attr,data=data,args=[0])
  157. #data["ATTRIBUT"][attr]["VALUE"] = v2
  158. client.send(cmd)
  159. def cb(self,event):
  160. #print("cb",self,event,data)
  161. print("cb",self.attr,self.mode,event)
  162. #print(dir(event),[str(event.type)])#.keys())
  163. try:
  164. #v = self.data["ATTRIBUT"][self.attr]
  165. global STORE
  166. global BLIND
  167. global FLASH
  168. global STONY_FX
  169. global LABEL
  170. change = 0
  171. if self.mode == "COMMAND":
  172. if self.attr == "CLEAR":
  173. if event.num == 1:
  174. if STORE:
  175. self.data.val_commands["STORE"] = 0
  176. STORE = 0
  177. self.data.elem_commands["STORE"]["bg"] = "lightgrey"
  178. else:
  179. for fix in self.data.fixtures:
  180. print( "clr",fix)
  181. data = self.data.fixtures[fix]
  182. #print("elm",self.data.elem_attr[fix])
  183. for attr in data["ATTRIBUT"]:
  184. if attr.endswith("-FINE"):
  185. continue
  186. self.data.elem_attr[fix][attr]["bg"] = "grey"
  187. data["ATTRIBUT"][attr]["ACTIVE"] = 0
  188. #print(data["ATTRIBUT"])
  189. if self.attr.startswith("FX:"):#SIN":
  190. if event.num == 1:
  191. cmd = ""
  192. for fix in self.data.fixtures:
  193. data = self.data.fixtures[fix]
  194. #print( "ADD FX",fix)
  195. for attr in data["ATTRIBUT"]:
  196. if attr.endswith("-FINE"):
  197. continue
  198. fx=""
  199. if "SIN" in self.attr:
  200. fx = "sinus:40:100:10"
  201. elif "COS" in self.attr:
  202. fx = "cosinus:40:100:10"
  203. if "FX" not in data["ATTRIBUT"][attr]:
  204. data["ATTRIBUT"][attr]["FX"] =""
  205. print("ADD FX",fix,attr,fx,data["ATTRIBUT"][attr]["ACTIVE"])
  206. if data["ATTRIBUT"][attr]["ACTIVE"]:
  207. print("++ADD FX",fix,attr,fx)
  208. data["ATTRIBUT"][attr]["FX"] = fx #"sinus:40:100:10"
  209. cmd+=update_dmx(attr,data,pfx="fx",value=fx)#,flash=FLASH)
  210. if cmd and not BLIND:
  211. client.send(cmd)
  212. elif self.attr == "FX OFF":
  213. if event.num == 1:
  214. client.send("fx0:alloff:,fxf:alloff:")
  215. self.data.elem_commands[self.attr]["bg"] = "magenta"
  216. elif self.attr == "FLASH":
  217. if event.num == 1:
  218. if FLASH:
  219. FLASH = 0
  220. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  221. else:
  222. FLASH = 1
  223. self.data.elem_commands[self.attr]["bg"] = "green"
  224. elif self.attr == "BLIND":
  225. if event.num == 1:
  226. if self.data.val_commands[self.attr]:
  227. self.data.val_commands[self.attr] = 0
  228. BLIND = 0
  229. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  230. else:
  231. self.data.val_commands[self.attr] = 1
  232. BLIND = 1
  233. self.data.elem_commands[self.attr]["bg"] = "red"
  234. print("BLIND",self.data.val_commands)
  235. elif self.attr == "LABEL":
  236. global LABEL
  237. if event.num == 1:
  238. if LABEL:
  239. LABEL = 0
  240. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  241. else:
  242. LABEL = 1
  243. self.data.elem_commands[self.attr]["bg"] = "red"
  244. elif self.attr == "STONY_FX":
  245. if event.num == 1:
  246. if STONY_FX:
  247. STONY_FX = 0
  248. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  249. else:
  250. STONY_FX = 1
  251. self.data.elem_commands[self.attr]["bg"] = "red"
  252. elif self.attr == "STORE":
  253. if event.num == 1:
  254. if self.data.val_commands[self.attr]:
  255. self.data.val_commands[self.attr] = 0
  256. STORE = 0
  257. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  258. else:
  259. self.data.val_commands[self.attr] = 1
  260. STORE = 1
  261. self.data.elem_commands[self.attr]["bg"] = "red"
  262. print("BLIND",self.data.val_commands)
  263. elif self.attr == "BACKUP":
  264. self.data.backup_presets()
  265. return 0
  266. elif self.mode == "INPUT":
  267. print(self.data.entry.get())
  268. if event.keycode == 36:
  269. x=self.data.entry.get()
  270. client.send(x)
  271. #self.data.entry.clean()
  272. #self.data
  273. #chat.send("")
  274. elif self.mode == "INPUT2":
  275. print(self.data.entry2.get())
  276. if event.keycode == 36:
  277. x=self.data.entry2.get()
  278. client.send(x)
  279. #self.data.entry.clean()
  280. elif self.mode == "INPUT3":
  281. print(self.data.entry3.get())
  282. if event.keycode == 36:
  283. x=self.data.entry3.get()
  284. client.send(x)
  285. #self.data.entry.clean()
  286. #self.data
  287. #chat.send("")
  288. elif self.mode == "PRESET":
  289. nr = self.attr #int(self.attr.split(":")[1])-1
  290. if event.num == 1:
  291. if STORE:
  292. print("STORE PRESET")
  293. sdata = {}
  294. for fix in self.data.fixtures:
  295. data = self.data.fixtures[fix]
  296. for attr in data["ATTRIBUT"]:
  297. if data["ATTRIBUT"][attr]["ACTIVE"]:
  298. if fix not in sdata:
  299. sdata[fix] = {}
  300. if attr not in sdata[fix]:
  301. sdata[fix][attr] = OrderedDict()
  302. if not STONY_FX:
  303. sdata[fix][attr]["VALUE"] = data["ATTRIBUT"][attr]["VALUE"]
  304. sdata[fix][attr]["FADE"] = fade
  305. else:
  306. sdata[fix][attr]["VALUE"] = None #data["ATTRIBUT"][attr]["VALUE"]
  307. if "FX" not in data["ATTRIBUT"][attr]:
  308. data["ATTRIBUT"][attr]["FX"] =""
  309. sdata[fix][attr]["FX"] = data["ATTRIBUT"][attr]["FX"]
  310. print(sdata)
  311. self.data.val_presets[nr] = sdata
  312. if len(sdata):
  313. fx_color = 0
  314. val_color = 0
  315. for fix in sdata:
  316. print( "$$$$",fix,sdata[fix])
  317. for attr in sdata[fix]:
  318. if "FX" in sdata[fix][attr]:
  319. if sdata[fix][attr]["FX"]:
  320. fx_color = 1
  321. if "VALUE" in sdata[fix][attr]:
  322. if sdata[fix][attr]["VALUE"] is not None:
  323. val_color = 1
  324. if val_color:
  325. self.data.elem_presets[nr]["bg"] = "yellow"
  326. if fx_color:
  327. self.data.elem_presets[nr]["fg"] = "blue"
  328. else:
  329. if fx_color:
  330. self.data.elem_presets[nr]["bg"] = "cyan"
  331. else:
  332. self.data.elem_presets[nr]["bg"] = "grey"
  333. #self.data.elem_presets[nr].option_add("*Font", FontBold)
  334. label = ""
  335. if nr in self.data.label_presets:
  336. #print(dir(self.data))
  337. label = self.data.label_presets[nr]
  338. txt = str(nr)+":EXEC:"+str(len(sdata))+"\n"+label
  339. self.data.elem_presets[nr]["text"] = txt
  340. print(self.data.val_presets)
  341. self.data.val_commands["STORE"] = 0
  342. STORE = 0
  343. self.data.elem_commands["STORE"]["bg"] = "lightgrey"
  344. elif LABEL:#else:
  345. label = "lalaal"
  346. import tkinter.simpledialog
  347. label = tkinter.simpledialog.askstring("LABEL","Preset "+str(nr))
  348. self.data.elem_presets[nr]["text"] = label
  349. self.data.label_presets[nr] = label
  350. l=self.data.val_presets[nr]
  351. txt=str(nr)+":EXEC:"+str(len(l))+"\n"+label
  352. #txt = "Preset:"+str(nr)+":\n"+str(len(l))+":"+label
  353. self.data.elem_presets[nr]["text"] = txt
  354. LABEL = 0
  355. self.data.elem_commands["LABEL"]["bg"] = "lightgrey"
  356. else:
  357. print("GO PRESET")
  358. if nr not in self.data.val_presets:
  359. self.data.val_presets[nr] = OrderedDict()
  360. self.data.val_presets[nr]["VALUE"] = None
  361. self.data.val_presets[nr]["FX"] = ""
  362. sdata = self.data.val_presets[nr]
  363. cmd = ""
  364. for fix in sdata:
  365. for attr in sdata[fix]:
  366. v2 = sdata[fix][attr]["VALUE"]
  367. v2_fx = sdata[fix][attr]["FX"]
  368. #print(fix,attr,v)
  369. if fix in self.data.fixtures:
  370. #print("==",self.data.fixtures[fix]["ATTRIBUT"])
  371. if attr in self.data.fixtures[fix]["ATTRIBUT"]:
  372. data = self.data.fixtures[fix]
  373. v=self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"]
  374. if v2 is not None:
  375. self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"] = v2
  376. self.data.elem_attr[fix][attr]["text"] = str(attr)+' '+str(round(v,2))
  377. if str(event.type) == "ButtonRelease":
  378. if FLASH :
  379. cmd+=update_dmx(attr,data,value="off",flash=FLASH)
  380. if v2_fx:
  381. cmd+=update_dmx(attr,data,pfx="fxf",value="off",flash=FLASH)#,flash=FLASH)
  382. else:
  383. cmd+=update_dmx(attr,data,flash=FLASH)
  384. if v2_fx:
  385. cmd+=update_dmx(attr,data,pfx="fx",value=v2_fx,flash=FLASH)#,flash=FLASH)
  386. #worker.fade_dmx(fix,attr,data,v,v2)
  387. if cmd:
  388. client.send(cmd )
  389. #print(sdata)
  390. if event.num == 3:
  391. if not STORE:
  392. print("GO PRESET")
  393. if nr not in self.data.val_presets:
  394. self.data.val_presets[nr] = OrderedDict()
  395. self.data.val_presets[nr]["VALUE"] = None
  396. self.data.val_presets[nr]["FX"] = ""
  397. sdata = self.data.val_presets[nr]
  398. cmd = ""
  399. for fix in sdata:
  400. for attr in sdata[fix]:
  401. v2 = sdata[fix][attr]["VALUE"]
  402. v2_fx = sdata[fix][attr]["FX"]
  403. #print(fix,attr,v)
  404. if fix in self.data.fixtures:
  405. #print("==",self.data.fixtures[fix]["ATTRIBUT"])
  406. if attr in self.data.fixtures[fix]["ATTRIBUT"]:
  407. data = self.data.fixtures[fix]
  408. v=self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"]
  409. if v2 is not None:
  410. self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"] = v2
  411. self.data.elem_attr[fix][attr]["text"] = str(attr)+' '+str(round(v,2))
  412. if str(event.type) == "ButtonRelease":
  413. if FLASH :
  414. cmd+=update_dmx(attr,data,value="off",flash=FLASH)
  415. if v2_fx:
  416. cmd+=update_dmx(attr,data,pfx="fxf",value="off",flash=FLASH)#,flash=FLASH)
  417. else:
  418. cmd+=update_dmx(attr,data,args=[0],flash=FLASH)
  419. if v2_fx:
  420. cmd+=update_dmx(attr,data,pfx="fx",value=v2_fx,flash=FLASH)#,flash=FLASH)
  421. #worker.fade_dmx(fix,attr,data,v,v2)
  422. if cmd:
  423. client.send(cmd )
  424. return 0
  425. elif self.mode == "INPUT":
  426. return 0
  427. if self.mode == "ENCODER":
  428. #if self.attr == "VDIM":
  429. # self.attr = "DIM"
  430. for fix in self.data.fixtures:
  431. data = self.data.fixtures[fix]
  432. for attr in data["ATTRIBUT"]:
  433. if attr.endswith("-FINE"):
  434. continue
  435. elem = self.data.elem_attr[fix][attr]
  436. if self.attr != attr:
  437. continue
  438. if event.num == 1:
  439. #self#encoder(attr=attr,data=data,elem=elem,action="click")
  440. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  441. elem["bg"] = "yellow"
  442. if "FX" in data["ATTRIBUT"][attr]:#["FX"]:# = 1
  443. if data["ATTRIBUT"][attr]["FX"]:# = 1
  444. elem["fg"] = "cyan"
  445. else:
  446. elem["fg"] = "grey"
  447. if not data["ATTRIBUT"][attr]["ACTIVE"]:
  448. continue
  449. if event.num == 4:
  450. self.encoder(fix=fix,attr=attr,data=data,elem=elem,action="+")
  451. #if attr == "DIM":
  452. # self.encoder(attr="VDIM",data=data,elem=elem,action="+")
  453. elif event.num == 5:
  454. self.encoder(fix=fix,attr=attr,data=data,elem=elem,action="-")
  455. #if attr == "DIM":
  456. # self.encoder(attr="VDIM",data=data,elem=elem,action="-")
  457. return 0
  458. if event.num == 1:
  459. self.encoder(fix=0,attr=self.attr,data=self.data,elem=self.elem,action="click")
  460. elif event.num == 4:
  461. self.encoder(fix=0,attr=self.attr,data=self.data,elem=self.elem,action="+")
  462. elif event.num == 5:
  463. self.encoder(fix=0,attr=self.attr,data=self.data,elem=self.elem,action="-")
  464. except Exception as e:
  465. print("== cb EXCEPT",e)
  466. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  467. #print(self.elem["text"],self.attr,self.data)
  468. def wheel(event,d=None):
  469. print("wheel",event,d)
  470. import copy
  471. frame_fix = tk.Frame(root,bg="lightblue",width="100px")
  472. frame_fix.pack(fill=tk.BOTH, side=tk.TOP)
  473. class Master():
  474. def __init__(self):
  475. self.load()
  476. self.all_attr =["DIM","VDIM","PAN","TILT"]
  477. self.elem_attr = {}
  478. self.commands =["BLIND","CLEAR","STORE","EDIT","","","LABEL"
  479. ,"BACKUP","SET","","","SELECT","ACTIVATE","FLASH","",
  480. "STONY_FX","FX OFF", "FX:SIN","FX:COS",]
  481. self.elem_commands = {}
  482. self.val_commands = {}
  483. self.elem_presets = {}
  484. self.load_presets()
  485. for i in range(8*8):
  486. if i not in self.val_presets:
  487. name = "Preset:"+str(i+1)+":\nXYZ"
  488. #self.presets[i] = [i]
  489. self.val_presets[i] = OrderedDict() #attr PAN , TILT, RED
  490. #self.val_presets[i]["VALUE"] = 0#OrderedDict()
  491. #self.val_presets[i]["FX"] = "" #OrderedDict()
  492. self.label_presets[i] = "-"
  493. def load(self):
  494. fixture = OrderedDict()
  495. DATA = OrderedDict()
  496. DATA["DIM"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  497. fix = {"DMX": 20, "UNIVERS": 2, "NAME": "D", "ATTRIBUT": DATA}
  498. fi = copy.deepcopy(fix)
  499. fi["DMX"] = 1
  500. fi["NAME"] = "F1"
  501. fixture["1"] = fi
  502. fi = copy.deepcopy(fix)
  503. fi["DMX"] = 2
  504. fi["NAME"] = "F2"
  505. fixture["2"] = fi
  506. fi = copy.deepcopy(fix)
  507. fi["DMX"] = 3
  508. fi["NAME"] = "F3"
  509. fixture["3"] = fi
  510. fi = copy.deepcopy(fix)
  511. fi["DMX"] = 4
  512. fi["NAME"] = "F4"
  513. fixture["4"] = fi
  514. fi = copy.deepcopy(fix)
  515. fi["DMX"] = 11
  516. fi["NAME"] = "FL"
  517. fixture["11"] = fi
  518. fi = copy.deepcopy(fix)
  519. fi["DMX"] = 24
  520. fi["NAME"] = "P"
  521. fixture["24"] = fi
  522. DATA = OrderedDict()
  523. DATA["DIM"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  524. DATA["RED"] = {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  525. DATA["GREEN"] = {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  526. DATA["BLUE"] = {"NR": 5, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  527. fix = {"DMX": 20, "UNIVERS": 2, "NAME": "IRGB", "ATTRIBUT": DATA}
  528. fi = copy.deepcopy(fix)
  529. fi["DMX"] = 401
  530. #fixture["1001"] = fi
  531. fi = copy.deepcopy(fix)
  532. fi["DMX"] = 421
  533. fi["ATTRIBUT"]["BLUE"]["VALUE"] = 22
  534. #fixture["1002"] = fi
  535. fi = copy.deepcopy(fix)
  536. fi["DMX"] = 441
  537. fi["ATTRIBUT"]["BLUE"]["VALUE"] = 22
  538. #fixture["1003"] = fi
  539. DATA = OrderedDict()
  540. DATA["VDIM"] = {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  541. DATA["RED"] = {"NR": 2, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  542. DATA["GREEN"] = {"NR": 1, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  543. DATA["BLUE"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  544. fix3 = {"DMX": 20, "UNIVERS": 2, "NAME": "V+RGB", "ATTRIBUT": DATA}
  545. fi = copy.deepcopy(fix3)
  546. fi["DMX"] = 330
  547. #fixture["2001"] = fi
  548. fi = copy.deepcopy(fix3)
  549. fi["DMX"] = 335
  550. #fixture["2002"] = fi
  551. fi = copy.deepcopy(fix3)
  552. fi["DMX"] = 240
  553. #fixture["2003"] = fi
  554. fi = copy.deepcopy(fix3)
  555. fi["DMX"] = 245
  556. #fixture["2004"] = fi
  557. fi = copy.deepcopy(fix3)
  558. fi["DMX"] = 250
  559. #fixture["2005"] = fi
  560. fi = copy.deepcopy(fix3)
  561. fi["DMX"] = 355
  562. #fixture["2006"] = fi
  563. DATA = OrderedDict()
  564. DATA["SHUTTER"] = {"NR": 5, "MASTER": "", "MODE": "S", "VALUE": 5.0,"ACTIVE":0}
  565. DATA["VDIM"] = {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  566. DATA["PAN"] = {"NR": 0, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  567. DATA["PAN-FINE"] = {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  568. DATA["TILT"] = {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  569. DATA["TILT-FINE"]= {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  570. DATA["RED"] = {"NR": 6, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  571. DATA["GREEN"] = {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  572. DATA["BLUE"] = {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  573. fixTMH = {"DMX": 20, "UNIVERS": 2, "NAME": "MH-BEAM", "ATTRIBUT": DATA}
  574. fi = copy.deepcopy(fixTMH)
  575. fi["DMX"] = 241
  576. fixture["3001"] = fi
  577. fi = copy.deepcopy(fixTMH)
  578. fi["DMX"] = 261
  579. fixture["3002"] = fi
  580. DATA = OrderedDict()
  581. DATA["DIM"] = {"NR": 17, "MASTER": "1", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  582. DATA["PAN"] = {"NR": 0, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  583. DATA["PAN-FINE"] = {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  584. DATA["TILT"] = {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  585. DATA["TILT-FINE"] = {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  586. DATA["COLOR"] = {"NR": 8, "MASTER": "", "MODE": "S", "VALUE": 0.0,"ACTIVE":0}
  587. DATA["GOBO"] = {"NR": 9, "MASTER": "", "MODE": "S", "VALUE": 0.0,"ACTIVE":0}
  588. DATA["G-ROT"] = {"NR": 8, "MASTER": "", "MODE": "S", "VALUE": 192.0,"ACTIVE":0}
  589. DATA["PRINSMA"] = {"NR": 10, "MASTER": "", "MODE": "S", "VALUE": 0.0,"ACTIVE":0}
  590. DATA["P-ROT"] = {"NR": 11, "MASTER": "", "MODE": "S", "VALUE": 0.0,"ACTIVE":0}
  591. DATA["FOCUS"] = {"NR": 14, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  592. DATA["ZOOM"] = {"NR": 13, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  593. DATA["FROST"] = {"NR": 15, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  594. DATA["CONTROL"] = {"NR": 5, "MASTER": "", "MODE": "S", "VALUE": 5.0,"ACTIVE":0}
  595. fixREUSH = {"DMX": 300, "UNIVERS": 2, "NAME": "RUSH-BEAM", "ATTRIBUT": DATA}
  596. fi = copy.deepcopy(fixREUSH)
  597. fi["DMX"] = 201
  598. fixture["701"] = fi
  599. fi = copy.deepcopy(fixREUSH)
  600. fi["DMX"] = 220
  601. #fixture["702"] = fi
  602. fi = copy.deepcopy(fixREUSH)
  603. fi["DMX"] = 239
  604. #fixture["703"] = fi
  605. fi = copy.deepcopy(fixREUSH)
  606. fi["DMX"] = 258
  607. #fixture["704"] = fi
  608. fi = copy.deepcopy(fixREUSH)
  609. fi["DMX"] = 277
  610. #fixture["705"] = fi
  611. fi = copy.deepcopy(fixREUSH)
  612. fi["DMX"] = 296
  613. #fixture["706"] = fi
  614. self.fixtures = fixture
  615. def load_presets(self):
  616. filename="presets"
  617. d,l = self._load(filename)
  618. self.val_presets = d
  619. self.label_presets = l
  620. def _load(self,filename):
  621. xfname = "show/"+show_name+"/"+str(filename)+".sav"
  622. print("load",xfname)
  623. f = open(xfname,"r")
  624. lines = f.readlines()
  625. f.close()
  626. data = OrderedDict()
  627. labels = OrderedDict()
  628. for line in lines:
  629. key,label,rdata = line.split("\t",2)
  630. key = int(key)
  631. #print(xfname,"load",key,label)
  632. #print(line)
  633. jdata = json.loads(rdata,object_pairs_hook=OrderedDict)
  634. data[key] = jdata
  635. labels[key] = label
  636. return data,labels
  637. def backup_presets(self):
  638. filename = "presets"
  639. data = self.val_presets
  640. labels = self.label_presets
  641. self._backup(filename,data,labels)
  642. def _backup(self,filename,data,labels):
  643. #fixture
  644. xfname = "show/"+show_name+"/"+str(filename)+".sav"
  645. print("backup",xfname)
  646. f = open(xfname,"w")
  647. for key in data:
  648. line = data[key]
  649. print(line)
  650. label = "label"
  651. if key in labels:
  652. label = labels[key]
  653. if label == "Name-"+str(key):
  654. label = ""
  655. print(xfname,"load",key,label,len(line))
  656. f.write(str(key)+"\t"+label+"\t"+json.dumps(line)+"\n")
  657. f.close()
  658. def draw_dim(self,fix,data,c=0,r=0,frame=None):
  659. i=0
  660. if frame is None:
  661. frame = tk.Frame(root,bg="black")
  662. frame.pack(fill=tk.X, side=tk.TOP)
  663. #b = tk.Button(frame,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20)
  664. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  665. #b.grid(row=r, column=c, sticky=tk.W+tk.E)
  666. #c+=1
  667. #r+=1
  668. if fix not in self.elem_attr:
  669. self.elem_attr[fix] = {}
  670. for attr in data["ATTRIBUT"]:
  671. if attr not in self.all_attr:
  672. self.all_attr.append(attr)
  673. if attr not in self.elem_attr[fix]:
  674. self.elem_attr[fix][attr] = []
  675. if attr.endswith("-FINE"):
  676. continue
  677. v= data["ATTRIBUT"][attr]["VALUE"]
  678. b = tk.Button(frame,bg="lightblue", text=""+str(fix)+" "+data["NAME"],width=4)
  679. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  680. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  681. c+=1
  682. b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=6)
  683. self.elem_attr[fix][attr] = b
  684. b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb)
  685. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  686. c+=1
  687. if c >=12:
  688. c=0
  689. r+=1
  690. return c,r
  691. def draw_fix(self,fix,data):
  692. i=0
  693. c=0
  694. r=0
  695. frame = tk.Frame(frame_fix,bg="black")
  696. frame.pack(fill=tk.X, side=tk.TOP)
  697. b = tk.Button(frame,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20)
  698. b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  699. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  700. c+=1
  701. #r+=1
  702. if fix not in self.elem_attr:
  703. self.elem_attr[fix] = {}
  704. for attr in data["ATTRIBUT"]:
  705. if attr not in self.all_attr:
  706. self.all_attr.append(attr)
  707. if attr not in self.elem_attr[fix]:
  708. self.elem_attr[fix][attr] = []
  709. if attr.endswith("-FINE"):
  710. continue
  711. v= data["ATTRIBUT"][attr]["VALUE"]
  712. b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=8)
  713. self.elem_attr[fix][attr] = b
  714. b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb)
  715. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  716. c+=1
  717. if c >=8:
  718. c=1
  719. r+=1
  720. def draw_enc(self):
  721. i=0
  722. c=0
  723. r=0
  724. #frame = tk.Frame(root,bg="black")
  725. #frame.pack(fill=tk.X, side=tk.TOP)
  726. #b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  727. #b.grid(row=r, column=c, sticky=tk.W+tk.E)
  728. #r=0
  729. frame = tk.Frame(root2,bg="black")
  730. frame.pack(fill=tk.X, side=tk.TOP)
  731. b = tk.Button(frame,bg="lightblue", text="ENCODER",width=6)
  732. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  733. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  734. #r+=1
  735. c+=1
  736. for attr in self.all_attr:
  737. if attr.endswith("-FINE"):
  738. continue
  739. v=0
  740. b = tk.Button(frame,bg="orange", text=str(attr)+'',width=6)
  741. b.bind("<Button>",Xevent(fix=0,elem=b,attr=attr,data=self,mode="ENCODER").cb)
  742. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  743. c+=1
  744. if c >=7:
  745. c=0
  746. r+=1
  747. def draw_command(self):
  748. i=0
  749. c=0
  750. r=0
  751. #frame = tk.Frame(root,bg="black")
  752. #frame.pack(fill=tk.X, side=tk.TOP)
  753. #b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  754. #b.grid(row=r, column=c, sticky=tk.W+tk.E)
  755. #r=0
  756. frame = tk.Frame(root2,bg="black")
  757. frame.pack(fill=tk.X, side=tk.TOP)
  758. b = tk.Button(frame,bg="lightblue", text="COMM.",width=6)
  759. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  760. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  761. #r+=1
  762. c+=1
  763. for comm in self.commands:
  764. v=0
  765. b = tk.Button(frame,bg="lightgrey", text=str(comm),width=6)
  766. if comm not in self.elem_commands:
  767. self.elem_commands[comm] = b
  768. self.val_commands[comm] = 0
  769. b.bind("<Button>",Xevent(fix=0,elem=b,attr=comm,data=self,mode="COMMAND").cb)
  770. if comm == "FX OFF":
  771. b["bg"] = "magenta"
  772. if comm:
  773. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  774. c+=1
  775. if c >=6:
  776. c=0
  777. r+=1
  778. def draw_preset(self):
  779. i=0
  780. c=0
  781. r=0
  782. frame = tk.Frame(root,bg="black")
  783. frame.pack(fill=tk.X, side=tk.TOP)
  784. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  785. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  786. r=0
  787. frame = tk.Frame(root,bg="black")
  788. frame.pack(fill=tk.X, side=tk.TOP)
  789. b = tk.Button(frame,bg="lightblue", text="EXEC")
  790. #b.bind("<Button>",Xevent(elem=b).cb)
  791. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  792. r+=1
  793. for k in self.val_presets:
  794. v=0
  795. label = ""
  796. if k in self.label_presets:
  797. label = self.label_presets[k]
  798. print([label])
  799. txt=str(k)+":EXEC:"+str(len(self.label_presets[k]))+"\n"+label
  800. b = tk.Button(frame,bg="grey", text=txt,width=8,height=2)
  801. b.bind("<Button>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb)
  802. b.bind("<ButtonRelease>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb)
  803. if k in self.val_presets and len(self.val_presets[k]) :
  804. b["bg"] = "yellow"
  805. sdata = self.val_presets[k]
  806. if len(sdata):
  807. fx_color = 0
  808. val_color = 0
  809. for fix in sdata:
  810. print( "$$$$",fix,sdata[fix])
  811. for attr in sdata[fix]:
  812. if "FX" in sdata[fix][attr]:
  813. if sdata[fix][attr]["FX"]:
  814. fx_color = 1
  815. if "VALUE" in sdata[fix][attr]:
  816. if sdata[fix][attr]["VALUE"] is not None:
  817. val_color = 1
  818. if val_color:
  819. b["bg"] = "gold"
  820. if fx_color:
  821. b["fg"] = "blue"
  822. else:
  823. if fx_color:
  824. b["bg"] = "cyan"
  825. else:
  826. b["bg"] = "grey"
  827. if k not in self.elem_presets:
  828. self.elem_presets[k] = b
  829. #self.val_presets[preset] = 0
  830. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  831. c+=1
  832. if c >=8:
  833. c=0
  834. r+=1
  835. def draw_input(self):
  836. i=0
  837. c=0
  838. r=0
  839. frame = tk.Frame(root2,bg="black")
  840. frame.pack(fill=tk.X, side=tk.TOP)
  841. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  842. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  843. r=0
  844. frame = tk.Frame(root2,bg="black")
  845. frame.pack(fill=tk.X, side=tk.TOP)
  846. b = tk.Label(frame, text="send:")
  847. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  848. c+=1
  849. b = tk.Entry(frame,bg="grey", text="",width=50)
  850. self.entry = b
  851. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb)
  852. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb)
  853. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  854. b.insert("end","d0:127,fx241:sinus:50:50:10,fx243:cosinus:50:50:10,d201:127,fx201:sinus:50:300:10")
  855. r+=1
  856. b = tk.Entry(frame,bg="grey", text="",width=20)
  857. self.entry2 = b
  858. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT2").cb)
  859. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT2").cb)
  860. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  861. b.insert("end","d1:0:4")
  862. r+=1
  863. b = tk.Entry(frame,bg="grey", text="",width=20)
  864. self.entry3 = b
  865. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb)
  866. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb)
  867. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  868. b.insert("end","fx:alloff:::")
  869. def render(self):
  870. r=0
  871. c=0
  872. dim_frame = tk.Frame(frame_fix,bg="black")
  873. dim_frame.pack(fill=tk.X, side=tk.TOP)
  874. for fix in self.fixtures:
  875. data = self.fixtures[fix]
  876. print( fix )
  877. if(len(data["ATTRIBUT"].keys()) <= 1):
  878. c,r=self.draw_dim(fix,data,c=c,r=r,frame=dim_frame)
  879. else:
  880. self.draw_fix(fix,data)
  881. self.draw_enc()
  882. self.draw_command()
  883. self.draw_input()
  884. self.draw_preset()
  885. master =Master()
  886. master.render()
  887. root.mainloop()
  888. sys.exit()