From 454b134745aa2c9bf5efa89dbf75a43339ddac90 Mon Sep 17 00:00:00 2001 From: sparks-alec Date: Mon, 14 Feb 2022 03:25:37 -0500 Subject: [PATCH] lint all the things --- plugins/artnet/icon.png | Bin 0 -> 1457 bytes plugins/artnet/icon.psd | Bin 0 -> 25593 bytes plugins/artnet/info.html | 2 + plugins/artnet/main.js | 119 ++++++++++++++++++++ plugins/artnet/styles.css | 29 +++++ plugins/artnet/template.ejs | 64 +++++++++++ plugins/eos/info.html | 15 +++ plugins/eos/main.js | 136 ++++++++++------------- plugins/eos/styles.css | 16 +-- plugins/eos/template.ejs | 2 - plugins/pjlink/info.html | 4 + plugins/pjlink/main.js | 119 ++++++++++---------- plugins/qlab/cart.ejs | 10 +- plugins/qlab/cue.ejs | 7 +- plugins/qlab/info.html | 4 + plugins/qlab/main.js | 211 ++++++++++++++++++------------------ plugins/qlab/styles.css | 78 +++++++------ plugins/qlab/tile.ejs | 36 +++--- plugins/sacn/icon.png | Bin 0 -> 713 bytes plugins/sacn/icon.psd | Bin 0 -> 25792 bytes plugins/sacn/info.html | 1 + plugins/sacn/main.js | 158 +++++++++++++++++++++++++++ plugins/sacn/styles.css | 29 +++++ plugins/sacn/template.ejs | 58 ++++++++++ plugins/watchout/info.html | 0 plugins/watchout/main.js | 50 +++++---- plugins/x32/info.html | 0 plugins/x32/main.js | 101 ++++++++--------- plugins/xair/info.html | 0 plugins/xair/main.js | 106 +++++++++--------- 30 files changed, 909 insertions(+), 446 deletions(-) create mode 100644 plugins/artnet/icon.png create mode 100644 plugins/artnet/icon.psd create mode 100644 plugins/artnet/info.html create mode 100644 plugins/artnet/main.js create mode 100644 plugins/artnet/styles.css create mode 100644 plugins/artnet/template.ejs create mode 100644 plugins/eos/info.html create mode 100644 plugins/pjlink/info.html create mode 100644 plugins/qlab/info.html create mode 100644 plugins/sacn/icon.png create mode 100644 plugins/sacn/icon.psd create mode 100644 plugins/sacn/info.html create mode 100644 plugins/sacn/main.js create mode 100644 plugins/sacn/styles.css create mode 100644 plugins/sacn/template.ejs create mode 100644 plugins/watchout/info.html create mode 100644 plugins/x32/info.html create mode 100644 plugins/xair/info.html diff --git a/plugins/artnet/icon.png b/plugins/artnet/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8ab4d7becc4a5454f3f5ce6104d7a06ef781b136 GIT binary patch literal 1457 zcmV;i1y1^jP)CmsxC7RT#&A=iWOTGt*9?wp1vkWfO{m8z!Qt5D=Fj z(F8~kqJoJi#-JD_LF1D?_#`GS4`K-Tpd>~#B0<6uWRn;{%3>`P3v`{%Oqbd2+;fi) zw+u7ROi^EW@O!-HJOBUr{^wiH75Yc#6gR-M8$k+Slv)r1)ZeubpbOA70e~qLa|j3a^H=9U+!YE+gpH`RKPuRz(eH9kdFGU$~{5lf5b4 zKN)4m!ZF;`6r(380kBc@rEQ`qN6ctSvid+LCzjMRtJ2Ho&HZ^;cUO5C?RT-MDOObS zta)961$BP5Hun=wO3p^oJU6KRyX_(T#pC_FdTWU73vOm->i{Ps>Ea9}EGxApV8t!vm^OSmry5Oww4pZW zW@&wZZ7l>HAG`NSYkP6#5EVuYdd?ZPog1s+ZCdo0bm z!#&wVEJ-}6+|Ar^ei}!4ITtfI6EzDQEn6|KHb7^>f(vkarI&j~k6`P$7`Dn}%f=-H zZG#zLco7T$mnPWNI!Jd?vSnTkb9S_m%oH9sZb{@&7&g!nOS9ovxFon3hB>c}Up~}@ zCg9`ystX*IB2PMjla$x9Qry|CUc>3JtM+y>zb?RYZv+1&wvorC1jHO|M<%>V9ENpMYE=Z;ko;*6zuW^V`g*7(^lv%-loCj!Or zS$jP*uA&sn(6dpK*A8~_@!T4kA|?Z-ofpDzQf7UIOD-XtS}tZ^UKr$#swf{kFq*Vw zbGXClTmom_x(op-KYCj!Ea!Dp@-=AyWTYZ9On-ahSeS+~HxG{wkhGi{>Pt)N%G~T< zRGW8?nt;>2X;$s;A}(!At2nL!u=7%ao|H{vg&U79@MwZR;}+d13rjlp|Mt&ej&vqC z(2-AR4}>Rjb$q)hurMHoN!*ErHID`3{p;apw@3t={3*= z++XeG{D6faps~VDcS6!SVDa?CAmOA$+BO-f2)Q*bCnO2W=FUnF$Ge@^NUh&sUwg7B zu?EilM$?kh5tHNLG{1yXbfqNqK^IfXTzE8a>w<7f5=lwCn&7rd54t7@n>JFx2M&O)J+}58k1hy#bPQe4osvi(ZYh56Gda|iB7^gI54ts^ zf{SsBeOHo51>uzBL?n%^6m4+}k1iPL(P&RfY;f?3v{v!I`*->a{^(E_0MCyn00000 LNkvXXu0mjfH*T*A literal 0 HcmV?d00001 diff --git a/plugins/artnet/icon.psd b/plugins/artnet/icon.psd new file mode 100644 index 0000000000000000000000000000000000000000..7abee51b59b21da40dbf27a208fe01834ed30c92 GIT binary patch literal 25593 zcmeHP30PCd+MbhyRRkB@{o53^Y6S_K2z6sopcO?HZEJh`gd{*DBryqV7pu0~_E@*N zwN|ZFYpt~I)}<=q+TL2*fFS#hxNo==67qjD=OjRgx!$(-`S1TcIf0XzZ<}x4`DV^{ zPM$eqLu29)g_wg2U(b+#M}*68ytHU+XjC+hM=B13IS9cYBD7(I)}!g}>-W7+_TT)~ zTgl&@5nnn&ctbHSsBzrHETvGCD$(#0CCO6xc#qphPk8X9;_)7{0-^=c$}mZaG%`me ziOZQ5FUm<31&KW-PH-NV6`Yl(Op|DY{H!#YTpgS>-a{x>BuavzjLF^}d?KPr9q$o> z8T?nGWB6eTm4qKS+Q&;I5D55zL8HaOM4>1#(Ub2h@b&Q)_KKnVFfRGyO&@RLR~xK|w*@0$*=mUoVjGQfJFG z!YnVjdI)30XeV5v7OA94jZ`7$W4ppcMY?9ZhX-!Rbg&&uQ<@r*t4EVgjut7>yt9N# zZ=cZuZ%ayIkx56Hu96Yg#3FBrOp+#%Yt*3UV^I${RVI<9LL_;)+g&LvJim#Wz*UQH*9+drjf(2kDz+|P9thpV9SelgmR94z0 zJJ=A5f|C@gG@)jKP^pwjMM4~X-WhT+8&f7+$9cDlcF-rW5ga8~YlL!QS6fWM!Ye}HI=mvF2^?B(O*6CfPx>*G5%X)FOLI=Z8J7t`SiQ92G! z*0dN*OMC;zNPNc%y~Ke6v6sKt$JZ+;P%QEii-Qs+;zU7^Sj^xLraP#2F+E)+g|$T} z>mY-@|96|PV5Un`ky15;Uv`JEgy1BLN1SACXR47QlafV1DO9N?c#e$sFisNFs$p6b zunw7P!9o!pzzHH8?-KDi?@rWqw@jL>nzZWxJ{`)8{SN9+ZX+{ABDXeS7*j;*$wt(Q zBu%DJB?(D}n0Sh*%oy#gWo~_(H(qUJ(*M9XsD&ASZ4?s4;y{T{fWT|)SUCAh#=tZh zBb0aveEbsw1!F`)ancy$DF2(I0Mo`dDBjm6*e3ukZN>%X?-&K&(LS9Q)TbGR_81nW z2<6EV@dR&U$BcykPXqUK>mLKmzcp}Ax>Ec-0~hdrIB?87?7ScvFA-fA&~c_qQ*f9< zrcgyI#F7bq-d;)ZE%?ZV!djE%Q`-0TpL_wfLO2E z;IfX78P^7v86eiHHn^>_Np^e&lii>VaP9&B%#PA-N)>Fzo1U&wrfYy` zhecx4nz%&RzegmZE+_`6kODqQh>zls1Zhw@QesocS!t4n8Zi?p)5uwm zToTizGL2MDOakADNQXtg`ZBZs^+jxg;{~Vo9{1|d_4 zRbrFX(WXk6N*>l;k!#v3Qxj!s6K7hoCc{*joF)r5RRG6!)1ji&WEKbpB@`PG8V25w z?Y*&LK3}XzPn@Kv#vYO*LM87)3zc=13ss5Z6XcpHLtSGYGBA5bKGQ}AKG$vk?V@LbtO;cMc1?0)O+gobxwzeXennCj0EtM^IW ziJaj?ktiLGV-q5siEd0LvJVI~5_u;j0Y?UBdqSaD%I42LH&J}C7J3cNMwtLY!I95W zh|R}PM|fr#EFRn@%(lof{1qO-0-MHL(@F1mc#AqhWY0R`3P_zpFD3h&UCL$XSduIxmzSCDPG#>p$IpF6^!Ebb%q@ccw(ElRIC8?1eH-yfC?w zl&eT0lf_H2G*Rlv_~@y|WzNw^?j-D#qEO|8$fU`}tB@Ph`A8!fdhQ^WBni{Wvg?!~ zQE4oQ&oq)di+4**CY$U!fZLO?9~xm|fC`$XkYlW!GzukLzSWYB>zcC+7Qil4mqfB) zcA!b;D&2TvRw3yqO)xavEII;KId!<<-~t4&|sD zX!SzDsGm@zR))mHOl7pYoMAFOEMn$iffu%w6!k~RxDPTn?YDpFvuA=eo?SFL6S|4v zRSppQczqCw)uJ>gKvn{;-$;WrPonbVN6AH_@k=*+ z1XvD_8U9A-ek>Uas_(^inqo7&Cu9h$s7u;uiE9x0;YWn}|J+U+x)D-B$hZ#v3OnhA zj6FD04|)Hpu1@m9S1^!u356WA(qOp%Jj|h$2(jq??>@bI_wVUK4)%+wn4hWc-MV#m?cT%HwTHW_tE)Rc zxw>cg6E`Gr5$>lxQ%f~KchOoEC-1)xt?khI$2^})D zPwdG=KY!JN-@_b+t&F=R?oS!M zYU>C4SD!AdZ{Bv`%%z40Gm|nFt@--k*`mgWff2KkGZ(Mj{=>QAE02024hOvD5uY6F z?E;7k&-wJ?fd_LvdfWNVU*V2DI2rr<9lxQ8HL3+G!{Yjg)c$ve*<%MBo)5^^f)iW% zi6QG1XN7fd3UeVTf1^UekYI`cA=_o(D`{SzZ+0fa@!}7uU;Qjef-44 zNAcm4bA%DYyDuE@?ylC`hTo39JA04k$?TN9+iQK+#%I0NEw}uX0lod&*#5tqYjyj| zfMz{&K&+i@4_eu~}KE5oPHs6Hppym@J5PT3moFUtznFS+>I;r+8j zk&k}3pQ~PfE5v|`mKjjk#O68C`vPUo>8|1p`A)pkxAYAW&Bss7n>FvE#(?Tqt@vo) z!AnQo>tEo{eLJt>-DgJ`O31u_j)eUzI8zjy+)xM-Ln@aDw~TzaiA;gA2L9Egqy!1~ ze<8s~zOZQeBAk&i**MPwiiq-!jz%v)!4Wx7y~wQ?z6(IqKyr(W8&9MLnaXph5v&ZP zeUuML{+sHcZqXe@S^RRCyhY)kf8l6L=a`33i;jK6Z02(|R$EuCMcOg&n z?=V%EEm86PupL>tTnhRaYX>wH2~jqLg$nVJA9J4ouc=Z2k0%pmtB8EI6t3W;e|ESo zk|pBIfrkeO*QN5LES68|sq$1s$GS|dOzKn@$*_Ig5prM~>XbCxMkM@`I~!5DTElRW zKYZh>H*OBJ@JqAsYl>Kk6L=|6#Y@v9`0hXC@&dny!={cSek5h7aA;%QE(hGZ>4At* z=OYI7dsv9mjN9Sd!KicY63;{`Ig9!vECI(;qwW|b$4M<8&l+s21M-e23ht~j2=W^6 z!H4i!8xa)WyIVSTqVaUmn67x7nW~B>2$@bf_rl z$weHNqeHHCM-Qy{ba_QQu+Y0#!de*>U?dzGI%350ulz`*EJk*_WGq7uO&*NXA;-K3 z5slE$Uqf|_23Q>RNh{(`oBvW0v_5f#u?^6emiuxma_zQq28!Fh<@?+nyBDL4;Flh8 zRS(OCLt74IIq3bmdGE}d_kI%EL|DAcZA;H}*CRWJiy3Ia(H3JXysT{wKYa#ty9*g; z;c-kqj7`~PevdpGgl))<_j4v%*sjnoa}PX|yb4!B&iPC<@3(~bgoIbZ*;c5G18vA@ zskS$w&Savu8}tWx$5yb;Q5lDT=X3_{zfNVLg~v=yQRzqZ$np6)CCbY}3))?v(og7+ z!}Qxz_5hiPlb&!gPE!Eb{EAB&v@qYvsm+<|h&CU=PE&J_w;~75*88bQ-EgukpLcpS zTC)#x`gy)FVzmE2N6O)OsrTTRh)H86y!htqp$XFoGa_L`9bu?n$xXFNTjA zk{UF0u0LT;os0&04pGDf2}4lYdl4^$s75IUp&4$B*@zKtgZe&WHz+XDBg!GJ)J9h4x=gK=# zU0VA4Z>6PWm1CHQKd|{-U@O-2b|3NiHx9E?Q&P?pq@+mazynQ)c+JATr{QOcG#u9s zg*f6j!k|OMch4J%)<9~K_7QLfm3RW@D;Ro+_}4cea9A;|@N&L!_+>qg_}{Y72PaK*yX-y4^J*fF_zT(S1ETOF zcFQ&U07A2GK$gY%XEs_;sGrGuZ8BnA&cZ>xyvQA%31y>quj&u;@>a19P+3QT=Y0Na zgwE!m5AsYcQCY_!;D=vPp;JI__khaGhk%c{7qR~>R-ClY$vTGveqnWS23mB+nF;tU zFd+aj^~qLb&)NPc4W(bzpW&Tfi#|I*0@Lfw5#9kL-ctpGXGDbrP8=_Meb}rSgc&(& zWYimDXZZNPG1DC$UyhqRYN#xDm@0rUr%geFyoSz=4;F8sIgMJ9a=+NO#Xa8}Cn8<6)YzYrHAmRcCR$$L4>VyZb#?US4f^dBN}H zoTeI+$E`WPAU`c86WgL3-K=h5aP=IQUKugC9D@X z-t%8TYas=ee~jb349ELc02bo?jg1iRC!LV|BkE<@*^hB7Vh)6wecq8(YgW}J01M5( zIT^y5Wz0H;<9&7>mHIKV+b3rkINpyW!1$esk}QLGFU0YVHNc|h3W)cZ_oqs6ystL4 zLE=3c$NSnil(2LAzTMyN{}_EmRJiH78WQg{@1PH_E_iRjg2gF_i3MKHj+MWVcrVOG zi*d9ut?=I3;qdDQ9Pip}wCI$HZkMwUd0iLbc)yr~7PTw5<{U)m^;;0{+zUBqVUd0o zj(0ZTvJXQ{uec2H{&NnRcU^ykm%p0zjmkcTlMiFV`Q|a)7+gPl?(Dgr)}haT zAYnWD&5_~WjlF`QqHROH_ z-<3>>R;L07o+XmIRV?I->F~B%xX+^=LcRTd&G<8qGZvevQp-F2_+sS3s*mi_gmV-s z_Lmp92?K%@Zh2V(mf$8yvpW1TZv$$0x#-i`>}zh*uCq;CC6CG3Hy(HTF~c5S zU#eEfJJHZ&x#_nJQU(K#@XBK)etk2PT_tj1qD+FHCSwZw6OcVa1-?TPyb?8?i1zF( z8WEFVO}bBK>G%|IPHg<0*`j?nqg!$5N~J=jF|`Sq8oh?`4z*Kc1xE#yTG^ zRpU-#HDf+77_Rc|IWUv^4uq_?ALPD+NjBUMvId+X{`3#-jpj>$7bHWEM(r0jWT(6FAI4$EC-gdZXJRJ z#A4QsIhM0-9Wq$Xx(UNl)~$mFSC*1)=nb-zb7OgnDYp*skmZb92hZ~?B;1&6A>Y=) zouH+3TL&Zbq-+~I`-Ehhuq@=-m~J7}Cgd)eHtw|LL>tRn%(Jn(PfD{f?@3uU<~=FN zCN`gtW9yhF4siG1N~0xunzv->^5sj~XtezC3baH=bB@=qZKHebuDe`Pc4oyVwRdmb zx_0f>t=o6D>S^xkio(;tJa%!_stvyvFWvv+ks}S)j~qFAbgiCt%saQbel<-WJKsig zmR{eYr>TM}9oU3*16rEiT)PZ(=#y(7 zF$x@d(=V+wch}kPjzHTxel@nhrFWHm-%7hKzqp&;d%3v0tfc&Bx)7Y=(Runi8+5em z(mSW=^UY_^oIQK~2;tb#`NbEmtkBbTORwkC=WAM+7BG2flNQLITmy0)OSY%;%jr!I z4z&Tj$tYf?u#F`qvDKwrhH z{gt#0tZHB_Z!D(i2C!DkwgU7TKz>8>3A(;R;~e^AosM?c^~cVNQ>-vF4Z@ABwBxzE zH&4>%8N=!oY;bS-|wW?Zd!kQ z&$dH5=woMdH|;pF>G(Q&_ex?jcjL-+t3Uf>-L~)6Z(6fy?UJo)a(ArQv|PtLkb;Lp zty)x|({c(53-#JZg{0j0ptw!jy}J3%ox4{H3z}R0_~X%|wm+zra=n&YbnkXko7S=M z=B1*NTXza-+Zw0`kM#|xSg&=wa<%9|kyhJqtqtrwF4JqNTlaO^Hmy@(bBXq5Bg-lN zqZBx|3CFeemR4KVTnIYas)h&GbPU4)`px&-ZaB8oV9r%tWvh`v)!f&YIMy~}dcnO0 zmd@1{+^^AT9UoNHU)O3cKdNL6akQm3TD9Ejt5pqcTB_m(OXg~;?^d^JT?=p4Xlw4= zzIXTTy=z+R5l?%it))b#wJT_8(q3!TU*%n^Ck#7n)14a+0V2DCM_07hnp+ruFuCC2 zEpxKHw&|X>w6(4ci-RGfxErQxYjtH>ZNbAP?bXNn8eVNBX@H}>avzYo@fZLER#U6~ zKCk&kM^@p(+gj~|4%R@W8Bi~2ZR|qUX&tKdRrfjzKWNq3Uu}5|?my5KatpM#n_=9w zjo_T!owf$;l~&yY?oI8@dpd1@ZE0OeX?byhwxFb;w79yevb>_AuC}D68uO}ZN~-G0 ztINu2Yl`Y?Dk~~WFE^BzG?rmrb)~kr^m1cOd0nNp@oH6R<(1OLVr|VOVza8`QgKmn ZL2-H2<mKF4_P9 literal 0 HcmV?d00001 diff --git a/plugins/artnet/info.html b/plugins/artnet/info.html new file mode 100644 index 0000000..4284f4e --- /dev/null +++ b/plugins/artnet/info.html @@ -0,0 +1,2 @@ +

