From 45a6d59b5e2fbcab8ec6a4268769ecbc7409f4b0 Mon Sep 17 00:00:00 2001 From: Marek Frniak Date: Thu, 10 Sep 2026 21:39:00 +0200 Subject: [PATCH] kick1 - priebezne stabilne - pred velkym zadanim --- .../Debug/net472/AppDiagnostic.Logging.dll | Bin 12800 -> 12800 bytes .../Debug/net472/AppDiagnostic.Logging.pdb | Bin 5404 -> 5404 bytes .../Release/net472/AppDiagnostic.Logging.dll | Bin 11776 -> 12288 bytes .../Release/net472/AppDiagnostic.Logging.pdb | Bin 4476 -> 4764 bytes .../AppDiagnostic.Logging.AssemblyInfo.cs | 2 +- ...iagnostic.Logging.AssemblyInfoInputs.cache | 2 +- .../Debug/net472/AppDiagnostic.Logging.dll | Bin 12800 -> 12800 bytes .../Debug/net472/AppDiagnostic.Logging.pdb | Bin 5404 -> 5404 bytes .../AppDiagnostic.Logging.AssemblyInfo.cs | 2 +- ...iagnostic.Logging.AssemblyInfoInputs.cache | 2 +- ...tic.Logging.csproj.AssemblyReference.cache | Bin 5278 -> 6197 bytes ...tic.Logging.csproj.CoreCompileInputs.cache | 2 +- .../Release/net472/AppDiagnostic.Logging.dll | Bin 11776 -> 12288 bytes .../Release/net472/AppDiagnostic.Logging.pdb | Bin 4476 -> 4764 bytes .../API/InterfaceGCIToLaatzen.cs | 41 ++- .../Core/Threading/ApiWorker/ApiWorker.cs | 168 ++++++++- .../GenesisCommunicationSeq.cs | 134 ++++++- ...isCommunicationDiagnosticsForm.Designer.cs | 346 ++++++++++++++++++ .../UI/GenesisCommunicationDiagnosticsForm.cs | 78 ++++ .../GenesisCommunicationDiagnosticsForm.resx | 61 +++ TBF/TBF.csproj | 17 +- TBF/UI/MainWnd.cs | 2 +- 22 files changed, 823 insertions(+), 34 deletions(-) create mode 100644 TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.Designer.cs create mode 100644 TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.cs create mode 100644 TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.resx diff --git a/AppDiagnostic.Logging/bin/Debug/net472/AppDiagnostic.Logging.dll b/AppDiagnostic.Logging/bin/Debug/net472/AppDiagnostic.Logging.dll index fa3b3ef1cdf5b1c762785d7455d09bfabfd84e88..178529b66e5d0e8d2fed52e6c967204c3d4e3e79 100644 GIT binary patch delta 234 zcmZojX-JvS!J?R++qSVMLsek8RBXV;S5w`lXok!V@~qgfnMEz0S;O2o*&;19IVH`= zEH%~Kz$7Wj)FRC|$t*F&B+=N|+%m;HIV~yGBx!QD<|gJo!CjLbv;qWdCzu%i(LU?m z>2_xxmvCM1UKNfb3KTa|Qzj6NV%pGzH5W16gJai9j_bK++fp%^56#JaeGFG@x86NcHCB H`jJckBsoUl delta 234 zcmZojX-JvS!E%X{=i$bl3{`>H%V`&FOaA!u{aC-=R65;qGmBb0vxZ@^S(;^Hno&}c zS+aRbim8P~s#%&rN@9{hqLGEMS*nSFWwK$KrSar$%}vZ({7y}F&J!NkC`@6f F1ORCfPICYN diff --git a/AppDiagnostic.Logging/bin/Debug/net472/AppDiagnostic.Logging.pdb b/AppDiagnostic.Logging/bin/Debug/net472/AppDiagnostic.Logging.pdb index c8da8e1d13d79209e75572351619f2cc8916f571..5325f29ac4e8c3140b81861daccb536f525a7a16 100644 GIT binary patch delta 69 zcmV-L0J{I2Dx4~id=x#9G%@@u%}0qw+@1;(ep70W5xTLEBMBg$Z;NxL5k}qJTptTz bkb}~a#bwI&sgh4m(cXl+c-UHiQ^ zW5?Nrf%*FX{`dat9ev7o-t2d?nbyD0ger!w>wk+iu}1#|Hj~Zrr&x8#NqCT- z75H)r&}qbYww#FhRWm!%rL6&a2_uXsItI|KB3n4joknE25kOsws82;9gv=p~4|)#d z=D@EWfKf_Awsl!`zMMM*zk^;tYGVVQxBA06VV`kY@(H zB0PiMbf7s_3>+(wilKh#b%xZsr9ig~Fl8CdLbwQMz1t`YK(d@ndh!{vKxtO00z(;D zQe$Z=r(Mu-6v>r-KSZ6om7Arz7{KDftHN_XO41=$OIe3JWeLRbYQW#+syGp07P#uO3}b(+@#YGe0jNjKOOQRjX|ir5iR$M?#$@vtRQ zmTTi-H>4R3t~w`UZE`ZUL@H-P?yGCj>kFC!Zu?)%s8lYzIZ(Eknl~5ErVv+L^X7rc zt&l!Cl$mnjbt+lZXMM=wj`z+fLF(Hz2#$VXS^itDhoi<6fV$ac__|1=-Ch$ZpK8 z0=4Gcy%A%L@;DOJQ^}2_;p8G2jk=)0ULl#QJ9f2%g)s6K0qmw}hPN0(h?_#*KxDWC zwB;jp;tj9H_X2fkEV3#v1D{AV+B8hu#Wh6@CTh^+F%eU{MsNw3+=Qa0m?cKA4Xh_a-D_cuR?FtC>&PQv}^I zzd}@`F#~nUTXjtX$>!2LE&KGA!y0A@?xI-;K6D4JHFt54gu6mkXl6-MKwY!q7)o21 z!lGIG;TaDAx zG`9}xZizofyKprcl_uS~EsehIPLcacVXU z4#Y40;EI%ixbEP5tz%(m#)p<{NKrqQ90ptt!7IJzjVw;ft<)Y^i+ zrGH|DY0|E?ELspeg3*=wK10yoniBs@;Xf#R$dI6HQQ<`vapHW2VK>8vcs{#_A z4i*Om?J|~N(tyGl)(WJu1+FcsKq?l!6FLR_t-`1wL$+!%SYzJxNXS&K`+`zV*%I#z z$voiVzTCk>A~PucyOyEn<)NVu{nwzDE>V*meGq@W=?9IV5b#JA246gBA{n;gN>m< zEYh1fHb2C`-pR4=Sc6!;_j2rq76ZGOV{XXt)? z4iC^i{7wK%lZinbomxr9>9c@j`*Q40w15jLMq86(7v(%UlVer5L?-EIHFE4#97U6= z6gyzvLC3%va_nAO%uSk|V+T=vkQU@v`cYILq$N4}76vU^m1Dogm_-|N>@oaiv1v<= z{QzrbQzFM~y%QaxKgVY15wJUR?2_ojK^x04!-#-AkYoRu=A9I#zsb=*@(9=?Ikw8| z#NB@)$GXi3*kqQe9gWZr6?>TK#R^!q;+KUy39Vu+kJ9NJ`#0Lm9V&CPV{g+oUO>AP zn;<7I-Ny^*@hnw`20tiKS)TY}d*y`rLw7?g&itO^7J z5;;8|3exX`jG{n6B|wWBfOv%}oUd?^!Y+mD6m~1TL*WsipidPtCgmzN60D#G_MA~i zNu^IxdOlt$Z7hSGo{vcp8l~4mZP46>laQp#_I1?7UgI|bKNdGZ<7r)RamM%>@Bw=( zoZc3SQ(Ud3o>{{u11vAEQxrP#PNq9bXF@-L zMu)tJZ3>=+yvlqX$vuK27^0ui+rVzz6ody(P+chf0aP-(g9_W2ypAC%(f&XM^kLA( zPn&x~rEG%zG4wS3g0^e*Y?AfpA3$!G$+0}(ID47TW{;w#4&Zw>qY_o|S+$~3wfJwc zbM|@`Wmev8>=#${$uxVD{nQ?07uXzojFqta_4|QOBD)K0HvKi^)AShot#a`xyIK1l z3qt;T7N#w9hMBaTE&+EE#|_^_25=9B_$*w_{lI)W04$}Wz#4i6*hHTL+iAKsi@r*= zT6z{Op*E0JYG4Dfhi<2DXc_9Egmxe820o$WNlMXv?X;55LO!IOSMo=Y596&O=LcDe zp4DPXu2R?l&5yK&N?xR}3z~n{wktWFR*xi9?`z{qJ_z}D+7TuHNZ|#A42dPQDus&_ z#ua81jw^gZ;c12E6_O^cVhR^3+^#UA@Chv~hfgbVULonqK;c4#+Z7g4FAdX^^bY-o zVyu}hVJp}+b{F#*N=L5`;6}fy4dSQL+R!lY9ZTXp3J=iTkiV-&FDiVBauCSTn1hgQAjeU)Ar}HU6`{Q{yu9-u7o%h1 zFakNvKsRAH3sJ~rI2nw}frwuLLq?TAPB9oVyyK@su7)9_8sOceu>z)NWP`f)vkP5P zzee#KTcemaPlEaq!`p6-_a`Xjzc&5F(6Z#f&W-UQXcvzjA20p`vu|GQ_03x14fH1a{JUmM z2A0K#<9qzd(v$7dG&?Xd6dz7{1C;uI8W{KCm-Lls$Iq4C#Y`yI#0TPi{>t*&!1_dA zGUb1x{7z@l;NVTkc;A4R8cz1WVjyw+m*qpOXnmqbgw!ZkztigPTY{}AKa7hdt!IWB`uBnml{hr&G)y|be2$IE$yX# z!V2KOIQ2o=Poy>a(W>XuyYF4|$m6$^tvt2#ABSdqw(eEZV~m+vj936dG%9J>H1sm= z%yrQ6I4g^AEWI;V#F&$LG>iwHM_>^)Vw{Dc(}j~cnitcdKdSzJG>oIkoVoa$fa#FR zbb~pYq?hz27@C^FOi}18Von74JDH~g@Kjc;$0*vb6wgnK=}woEITr1YW?phK&kKV) zk?2+!b2)1(Jcqdm2V$^3s_+Q%4?Eo$bw(lbeEi+dvoV~dsEV5*LyM;S3!OU<)`{3L zR_J72Vflz@D9MSKF_OdigyiHbILoI1LXVm%#=is%t&E!}iHB{}8xBV^zlvrq=msz2 zK|^;k2g`VQK(33Ed8iEL<$)_|CnBJ>$^#rLScYLgT+?b_ijK4FieB=&YLYwTl4!zN zif&5W_$3&X2TW2?orobh0ziRbJT;fX_?o(l zmGg^hPq`iKJ)OOYo}In3=Oq#yt#fwlnA_RgzGGf|=bU(Zd&m5p9X-7}5_5L=musJ# zixakbxZ=me*4)A&KaTI2W%#NeMz|MBOni4N$G5>hS63Z*@wL?r4}83CS?2vW zZg}PP%4XlJpO~Ffo?DnxO5YQ~XHMSN@UzVyH+=u&W3a#S`Kgp+6IDh0YMR_&NEAFKm* Zy%b%7 delta 5216 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 K{)F{a8vg^N>l_;Z diff --git a/AppDiagnostic.Logging/bin/Release/net472/AppDiagnostic.Logging.pdb b/AppDiagnostic.Logging/bin/Release/net472/AppDiagnostic.Logging.pdb index 20f7774dcbba81d19e1a63bf6cf271a20ca32539..84738e995e58888d930259dd615ba0a77d4f806b 100644 GIT binary patch delta 1852 zcmY+Fe@t6d6vxkfeeHX%r7ZP0m=NQSm_;*ZmVk4K#yFS#VPc}mqAq4J>K3E;hcSLnc_nX6KKGvQ zIp^IU=iU4IZ|w+sWl0JQ**Q5Glx>xn#c z2nOb+9l$-eToKh^aC9q315RKA5sWcT3Vn=z8T~)#Z9<_sA!r}^)97c>ub|fzg`QRf z9YHTBRTC7|6nYW#>I#Ly2`~mufivJ0Z~HaYNh9@$W%_~%y4-=QG z1bUsBz`NsnZ~(21#^P!?-kyoK3-SjwJ#`^&KaW<>JX(d$OU<6w*dO8p-5kMUAVu$r#liJEbksNI)s{*QB_-i$UpYSg==$f z|M#UD`la;QgS(c?8-2EGnJpJ5GY)!wf9dh_@_k2osWXv3@rHj(k?maB!-?jU3JNyWeSvVu z#Z5U1g3=|$?Lg;fcsMd-h*+zLb%<{9 delta 1603 zcmZ9MYitx%7>2)Zc6N4Vce}T8>DCsvc1sJf80ke6*S54(E5%S(N)QcLh;5_kQd-f* zz;;c{DmRq_5lu~qkZ6O^AQBU$k&6LJLZUH2|A;>jf&@%V{N*M3e$$y|;%uIC&U4-~ zb7sz**@>FJ?|Q2-zgs7&-a$0rCpt)IXGgaV4)u?qNn{Wqrs_3W($QWm?MK#hb)bF{ zUKfI|cp=vZZ@hZB{?~7QYu$U}m+6Vh=k`yYEIW*DT3h*nWuaz}0hor$K^>S!6roj4 z=Q7mcw@)|ZabY{X2Xz7jfDa7g8n2K>pP`;Y{SRuBHELm|$500xGq?_JgFocSar1v!K6)nTBL&WbTOb)?EH2|G#{ih|JX0L97-%*#1Kd@R=aRz& z@@`z0T-Mfg$z>&7mt1gNa=~@UkVYPMR&YQ(?{w5cT0jlF#2Fxe01M$!$6MjG z@R;MWX~h$8{5ROEQ3o$|a=Cdq`t5R?UA}3T@?w})pu`G2h)ScGpw|xGuzLzB>#ttE z(eBCFJ&aOLJQ$E~MgAq2vO)O{WbfBvH)OP0d>1e3hmkH+@9ZXH{)X(Z@gV0=QI4RmSaS5(Ao<3(zxfti-0xs5Yv7L*(T-?aTEnF<9y6F8?SctNQ5<~0Nu~}P8yxe+? zLVB}K^~AxkMxS~$y3{weURPg4*Rx-h#+I?6x?`OjQ2Sy{Y^n>fkJwVf@pTsF=;fXF ZHU-u9@g@!_E78E3$|TYpR(**F{sUEZztsQ$ diff --git a/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfo.cs b/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfo.cs index d8bf95e08..e08d8f20a 100644 --- a/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfo.cs +++ b/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("AppDiagnostic.Logging")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8c77df207addcf9ed024240630cb0c32c1fde253")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+73c8fecdf26ee704bb58f3b6ad4a3379d7cfbe4b")] [assembly: System.Reflection.AssemblyProductAttribute("AppDiagnostic.Logging")] [assembly: System.Reflection.AssemblyTitleAttribute("AppDiagnostic.Logging")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfoInputs.cache b/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfoInputs.cache index 226b27b48..48beda22d 100644 --- a/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfoInputs.cache +++ b/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfoInputs.cache @@ -1 +1 @@ -310753f2dd2c5b12720ac2b377209bbf1d64c37a00b3b643b72c1104163a0fd7 +dac526eb412111d5458e461c4bd83555b5401d4aabe90cd895bf1756693cdd5a diff --git a/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.dll b/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.dll index fa3b3ef1cdf5b1c762785d7455d09bfabfd84e88..178529b66e5d0e8d2fed52e6c967204c3d4e3e79 100644 GIT binary patch delta 234 zcmZojX-JvS!J?R++qSVMLsek8RBXV;S5w`lXok!V@~qgfnMEz0S;O2o*&;19IVH`= zEH%~Kz$7Wj)FRC|$t*F&B+=N|+%m;HIV~yGBx!QD<|gJo!CjLbv;qWdCzu%i(LU?m z>2_xxmvCM1UKNfb3KTa|Qzj6NV%pGzH5W16gJai9j_bK++fp%^56#JaeGFG@x86NcHCB H`jJckBsoUl delta 234 zcmZojX-JvS!E%X{=i$bl3{`>H%V`&FOaA!u{aC-=R65;qGmBb0vxZ@^S(;^Hno&}c zS+aRbim8P~s#%&rN@9{hqLGEMS*nSFWwK$KrSar$%}vZ({7y}F&J!NkC`@6f F1ORCfPICYN diff --git a/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.pdb b/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.pdb index c8da8e1d13d79209e75572351619f2cc8916f571..5325f29ac4e8c3140b81861daccb536f525a7a16 100644 GIT binary patch delta 69 zcmV-L0J{I2Dx4~id=x#9G%@@u%}0qw+@1;(ep70W5xTLEBMBg$Z;NxL5k}qJTptTz bkb}(=9Q!t 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 Zy%b%7 delta 5216 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 K{)F{a8vg^N>l_;Z diff --git a/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.pdb b/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.pdb index 20f7774dcbba81d19e1a63bf6cf271a20ca32539..84738e995e58888d930259dd615ba0a77d4f806b 100644 GIT binary patch delta 1852 zcmY+Fe@t6d6vxkfeeHX%r7ZP0m=NQSm_;*ZmVk4K#yFS#VPc}mqAq4J>K3E;hcSLnc_nX6KKGvQ zIp^IU=iU4IZ|w+sWl0JQ**Q5Glx>xn#c z2nOb+9l$-eToKh^aC9q315RKA5sWcT3Vn=z8T~)#Z9<_sA!r}^)97c>ub|fzg`QRf z9YHTBRTC7|6nYW#>I#Ly2`~mufivJ0Z~HaYNh9@$W%_~%y4-=QG z1bUsBz`NsnZ~(21#^P!?-kyoK3-SjwJ#`^&KaW<>JX(d$OU<6w*dO8p-5kMUAVu$r#liJEbksNI)s{*QB_-i$UpYSg==$f z|M#UD`la;QgS(c?8-2EGnJpJ5GY)!wf9dh_@_k2osWXv3@rHj(k?maB!-?jU3JNyWeSvVu z#Z5U1g3=|$?Lg;fcsMd-h*+zLb%<{9 delta 1603 zcmZ9MYitx%7>2)Zc6N4Vce}T8>DCsvc1sJf80ke6*S54(E5%S(N)QcLh;5_kQd-f* zz;;c{DmRq_5lu~qkZ6O^AQBU$k&6LJLZUH2|A;>jf&@%V{N*M3e$$y|;%uIC&U4-~ zb7sz**@>FJ?|Q2-zgs7&-a$0rCpt)IXGgaV4)u?qNn{Wqrs_3W($QWm?MK#hb)bF{ zUKfI|cp=vZZ@hZB{?~7QYu$U}m+6Vh=k`yYEIW*DT3h*nWuaz}0hor$K^>S!6roj4 z=Q7mcw@)|ZabY{X2Xz7jfDa7g8n2K>pP`;Y{SRuBHELm|$500xGq?_JgFocSar1v!K6)nTBL&WbTOb)?EH2|G#{ih|JX0L97-%*#1Kd@R=aRz& z@@`z0T-Mfg$z>&7mt1gNa=~@UkVYPMR&YQ(?{w5cT0jlF#2Fxe01M$!$6MjG z@R;MWX~h$8{5ROEQ3o$|a=Cdq`t5R?UA}3T@?w})pu`G2h)ScGpw|xGuzLzB>#ttE z(eBCFJ&aOLJQ$E~MgAq2vO)O{WbfBvH)OP0d>1e3hmkH+@9ZXH{)X(Z@gV0=QI4RmSaS5(Ao<3(zxfti-0xs5Yv7L*(T-?aTEnF<9y6F8?SctNQ5<~0Nu~}P8yxe+? zLVB}K^~AxkMxS~$y3{weURPg4*Rx-h#+I?6x?`OjQ2Sy{Y^n>fkJwVf@pTsF=;fXF ZHU-u9@g@!_E78E3$|TYpR(**F{sUEZztsQ$ diff --git a/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs b/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs index b4bca85a0..ca2c7d263 100644 --- a/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs +++ b/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs @@ -282,7 +282,7 @@ namespace GenesisCordonelInterface.API PortConfig? str, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => InitSlot(slot, cfg, pwd, req, str), token); + return GetWorker(slot).RunAsync(() => InitSlot(slot, cfg, pwd, req, str), token, nameof(InitSlot)); } public PublicModels.GciInitSlotResult InitSlot( @@ -334,7 +334,7 @@ namespace GenesisCordonelInterface.API PortConfig? str, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => UpdateSlot(slot, cfg, pwd, req, str), token); + return GetWorker(slot).RunAsync(() => UpdateSlot(slot, cfg, pwd, req, str), token, nameof(UpdateSlot)); } public PublicModels.GciInitSlotResult UpdateSlot( @@ -491,7 +491,7 @@ namespace GenesisCordonelInterface.API int slot, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => GetOneMeterInfo(slot), token); + return GetWorker(slot).RunAsync(() => GetOneMeterInfo(slot), token, nameof(GetOneMeterInfo)); } public PublicModels.GciSlotInfo GetOneMeterInfo(int slot) @@ -702,7 +702,7 @@ namespace GenesisCordonelInterface.API int slot, CancellationToken token = default(CancellationToken)) { - return GetWorker(slot).RunAsync(() => DetectStreamingPort(slot), token); + return GetWorker(slot).RunAsync(() => DetectStreamingPort(slot), token, nameof(DetectStreamingPort)); } public PortDetectionResult DetectStreamingPort(int slot) @@ -757,7 +757,7 @@ namespace GenesisCordonelInterface.API int slot, CancellationToken token = default(CancellationToken)) { - return GetWorker(slot).RunAsync(() => DetectRequestPort(slot), token); + return GetWorker(slot).RunAsync(() => DetectRequestPort(slot), token, nameof(DetectRequestPort)); } public PortDetectionResult DetectRequestPort(int slot) @@ -807,7 +807,7 @@ namespace GenesisCordonelInterface.API #region ================================== LOGIN ================================== public Task LoginOneSlotAsync(int slot, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => LoginOneSlot(slot), token); + return GetWorker(slot).RunAsync(() => LoginOneSlot(slot), token, nameof(LoginOneSlot)); } public PublicModels.GciLoginResult LoginOneSlot(int slot) @@ -881,7 +881,7 @@ namespace GenesisCordonelInterface.API public Task ConnectOneSlotAsync(int slot, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => ConnectOneSlot(slot), token); + return GetWorker(slot).RunAsync(() => ConnectOneSlot(slot), token, nameof(ConnectOneSlot)); } public PublicModels.GciConnectResult ConnectOneSlot(int slot) @@ -972,7 +972,7 @@ namespace GenesisCordonelInterface.API int slot, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => Disconnect(slot), token); + return GetWorker(slot).RunAsync(() => Disconnect(slot), token, nameof(Disconnect)); } public PublicModels.GciDisconnectResult Disconnect(int slot) @@ -1059,7 +1059,7 @@ namespace GenesisCordonelInterface.API int slot, CancellationToken token = default(CancellationToken)) { - return GetWorker(slot).RunAsync(() => GetPcbId(slot), token, "GetPcbId"); + return GetWorker(slot).RunAsync(() => GetPcbId(slot), token, nameof(GetPcbId)); } public PublicModels.GciGetPcbIdResult GetPcbId(int slot) @@ -1112,7 +1112,7 @@ namespace GenesisCordonelInterface.API public Task ReadRegisterAsync(int slot, string name, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => ReadRegister(slot, name), token); + return GetWorker(slot).RunAsync(() => ReadRegister(slot, name), token, nameof(ReadRegister)); } public RegisterReadResult ReadRegister(int slot, string name) @@ -1166,7 +1166,7 @@ namespace GenesisCordonelInterface.API bool refreshSystemState = false, CancellationToken token = default) { - return GetWorker(slot).RunAsync(() => WriteRegister(slot, registerName, value, storeToDevice, refreshSystemState), token); + return GetWorker(slot).RunAsync(() => WriteRegister(slot, registerName, value, storeToDevice, refreshSystemState), token, nameof(WriteRegister)); } public RegisterWriteResult WriteRegister( @@ -1279,7 +1279,7 @@ namespace GenesisCordonelInterface.API { return GetWorker(slot).RunAsync(() => SetMeterPassword(slot, password), token, - "SetMeterPassword"); + nameof(SetMeterPassword)); } public PublicModels.GciSetPasswordResult SetMeterPassword( @@ -1826,7 +1826,8 @@ namespace GenesisCordonelInterface.API { return GetWorker(slot).RunAsync( () => PreAdjustment_Preparation(slot), - token); + token, + nameof(PreAdjustment_Preparation)); } public PreAdjustmentProcessResult PreAdjustment_PreparationDirect() @@ -1925,7 +1926,8 @@ namespace GenesisCordonelInterface.API { return GetWorker(slot).RunAsync( () => PreAdjustment_AmplitudeTest(slot), - token); + token, + nameof(PreAdjustment_AmplitudeTest)); } public PreAdjustmentProcessResult PreAdjustment_AmplitudeTestDirect() @@ -2015,7 +2017,8 @@ namespace GenesisCordonelInterface.API { return GetWorker(slot).RunAsync( () => PreAdjustment_TemperatureCalibration(slot), - token); + token, + nameof(PreAdjustment_TemperatureCalibration)); } public PreAdjustmentProcessResult PreAdjustment_TemperatureCalibrationDirect() @@ -2112,7 +2115,8 @@ namespace GenesisCordonelInterface.API { return GetWorker(slot).RunAsync( () => PreAdjustment_OffsetTest(slot), - token); + token, + nameof(PreAdjustment_OffsetTest)); } public PreAdjustmentProcessResult PreAdjustment_OffsetTestDirect() @@ -2207,7 +2211,8 @@ namespace GenesisCordonelInterface.API { return GetWorker(slot).RunAsync( () => PreAdjustment_Completion(slot), - token); + token, + nameof(PreAdjustment_Completion)); } public PreAdjustmentProcessResult PreAdjustment_CompletionDirect() @@ -2317,4 +2322,4 @@ namespace GenesisCordonelInterface.API } #endregion } -} \ No newline at end of file +} diff --git a/GenesisCordonelInterface/Core/Threading/ApiWorker/ApiWorker.cs b/GenesisCordonelInterface/Core/Threading/ApiWorker/ApiWorker.cs index e154e4112..759ba54c8 100644 --- a/GenesisCordonelInterface/Core/Threading/ApiWorker/ApiWorker.cs +++ b/GenesisCordonelInterface/Core/Threading/ApiWorker/ApiWorker.cs @@ -174,7 +174,8 @@ namespace GenesisCordonelInterface.Core.Threading public sealed class ApiWorker : IDisposable { - private static readonly NLog.ILogger Logger = NLog.LogManager.GetLogger("GenesisCordonelInterface-threading"); + private static readonly NLog.ILogger Logger = NLog.LogManager.GetLogger("GenesisCordonelInterface.SlotWorker"); + private static long nextRequestId; /// /// Thread-safe FIFO queue holding work items. /// @@ -232,6 +233,12 @@ namespace GenesisCordonelInterface.Core.Threading }; thread.Start(); + + Logger.Info( + "[SLOT-WORKER] CREATED Worker={0}, WorkerThread={1}, CallerThread={2}", + Name, + thread.ManagedThreadId, + Thread.CurrentThread.ManagedThreadId); } /// @@ -251,31 +258,93 @@ namespace GenesisCordonelInterface.Core.Threading var tcs = new TaskCompletionSource( TaskCreationOptions.RunContinuationsAsynchronously); + long requestId = Interlocked.Increment(ref nextRequestId); + string operation = string.IsNullOrWhiteSpace(operationName) ? action.Method.Name : operationName; + int callerThreadId = Thread.CurrentThread.ManagedThreadId; + Stopwatch queueWait = Stopwatch.StartNew(); + try { - Debug.WriteLine($"ENQUEUE {operationName} slot worker={Name} time={DateTime.Now:HH:mm:ss.fff}"); + Logger.Debug( + "[SLOT-REQUEST] ENQUEUE RequestId={0}, Worker={1}, Operation={2}, CallerThread={3}, QueueLengthBefore={4}", + requestId, + Name, + operation, + callerThreadId, + QueueLength); + queue.Add(() => { if (token.IsCancellationRequested) { + queueWait.Stop(); + LastActivity = DateTime.Now; + + Logger.Warn( + "[SLOT-REQUEST] CANCELLED_BEFORE_START RequestId={0}, Worker={1}, Operation={2}, WorkerThread={3}, QueueWaitMs={4}, QueueLength={5}", + requestId, + Name, + operation, + Thread.CurrentThread.ManagedThreadId, + queueWait.ElapsedMilliseconds, + QueueLength); + tcs.TrySetCanceled(); return; } + Stopwatch execution = Stopwatch.StartNew(); + try { IsBusy = true; - CurrentOperation = operationName ?? action.Method.Name; + CurrentOperation = operation; LastActivity = DateTime.Now; LastError = null; + queueWait.Stop(); + + Logger.Debug( + "[SLOT-REQUEST] START RequestId={0}, Worker={1}, Operation={2}, WorkerThread={3}, CallerThread={4}, QueueWaitMs={5}, QueueLength={6}", + requestId, + Name, + operation, + Thread.CurrentThread.ManagedThreadId, + callerThreadId, + queueWait.ElapsedMilliseconds, + QueueLength); + var result = action(); tcs.TrySetResult(result); + + execution.Stop(); + + Logger.Debug( + "[SLOT-REQUEST] COMPLETE RequestId={0}, Worker={1}, Operation={2}, WorkerThread={3}, DurationMs={4}, QueueLength={5}", + requestId, + Name, + operation, + Thread.CurrentThread.ManagedThreadId, + execution.ElapsedMilliseconds, + QueueLength); } catch (Exception ex) { + execution.Stop(); LastError = ex.Message; + + Logger.Error( + ex, + "[SLOT-REQUEST] FAILED RequestId={0}, Worker={1}, Operation={2}, WorkerThread={3}, DurationMs={4}, QueueLength={5}, Error={6}", + requestId, + Name, + operation, + Thread.CurrentThread.ManagedThreadId, + execution.ElapsedMilliseconds, + QueueLength, + ex.Message); + tcs.TrySetException(ex); } finally @@ -286,13 +355,47 @@ namespace GenesisCordonelInterface.Core.Threading } }, token); } + catch (OperationCanceledException) + { + queueWait.Stop(); + + Logger.Warn( + "[SLOT-REQUEST] ENQUEUE_CANCELLED RequestId={0}, Worker={1}, Operation={2}, CallerThread={3}, QueueWaitMs={4}", + requestId, + Name, + operation, + callerThreadId, + queueWait.ElapsedMilliseconds); + + tcs.TrySetCanceled(); + } catch (ObjectDisposedException ex) { + queueWait.Stop(); + + Logger.Error( + ex, + "[SLOT-REQUEST] ENQUEUE_FAILED RequestId={0}, Worker={1}, Operation={2}, Reason=WorkerDisposed", + requestId, + Name, + operation); + tcs.TrySetException(ex); } catch (InvalidOperationException ex) { - tcs.TrySetException(new ObjectDisposedException(nameof(ApiWorker), ex)); + queueWait.Stop(); + + var disposedException = new ObjectDisposedException(nameof(ApiWorker), ex); + + Logger.Error( + disposedException, + "[SLOT-REQUEST] ENQUEUE_FAILED RequestId={0}, Worker={1}, Operation={2}, Reason=QueueCompleted", + requestId, + Name, + operation); + + tcs.TrySetException(disposedException); } return tcs.Task; @@ -327,6 +430,11 @@ namespace GenesisCordonelInterface.Core.Threading /// private void WorkerLoop() { + Logger.Info( + "[SLOT-WORKER] THREAD_STARTED Worker={0}, WorkerThread={1}", + Name, + Thread.CurrentThread.ManagedThreadId); + try { foreach (var item in queue.GetConsumingEnumerable()) @@ -339,7 +447,26 @@ namespace GenesisCordonelInterface.Core.Threading } catch (ObjectDisposedException) { - // worker is shutting down + Logger.Debug( + "[SLOT-WORKER] QUEUE_DISPOSED Worker={0}, WorkerThread={1}", + Name, + Thread.CurrentThread.ManagedThreadId); + } + catch (Exception ex) + { + Logger.Error( + ex, + "[SLOT-WORKER] THREAD_FAILED Worker={0}, WorkerThread={1}, Error={2}", + Name, + Thread.CurrentThread.ManagedThreadId, + ex.Message); + } + finally + { + Logger.Info( + "[SLOT-WORKER] THREAD_STOPPED Worker={0}, WorkerThread={1}", + Name, + Thread.CurrentThread.ManagedThreadId); } } @@ -351,14 +478,41 @@ namespace GenesisCordonelInterface.Core.Threading if (disposed) return; + Logger.Info( + "[SLOT-WORKER] DISPOSE_BEGIN Worker={0}, CallerThread={1}, WorkerThread={2}, IsBusy={3}, CurrentOperation={4}, QueueLength={5}", + Name, + Thread.CurrentThread.ManagedThreadId, + thread.ManagedThreadId, + IsBusy, + CurrentOperation ?? "", + QueueLength); + disposed = true; queue.CompleteAdding(); if (Thread.CurrentThread != thread && thread.IsAlive) - thread.Join(1000); + { + bool stopped = thread.Join(1000); + if (!stopped) + { + Logger.Warn( + "[SLOT-WORKER] DISPOSE_WAIT_TIMEOUT Worker={0}, WorkerThread={1}, CurrentOperation={2}, QueueLength={3}", + Name, + thread.ManagedThreadId, + CurrentOperation ?? "", + QueueLength); + } + } queue.Dispose(); + + Logger.Info( + "[SLOT-WORKER] DISPOSE_END Worker={0}, CallerThread={1}, WorkerThread={2}, ThreadAlive={3}", + Name, + Thread.CurrentThread.ManagedThreadId, + thread.ManagedThreadId, + thread.IsAlive); } } -} \ No newline at end of file +} diff --git a/TBF/Rig/TestMethods/GenesisCommunication/GenesisCommunicationSeq.cs b/TBF/Rig/TestMethods/GenesisCommunication/GenesisCommunicationSeq.cs index 100b8ddf3..a4c12f250 100644 --- a/TBF/Rig/TestMethods/GenesisCommunication/GenesisCommunicationSeq.cs +++ b/TBF/Rig/TestMethods/GenesisCommunication/GenesisCommunicationSeq.cs @@ -33,6 +33,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication public class GenesisCommunicationSeq : SequenceBase { private static readonly ILog log = LogManager.GetLogger(typeof(GenesisCommunicationSeq)); + private static readonly NLog.ILogger preadjustmentLogger = NLog.LogManager.GetLogger("GenesisCordonelInterface.GenesisCommunication.Preadjustment"); public const string Q2correctedFromCmd = "Q2 corrected from "; public const string StrictQ2ErrorCheckStr = "Strict Q2 error check "; @@ -50,6 +51,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication System.Windows.Forms.Form modelessDlg; + private GenesisCommunicationDiagnosticsForm preadjustmentDiagnosticsForm; /// delegate void iPerlCommFormDlgt(GenesisCommunicationSeq myRef, TestMethod method, Test test, iPerlCommunicationParams testParams); /// @@ -69,6 +71,40 @@ namespace TBF.Rig.TestMethods.GenesisCommunication modelessDlg = null; } + private delegate void PreadjustmentDiagnosticsFormDelegate(GenesisCommunicationSeq sequence, GciBridgeType bridge, string activity); + + private void OpenPreadjustmentDiagnosticsForm(GenesisCommunicationSeq sequence, GciBridgeType bridge, string activity) + { + sequence.ClosePreadjustmentDiagnosticsForm(); + sequence.preadjustmentDiagnosticsForm = new GenesisCommunicationDiagnosticsForm(bridge, activity); + sequence.preadjustmentDiagnosticsForm.Show(); + } + + private void ClosePreadjustmentDiagnosticsForm() + { + if (preadjustmentDiagnosticsForm == null) + return; + + if (!preadjustmentDiagnosticsForm.IsDisposed) + preadjustmentDiagnosticsForm.Close(); + + preadjustmentDiagnosticsForm.Dispose(); + preadjustmentDiagnosticsForm = null; + } + + private void ShowPreadjustmentDiagnostics(GciBridgeType bridge, string activity) + { + Program.MainWnd.Invoke(new PreadjustmentDiagnosticsFormDelegate(OpenPreadjustmentDiagnosticsForm), new object[] { this, bridge, activity }); + } + + private void HidePreadjustmentDiagnostics() + { + if (Program.MainWnd == null || Program.MainWnd.IsDisposed) + return; + + Program.MainWnd.Invoke(new Action(ClosePreadjustmentDiagnosticsForm)); + } + /// /// Flying start mass collection method sequence @@ -458,24 +494,74 @@ namespace TBF.Rig.TestMethods.GenesisCommunication Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnActivity(this, testParams.Activity); + preadjustmentLogger.Info( + "[PREADJUSTMENT] START Test={0}, Part={1}, Activity={2}, MeterSize={3}, Temperature={4}, CallerThread={5}", + test.Name, + test.Part, + testParams.Activity, + testParams.MeterSize, + testParams.Temperature, + Thread.CurrentThread.ManagedThreadId); + try { readers = GetPreadjustmentReaders(test); GciBridgeType bridge = GetCommonGciBridge(readers); + + preadjustmentLogger.Info( + "[PREADJUSTMENT] CONTEXT Test={0}, Activity={1}, Bridge={2}, Slots={3}, ReaderCount={4}", + test.Name, + testParams.Activity, + bridge.Name, + string.Join(",", readers.Select(item => item.Value.GetSlotNr)), + readers.Count); + + ShowPreadjustmentDiagnostics(bridge, testParams.Activity); success = ExecutePreadjustmentActivity(bridge, readers, testParams, out response); } catch (Exception ex) { response = ex.Message; log.Error(string.Format("{0} failed.", testParams.Activity), ex); + + preadjustmentLogger.Error( + ex, + "[PREADJUSTMENT] FAILED Test={0}, Part={1}, Activity={2}, DurationMs={3}, Error={4}", + test.Name, + test.Part, + testParams.Activity, + (long)(DateTime.Now - startTime).TotalMilliseconds, + ex.Message); + } + finally + { + HidePreadjustmentDiagnostics(); } UpdatePreadjustmentResult(test, method, readers, success, startTime); if (success) + { log.InfoFormat("{0} finished successfully. {1}", testParams.Activity, response); + preadjustmentLogger.Info( + "[PREADJUSTMENT] COMPLETE Test={0}, Part={1}, Activity={2}, Success=True, DurationMs={3}, Response={4}", + test.Name, + test.Part, + testParams.Activity, + (long)(DateTime.Now - startTime).TotalMilliseconds, + response); + } else + { log.ErrorFormat("{0} failed. {1}", testParams.Activity, response); + preadjustmentLogger.Error( + "[PREADJUSTMENT] COMPLETE Test={0}, Part={1}, Activity={2}, Success=False, DurationMs={3}, Response={4}", + test.Name, + test.Part, + testParams.Activity, + (long)(DateTime.Now - startTime).TotalMilliseconds, + response); + } Bridge.OnActivity(this, string.Format("{0}: {1}", testParams.Activity, response)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); @@ -537,10 +623,17 @@ namespace TBF.Rig.TestMethods.GenesisCommunication private static bool ExecutePreadjustmentActivity(GciBridgeType bridge, IList> readers, iPerlCommunicationParams testParams, out string response) { + preadjustmentLogger.Debug( + "[PREADJUSTMENT] DISPATCH Activity={0}, Bridge={1}, Slots={2}, Thread={3}", + testParams.Activity, + bridge.Name, + string.Join(",", readers.Select(item => item.Value.GetSlotNr)), + Thread.CurrentThread.ManagedThreadId); + if (string.Equals(testParams.Activity, PreadjustmentInitializationStr, StringComparison.OrdinalIgnoreCase)) { MeterSize meterSize; - if (!Enum.TryParse(testParams.MeterSize, true, out meterSize) || meterSize == MeterSize.NA) + if (!Enum.TryParse(testParams.MeterSize, true, out meterSize) || meterSize.ToString().EndsWith("MAX", StringComparison.OrdinalIgnoreCase)) throw new InvalidOperationException(string.Format("Meter size '{0}' is not valid.", testParams.MeterSize)); var progress = new ProcessProgress @@ -567,6 +660,15 @@ namespace TBF.Rig.TestMethods.GenesisCommunication PublicModels.PreAdjustmentInitializationResult result = bridge.Preadjustment_Initialization(progress, meterControls); response = result.ToString(); + + preadjustmentLogger.Debug( + "[PREADJUSTMENT] INITIALIZATION_RESULT Success={0}, MeterSize={1}, NumberOfPaths={2}, MeterCount={3}, Response={4}", + result.Success, + meterSize, + progress.Setting.NumberOfPaths, + meterControls.Count, + response); + return result.Success; } @@ -575,6 +677,13 @@ namespace TBF.Rig.TestMethods.GenesisCommunication var selectedSlots = readers.Select(item => new GciPublicModels.MeterBatchDebugStatus { Slot = item.Value.GetSlotNr, Selected = true }).ToList(); PublicModels.PreadjustmentDetectResult result = bridge.PreAdjustment_DetectDirect(selectedSlots, CancellationToken.None); response = result.ToString(); + + preadjustmentLogger.Debug( + "[PREADJUSTMENT] DETECT_RESULT Success={0}, Slots={1}, Response={2}", + result.Success, + string.Join(",", selectedSlots.Select(item => item.Slot)), + response); + return result.Success; } @@ -583,6 +692,12 @@ namespace TBF.Rig.TestMethods.GenesisCommunication // Keep temperature delivery as an explicit sibling GCI API activity. A procedure can run it simultaneously with temperature calibration. bool pushed = bridge.PreAdjustment_PushTemperature(testParams.Temperature); response = pushed ? string.Format("Temperature {0} °C was accepted.", testParams.Temperature) : "GCI preadjustment was not initialized; temperature was not accepted."; + + preadjustmentLogger.Debug( + "[PREADJUSTMENT] TEMPERATURE_PUSH Result={0}, Temperature={1}", + pushed, + testParams.Temperature); + return pushed; } @@ -601,6 +716,15 @@ namespace TBF.Rig.TestMethods.GenesisCommunication throw new InvalidOperationException(string.Format("Unsupported preadjustment activity '{0}'.", testParams.Activity)); response = processResult.ToString(); + + preadjustmentLogger.Debug( + "[PREADJUSTMENT] PROCESS_RESULT Activity={0}, Process={1}, Slot={2}, Success={3}, Error={4}", + testParams.Activity, + processResult.ProcessName, + processResult.Slot, + processResult.Success, + processResult.ErrorMessage ?? ""); + return processResult.Success; } @@ -625,6 +749,14 @@ namespace TBF.Rig.TestMethods.GenesisCommunication meterResult.WaterMeter.SerialNr = item.Value.SerialNr; meterResult.Passed = success; meterResult.TestDone = true; + + preadjustmentLogger.Debug( + "[PREADJUSTMENT] RESULT_UPDATE Test={0}, Part={1}, MeterPosition={2}, Slot={3}, Passed={4}", + test.Name, + test.Part, + item.Key, + item.Value.GetSlotNr, + success); } } diff --git a/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.Designer.cs b/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.Designer.cs new file mode 100644 index 000000000..f942bf50e --- /dev/null +++ b/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.Designer.cs @@ -0,0 +1,346 @@ +namespace TBF.Rig.TestMethods.GenesisCommunication +{ + partial class GenesisCommunicationDiagnosticsForm + { + private System.ComponentModel.IContainer components = null; + + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + components.Dispose(); + + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle lastActivityCellStyle = new System.Windows.Forms.DataGridViewCellStyle(); + this.diagnosticsToolStrip = new System.Windows.Forms.ToolStrip(); + this.activityToolStripLabel = new System.Windows.Forms.ToolStripLabel(); + this.refreshToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.showBridgeToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.mainSplitContainer = new System.Windows.Forms.SplitContainer(); + this.slotsGroupBox = new System.Windows.Forms.GroupBox(); + this.slotsDataGridView = new System.Windows.Forms.DataGridView(); + this.slotColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.selectedColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.pcbIdColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.connectedColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.loggedOnColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.fwVersionColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.requestPortColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.requestPortTypeColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.streamingPortColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.interfaceVersionColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.workersGroupBox = new System.Windows.Forms.GroupBox(); + this.workersDataGridView = new System.Windows.Forms.DataGridView(); + this.workerSlotColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.workerNameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.queueLengthColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.busyColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.currentOperationColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.lastErrorColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.lastActivityColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.diagnosticsStatusStrip = new System.Windows.Forms.StatusStrip(); + this.statusToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.refreshTimer = new System.Windows.Forms.Timer(this.components); + this.diagnosticsToolStrip.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.mainSplitContainer)).BeginInit(); + this.mainSplitContainer.Panel1.SuspendLayout(); + this.mainSplitContainer.Panel2.SuspendLayout(); + this.mainSplitContainer.SuspendLayout(); + this.slotsGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.slotsDataGridView)).BeginInit(); + this.workersGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.workersDataGridView)).BeginInit(); + this.diagnosticsStatusStrip.SuspendLayout(); + this.SuspendLayout(); + // + // diagnosticsToolStrip + // + this.diagnosticsToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.diagnosticsToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.activityToolStripLabel, + this.refreshToolStripButton, + this.showBridgeToolStripButton}); + this.diagnosticsToolStrip.Location = new System.Drawing.Point(0, 0); + this.diagnosticsToolStrip.Name = "diagnosticsToolStrip"; + this.diagnosticsToolStrip.Size = new System.Drawing.Size(1234, 25); + this.diagnosticsToolStrip.TabIndex = 0; + // + // activityToolStripLabel + // + this.activityToolStripLabel.Name = "activityToolStripLabel"; + this.activityToolStripLabel.Size = new System.Drawing.Size(99, 22); + this.activityToolStripLabel.Text = "Running activity:"; + // + // refreshToolStripButton + // + this.refreshToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.refreshToolStripButton.Name = "refreshToolStripButton"; + this.refreshToolStripButton.Size = new System.Drawing.Size(50, 22); + this.refreshToolStripButton.Text = "Refresh"; + this.refreshToolStripButton.Click += new System.EventHandler(this.refreshToolStripButton_Click); + // + // showBridgeToolStripButton + // + this.showBridgeToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.showBridgeToolStripButton.Name = "showBridgeToolStripButton"; + this.showBridgeToolStripButton.Size = new System.Drawing.Size(124, 22); + this.showBridgeToolStripButton.Text = "Open GCI Bridge GUI"; + this.showBridgeToolStripButton.Click += new System.EventHandler(this.showBridgeToolStripButton_Click); + // + // mainSplitContainer + // + this.mainSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.mainSplitContainer.Location = new System.Drawing.Point(0, 25); + this.mainSplitContainer.Name = "mainSplitContainer"; + this.mainSplitContainer.Panel1.Controls.Add(this.slotsGroupBox); + this.mainSplitContainer.Panel2.Controls.Add(this.workersGroupBox); + this.mainSplitContainer.Size = new System.Drawing.Size(1234, 534); + this.mainSplitContainer.SplitterDistance = 710; + this.mainSplitContainer.TabIndex = 1; + // + // slotsGroupBox + // + this.slotsGroupBox.Controls.Add(this.slotsDataGridView); + this.slotsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.slotsGroupBox.Location = new System.Drawing.Point(0, 0); + this.slotsGroupBox.Name = "slotsGroupBox"; + this.slotsGroupBox.Padding = new System.Windows.Forms.Padding(6); + this.slotsGroupBox.Size = new System.Drawing.Size(710, 534); + this.slotsGroupBox.TabIndex = 0; + this.slotsGroupBox.TabStop = false; + this.slotsGroupBox.Text = "GCI slots"; + // + // slotsDataGridView + // + this.slotsDataGridView.AllowUserToAddRows = false; + this.slotsDataGridView.AllowUserToDeleteRows = false; + this.slotsDataGridView.AllowUserToResizeRows = false; + this.slotsDataGridView.AutoGenerateColumns = false; + this.slotsDataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.DisplayedCells; + this.slotsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.slotsDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.slotColumn, + this.selectedColumn, + this.pcbIdColumn, + this.connectedColumn, + this.loggedOnColumn, + this.fwVersionColumn, + this.requestPortColumn, + this.requestPortTypeColumn, + this.streamingPortColumn, + this.interfaceVersionColumn}); + this.slotsDataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.slotsDataGridView.Location = new System.Drawing.Point(6, 19); + this.slotsDataGridView.MultiSelect = false; + this.slotsDataGridView.Name = "slotsDataGridView"; + this.slotsDataGridView.ReadOnly = true; + this.slotsDataGridView.RowHeadersWidth = 35; + this.slotsDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.slotsDataGridView.Size = new System.Drawing.Size(698, 509); + this.slotsDataGridView.TabIndex = 0; + // + // slot columns + // + this.slotColumn.DataPropertyName = "Slot"; + this.slotColumn.HeaderText = "Slot"; + this.slotColumn.Name = "slotColumn"; + this.slotColumn.ReadOnly = true; + this.selectedColumn.DataPropertyName = "Selected"; + this.selectedColumn.HeaderText = "Selected"; + this.selectedColumn.Name = "selectedColumn"; + this.selectedColumn.ReadOnly = true; + this.pcbIdColumn.DataPropertyName = "PcbId"; + this.pcbIdColumn.HeaderText = "PCB ID"; + this.pcbIdColumn.Name = "pcbIdColumn"; + this.pcbIdColumn.ReadOnly = true; + this.connectedColumn.DataPropertyName = "IsConnected"; + this.connectedColumn.HeaderText = "Connected"; + this.connectedColumn.Name = "connectedColumn"; + this.connectedColumn.ReadOnly = true; + this.loggedOnColumn.DataPropertyName = "IsLoggedOn"; + this.loggedOnColumn.HeaderText = "Logged on"; + this.loggedOnColumn.Name = "loggedOnColumn"; + this.loggedOnColumn.ReadOnly = true; + this.fwVersionColumn.DataPropertyName = "FwVersion"; + this.fwVersionColumn.HeaderText = "FW version"; + this.fwVersionColumn.Name = "fwVersionColumn"; + this.fwVersionColumn.ReadOnly = true; + this.requestPortColumn.DataPropertyName = "RequestPort"; + this.requestPortColumn.HeaderText = "Request port"; + this.requestPortColumn.Name = "requestPortColumn"; + this.requestPortColumn.ReadOnly = true; + this.requestPortTypeColumn.DataPropertyName = "RequestPortType"; + this.requestPortTypeColumn.HeaderText = "Request type"; + this.requestPortTypeColumn.Name = "requestPortTypeColumn"; + this.requestPortTypeColumn.ReadOnly = true; + this.streamingPortColumn.DataPropertyName = "StreamingPort"; + this.streamingPortColumn.HeaderText = "Streaming port"; + this.streamingPortColumn.Name = "streamingPortColumn"; + this.streamingPortColumn.ReadOnly = true; + this.interfaceVersionColumn.DataPropertyName = "InterfaceVersion"; + this.interfaceVersionColumn.HeaderText = "Interface version"; + this.interfaceVersionColumn.Name = "interfaceVersionColumn"; + this.interfaceVersionColumn.ReadOnly = true; + // + // workersGroupBox + // + this.workersGroupBox.Controls.Add(this.workersDataGridView); + this.workersGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.workersGroupBox.Location = new System.Drawing.Point(0, 0); + this.workersGroupBox.Name = "workersGroupBox"; + this.workersGroupBox.Padding = new System.Windows.Forms.Padding(6); + this.workersGroupBox.Size = new System.Drawing.Size(520, 534); + this.workersGroupBox.TabIndex = 0; + this.workersGroupBox.TabStop = false; + this.workersGroupBox.Text = "GCI workers"; + // + // workersDataGridView + // + this.workersDataGridView.AllowUserToAddRows = false; + this.workersDataGridView.AllowUserToDeleteRows = false; + this.workersDataGridView.AllowUserToResizeRows = false; + this.workersDataGridView.AutoGenerateColumns = false; + this.workersDataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.DisplayedCells; + this.workersDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.workersDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.workerSlotColumn, + this.workerNameColumn, + this.queueLengthColumn, + this.busyColumn, + this.currentOperationColumn, + this.lastErrorColumn, + this.lastActivityColumn}); + this.workersDataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.workersDataGridView.Location = new System.Drawing.Point(6, 19); + this.workersDataGridView.MultiSelect = false; + this.workersDataGridView.Name = "workersDataGridView"; + this.workersDataGridView.ReadOnly = true; + this.workersDataGridView.RowHeadersWidth = 35; + this.workersDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.workersDataGridView.Size = new System.Drawing.Size(508, 509); + this.workersDataGridView.TabIndex = 0; + // + // worker columns + // + this.workerSlotColumn.DataPropertyName = "Slot"; + this.workerSlotColumn.HeaderText = "Slot"; + this.workerSlotColumn.Name = "workerSlotColumn"; + this.workerSlotColumn.ReadOnly = true; + this.workerNameColumn.DataPropertyName = "Name"; + this.workerNameColumn.HeaderText = "Name"; + this.workerNameColumn.Name = "workerNameColumn"; + this.workerNameColumn.ReadOnly = true; + this.queueLengthColumn.DataPropertyName = "QueueLength"; + this.queueLengthColumn.HeaderText = "Queue length"; + this.queueLengthColumn.Name = "queueLengthColumn"; + this.queueLengthColumn.ReadOnly = true; + this.busyColumn.DataPropertyName = "IsBusy"; + this.busyColumn.HeaderText = "Busy"; + this.busyColumn.Name = "busyColumn"; + this.busyColumn.ReadOnly = true; + this.currentOperationColumn.DataPropertyName = "CurrentOperation"; + this.currentOperationColumn.HeaderText = "Current operation"; + this.currentOperationColumn.Name = "currentOperationColumn"; + this.currentOperationColumn.ReadOnly = true; + this.lastErrorColumn.DataPropertyName = "LastError"; + this.lastErrorColumn.HeaderText = "Last error"; + this.lastErrorColumn.Name = "lastErrorColumn"; + this.lastErrorColumn.ReadOnly = true; + this.lastActivityColumn.DataPropertyName = "LastActivity"; + lastActivityCellStyle.Format = "G"; + this.lastActivityColumn.DefaultCellStyle = lastActivityCellStyle; + this.lastActivityColumn.HeaderText = "Last activity"; + this.lastActivityColumn.Name = "lastActivityColumn"; + this.lastActivityColumn.ReadOnly = true; + // + // diagnosticsStatusStrip + // + this.diagnosticsStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.statusToolStripStatusLabel}); + this.diagnosticsStatusStrip.Location = new System.Drawing.Point(0, 559); + this.diagnosticsStatusStrip.Name = "diagnosticsStatusStrip"; + this.diagnosticsStatusStrip.Size = new System.Drawing.Size(1234, 22); + this.diagnosticsStatusStrip.TabIndex = 2; + // + // statusToolStripStatusLabel + // + this.statusToolStripStatusLabel.Name = "statusToolStripStatusLabel"; + this.statusToolStripStatusLabel.Size = new System.Drawing.Size(122, 17); + this.statusToolStripStatusLabel.Text = "Waiting for GCI data..."; + // + // refreshTimer + // + this.refreshTimer.Interval = 250; + this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick); + // + // GenesisCommunicationDiagnosticsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1234, 581); + this.Controls.Add(this.mainSplitContainer); + this.Controls.Add(this.diagnosticsStatusStrip); + this.Controls.Add(this.diagnosticsToolStrip); + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(900, 400); + this.Name = "GenesisCommunicationDiagnosticsForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Genesis Communication - GCI diagnostics"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GenesisCommunicationDiagnosticsForm_FormClosed); + this.Load += new System.EventHandler(this.GenesisCommunicationDiagnosticsForm_Load); + this.diagnosticsToolStrip.ResumeLayout(false); + this.diagnosticsToolStrip.PerformLayout(); + this.mainSplitContainer.Panel1.ResumeLayout(false); + this.mainSplitContainer.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.mainSplitContainer)).EndInit(); + this.mainSplitContainer.ResumeLayout(false); + this.slotsGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.slotsDataGridView)).EndInit(); + this.workersGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.workersDataGridView)).EndInit(); + this.diagnosticsStatusStrip.ResumeLayout(false); + this.diagnosticsStatusStrip.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + } + + #endregion + + private System.Windows.Forms.ToolStrip diagnosticsToolStrip; + private System.Windows.Forms.ToolStripLabel activityToolStripLabel; + private System.Windows.Forms.ToolStripButton refreshToolStripButton; + private System.Windows.Forms.ToolStripButton showBridgeToolStripButton; + private System.Windows.Forms.SplitContainer mainSplitContainer; + private System.Windows.Forms.GroupBox slotsGroupBox; + private System.Windows.Forms.DataGridView slotsDataGridView; + private System.Windows.Forms.GroupBox workersGroupBox; + private System.Windows.Forms.DataGridView workersDataGridView; + private System.Windows.Forms.StatusStrip diagnosticsStatusStrip; + private System.Windows.Forms.ToolStripStatusLabel statusToolStripStatusLabel; + private System.Windows.Forms.Timer refreshTimer; + private System.Windows.Forms.DataGridViewTextBoxColumn slotColumn; + private System.Windows.Forms.DataGridViewCheckBoxColumn selectedColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn pcbIdColumn; + private System.Windows.Forms.DataGridViewCheckBoxColumn connectedColumn; + private System.Windows.Forms.DataGridViewCheckBoxColumn loggedOnColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn fwVersionColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn requestPortColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn requestPortTypeColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn streamingPortColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn interfaceVersionColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn workerSlotColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn workerNameColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn queueLengthColumn; + private System.Windows.Forms.DataGridViewCheckBoxColumn busyColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn currentOperationColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn lastErrorColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn lastActivityColumn; + } +} diff --git a/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.cs b/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.cs new file mode 100644 index 000000000..f19f7471c --- /dev/null +++ b/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using GciBridgeType = TBF.Rig.BridgeComponents.GciBridge.GciBridge; +using GciPublicModels = GenesisCordonelInterface.API.PublicModels; + +namespace TBF.Rig.TestMethods.GenesisCommunication +{ + /// + /// Displays live GCI slot and worker information while a GenesisCommunication + /// preadjustment activity is running. + /// + public partial class GenesisCommunicationDiagnosticsForm : Form + { + private readonly GciBridgeType bridge; + private readonly string activity; + + public GenesisCommunicationDiagnosticsForm(GciBridgeType bridge, string activity) + { + if (bridge == null) + throw new ArgumentNullException("bridge"); + + this.bridge = bridge; + this.activity = activity ?? string.Empty; + + InitializeComponent(); + activityToolStripLabel.Text = "Running activity: " + this.activity; + } + + private void GenesisCommunicationDiagnosticsForm_Load(object sender, EventArgs e) + { + RefreshDiagnostics(); + refreshTimer.Start(); + } + + private void GenesisCommunicationDiagnosticsForm_FormClosed(object sender, FormClosedEventArgs e) + { + refreshTimer.Stop(); + } + + private void refreshTimer_Tick(object sender, EventArgs e) + { + RefreshDiagnostics(); + } + + private void refreshToolStripButton_Click(object sender, EventArgs e) + { + RefreshDiagnostics(); + } + + private void showBridgeToolStripButton_Click(object sender, EventArgs e) + { + bridge.ShowGui(); + } + + private void RefreshDiagnostics() + { + try + { + var api = bridge.gciExternalInterface; + List slotStatuses = api == null + ? new List() + : api.GetMeterBatchDebugStatuses() ?? new List(); + List workerStatuses = api == null + ? new List() + : api.GetWorkerDebugStatuses() ?? new List(); + + slotsDataGridView.DataSource = slotStatuses; + workersDataGridView.DataSource = workerStatuses; + statusToolStripStatusLabel.Text = string.Format("Updated {0:HH:mm:ss.fff} | Slots: {1} | Workers: {2}", DateTime.Now, slotStatuses.Count, workerStatuses.Count); + } + catch (Exception ex) + { + statusToolStripStatusLabel.Text = "Diagnostic refresh failed: " + ex.Message; + } + } + } +} diff --git a/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.resx b/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.resx new file mode 100644 index 000000000..3ac5e42c8 --- /dev/null +++ b/TBF/Rig/TestMethods/GenesisCommunication/UI/GenesisCommunicationDiagnosticsForm.resx @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj index b9c766b6c..8d6909bba 100644 --- a/TBF/TBF.csproj +++ b/TBF/TBF.csproj @@ -2011,6 +2011,12 @@ TestMethodCfgCtrl.cs + + Form + + + GenesisCommunicationDiagnosticsForm.cs + Component @@ -4006,6 +4012,9 @@ TestMethodCfgCtrl.cs + + GenesisCommunicationDiagnosticsForm.cs + GrabImageCfgCtrl.cs @@ -4685,8 +4694,12 @@ Form - - + + GenesisCommunicationForm.cs + + + GenesisCommunicationForm.cs + diff --git a/TBF/UI/MainWnd.cs b/TBF/UI/MainWnd.cs index 70933832a..51427afb0 100644 --- a/TBF/UI/MainWnd.cs +++ b/TBF/UI/MainWnd.cs @@ -649,7 +649,7 @@ namespace TBF.UI } reloadProceduresButton.Enabled = procedureComboBox.Enabled = ((args.Flags & ButtonsEtc.ProcedureCmbBoxEn) != 0); - optoHeadsToolStripMenuItem.Enabled = ((args.Flags & ButtonsEtc.ProcedureCmbBoxEn) != 0); + optoHeadsToolStripMenuItem.Enabled = true;//((args.Flags & ButtonsEtc.ProcedureCmbBoxEn) != 0); if (procedureComboBox.Enabled) {