#!/usr/bin/python3 import json import time import sys import copy import os import tkinter as tk import traceback import _thread as thread sys.path.insert(0,"/opt/LibreLight/Xdesk/") gui=None INIT_OK = 1 IS_GUI = 0 import __main__ as MAIN import lib.meta as meta import tool.git as git CAPTION = "FX3" title = CAPTION title += git.get_all() from lib.cprint import cprint import lib.libtk as libtk import lib.libtk2 as libtk2 import lib.zchat as chat import lib.mytklib as mytklib import lib.tkevent as tkevent #import tkgui.draw as draw import tool.movewin as movewin movewin.check_is_started("FX3","/opt/LibreLight/Xdesk/tkgui/FX3.py") class rEvent(): def __init__(self): self.num = 1 self.type = "rEvent " console = chat.Client() #port=50001) def jsend(jdatas): jtxt = jdatas #jtxt = json.dumps(jtxt) #jtxt = jtxt.encode() console.send( jtxt ) #b"\00 ") def _add_space(frame,r,c): b = tk.Canvas(frame,bg="black", height=2,bd=0,width=6,highlightthickness=0) #,bd="black") b.grid(row=r, column=c, sticky=tk.W+tk.E) r+=1 c=0 return r,c def basic(): for i in range(4): k = "GRP:1" #.format(i+1) MAIN.meta.fx3_grid[k].val("POS") k = "ATTR:1" #.format(i+1) MAIN.meta.fx3_grid[k].val("-") k = "ATTR:2" #.format(i+1) MAIN.meta.fx3_grid[k].val("-") k = "ATTR:3" #.format(i+1) MAIN.meta.fx3_grid[k].val("-") k = "ATTR:4" #.format(i+1) MAIN.meta.fx3_grid[k].val("-") k = "SIZE:{}".format(i+1) MAIN.meta.fx3_grid[k].val(255) MAIN.meta.fx3_grid[k].data["init_value"] = 255 MAIN.meta.fx3_grid[k].data["max"] = 1024 MAIN.meta.fx3_grid[k].data["cycle"] = [0,127,255] k = "SPEED:{}".format(i+1) MAIN.meta.fx3_grid[k].val(10) MAIN.meta.fx3_grid[k].data["init_value"] = 10 MAIN.meta.fx3_grid[k].data["max"] = 1024 MAIN.meta.fx3_grid[k].data["cycle"] = [0,5,25,30,100,255] k = "OFFSET:{}".format(i+1) MAIN.meta.fx3_grid[k].val(100) MAIN.meta.fx3_grid[k].data["init_value"] = 100 MAIN.meta.fx3_grid[k].data["max"] = 1024 MAIN.meta.fx3_grid[k].data["inc"] = 25 k = "WIDTH:{}".format(i+1) MAIN.meta.fx3_grid[k].val(25) MAIN.meta.fx3_grid[k].data["init_value"] = 25 MAIN.meta.fx3_grid[k].data["max"] = 100 MAIN.meta.fx3_grid[k].data["inc"] = 5 k = "START:{}".format(i+1) MAIN.meta.fx3_grid[k].val(0) MAIN.meta.fx3_grid[k].data["init_value"] = 0 MAIN.meta.fx3_grid[k].data["max"] = 1024 MAIN.meta.fx3_grid[k].data["inc"] = 5 k = "SHUFFLE:{}".format(i+1) MAIN.meta.fx3_grid[k].val(0) MAIN.meta.fx3_grid[k].data["init_value"] = 0 MAIN.meta.fx3_grid[k].data["max"] = 1 k = "DIR:{}".format(i+1) MAIN.meta.fx3_grid[k].val(1) MAIN.meta.fx3_grid[k].data["init_value"] = 1 MAIN.meta.fx3_grid[k].data["max"] = 1 k = "INVERT:{}".format(i+1) MAIN.meta.fx3_grid[k].val(1) MAIN.meta.fx3_grid[k].data["init_value"] = 1 MAIN.meta.fx3_grid[k].data["max"] = 1 k = "BASE:{}".format(i+1) MAIN.meta.fx3_grid[k].val(1) MAIN.meta.fx3_grid[k].data["init_value"] = 0 MAIN.meta.fx3_grid[k].data["max"] = 1 MAIN.meta.fx3_grid[k].data["min"] = -1 basic() def get_fx3_grid(): fx3_grid = MAIN.meta.fx3_grid # OptionBuffer() out = [] for k,v in fx3_grid.items(): # re-order fx3_grid to command vv = v.val() kk,ii = k.split(":") ii = int(ii)-1 if len(out) <= ii: #extand list out.append({}) out[ii][kk] = vv return out def reshape_grid_to_jdata(grid_data1): grid_data2 = {} if not grid_data1: print("reshape_grid_to_jdata() no grid_data2 !") return grid_data2 for i in grid_data1: attr = i["ATTR"].strip() if attr: #grid_data2[attr] = {"event":"FX3","MODE":"FX2","DMX":-11,"DMX-FINE":-99,"FIX":"","ATTR":"","VALUE":None,"FX2":i} grid_data2[attr] = {"event":"FX3","MODE":"FX","DMX":-11,"DMX-FINE":-99,"FIX":"","ATTR":"","VALUE":None,"FX2":i} return grid_data2 def update_dmx_adresses(grid_data2): patch = mc_api.get_patch() patch = mc_api.patch_order_by_fix(patch) out=[] for i in grid_data2: ID = i["FIX"] attr = i["ATTR"] #print("address",[ID,attr,i,ID in patch]) if ID in patch: v = patch[ID] if attr in v["ATTR"]: dmx = v["ATTR"][attr] i["DMX"]=dmx attr += "-FINE" if attr in v["ATTR"]: dmx = v["ATTR"][attr] i["DMX-FINE"]=dmx #cprint("333-- FX3:",i,color="yellow") return grid_data2 def extract_fixture_list(grid_data3): #print() out = {} for k,v in enumerate(grid_data3): #print("calc_off",k,v) if v["FIX"] not in out: out[v["FIX"]] = 0 else: out[v["FIX"]] += 1 return out def correct_base(grid_data3): for k,v in enumerate(grid_data3): #print("BASE:",[k,v]) if type(v["FX2"]["BASE"]) not in [int,float]: continue if v["FX2"]["BASE"] < 0: v["FX2"]["BASE"] = "-" elif v["FX2"]["BASE"] > 0: v["FX2"]["BASE"] = "+" else: v["FX2"]["BASE"] = "0" def calculate_offset(grid_data3,wing=None): if wing is None: fix = extract_fixture_list(grid_data3) else: fix = wing #print() print("---"*10) offset = {} if not wing: cprint("calculate_offset not wing !") return if len(wing) <= 0: cprint("calculate_offset not wing !") return offset_len = len(wing[0])-1 if offset_len <= 0: offset_len = 1 #offset = grid_data3[0]["FX2"]["OFFSET"]/offset_len for k,v in enumerate(grid_data3): _offset = v["FX2"]["OFFSET"] attr = v["ATTR"] if attr not in offset: offset[attr] = 0 offset[attr] += _offset/offset_len for i,wing in enumerate(fix): for j,f in enumerate(wing): print(i,j) for k,v in enumerate(grid_data3): if f != v["FIX"]: continue attr = v["ATTR"] nof = round( offset[attr]*j,2 ) # ID v["FX2"]["OFFSET"] = nof v["FX2"]["WING"] = i print(" ",f,attr,v["FX2"],nof) def merge_grid_and_programmer(programmer,grid_data2): out=[] for k,v in enumerate(programmer): attr = v["ATTR"] ID = v["ID"] #print("merge_grid..",v) if attr in grid_data2: tmp = copy.deepcopy(grid_data2[attr]) if "GRP" in tmp["FX2"]: del tmp["FX2"]["GRP"] #print(" tmp",tmp) _offset = tmp["FX2"]["OFFSET"] tmp["ATTR"] = attr tmp["FIX"] = ID out.append(tmp) return out def log(x,name="log",color="yellow"): #print() if type(x) in [dict]: #,OrderedDict]: for k,v in x.items(): cprint(name,[k,v],color=color) else: for k,v in enumerate(x): cprint(name,[k,v],color=color) import lib.fxlib as fxlib def calculate_wing_shuffle(grid_data3): fixtures = [] for i,f in enumerate(grid_data3): print("WING",i,f) fix = f["FIX"] if fix not in fixtures: fixtures.append(fix) fx_prm={} fx_prm["SHUFFLE"] = 1 fx_prm["WING"] = 2 if len(grid_data3) <= 0: cprint("calculate_wing_shuffle no grid_data3 !") return print() print(grid_data3[0]) fx_prm["WING"] = int(grid_data3[0]["FX2"]["WING"]) fx_prm["SHUFFLE"] = int(grid_data3[0]["FX2"]["SHUFFLE"]) a=fxlib.process_wings(fixtures,fx_prm) print(a) return a def grid_stop(grid_data1): if not grid_data1: return for v in grid_data1: v["SPEED"] = 0 print("grid_stop",v) def grid_off(grid_data1): if not grid_data1: return for v in grid_data1: v["SIZE"] = 0 print("grid_off",v) class tk_event_fx(): """ global input event Handeler for short cut's ... etc """ def __init__(self,fix,elem,attr=None,data=None,mode=None): self.fix = fix self.data = data # gui / master self.attr = attr self.elem = elem self.mode = mode self.ATTR_GRP = "" def command_fx3(self,event=None,mode=""): prm = [] ct = "" #print(" --", self.attr) fx3_grid = MAIN.meta.fx3_grid # OptionBuffer() if self.attr in ["START","STOP","OFF"]: grid_data1 = get_fx3_grid() #if self.attr in ["STOP"]: # grid_stop(grid_data1) if self.attr in ["OFF"]: grid_off(grid_data1) grid_data2 = reshape_grid_to_jdata(grid_data1) programmer = mc_api.get_programmer() grid_data3 = merge_grid_and_programmer(programmer,grid_data2) wing = calculate_wing_shuffle(grid_data3) calculate_offset(grid_data3,wing) correct_base(grid_data3) update_dmx_adresses(grid_data3) grid_data4 = [] for i in grid_data3: cprint(" ", i,color="green") grid_data4.append(i) msg=json.dumps(grid_data4).encode("utf-8") cprint("SEND FX3:",color="green") cmd_client.send(msg) if self.attr not in fx3_grid: fx_data = {} if self.attr == "CIRCLE": for k,v in fx3_grid.items(): if k.startswith("ATTR"): print(self.attr,k,v) if self.attr == "PLAY": for k,v in fx3_grid.items(): vv = v.val() k_name , k_nr = k.split(":") if k_nr not in fx_data: fx_data[k_nr] = {} fx_data[k_nr][k_name] = vv #print("**",k,vv,v) for k,v in fx_data.items(): print("fx33",k,v) if "ATTR" in v and v["ATTR"] != " ": print("HH",k,v) #print() return fx_func = MAIN.meta.OptionBuffer() if self.attr.startswith("ATTR:"): col = self.attr.split(":")[1] fx_func1 = fx3_grid["GRP:"+str(col)] GRP = fx_func1.val() if GRP != self.ATTR_GRP: self.ATTR_GRP = GRP fx_func1.val(GRP) fx3_grid[self.attr] = MAIN.meta.Optionbuffer_create_ATTR(GRP) fx_func = fx3_grid[self.attr] print(fx_func.data) fx_func.data["wrap"] = 1 else: fx_func = fx3_grid[self.attr] fx_func.data["wrap"] = 1 print("func",fx_func,fx_func.val()) if event.num == 3: fx_func.reset() elif event.num == 4: fx_func.inc() elif event.num == 5: fx_func.dec() v=fx_func.val() #print(v) #print(self.elem) self.elem["text"] = v return def command(self,event=None,mode=""): cprint("tkevent.tk_event_fx.command") cprint(" ",self.mode) prm = None ct = None if self.mode == "FX-3": return self.command_fx3(event,mode=mode) def cb(self,event): cprint("tkevent.EVENT_fx.cb:",[self.attr,self.mode,event],color='yellow') cprint(" ",["type",event.type,"num",event.num]) try: change = 0 if self.attr == "REC-FX": msg=json.dumps([{"event":"REC-FX","VALUE":255,"DATA":{}}]).encode("utf-8") global modes if "REC-FX" in modes: msg=json.dumps([{"event":"REC-FX","VALUE":0,"DATA":{}}]).encode("utf-8") cmd_client.send(msg) # diable LABEL mode elif self.attr == "FX OFF": msg=json.dumps([{"event":"FX-OFF","VALUE":255,"DATA":{}}]).encode("utf-8") cmd_client.send(msg) # diable LABEL mode elif self.mode.startswith("FX"): self.command(event) return 0 except Exception as e: cprint("== cb EXCEPT",e,color="red") cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red") cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red") return 1 def motion(code="circle"): #basic() k = "GRP:1" #.format(i+1) MAIN.meta.fx3_grid[k].val("POS") MAIN.meta.change_grp(name=k,val="POS") k = "GRP:2" #.format(i+1) MAIN.meta.fx3_grid[k].val("POS") MAIN.meta.change_grp(name=k,val="POS") k = "GRP:3" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") MAIN.meta.change_grp(name=k,val=" ") k = "GRP:4" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") MAIN.meta.change_grp(name=k,val=" ") k = "GRP:5" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") MAIN.meta.change_grp(name=k,val=" ") k = "GRP:6" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") MAIN.meta.change_grp(name=k,val=" ") k = "ATTR:1" #.format(i+1) MAIN.meta.fx3_grid[k].val("PAN") k = "ATTR:2" #.format(i+1) MAIN.meta.fx3_grid[k].val("TILT") k = "ATTR:3" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") k = "ATTR:4" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") k = "ATTR:5" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") k = "ATTR:6" #.format(i+1) MAIN.meta.fx3_grid[k].val(" ") k = "TYPE:1" MAIN.meta.fx3_grid[k].val("sinus") k = "TYPE:2" MAIN.meta.fx3_grid[k].val("cosinus") k = "WIDTH:1" MAIN.meta.fx3_grid[k].val(255) k = "WIDTH:2" MAIN.meta.fx3_grid[k].val(255) k = "BASE:1" MAIN.meta.fx3_grid[k].val(0) k = "BASE:2" MAIN.meta.fx3_grid[k].val(0) for i in range(1,5+1): k = "START:"+str(i) MAIN.meta.fx3_grid[k].val(0) if code == "circle": k = "SIZE:1" MAIN.meta.fx3_grid[k].val(100) k = "SIZE:2" MAIN.meta.fx3_grid[k].val(100) if code == "pan": k = "SIZE:1" MAIN.meta.fx3_grid[k].val(100) k = "SIZE:2" MAIN.meta.fx3_grid[k].val(0) if code == "tilt": k = "SIZE:1" MAIN.meta.fx3_grid[k].val(0) k = "SIZE:2" MAIN.meta.fx3_grid[k].val(100) if code == "flay": k = "SIZE:1" MAIN.meta.fx3_grid[k].val(0) k = "SIZE:2" MAIN.meta.fx3_grid[k].val(100) k = "SIZE:3" MAIN.meta.fx3_grid[k].val(100) k = "START:2" MAIN.meta.fx3_grid[k].val(20) k = "TYPE:2" MAIN.meta.fx3_grid[k].val("ramp") k = "TYPE:3" MAIN.meta.fx3_grid[k].val("on") k = "GRP:3" MAIN.meta.fx3_grid[k].val("BEAM") MAIN.meta.change_grp(name=k,val="BEAM") k = "ATTR:3" MAIN.meta.fx3_grid[k].val("DIM") k = "WIDTH:3" MAIN.meta.fx3_grid[k].val(85) k = "BASE:3" MAIN.meta.fx3_grid[k].val(-1) if code == "street": k = "SIZE:1" MAIN.meta.fx3_grid[k].val(100) k = "SIZE:2" MAIN.meta.fx3_grid[k].val(0) k = "SIZE:3" MAIN.meta.fx3_grid[k].val(100) k = "START:1" MAIN.meta.fx3_grid[k].val(20) k = "TYPE:1" MAIN.meta.fx3_grid[k].val("ramp") k = "TYPE:3" MAIN.meta.fx3_grid[k].val("on") k = "GRP:3" MAIN.meta.fx3_grid[k].val("BEAM") MAIN.meta.change_grp(name=k,val="BEAM") k = "ATTR:3" MAIN.meta.fx3_grid[k].val("DIM") k = "WIDTH:3" MAIN.meta.fx3_grid[k].val(85) k = "BASE:3" MAIN.meta.fx3_grid[k].val(-1) def size(val=255): for i in range(4): k = "SIZE:{}".format(i+1) kt = "TYPE:{}".format(i+1) print(" ",k,val) if MAIN.meta.fx3_grid[kt].val() not in ["STATIC","-"]: v = MAIN.meta.fx3_grid[k].val() if v not in [0,0.0]: MAIN.meta.fx3_grid[k].val(val) refresh_fx3_elem(_filter="SIZE") def speed(val=255): for i in range(4): k = "SPEED:{}".format(i+1) kt = "TYPE:{}".format(i+1) print(" ",k,val) if MAIN.meta.fx3_grid[kt].val() not in ["STATIC","-"]: MAIN.meta.fx3_grid[k].val(val) refresh_fx3_elem(_filter="SPEED") def dim(code="dim"): for i in range(1,5+1): k = "GRP:" +str(i) MAIN.meta.change_grp(name=k,val="BEAM") MAIN.meta.fx3_grid[k].val("BEAM") k = "ATTR:"+str(i) MAIN.meta.fx3_grid[k].val(" ") k = "TYPE:"+str(i) MAIN.meta.fx3_grid[k].val("static") k = "WIDTH:"+str(i) MAIN.meta.fx3_grid[k].val(50) k = "BASE:"+str(i) MAIN.meta.fx3_grid[k].val(-1) k = "SIZE:"+str(i) MAIN.meta.fx3_grid[k].val(0) k = "ATTR:1" MAIN.meta.fx3_grid[k].val("DIM") if code == "dim": k = "TYPE:1" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:1" MAIN.meta.fx3_grid[k].val(255) def rgb(code="red"): #basic() for i in range(1,5+1): k = "GRP:" +str(i) MAIN.meta.change_grp(name=k,val="RGB") MAIN.meta.fx3_grid[k].val("RGB") k = "GRP:6" MAIN.meta.change_grp(name=k,val=" ") MAIN.meta.fx3_grid[k].val(" ") k = "ATTR:1" MAIN.meta.fx3_grid[k].val("RED") k = "ATTR:2" MAIN.meta.fx3_grid[k].val("GREEN") k = "ATTR:3" MAIN.meta.fx3_grid[k].val("BLUE") k = "ATTR:4" MAIN.meta.fx3_grid[k].val("WHITE") k = "ATTR:5" MAIN.meta.fx3_grid[k].val("AMBER") k = "ATTR:6" MAIN.meta.fx3_grid[k].val(" ") for i in range(1,5+1): k = "TYPE:"+str(i) MAIN.meta.fx3_grid[k].val("static") k = "WIDTH:"+str(i) MAIN.meta.fx3_grid[k].val(50) k = "BASE:"+str(i) MAIN.meta.fx3_grid[k].val(-1) k = "SIZE:"+str(i) MAIN.meta.fx3_grid[k].val(0) if code == "red": k = "TYPE:1" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:1" MAIN.meta.fx3_grid[k].val(255) if code == "green": k = "TYPE:2" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:2" MAIN.meta.fx3_grid[k].val(255) if code == "blue": k = "TYPE:3" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:3" MAIN.meta.fx3_grid[k].val(255) if code == "magenta": k = "TYPE:1" MAIN.meta.fx3_grid[k].val("fade") k = "TYPE:3" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:1" MAIN.meta.fx3_grid[k].val(255) k = "SIZE:3" MAIN.meta.fx3_grid[k].val(255) if code == "cyan": k = "TYPE:2" MAIN.meta.fx3_grid[k].val("fade") k = "TYPE:3" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:2" MAIN.meta.fx3_grid[k].val(255) k = "SIZE:3" MAIN.meta.fx3_grid[k].val(255) if code == "yellow": k = "TYPE:1" MAIN.meta.fx3_grid[k].val("fade") k = "TYPE:2" MAIN.meta.fx3_grid[k].val("fade") k = "SIZE:1" MAIN.meta.fx3_grid[k].val(255) k = "SIZE:2" MAIN.meta.fx3_grid[k].val(255) refresh_fx3_elem() def clear(): basic() for i in range(1,5+1): k = "GRP:"+str(i) MAIN.meta.fx3_grid[k].val(" ") k = "ATTR:"+str(i) MAIN.meta.fx3_grid[k].val(" ") k = "TYPE:"+str(i) MAIN.meta.fx3_grid[k].val(" ") motion("circle") def refresh_fx3_elem(_filter=""): ct = MAIN.meta.fx3 #moves prm = MAIN.meta.fx3_prm for comm in ct.labels: if comm not in ct.elem: continue b = ct.elem[comm] if comm in MAIN.meta.fx3_grid: if _filter and _filter != comm: continue v2 = MAIN.meta.fx3_grid[comm].val() v1 = b["text"] v2 = MAIN.meta.fx3_grid[comm].val() v1 = b["text"] if str(v2) != str(v1): #print(" change") b["text"] = str(v2) def refresh_fx3_loop(): while 1: refresh_fx3_elem() time.sleep(2) def _XXX(xcb,xcomm,xb): def XXX(event=None,**data): print("BTN:",xb["text"],xcomm) print("xXx "*22) print("XXX",event,data) if xcomm == "CIRCLE": motion("circle") elif xcomm == "PAN": motion("pan") elif xcomm == "TILT": motion("tilt") elif xcomm == "FLAY": motion("flay") elif xcomm == "STREET": motion("street") elif xcomm == "DIM": dim(code="dim") elif xcomm == "RED": rgb("red") elif xcomm == "GREEN": rgb("green") elif xcomm == "BLUE": rgb("blue") elif xcomm == "CYAN": rgb("cyan") elif xcomm == "MAGENTA": rgb("magenta") elif xcomm == "YELLOW": rgb("yellow") elif xcomm == "MINI": size(25) elif xcomm == "SMALL": size(50) elif xcomm == "NORMAL": size(100) elif xcomm == "BIG": size(255) elif xcomm == "SLOW": speed(5) elif xcomm == "MID": speed(25) elif xcomm == "FAST": speed(80) elif xcomm == "TURBO": speed(160) xcb(event) #,data) return XXX def _draw_fx3(frame,c,r,gui,mode="FX"): ct = MAIN.meta.fx3 #moves prm = MAIN.meta.fx3_prm for comm in ct.labels: print(" draw3",comm) if comm == "\n\n": b = tk.Label(frame,bg="black", text="-",font=space_font) b.grid(row=r, column=c,pady=0,padx=0, sticky=tk.W+tk.E) c=0 r+=1 continue if comm == "\n": c=0 r+=1 continue v=0 b = tk.Button(frame,bg="lightgrey", text=str(comm),width=6,height=1) ct.elem[comm] = b ct.val[comm] = 0 _cb = tk_event_fx(fix=0,elem=b,attr=comm,data=gui,mode=mode).cb _comm = comm _b = b XXX = _XXX(_cb,_comm,_b) b.bind("