Art-Net requires no configuration.

+

Art-Netâ„¢ Designed by and Copyright Artistic Licence Holdings Ltd

\ No newline at end of file diff --git a/plugins/artnet/main.js b/plugins/artnet/main.js new file mode 100644 index 0000000..519a5ef --- /dev/null +++ b/plugins/artnet/main.js @@ -0,0 +1,119 @@ +const _ = require('lodash'); + +exports.defaultName = "Art-Net"; +exports.connectionType = 'UDPsocket'; +exports.heartbeatInterval = 10000; +exports.searchOptions = { + type: 'UDPsocket', + searchBuffer: Buffer.from([65, 114, 116, 45, 78, 101, 116, 0x00, 0x00, 0x20, 0x00, 0x0e, 0x00, 0x00]), + devicePort: 6454, + listenPort: 6454, + validateResponse (msg, info, devices) { + return msg.toString('utf8', 0, 7) === "Art-Net"; + } +}; +exports.defaultPort = 6454; + +exports.ready = function ready(device) { + const d = device; + d.data.universes = {}; + d.data.orderedUniverses = []; + +}; + +exports.data = function data(device, buf) { + if(buf.length < 18){ + return + } + const univ = buf.readUInt8(14); + const d = device; + let u = d.data.universes[univ]; + + if(!u){ + d.data.universes[univ] = {}; + u = d.data.universes[univ]; + } + + u.sequence = buf.readUInt8(12); + u.net = buf.readUInt8(15); + u.opCode = buf.readUInt8(9); + u.version = buf.readUInt16BE(10); + u.slots = Array.prototype.slice.call(buf, 18); + d.data.ip = d.addresses[0]; + + if(!_.includes(d.data.orderedUniverses, univ)){ + d.data.orderedUniverses.push(univ); + d.data.orderedUniverses.sort(); + u.slotElems = []; + u.slotElemsSet = false; + + d.draw(); + updateElementsCache(d, d.data.universes, d.data.orderedUniverses); + + } + + device.update("universeData", { + u: univ, + universe: u + }); + + +}; + + +exports.heartbeat = function heartbeat(device) { + +}; + + + +let lastUpdate = Date.now(); +exports.update = function update(device, document, updateType, updateData){ + + const data = updateData; + const doc = document; + + if(updateType === "universeData" && data.universe){ + + if(Date.now() - lastUpdate > 1000){ + lastUpdate = Date.now(); + updateElementsCache(device, device.data.universes, device.data.orderedUniverses); + } + + const $elem = doc.getElementById(`universe-${data.u}`); + + if($elem && data.universe.slotElemsSet){ + + for(let i = 0; i < 512; i++){ + data.universe.slotElems[i].innerText = data.universe.slots[i]; + } + + doc.getElementById(`universe-${data.u}-sequence`).innerText = data.universe.sequence; + + + }else{ + device.draw(); + updateElementsCache(device, device.data.universes, device.data.orderedUniverses); + } + + }else if(updateType === "elementCache"){ + + data.orderedUniverses.forEach(univ => { + for(let i = 0; i < 512; i++){ + data.universes[univ].slotElems[i] = doc.getElementById(`${univ}-${i}`); + } + data.universes[univ].slotElemsSet = true; + }); + + } + + +} + +function updateElementsCache(device, univ, ordered){ + device.update("elementCache", { + universes: univ, + orderedUniverses: ordered + }); +} + diff --git a/plugins/artnet/styles.css b/plugins/artnet/styles.css new file mode 100644 index 0000000..fbd5beb --- /dev/null +++ b/plugins/artnet/styles.css @@ -0,0 +1,29 @@ +table { + margin-bottom: 50px; + background-color: #333; +} +td, +th { + width: 35px; +} +td { + background-color: black; + text-align: center; + border-radius: 3px; + color: white; + font-size: 13px; +} +th { + background-color: #222; + color: #ccc; + font-size: 11px; +} +td.data { + padding: 7px; + font-size: 12px; + text-align: left; +} +td.data em { + font-size: 14px; + color: #008bd2; +} diff --git a/plugins/artnet/template.ejs b/plugins/artnet/template.ejs new file mode 100644 index 0000000..8373f98 --- /dev/null +++ b/plugins/artnet/template.ejs @@ -0,0 +1,64 @@ +
+

<%= data.source %> Art-Net

+
+ + +
+<% data.orderedUniverses.forEach(univ => { + let universe = data.universes[univ]; +%> + + + + + + + + + + + + + + + + <% for(col=1; col<=16; col++){ %> + + <% } %> + + + <% let slot = 0; %> + <% for(row=0; row<32; row++){ %> + + + <% for(col=0; col<16; col++){ %> + <% slot++%> + + <% } %> + + <% } %> + + +
+ Universe +
<%= univ %> +
+ Sub-Net +
<%= universe.net %> +
+ Sequence +
<%= universe.sequence %> +
+ OpCode +
<%= universe.opCode %> +
+ Version +
<%= universe.version %> +
+ IP +
<%= data.ip %> +
<%= col %>
<%= row*16+1 %><%= universe.slots[slot-1] %>
+ +<% }); %> + +
\ No newline at end of file diff --git a/plugins/eos/info.html b/plugins/eos/info.html new file mode 100644 index 0000000..bd6e1c1 --- /dev/null +++ b/plugins/eos/info.html @@ -0,0 +1,15 @@ +

Connection Requirements

+ +

Shell/ECU → Network

+
    +
  • Enable ✔ TCP OSC. The TCP format dropdown does not matter.
  • +
  • Enable Third Party OSC
  • +
+If the "Third Party OSC" option is not available, Eos must be updated to 3.1 or newer. + +

System Settings → Show Control → OSC

+
    +
  • Enable ✔ OSC RX
  • +
  • Enable ✔ OSC TX
  • +
  • All other fields may be left to defaults or blank.
  • +
\ No newline at end of file diff --git a/plugins/eos/main.js b/plugins/eos/main.js index 2160eac..08eed38 100644 --- a/plugins/eos/main.js +++ b/plugins/eos/main.js @@ -1,7 +1,6 @@ -let _ = require('lodash'); +const _ = require('lodash'); const fs = require('fs'); - exports.defaultName = 'ETC Eos'; exports.connectionType = 'osc'; exports.searchOptions = { @@ -11,71 +10,55 @@ exports.searchOptions = { 'ascii' ), testPort: 3032, - validateResponse: function (msg, info) { + validateResponse (msg, info) { return msg.toString().indexOf('/eos/out'); }, }; -exports.defaultPort = 3032; +exports.defaultPort = 3037; -// "\xc0/eos/ping\x00\x00\x2c\x00\x00\x00\xc0" -exports.ready = function (device) { +exports.ready = function ready(device) { device.send('/eos/get/cuelist/count'); device.send('/eos/get/version'); device.send('/eos/subscribe', [{ type: 'i', value: 1 }]); }; -exports.data = function (device, osc) { - const address = osc.address; +exports.data = function data(device, osc) { const p = osc.address.split('/'); + const d = device; p.shift(); - //console.log(address) + // console.log(osc.address) - if (p[1] == 'out' && p[2] == 'show' && p[3] == 'name') { - device.data.showName = osc.args[0]; - device.data.cuelists = {}; + if (match(p, ['eos','out','show','name'])) { + d.data.showName = osc.args[0]; + d.data.cuelists = {}; this.deviceInfoUpdate(device, 'defaultName', osc.args[0]); - } else if (osc.address == '/eos/out/get/cuelist/count') { + } else if (match(p, ['eos','out','get','cuelist','count'])) { for (let i = 0; i < osc.args[0]; i++) { - device.send(`/eos/get/cuelist/index/${i}`); + d.send(`/eos/get/cuelist/index/${i}`); } - } else if ( - p[1] == 'out' && - p[2] == 'get' && - p[3] == 'cuelist' && - p[5] == 'list' - ) { - device.data.cuelists[p[4]] = {}; - device.send(`/eos/get/cue/${p[4]}/count`); + } else if (match(p, ['eos','out','get','cuelist','*','list','*','*'])) { + d.data.cuelists[p[4]] = {}; + d.send(`/eos/get/cue/${p[4]}/count`); - } else if ( - p[1] == 'out' && - p[2] == 'get' && - p[3] == 'cue' && - p[5] == 'count' - ) { + } else if (match(p, ['eos','out','get','cue','*','count'])) { for (let i = 0; i < osc.args[0]; i++) { device.send(`/eos/get/cue/${p[4]}/index/${i}`); } - } else if ( - p[1] == 'out' && - p[2] == 'get' && - p[3] == 'cue' && - p[7] == 'list' - ) { + } else if (match(p, ['eos','out','get','cue','*','*','*','list','*','*'])) { this.deviceInfoUpdate(device, 'status', 'ok'); - if (device.data.cuelists[p[4]][p[5]] == undefined) { - device.data.cuelists[p[4]][p[5]] = {}; + if (d.data.cuelists[p[4]][p[5]] === undefined) { + d.data.cuelists[p[4]][p[5]] = {}; } - device.data.cuelists[p[4]][p[5]][p[6]] = { + d.data.cuelists[p[4]][p[5]][p[6]] = { uid: osc.args[1], label: osc.args[2], uptimeduration: osc.args[3], @@ -111,56 +94,34 @@ exports.data = function (device, osc) { }); - } else if (p[1] == 'out' && p[2] == 'get' && p[3] == 'cue' && p.length == 6) { - // console.log("cue "+p[4]+" "+p[5]+" deleted") - + } else if (match(p, ['eos','out','get','cue','*','*'])) { // There's no OSC notification of the deletion of a part. It just tells you to update the parent cue and remaining children. // So: we should fetch all the parts of a cue somehow every time there's an update to a cue. - - delete device.data.cuelists[p[4]][p[5]]; - device.draw(); + delete d.data.cuelists[p[4]][p[5]]; + d.draw(); - } else if ( - p[1] == 'out' && - p[2] == 'get' && - p[3] == 'cue' && - p[7] == 'actions' - ) { - if (osc.args.length == 3) { - device.data.cuelists[p[4]][p[5]][0].extlinks = osc.args[2]; + } else if (match(p, ['eos','out','get','cue','*','*','*','actions','list','*','*'])) { + if (osc.args.length === 3) { + d.data.cuelists[p[4]][p[5]][0].extlinks = osc.args[2]; } - } else if ( - p[1] == 'out' && - p[2] == 'event' && - p[3] == 'cue' && - p[6] == 'fire' - ) { - device.data.activeCue = p[5]; - - device.draw(); - device.update("activeCue", {uid: device.data.cuelists[p[4]][p[5]][0].uid}); + } else if (match(p, ['eos','out','event','cue','*','*','fire'])) { + d.data.activeCue = p[5]; + d.draw(); + d.update("activeCue", {uid: device.data.cuelists[p[4]][p[5]][0].uid}); - } else if (p[1] == 'out' && p[2] == 'notify' && p[3] == 'cue') { + } else if (match(p, ['eos','out','notify','cue','*','*','*','*'])) { const cueList = p[4]; - const listIndex = p[6]; - const listCount = p[7]; const cueNumber = osc.args[1]; - device.send(`/eos/get/cue/${cueList}/${cueNumber}`); + d.send(`/eos/get/cue/${cueList}/${cueNumber}`); - } else if ( - p[2] == 'cmd' || - p[2] == 'ping' || - p[2] == 'user' || - p[2] == 'softkey' - ) { - } else if (p[3] == 'version') { - device.data.version = osc.args[0]; + } else if (match(p, ['eos','out','get','version'])) { + d.data.version = osc.args[0]; } else { @@ -170,12 +131,13 @@ exports.data = function (device, osc) { // console.log(p) }; -let cueTemplate = _.template(fs.readFileSync(`./plugins/eos/cue.ejs`)); -exports.update = function(device, doc, updateType, data){ +const cueTemplate = _.template(fs.readFileSync(`./plugins/eos/cue.ejs`)); - if(updateType == "cueData"){ - $elem = doc.getElementById(data.uid); +exports.update = function update(device, doc, updateType, data){ + + if(updateType === "cueData"){ + const $elem = doc.getElementById(data.uid); if($elem){ $elem.outerHTML = cueTemplate({ @@ -189,8 +151,8 @@ exports.update = function(device, doc, updateType, data){ } - }else if(updateType == "activeCue"){ - $elem = doc.getElementById(data.uid); + }else if(updateType === "activeCue"){ + const $elem = doc.getElementById(data.uid); $elem.scrollIntoView({behavior: "smooth", block: "center"}); } @@ -199,6 +161,20 @@ exports.update = function(device, doc, updateType, data){ } -exports.heartbeat = function (device) { +exports.heartbeat = function heartbeat(device) { device.send('/eos/ping'); }; + + +function match(osc, array){ + let out = true; + if(osc.length !== array.length){ + return false; + } + array.forEach((m, i)=> { + if(osc[i] !== m && m !== "*"){ + out = false; + } + }); + return out; +} \ No newline at end of file diff --git a/plugins/eos/styles.css b/plugins/eos/styles.css index 8c14427..7f17bbd 100644 --- a/plugins/eos/styles.css +++ b/plugins/eos/styles.css @@ -25,7 +25,7 @@ td.num { font-weight: 600; font-size: 16px; } - + .scene { background-color: black; border-top: #141414 2px solid; @@ -51,13 +51,13 @@ td.num { tr.active-cue { color: #c78b07; } -tr.active-cue td.num div{ - margin: 0px; - padding: 1px 6px; - background-color: #c78b07; - border-radius: 4px; - color: black; - } +tr.active-cue td.num div { + margin: 0px; + padding: 1px 6px; + background-color: #c78b07; + border-radius: 4px; + color: black; +} tr.active-cue .time { border-color: #c78b07; } diff --git a/plugins/eos/template.ejs b/plugins/eos/template.ejs index daf77b8..b77c514 100644 --- a/plugins/eos/template.ejs +++ b/plugins/eos/template.ejs @@ -44,5 +44,3 @@ <% } %> - - diff --git a/plugins/pjlink/info.html b/plugins/pjlink/info.html new file mode 100644 index 0000000..edbdc3c --- /dev/null +++ b/plugins/pjlink/info.html @@ -0,0 +1,4 @@ +

Connection Requirements

+
    +
  • Requires no password on the projector
  • +
\ No newline at end of file diff --git a/plugins/pjlink/main.js b/plugins/pjlink/main.js index a7cf3a5..80586cf 100644 --- a/plugins/pjlink/main.js +++ b/plugins/pjlink/main.js @@ -9,13 +9,13 @@ exports.searchOptions = { searchBuffer: Buffer.from([0x25, 0x32, 0x53, 0x52, 0x43, 0x48, 0x0d]), devicePort: 4352, listenPort: 4352, - validateResponse: function (msg, info) { + validateResponse (msg, info) { return msg.toString().indexOf('%2ACKN=') >= 0; }, }; exports.defaultPort = 4352; -exports.ready = function (device) { +exports.ready = function ready(device) { // Power status query // device.send("%1POWR ?\r"); }; @@ -23,96 +23,99 @@ let password = false; function processPJLink(device, str, that) { const arr = str.split('%'); - for (var key in arr) { - var split = arr[key].split('='); - var key = split[0]; - var value = split[1]; + const d = device; - switch (key) { - case '1POWR': - device.data.power = value; - break; - case '1INPT': - device.data.input = value; - break; - case '1AVMT': - device.data.avmute = value; - break; - case '1ERST': - device.data.fanError = value[0]; - device.data.lampError = value[1]; - device.data.tempError = value[2]; - device.data.coverError = value[3]; - device.data.filterError = value[4]; - device.data.otherError = value[5]; - break; - case '1LAMP': - device.data.lamp = value.split(' '); - break; - case '1NAME': - device.data.name = value; - that.deviceInfoUpdate(device, 'defaultName', device.data.name); - break; - case '1INF1': - device.data.info1 = value; - break; - case '1INF2': - device.data.info2 = value; - break; - case '2SNUM': - device.data.serial = value; - break; - case '2SVER': - device.data.version = value; - break; + arr.forEach((p) => { + const split = arr[p].split('='); + const key = split[0]; + const value = split[1]; + + if(key === '1POWR'){ + d.data.power = value; + + }else if(key === '1INPT'){ + d.data.input = value; + + }else if(key === '1AVMT'){ + d.data.avmute = value; + + }else if(key === '1ERST'){ + d.data.fanError = value[0]; + d.data.lampError = value[1]; + d.data.tempError = value[2]; + d.data.coverError = value[3]; + d.data.filterError = value[4]; + d.data.otherError = value[5]; + + }else if(key === '1LAMP'){ + d.data.lamp = value.split(' '); + + }else if(key === '1NAME'){ + d.data.name = value; + that.deviceInfoUpdate(d, 'defaultName', d.data.name); + + }else if(key === '1INF1'){ + d.data.info1 = value; + + }else if(key === '1INF2'){ + d.data.info2 = value; + + }else if(key === '2SNUM'){ + d.data.serial = value; + + }else if(key === '2SVER'){ + d.data.version = value; + } - } - device.draw(); + }); + + d.draw(); + } -exports.data = function (device, message) { +exports.data = function data(device, message) { this.deviceInfoUpdate(device, 'status', 'ok'); const msg = message.toString(); - if (msg.substring(0, 8) == 'PJLINK 1') { + if (msg.substring(0, 8) === 'PJLINK 1') { password = md5(`${msg.substring(9, 17)}JBMIAProjectorLink`); device.send( `${password}%1POWR ?\r%1INPT ?\r%1AVMT ?\r%1ERST ?\r%1LAMP ?\r%1NAME ?\r%1INF1 ?\r%1INF2 ?\r%2SNUM ?\r%2SVER ?\r` ); } - if (msg.substring(0, 7) == '%1POWR=') { + if (msg.substring(0, 7) === '%1POWR=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1INPT=') { + if (msg.substring(0, 7) === '%1INPT=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1AVMT=') { + if (msg.substring(0, 7) === '%1AVMT=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1ERST=') { + if (msg.substring(0, 7) === '%1ERST=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1LAMP=') { + if (msg.substring(0, 7) === '%1LAMP=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1NAME=') { + if (msg.substring(0, 7) === '%1NAME=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1INF1=') { + if (msg.substring(0, 7) === '%1INF1=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%1INF2=') { + if (msg.substring(0, 7) === '%1INF2=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%2SNUM=') { + if (msg.substring(0, 7) === '%2SNUM=') { processPJLink(device, msg, this); } - if (msg.substring(0, 7) == '%2SVER=') { + if (msg.substring(0, 7) === '%2SVER=') { processPJLink(device, msg, this); } }; -exports.heartbeat = function (device) { +exports.heartbeat = function heartbeat(device) { if (password) { device.send( `${password}%1POWR ?\r%1INPT ?\r%1AVMT ?\r%1ERST ?\r%1LAMP ?\r%1NAME ?\r%1INF1 ?\r%1INF2 ?\r%2SNUM ?\r%2SVER ?\r` diff --git a/plugins/qlab/cart.ejs b/plugins/qlab/cart.ejs index e5b263b..6b76b4f 100644 --- a/plugins/qlab/cart.ejs +++ b/plugins/qlab/cart.ejs @@ -10,12 +10,10 @@ <% for(let r=0; r <% for(let c=0; c -
+ <% let style = `style="left:${width*c}%; top:${height*r}px; width:${width }%; height:${height}px;"`; %> + +
>
+ <% } %> <% } %> diff --git a/plugins/qlab/cue.ejs b/plugins/qlab/cue.ejs index 30bb8f2..0198dd7 100644 --- a/plugins/qlab/cue.ejs +++ b/plugins/qlab/cue.ejs @@ -157,17 +157,18 @@ if(value>0){ let percent = value/def*100; - let bg = "background: black; background: linear-gradient(90deg, "+fill+" "+percent+"%, transparent "+percent+"%);"; + let bg = `style='background: black; background: linear-gradient(90deg, ${fill} ${percent}%, transparent ${percent}%);`; if(cue.paused){ bg+= "outline-color: "+border+";"; bg+= "color: white;"; } + bg+="'"; - return "
"+prettyFormatTime(Math.min(def, value))+""; + return `
"+prettyFormatTime(Math.min(def, value))+"`; }else if(type=="postWait" || type=="action"){ - return ""+prettyFormatTime(def)+""; + return `${prettyFormatTime(def)}`; }else{ return prettyFormatTime(def); diff --git a/plugins/qlab/info.html b/plugins/qlab/info.html new file mode 100644 index 0000000..5ca65d1 --- /dev/null +++ b/plugins/qlab/info.html @@ -0,0 +1,4 @@ +

Connection Requirements

+
    +
  • No Passcode
  • +
\ No newline at end of file diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js index 8009d8b..c70f689 100644 --- a/plugins/qlab/main.js +++ b/plugins/qlab/main.js @@ -1,4 +1,4 @@ -let _ = require('lodash'); +const _ = require('lodash'); const fs = require('fs'); let lastElapsedUpdate = Date.now(); @@ -12,66 +12,62 @@ exports.searchOptions = { bonjourName: 'qlab', }; -exports.ready = function (device) { +exports.ready = function ready(device) { device.send(`/version`); device.send('/workspaces'); }; -exports.data = function (device, oscData) { - const address = oscData.address; - let osc = oscData.address.split('/'); +exports.data = function data(device, oscData) { + const osc = oscData.address.split('/'); osc.shift(); - - let data; + const d = device; - //console.log(address) + // console.log(oscData.address) if(match(osc, ["reply", "version"])){ - let json = JSON.parse(oscData.args[0]); - device.data.version = json.data; + const json = JSON.parse(oscData.args[0]); + d.data.version = json.data; - this.deviceInfoUpdate(device, 'status', 'ok'); + this.deviceInfoUpdate(d, 'status', 'ok'); }else if(match(osc, ["reply", "workspaces"])){ - let json = JSON.parse(oscData.args[0]); - device.data.workspaces = {}; + const json = JSON.parse(oscData.args[0]); + d.data.workspaces = {}; json.data.forEach(wksp => { - device.data.workspaces[wksp.uniqueID] = { + d.data.workspaces[wksp.uniqueID] = { uniqueID: wksp.uniqueID, displayName: wksp.displayName, cueLists: {}, cues: {} } - device.send(`/workspace/${wksp.uniqueID}/connect`); + d.send(`/workspace/${wksp.uniqueID}/connect`); }); - console.log(device.data.workspaces); - }else if(match(osc, ["reply", "workspace", "*", "connect"])){ - device.send(`/workspace/${osc[2]}/updates`, [ + d.send(`/workspace/${osc[2]}/updates`, [ { type: 'i', value: 1 }, ]); - device.send(`/workspace/${osc[2]}/cueLists`); + d.send(`/workspace/${osc[2]}/cueLists`); }else if(match(osc, ["reply", "workspace", "*", "cueLists"])){ - this.deviceInfoUpdate(device, 'status', 'ok'); + this.deviceInfoUpdate(d, 'status', 'ok'); - let workspace = device.data.workspaces[osc[2]]; - let json = JSON.parse(oscData.args[0]); + const workspace = d.data.workspaces[osc[2]]; + const json = JSON.parse(oscData.args[0]); workspace.cueLists = {}; workspace.cues = {}; @@ -82,13 +78,13 @@ exports.data = function (device, oscData) { addChildrenToWorkspace(workspace, ql); }); - device.draw(); + d.draw(); - setTimeout(function(){ + setTimeout(() => { json.data.forEach(ql => { workspace.cueLists[ql.uniqueID] = ql; - getValuesForKeys(device, json.workspace_id, ql); + getValuesForKeys(d, json.workspace_id, ql); }); }, 0); @@ -96,31 +92,32 @@ exports.data = function (device, oscData) { }else if(match(osc, ["reply", "cue_id", "*", "children"])){ - let json = JSON.parse(oscData.args[0]); - let workspace = device.data.workspaces[json.workspace_id]; - let cue_id = osc[2]; - let cue = workspace.cues[cue_id]; + const json = JSON.parse(oscData.args[0]); + const workspace = d.data.workspaces[json.workspace_id]; + const cueID = osc[2]; + const cue = workspace.cues[cueID]; if(!_.isEqual(cue.cues, json.data)){ - workspace.cueLists[cue_id].cues = json.data; - addChildrenToWorkspace(workspace, workspace.cueLists[cue_id]); + workspace.cueLists[cueID].cues = json.data; + addChildrenToWorkspace(workspace, workspace.cueLists[cueID]); - device.draw(); + d.draw(); - getValuesForKeys(device, json.workspace_id, cue); + getValuesForKeys(d, json.workspace_id, cue); } }else if(match(osc, ["reply", "cue_id", "*", "valuesForKeys"])){ - let json = JSON.parse(oscData.args[0]); - let cueValues = json.data; + const json = JSON.parse(oscData.args[0]); + const cueValues = json.data; - let workspace = device.data.workspaces[json.workspace_id]; + const workspace = d.data.workspaces[json.workspace_id]; let cue = workspace.cues[cueValues.uniqueID]; if(!cue){ - cue = workspace.cues[cueValues.uniqueID] = {}; + workspace.cues[cueValues.uniqueID] = {}; + cue = workspace.cues[cueValues.uniqueID]; } cue.uniqueID = cueValues.uniqueID; @@ -149,15 +146,15 @@ exports.data = function (device, oscData) { cue.actionElapsed = cueValues.actionElapsed; cue.postWaitElapsed = cueValues.postWaitElapsed; - let nestedGroupModes = []; - let nestedGroupPosition = [0]; - var obj = cue; + const nestedGroupModes = []; + const nestedGroupPosition = [0]; + let obj = cue; - while(obj.parent!="[root group of cue lists]"){ + while(obj.parent !== "[root group of cue lists]"){ nestedGroupModes.push(obj.groupMode); let pos = _.findIndex(workspace.cues[obj.parent].cues, {uniqueID: obj.uniqueID}); - pos= Math.abs(pos-workspace.cues[obj.parent].cues.length)-1; + pos = Math.abs(pos - workspace.cues[obj.parent].cues.length) - 1; nestedGroupPosition.push(pos) obj = workspace.cues[obj.parent]; @@ -165,61 +162,61 @@ exports.data = function (device, oscData) { cue.nestedGroupModes = nestedGroupModes; cue.nestedGroupPosition = nestedGroupPosition; - //console.log("draw "+cue.number) + // console.log("draw "+cue.number) - device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace}); + d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace}); }else if(match(osc, ["reply", "cue_id", "*", "preWaitElapsed"])){ - let json = JSON.parse(oscData.args[0]); - let workspace = device.data.workspaces[json.workspace_id]; - let cue = workspace.cues[osc[2]]; + const json = JSON.parse(oscData.args[0]); + const workspace = d.data.workspaces[json.workspace_id]; + const cue = workspace.cues[osc[2]]; cue.preWaitElapsed = json.data; lastElapsedUpdate = Date.now(); - device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace}); + d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace}); }else if(match(osc, ["reply", "cue_id", "*", "actionElapsed"])){ - let json = JSON.parse(oscData.args[0]); - let workspace = device.data.workspaces[json.workspace_id]; - let cue = workspace.cues[osc[2]]; + const json = JSON.parse(oscData.args[0]); + const workspace = d.data.workspaces[json.workspace_id]; + const cue = workspace.cues[osc[2]]; cue.actionElapsed = json.data; lastElapsedUpdate = Date.now(); - device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace}); + d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace}); }else if(match(osc, ["reply", "cue_id", "*", "postWaitElapsed"])){ - let json = JSON.parse(oscData.args[0]); - let workspace = device.data.workspaces[json.workspace_id]; - let cue = workspace.cues[osc[2]]; + const json = JSON.parse(oscData.args[0]); + const workspace = device.data.workspaces[json.workspace_id]; + const cue = workspace.cues[osc[2]]; cue.postWaitElapsed = json.data; lastElapsedUpdate = Date.now(); - device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace}); + d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace}); }else if(match(osc, ["update", "workspace", "*", "cue_id", "*"])){ - let workspace = device.data.workspaces[osc[2]]; + const workspace = d.data.workspaces[osc[2]]; if(workspace){ - let cueLists = Object.keys(workspace.cueLists); - let cue_id = osc[4]; + const cueLists = Object.keys(workspace.cueLists); + const cueID = osc[4]; - if(cue_id!="[root group of cue lists"){ - if(cueLists.includes(cue_id)){ - device.send(`/workspace/${workspace.uniqueID}/cue_id/${cue_id}/children`); + if(cueID !== "[root group of cue lists"){ + if(cueLists.includes(cueID)){ + d.send(`/workspace/${workspace.uniqueID}/cue_id/${cueID}/children`); } - device.send(`/workspace/${osc[2]}/cue_id/${cue_id}/valuesForKeys`, [ + d.send(`/workspace/${osc[2]}/cue_id/${cueID}/valuesForKeys`, [ {type: 's', value: valuesForKeysString} ]); @@ -229,40 +226,40 @@ exports.data = function (device, oscData) { }else if(match(osc, ["update", "workspace", "*"])){ // occurs when cue lists are reordered or a list is deleted - device.send(`/workspace/${osc[2]}/cueLists`); + d.send(`/workspace/${osc[2]}/cueLists`); }else if(match(osc, ["update", "workspace", "*", "dashboard"])){ - //this workspace might be new, let's check - - if(device.data.workspaces[osc[2]]){ + // this workspace might be new, let's check + if(d.data.workspaces[osc[2]]){ + // }else{ console.log("new workspace!"); - device.send('/workspaces'); + d.send('/workspaces'); } }else if(match(osc, ["update", "workspace", "*", "cueList", "*", "playbackPosition"])){ - let workspace = device.data.workspaces[osc[2]]; + const workspace = d.data.workspaces[osc[2]]; if(workspace){ - let cue = workspace.cues[oscData.args[0]]; + const cue = workspace.cues[oscData.args[0]]; if(cue){ workspace.playbackPosition = oscData.args[0] ? cue.uniqueID : ""; - device.update("updatePlaybackPosition", {cue: cue}); + d.update("updatePlaybackPosition", {'cue': cue}); } } }else if(match(osc, ["update", "workspace", "*", "disconnect"])){ - delete device.data.workspaces[osc[2]]; - device.draw(); + delete d.data.workspaces[osc[2]]; + d.draw(); }else{ - //console.log(address) + // console.log(address) } @@ -270,25 +267,24 @@ exports.data = function (device, oscData) { }; -let cueTemplate = _.template(fs.readFileSync(`./plugins/qlab/cue.ejs`)); -let tileTemplate = _.template(fs.readFileSync(`./plugins/qlab/tile.ejs`)); -let cartTemplate = _.template(fs.readFileSync(`./plugins/qlab/cart.ejs`)); -let listTemplate = _.template(fs.readFileSync(`./plugins/qlab/cuelist.ejs`)); +const cueTemplate = _.template(fs.readFileSync(`./plugins/qlab/cue.ejs`)); +const tileTemplate = _.template(fs.readFileSync(`./plugins/qlab/tile.ejs`)); +const cartTemplate = _.template(fs.readFileSync(`./plugins/qlab/cart.ejs`)); -exports.update = function(device, doc, updateType, data){ +exports.update = function update(device, doc, updateType, data){ - if(updateType=="updateCueData"){ - $elem = doc.getElementById(data.cue.uniqueID); + if(updateType === "updateCueData"){ + const $elem = doc.getElementById(data.cue.uniqueID); if($elem){ - if(data.cue.type=="Cue List"){ - $elem.outerHTML = '

'+data.workspace.displayName+' — '+data.cue.name+'

'; + if(data.cue.type === "Cue List"){ + $elem.outerHTML = `

${data.workspace.displayName} — ${data.cue.name}

`; - }else if(data.cue.type=="Cart"){ - $elem.outerHTML = cartTemplate({tileTemplate: tileTemplate, cueList: data.cue, allCues: data.workspace.cues}); + }else if(data.cue.type === "Cart"){ + $elem.outerHTML = cartTemplate({'tileTemplate': tileTemplate, 'cueList': data.cue, 'allCues': data.workspace.cues}); - }else if(data.cue.cartPosition && data.cue.cartPosition[0]!=0){ + }else if(data.cue.cartPosition && data.cue.cartPosition[0] !== 0){ $elem.outerHTML = tileTemplate(data); }else{ @@ -296,13 +292,13 @@ exports.update = function(device, doc, updateType, data){ } } - }else if(updateType=="updatePlaybackPosition"){ + }else if(updateType === "updatePlaybackPosition"){ Array.from(doc.getElementsByClassName("playback-position")).forEach( - function($elem, index, array) { + ($elem, index, array) => { $elem.classList.remove("playback-position"); }); - $elem = doc.getElementById(data.cue.uniqueID); + const $elem = doc.getElementById(data.cue.uniqueID); $elem.classList.add("playback-position"); $elem.scrollIntoView({behavior: "smooth", block: "center"}); @@ -319,30 +315,31 @@ exports.update = function(device, doc, updateType, data){ const valuesForKeysString = '["uniqueID","number","name","listName","isBroken","isRunning","isLoaded","isFlagged",' -+'"type","children","preWait","postWait","currentDuration","colorName","continueMode",' -+'"mode","parent","cartRows","cartColumns","cartPosition","displayName","preWaitElapsed",' -+'"actionElapsed","postWaitElapsed","isPaused"]'; ++ '"type","children","preWait","postWait","currentDuration","colorName","continueMode",' ++ '"mode","parent","cartRows","cartColumns","cartPosition","displayName","preWaitElapsed",' ++ '"actionElapsed","postWaitElapsed","isPaused"]'; function addChildrenToWorkspace(workspace, q){ - workspace.cues[q.uniqueID] = q; - workspace.cues[q.uniqueID].nestedGroupModes = []; - workspace.cues[q.uniqueID].nestedGroupPosition = []; + const w = workspace; + w.cues[q.uniqueID] = q; + w.cues[q.uniqueID].nestedGroupModes = []; + w.cues[q.uniqueID].nestedGroupPosition = []; if(q.cues){ - q.cues.forEach(q => { - addChildrenToWorkspace(workspace, q); + q.cues.forEach(cue => { + addChildrenToWorkspace(w, cue); }); } } -function getValuesForKeys(device, workspace_id, q){ - device.send(`/workspace/${workspace_id}/cue_id/${q.uniqueID}/valuesForKeys`, [ +function getValuesForKeys(device, workspaceID, q){ + device.send(`/workspace/${workspaceID}/cue_id/${q.uniqueID}/valuesForKeys`, [ {type: 's', value: valuesForKeysString} ]); if(q.cues){ - q.cues.forEach(q => { - getValuesForKeys(device, workspace_id, q); + q.cues.forEach(cue => { + getValuesForKeys(device, workspaceID, cue); }); } } @@ -350,11 +347,11 @@ function getValuesForKeys(device, workspace_id, q){ function match(osc, array){ let out = true; - if(osc.length!=array.length){ + if(osc.length !== array.length){ return false; } - array.forEach((match, i)=> { - if(osc[i]!=match && match!="*"){ + array.forEach((m, i)=> { + if(osc[i] !== m && m !== "*"){ out = false; } }); @@ -363,16 +360,16 @@ function match(osc, array){ let interval = 5; let heartbeatCount = 0; -exports.heartbeat = function (device) { +exports.heartbeat = function heartbeat(device) { heartbeatCount++; - if(Date.now()-lastElapsedUpdate>300){ + if(Date.now() - lastElapsedUpdate > 300){ interval = 5; }else{ interval = 1; } - if(heartbeatCount%interval==0){ + if(heartbeatCount % interval === 0){ device.send(`/cue/active/preWaitElapsed`); device.send(`/cue/active/actionElapsed`); device.send(`/cue/active/postWaitElapsed`); diff --git a/plugins/qlab/styles.css b/plugins/qlab/styles.css index f97bb37..9fc38f0 100644 --- a/plugins/qlab/styles.css +++ b/plugins/qlab/styles.css @@ -170,77 +170,73 @@ tr.playback-position .q-gray-text { color: #424242; } .q-time-elapsed { - margin: 0px 2px; - outline: #49c042 1px solid; + margin: 0px 2px; + outline: #49c042 1px solid; line-height: 18px; } - - - -.cart{ +.cart { position: relative; - height: 600px; - width: 100%; + height: 600px; + width: 100%; background-color: #2c2b2a; } -.cartCueWrapper{ - display: block; +.cartCueWrapper { + display: block; position: absolute; box-sizing: border-box; - padding: 3px; + padding: 3px; } -.cartCue{ - height: 100%; +.cartCue { + height: 100%; box-sizing: border-box; - border: 3px solid; - border-radius: 6px; - color: white; + border: 3px solid; + border-radius: 6px; + color: white; } -.cartCue p{ - margin: 10px; +.cartCue p { + margin: 10px; } -.cartCueIcon{ +.cartCueIcon { position: absolute; - right: 13px; - top: 13px; + right: 13px; + top: 13px; } -.cartColor-red{ - border-color: #ff4242; - background-color: #9b3726; +.cartColor-red { + border-color: #ff4242; + background-color: #9b3726; } -.cartColor-orange{ - border-color: #ffa500; +.cartColor-orange { + border-color: #ffa500; background-color: #ad6026; } -.cartColor-green{ - border-color: #01d52f; +.cartColor-green { + border-color: #01d52f; background-color: #397f27; } -.cartColor-blue{ - border-color: #536de0; +.cartColor-blue { + border-color: #536de0; background-color: #304893; } -.cartColor-purple{ - border-color: #a601c0; +.cartColor-purple { + border-color: #a601c0; background-color: #592d74; } -.cartColor-none{ - border-color: #95929f; - background-color: #3b3b3b +.cartColor-none { + border-color: #95929f; + background-color: #3b3b3b; } -.cartBlank{ - border-color: #1f1f1f; +.cartBlank { + border-color: #1f1f1f; background-color: #1f1f1f; } -.cartCueWrapper.playback-position .cartCue{ - border-color: #88b3db; - outline: #88b3db 1px solid; +.cartCueWrapper.playback-position .cartCue { + border-color: #88b3db; + outline: #88b3db 1px solid; box-shadow: 0px 0px 3px 3px #88b3db, inset 0px 0px 5px #88b3db; } - @media screen and (min-width: 0px) and (max-width: 750px) { .hide-medium { display: none; diff --git a/plugins/qlab/tile.ejs b/plugins/qlab/tile.ejs index 7d8a128..ca8e9e2 100644 --- a/plugins/qlab/tile.ejs +++ b/plugins/qlab/tile.ejs @@ -14,26 +14,24 @@ left = (cue.cartPosition[1]-1)*width; } + let style = `style="left:${left}%; top:${top}px; width:${width }%; height:${height}px;"`; + %> -
+
> -
- <% if(cue.broken){ %> - - <% }else if(cue.running){ %> - - <% }else{ %> - - <% } %> -
-
-

<%= cue.number %> • <%= cue.displayName %>

-
+
+ <% if(cue.broken){ %> + + <% }else if(cue.running){ %> + + <% }else{ %> + + <% } %> +
-
\ No newline at end of file +
+

<%= cue.number %> • <%= cue.displayName %>

+
+ +
\ No newline at end of file diff --git a/plugins/sacn/icon.png b/plugins/sacn/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ef9783e7b8c68affa873280ff149aa65b5c4ff11 GIT binary patch literal 713 zcmV;)0yh1LP)0C;aOEuY_rcEvxcLAgQxzOrOyG7xlM~MOz+@a=zAepJPeUwT-YGy&CtL`? z(I&8%!B!)rh~U@^JPg5^6YwPg$yIfLnwC@WH33E=gvKB`E2M~@8o+3RUN0n;;oYQu zFo3re>UYC%7&2=b!CN2=b1XM;@K*+GfZP4h>5+uy6`qD0gJoYr-SJ5;bhm8|Y_+H^ zse@DbZeB{l`zT~Jwt}KSM>Evgi#2qC3mTt-)7P~@3knTDZ})~NvYoSORd(!cf#-Mh ze`;xPp)qRh5a`kdRjZ*3{Azr|=Fp_@wCa+ElWR*45bXtIrDDebz7Fsll&|bQ0LR-^ z5u#(89WDl-&kvt}!2KuiA*v7B-VB$6aHs(ukHDiB!c9g5A8v%J=fLBF8WZfa!SnQ v9u>(AsiG3=kldd{Y7JIW#aKeycIWyB>z4o00000NkvXXu0mjfW2Qj- literal 0 HcmV?d00001 diff --git a/plugins/sacn/icon.psd b/plugins/sacn/icon.psd new file mode 100644 index 0000000000000000000000000000000000000000..9e2d797a92c6caf9c727bf069fae578e4ac3d58a GIT binary patch literal 25792 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 literal 0 HcmV?d00001 diff --git a/plugins/sacn/info.html b/plugins/sacn/info.html new file mode 100644 index 0000000..4e4c755 --- /dev/null +++ b/plugins/sacn/info.html @@ -0,0 +1 @@ +

sACN requires no configuration.

\ No newline at end of file diff --git a/plugins/sacn/main.js b/plugins/sacn/main.js new file mode 100644 index 0000000..bf9f3a0 --- /dev/null +++ b/plugins/sacn/main.js @@ -0,0 +1,158 @@ +const _ = require('lodash'); + +exports.defaultName = 'sACN Universe'; +exports.connectionType = 'multicast'; +exports.defaultPort = 5568; +exports.heartbeatInterval = 5000; +exports.searchOptions = { + type: "multicast", + address: getMulticastGroup(1), + port: 5568, + validateResponse (msg, info) { + return msg.toString('utf8', 4, 13) === "ASC-E1.17"; + }, +}; +exports.defaultPort = 5568; + +exports.ready = function ready(device) { + + const d = device; + d.data.universes = {}; + d.data.source = "Unknown Source"; + d.data.orderedUniverses = []; + + // device.draw(); + for(let i = 1; i <= 16; i++){ + d.connection.addMembership(getMulticastGroup(i)); + } + +}; + + +exports.data = function data(device, buf) { + + const univ = buf.readUInt16BE(113); + const d = device; + + let u = d.data.universes[univ]; + + if(!u){ + d.data.universes[univ] = {}; + u = d.data.universes[univ]; + } + + u.sequence = buf.readUInt8(111); + u.priority = buf.readUInt8(108); + u.cid = buf.toString('hex', 22, 38); + u.slots = Array.prototype.slice.call(buf, 126); + if(buf.readUInt8(125) !== 0){ + u.startCode = buf.readUInt8(125); + } + + + d.data.source = buf.toString('utf8', 44, 108); + d.displayName = `${d.data.source} sACN`; + d.data.ip = d.addresses[0]; + + if(!_.includes(d.data.orderedUniverses, univ)){ + d.data.orderedUniverses.push(univ); + d.data.orderedUniverses.sort(); + u.slotElems = []; + u.slotElemsSet = false; + + d.draw(); + updateElementsCache(d, d.data.universes, d.data.orderedUniverses); + + } + + d.update("universeData", { + u: univ, + universe: u, + startCode: u.startCode + }); + +}; + + +exports.heartbeat = function heartbeat(device) { + +}; + + + +let lastUpdate = Date.now(); +exports.update = function update(device, doc, updateType, updateData){ + + const d = device; + const data = updateData; + + if(updateType === "universeData" && data.universe){ + + if(Date.now() - lastUpdate > 1000){ + lastUpdate = Date.now(); + updateElementsCache(d, d.data.universes, d.data.orderedUniverses); + } + + const $elem = doc.getElementById(`universe-${data.u}`); + + if($elem && data.universe.slotElemsSet){ + + if(data.universe.priority > 0){ + for(let i = 0; i < 512; i++){ + data.universe.slotElems[i].innerText = data.universe.slots[i]; + } + + const $code = doc.getElementById(`universe-${data.u}-code`); + if(data.startCode === 0xDD){ + $code.innerText = "Net3" + }else if(data.startCode === 0x17){ + $code.innerText = "Text" + }else if(data.startCode === 0xCF){ + $code.innerText = "SIP" + }else if(data.startCode === 0xCC){ + $code.innerText = "RDM" + } + + } + + }else{ + d.draw(); + updateElementsCache(d, d.data.universes, d.data.orderedUniverses); + } + + }else if(updateType === "elementCache"){ + + data.orderedUniverses.forEach(univ => { + for(let i = 0; i < 512; i++){ + data.universes[univ].slotElems[i] = doc.getElementById(`${univ}-${i}`); + } + data.universes[univ].slotElemsSet = true; + }); + + } + + +} + + +function updateElementsCache(device, univ, ordered){ + device.update("elementCache", { + universes: univ, + orderedUniverses: ordered + }); +} + + + + + + + +// From https://github.com/hhromic/e131-node/blob/master/lib/e131.js +function getMulticastGroup(universe) { + if (universe < 1 || universe > 63999) { + throw new RangeError('universe should be in the range [1-63999]'); + } + return `239.255.${universe >> 8}.${universe & 0xff}`; + +} \ No newline at end of file diff --git a/plugins/sacn/styles.css b/plugins/sacn/styles.css new file mode 100644 index 0000000..47209a9 --- /dev/null +++ b/plugins/sacn/styles.css @@ -0,0 +1,29 @@ +table { + margin-bottom: 50px; + background-color: #333; +} +td, +th { + width: 35px; +} +td { + background-color: black; + text-align: center; + border-radius: 3px; + color: white; + font-size: 13px; +} +th { + background-color: #222; + color: #ccc; + font-size: 11px; +} +td.data { + padding: 7px; + font-size: 12px; + text-align: left; +} +td.data em { + font-size: 14px; + color: #ff0033; +} diff --git a/plugins/sacn/template.ejs b/plugins/sacn/template.ejs new file mode 100644 index 0000000..de4a90a --- /dev/null +++ b/plugins/sacn/template.ejs @@ -0,0 +1,58 @@ +
+

<%= data.source %> sACN (E1.31)

+
+ + +
+<% data.orderedUniverses.forEach(univ => { + let universe = data.universes[univ]; +%> + + + + + + + + + + + + + <% for(col=1; col<=16; col++){ %> + + <% } %> + + + <% let slot = 0; %> + <% for(row=0; row<32; row++){ %> + + + <% for(col=0; col<16; col++){ %> + <% slot++%> + + <% } %> + + <% } %> + + +
+ Universe +
<%= univ %> +
+ Priority +
<%= universe.priority %> +
+ CID +
<%= universe.cid %> +
+ IP +
<%= data.ip %> +
+ Flavor +
0 +
<%= col %>
<%= row*16+1 %><%= universe.slots[slot-1] %>
+ +<% }); %> + +
\ No newline at end of file diff --git a/plugins/watchout/info.html b/plugins/watchout/info.html new file mode 100644 index 0000000..e69de29 diff --git a/plugins/watchout/main.js b/plugins/watchout/main.js index 1c43cca..0f4c7dd 100644 --- a/plugins/watchout/main.js +++ b/plugins/watchout/main.js @@ -5,47 +5,49 @@ exports.searchOptions = { type: 'TCPport', searchBuffer: Buffer.from('authenticate 1\n', 'ascii'), testPort: 3040, - validateResponse: function (msg, info) { - return msg.toString().substring(0, 5) == 'Ready'; + validateResponse (msg, info) { + return msg.toString().substring(0, 5) === 'Ready'; }, }; exports.defaultPort = 3040; -exports.ready = function (device) { +exports.ready = function ready(device) { device.send('authenticate 1\n'); }; -exports.data = function (device, message) { +exports.data = function data(device, message) { const msg = message.toString(); - if (msg.substring(0, 5) == 'Ready') { - device.send('getStatus\n'); - } - if (msg.substring(0, 5) == 'Reply') { + const d = device; + + if (msg.substring(0, 5) === 'Ready') { + d.send('getStatus\n'); + + }else if (msg.substring(0, 5) === 'Reply') { const arr = msg.split(' '); - device.data.showName = ''; + d.data.showName = ''; let i = 0; - while (arr[i][arr[i].length - 1] != '"') { + while (arr[i][arr[i].length - 1] !== '"') { i++; - device.data.showName += `${arr[i]} `; + d.data.showName += `${arr[i]} `; } - device.data.showName = device.data.showName.substring( + d.data.showName = d.data.showName.substring( 1, - device.data.showName.length - 2 + d.data.showName.length - 2 ); i--; - device.data.busy = arr[i + 2]; - device.data.health = arr[i + 3]; - device.data.displayOpen = arr[i + 4]; - device.data.showActive = arr[i + 5]; - device.data.programmerOnline = arr[i + 6]; - device.data.position = Number(arr[i + 7]).toFixed(2); - device.data.rate = arr[i + 8]; - device.data.standby = arr[i + 9]; + d.data.busy = arr[i + 2]; + d.data.health = arr[i + 3]; + d.data.displayOpen = arr[i + 4]; + d.data.showActive = arr[i + 5]; + d.data.programmerOnline = arr[i + 6]; + d.data.position = Number(arr[i + 7]).toFixed(2); + d.data.rate = arr[i + 8]; + d.data.standby = arr[i + 9]; - this.deviceInfoUpdate(device, 'defaultName', device.data.showName); - device.draw(); + this.deviceInfoUpdate(d, 'defaultName', d.data.showName); + d.draw(); } // if(msg.substring(0, 5)=="Error"){ // device.data.error = msg.substring(6, 7); @@ -53,6 +55,6 @@ exports.data = function (device, message) { // console.log(msg) }; -exports.heartbeat = function (device) { +exports.heartbeat = function heartbeat(device) { device.send('getStatus\n'); }; diff --git a/plugins/x32/info.html b/plugins/x32/info.html new file mode 100644 index 0000000..e69de29 diff --git a/plugins/x32/main.js b/plugins/x32/main.js index 7e20e5b..4d41dda 100644 --- a/plugins/x32/main.js +++ b/plugins/x32/main.js @@ -6,24 +6,25 @@ exports.searchOptions = { searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]), devicePort: 10023, listenPort: 0, - validateResponse: function (msg, info) { - return msg.toString().indexOf('/xinfo') == 0; + validateResponse (msg, info) { + return msg.toString().indexOf('/xinfo') === 0; }, }; exports.defaultPort = 10023; -exports.ready = function (device) { - device.data.channelFaders = new Array(32).fill(0); - device.data.channelFadersDB = new Array(32).fill(0); - device.data.channelMutes = new Array(32).fill(0); - device.data.channelNames = new Array(32).fill('end'); - device.data.channelColors = new Array(32); +exports.ready = function ready(device) { + const d = device; + d.data.channelFaders = new Array(32).fill(0); + d.data.channelFadersDB = new Array(32).fill(0); + d.data.channelMutes = new Array(32).fill(0); + d.data.channelNames = new Array(32).fill('end'); + d.data.channelColors = new Array(32); - device.data.stereoFader = 0; - device.data.stereoFaderDB = 0; - device.data.stereoMute = 0; + d.data.stereoFader = 0; + d.data.stereoFaderDB = 0; + d.data.stereoMute = 0; - device.send(Buffer.from('/xinfo')); + d.send(Buffer.from('/xinfo')); // device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); // device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); @@ -40,31 +41,33 @@ function parseAddress(msg) { function convertToDBTheBehringerWay(f) { if (f >= 0.5) { return f * 40 - 30; - } else if (f >= 0.25) { - return f * 80 - 50; - } else if (f >= 0.0625) { - return f * 160 - 70; - } else { - return f * 480 - 90; } + if (f >= 0.25) { + return f * 80 - 50; + } + if (f >= 0.0625) { + return f * 160 - 70; + } + return f * 480 - 90; } -exports.data = function (device, buf) { +exports.data = function data(device, buf) { this.deviceInfoUpdate(device, 'status', 'ok'); const msg = buf.toString().split('\u0000\u0000'); + const d = device; - if (msg[0] == '/xinfo') { + if (msg[0] === '/xinfo') { this.deviceInfoUpdate(device, 'defaultName', msg[4]); - device.data.name = msg[4]; - device.data.ip = msg[2]; - device.data.firmware = msg[7]; - device.data.model = msg[5]; + d.data.name = msg[4]; + d.data.ip = msg[2]; + d.data.firmware = msg[7]; + d.data.model = msg[5]; - device.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000')); - device.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000')); + d.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000')); + d.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000')); for (let i = 0; i <= 32; i++) { - device.send( + d.send( Buffer.from( `/ch/${i .toString() @@ -72,59 +75,59 @@ exports.data = function (device, buf) { ) ); } - device.draw(); - } else if (msg[0] == '/meters/0') { + d.draw(); + } else if (msg[0] === '/meters/0') { // console.log(msg) } else if (msg[0].indexOf('/mix/fader') >= 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - if (addr[0] == 'ch') { - device.data.channelFaders[channel - 1] = buf.readFloatBE(24); - device.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay( + if (addr[0] === 'ch') { + d.data.channelFaders[channel - 1] = buf.readFloatBE(24); + d.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay( buf.readFloatBE(24) ); - } else if (addr[0] == 'lr') { - device.data.stereoFader = buf.readFloatBE(20); - device.data.stereoFaderDB = convertToDBTheBehringerWay( + } else if (addr[0] === 'lr') { + d.data.stereoFader = buf.readFloatBE(20); + d.data.stereoFaderDB = convertToDBTheBehringerWay( buf.readFloatBE(20) ); } - device.draw(); + d.draw(); } else if (msg[0].indexOf('/mix/on') >= 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - if (addr[0] == 'ch') { - device.data.channelMutes[channel - 1] = buf[23]; - } else if (addr[0] == 'lr') { - device.data.stereoMute = buf[19]; + if (addr[0] === 'ch') { + d.data.channelMutes[channel - 1] = buf[23]; + } else if (addr[0] === 'lr') { + d.data.stereoMute = buf[19]; } - device.draw(); - device.send( + d.draw(); + d.send( Buffer.from(`/ch/${addr[1]}/mix/fader\u0000\u0000\u0000\u0000`) ); } else if (msg[0].indexOf('/config/name') > 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - device.data.channelNames[channel - 1] = msg[2]; - device.draw(); - device.send( + d.data.channelNames[channel - 1] = msg[2]; + d.draw(); + d.send( Buffer.from(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`) ); } else if (msg[0].indexOf('/config/color') > 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - device.data.channelColors[channel - 1] = buf.readInt8(27); - device.draw(); - device.send(Buffer.from(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`)); + d.data.channelColors[channel - 1] = buf.readInt8(27); + d.draw(); + d.send(Buffer.from(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`)); } else { // console.log(msg) } // console.log(msg) }; -exports.heartbeat = function (device) { +exports.heartbeat = function heartbeat(device) { device.send(Buffer.from('/xremote')); }; diff --git a/plugins/xair/info.html b/plugins/xair/info.html new file mode 100644 index 0000000..e69de29 diff --git a/plugins/xair/main.js b/plugins/xair/main.js index 377632b..3c759c7 100644 --- a/plugins/xair/main.js +++ b/plugins/xair/main.js @@ -6,24 +6,25 @@ exports.searchOptions = { searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]), devicePort: 10024, listenPort: 0, - validateResponse: function (msg, info) { - return msg.toString().indexOf('/xinfo') == 0; + validateResponse (msg, info) { + return msg.toString().indexOf('/xinfo') === 0; }, }; exports.defaultPort = 10024; -exports.ready = function (device) { - device.data.channelFaders = new Array(32).fill(0); - device.data.channelFadersDB = new Array(32).fill(0); - device.data.channelMutes = new Array(32).fill(0); - device.data.channelNames = new Array(32).fill('end'); - device.data.channelColors = new Array(32); +exports.ready = function ready(device) { + const d = device; + d.data.channelFaders = new Array(32).fill(0); + d.data.channelFadersDB = new Array(32).fill(0); + d.data.channelMutes = new Array(32).fill(0); + d.data.channelNames = new Array(32).fill('end'); + d.data.channelColors = new Array(32); - device.data.stereoFader = 0; - device.data.stereoFaderDB = 0; - device.data.stereoMute = 0; + d.data.stereoFader = 0; + d.data.stereoFaderDB = 0; + d.data.stereoMute = 0; - device.send('/xinfo'); + d.send('/xinfo'); // device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); // device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")); @@ -40,36 +41,38 @@ function parseAddress(msg) { function convertToDBTheBehringerWay(f) { if (f >= 0.5) { return f * 40 - 30; - } else if (f >= 0.25) { - return f * 80 - 50; - } else if (f >= 0.0625) { - return f * 160 - 70; - } else { - return f * 480 - 90; } + if (f >= 0.25) { + return f * 80 - 50; + } + if (f >= 0.0625) { + return f * 160 - 70; + } + return f * 480 - 90; } -exports.data = function (device, buf) { +exports.data = function data(device, buf) { this.deviceInfoUpdate(device, 'status', 'ok'); const msg = buf.toString().split('\u0000'); + const d = device; - if (msg[0] == '/xinfo') { + if (msg[0] === '/xinfo') { if (msg[7].length > 0) { - device.data.name = msg[7]; + d.data.name = msg[7]; } else { - device.data.name = msg[6]; + d.data.name = msg[6]; } - device.data.ip = msg[5]; - device.data.firmware = msg[13]; - device.data.model = msg[9]; - this.deviceInfoUpdate(device, 'defaultName', device.data.name); + d.data.ip = msg[5]; + d.data.firmware = msg[13]; + d.data.model = msg[9]; + this.deviceInfoUpdate(d, 'defaultName', d.data.name); - device.send('/lr/mix/fader\u0000\u0000\u0000\u0000'); - device.send('/lr/mix/on\u0000\u0000\u0000\u0000'); + d.send('/lr/mix/fader\u0000\u0000\u0000\u0000'); + d.send('/lr/mix/on\u0000\u0000\u0000\u0000'); for (let i = 0; i <= 32; i++) { - device.send( + d.send( Buffer.from( `/ch/${i .toString() @@ -77,55 +80,60 @@ exports.data = function (device, buf) { ) ); } - device.draw(); - } else if (msg[0] == '/meters/0') { + d.draw(); + + } else if (msg[0] === '/meters/0') { // console.log(msg) } else if (msg[0].indexOf('/mix/fader') >= 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - if (addr[0] == 'ch') { - device.data.channelFaders[channel - 1] = buf.readFloatBE(24); - device.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay( + if (addr[0] === 'ch') { + d.data.channelFaders[channel - 1] = buf.readFloatBE(24); + d.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay( buf.readFloatBE(24) ); - } else if (addr[0] == 'lr') { - device.data.stereoFader = buf.readFloatBE(20); - device.data.stereoFaderDB = convertToDBTheBehringerWay( + } else if (addr[0] === 'lr') { + d.data.stereoFader = buf.readFloatBE(20); + d.data.stereoFaderDB = convertToDBTheBehringerWay( buf.readFloatBE(20) ); } - device.draw(); + d.draw(); + } else if (msg[0].indexOf('/mix/on') >= 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - if (addr[0] == 'ch') { - device.data.channelMutes[channel - 1] = buf[23]; - } else if (addr[0] == 'lr') { - device.data.stereoMute = buf[19]; + if (addr[0] === 'ch') { + d.data.channelMutes[channel - 1] = buf[23]; + } else if (addr[0] === 'lr') { + d.data.stereoMute = buf[19]; } device.draw(); device.send(`/ch/${addr[1]}/mix/fader\u0000\u0000\u0000\u0000`); + } else if (msg[0].indexOf('/config/name') > 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - device.data.channelNames[channel - 1] = msg[4]; - device.draw(); - device.send(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`); + d.data.channelNames[channel - 1] = msg[4]; + d.draw(); + d.send(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`); + } else if (msg[0].indexOf('/config/color') > 0) { const addr = parseAddress(msg[0]); const channel = Number(addr[1]); - device.data.channelColors[channel - 1] = buf.readInt8(27); - device.draw(); - device.send(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`); + d.data.channelColors[channel - 1] = buf.readInt8(27); + d.draw(); + d.send(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`); + } else { // console.log(msg) } // console.log(msg) }; -exports.heartbeat = function (device) { +exports.heartbeat = function heartbeat(device) { device.send('/xremote'); };