Form_Home.cs 722 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.IO;
  6. using System.Linq;
  7. //using System.Text;
  8. using Microsoft.Win32;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. using HslCommunication.LogNet;
  13. using MainForm.FaForm;
  14. using Sunny.UI;
  15. using MainForm.ClassFile.XiaomiAPI;
  16. using System.Diagnostics;
  17. using MainForm.Models;
  18. using SqlSugar;
  19. using EasyModbus;
  20. using ModBusClientSimple.Util;
  21. using csharp_networkprotocol_hpsocket;
  22. using MqttnetServerWin;
  23. using Sunny.UI.Win32;
  24. using MainForm.ClassFile.XiaomiAPI_AGV;
  25. using MainForm.ClassFile.XiaomiAPI_RouteCom;
  26. using HslCommunication.Controls;
  27. using EIP_Protocol;
  28. using MainForm.ClassFile.XiaomiAPI_MES;
  29. using NPOI.Util;
  30. using static MainForm.SQLHelper;
  31. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationInbound;
  32. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationOutbound;
  33. using MainForm.ClassFile.ProjectClass;
  34. using CommonLib;
  35. using Org.BouncyCastle.Asn1.IsisMtt;
  36. using System.Web.Services.Description;
  37. using System.Numerics;
  38. using MathNet.Numerics.RootFinding;
  39. using HslCommunication.Enthernet;
  40. using BZFAStandardLib;
  41. using MainForm.ClassFile;
  42. using NPOI.SS.Formula.Functions;
  43. using static MainForm.ClassFile.XiaomiAPI.XiaomiMqttClient_Extend;
  44. using System.Net.Http;
  45. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_UpLoadFile;
  46. using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;
  47. using System.Reflection;
  48. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationOutbound.XmMES_StationOutRequest_Body;
  49. using FaFrameUI;
  50. using System.Security.Policy;
  51. using static MainForm.ClassFile.XiaomiClass.MesHelper;
  52. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationOutbound.XmMES_StationOutRequest_Body;
  53. using System.Drawing.Imaging;
  54. using System.Drawing;
  55. using ICSharpCode.SharpZipLib.Zip;
  56. using System.Text.RegularExpressions;
  57. using System.Text;
  58. using SixLabors.ImageSharp;
  59. /*
  60. * 注:本源码对外提供,所以有些地方使用中文命名方法及变量
  61. */
  62. namespace MainForm
  63. {
  64. /// <summary>
  65. /// 记录日志的委托
  66. /// </summary>
  67. /// <param name="logType">日志类型</param>
  68. /// <param name="message">日志信息</param>
  69. public delegate void HomeMessageHandler(LogType logType, string message);
  70. /// <summary>
  71. /// 主页窗体
  72. /// </summary>
  73. public partial class Form_Home : Form
  74. {
  75. #region 常量
  76. //文本常量
  77. private const string Head = "开始采集";
  78. private const string Tail = "采集完成";
  79. private const string Body = "工位出站数据";
  80. private const string BodyCheck = "工位点检数据";
  81. private const string BodyRun = "整线运行数据";
  82. private const string BodyAlarm = "整线报警数据";
  83. #endregion 常量
  84. #region 变量
  85. /// <summary>
  86. /// 委托-记录日志的方法
  87. /// </summary>
  88. public event HomeMessageHandler MessageEvent;
  89. /// <summary>
  90. /// 日志接口
  91. /// </summary>
  92. ILogNet _PLCLogNet;
  93. /// <summary>
  94. /// 用于记录IOT MQTT日志
  95. /// </summary>
  96. ILogNet _IOTMqttLogNet;
  97. /// <summary>
  98. /// 用于记录AGV MQTT日志
  99. /// </summary>
  100. ILogNet _AGVMqttLogNet;
  101. //private int DataSwitch = 1; // 1-SQLServer;2-Excel
  102. // 定义信号量,index0给MES(true有信号,false无信号;set()让被控线程运行,Reset()让被控线程停止;WaitOne(等待时间)等待线程运行)
  103. // 间隔时间
  104. private int IntervalReadPLC = 300; //ms 读PLC
  105. private int IntervalMonitorMES = 1000; //ms MES心跳
  106. private int IntervalAlarm = 1000; //ms 数据(报警)查询与设备运行信息
  107. /// <summary>
  108. /// 设备报警数据
  109. /// </summary>
  110. uint[] _FaultDatas = { };
  111. uint[] _FaultDatas_Old = { };
  112. uint[] _FaultDatas2 = { };
  113. uint[] _FaultDatas_Old2 = { };
  114. // 软件状态
  115. private bool IsRun = true;
  116. #region PLC 与 TCP对象
  117. // 定义一个字典,存plc对象(通讯)
  118. ModbusClientHelper plc1Alarm; // PLC‘运行数据’与‘报警数据’线程用ModbusTCP
  119. Dictionary<int, ModbusClientHelper> Funs = new Dictionary<int, ModbusClientHelper>();
  120. // 定义TCPClient对象列表
  121. Dictionary<int, HPSocket_TcpClientHelper>
  122. _HPSocket_TcpClients = new Dictionary<int, HPSocket_TcpClientHelper>();
  123. // 定义MQTTHelper对象
  124. MQTTHelper _MQTTHelper = new MQTTHelper();
  125. #endregion PLC 与 TCP对象
  126. /// <summary>
  127. /// 上次的设备运行信息
  128. /// </summary>
  129. private string lineWorkingData1_OldStr = string.Empty;
  130. /// <summary>
  131. /// 设备报警字典-当前结果
  132. /// Dictionary<工位代码,List<报警信息>>
  133. /// </summary>
  134. private Dictionary<string, List<Alarm>> DicAlarms_Cur = new Dictionary<string, List<Alarm>>();
  135. public Dictionary<int, Inovance_EIP> FunsEip = new Dictionary<int, Inovance_EIP>();
  136. /// <summary>
  137. /// 单机用-设备状态
  138. /// </summary>
  139. //XiaomiDeviceState xmDeviceState = XiaomiDeviceState.Uninitialized;
  140. XiaomiDeviceStateData xmDeviceStateData = new XiaomiDeviceStateData();
  141. private int test_item_num = 0; //iot 过站数据序号
  142. public static string uuid = ""; //单工位或左工位
  143. public static string uuid2 = ""; //右工位
  144. private bool inpass = false; //保存进站测试状态
  145. public static XiaoMiParm xiaomiParm = new XiaoMiParm();
  146. //记录上传附件的信息
  147. public static FileUpload_FileData fileUploadData = new FileUpload_FileData();
  148. #endregion 变量
  149. #region 窗体基础事件
  150. /// <summary>
  151. /// 初始化
  152. /// </summary>
  153. public Form_Home()
  154. {
  155. InitializeComponent();
  156. CheckForIllegalCrossThreadCalls = false; // 不检查跨线程访问
  157. _PLCLogNet = new LogNetDateTime(GlobalContext.PlcLogDir, GenerateMode.ByEveryDay); // 按天记录日志
  158. _IOTMqttLogNet = new LogNetDateTime(GlobalContext.MqttLogDir, GenerateMode.ByEveryDay); // 按天记录日志
  159. _AGVMqttLogNet = new LogNetDateTime(GlobalContext.MqttLogDir, GenerateMode.ByEveryDay); // 按天记录日志
  160. GlobalContext.Set += new Action(UpdateProductInfo); // 产品信息变化时更新UI
  161. }
  162. /// <summary>
  163. /// 窗体加载事件
  164. /// </summary>
  165. public void Form_Home_Load(object sender, EventArgs e)
  166. {
  167. try
  168. {
  169. AddMessage(LogType.Info, "开始初始化程序");
  170. //组建plc对象字典
  171. //plc1Alarm = new ModbusClientHelper(GlobalContext.Machine1Address, GlobalContext.MachinePort);
  172. //plc1Alarm = new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine1Address);
  173. if (GlobalContext.IsUsePLC1)
  174. {
  175. GlobalContext.IsUsePLCNow = 1;
  176. GlobalContext.IsUseStationName = "[OP10]壳体清洁上料";
  177. FunsEip.Add(GlobalContext.IsUsePLCNow,
  178. new Inovance_EIP(GlobalContext.PC1Address, GlobalContext.Machine1Address)); //OP10 壳体清洁上料装备
  179. }
  180. if (GlobalContext.IsUsePLC2)
  181. {
  182. GlobalContext.IsUsePLCNow = 2;
  183. GlobalContext.IsUseStationName = "[OP20]上盖板上料装备";
  184. FunsEip.Add(GlobalContext.IsUsePLCNow,
  185. new Inovance_EIP(GlobalContext.PC2Address, GlobalContext.Machine2Address)); //OP20 顶盖上料设备
  186. }
  187. if (GlobalContext.IsUsePLC3)
  188. {
  189. GlobalContext.IsUsePLCNow = 3;
  190. GlobalContext.IsUseStationName = "[OP30]点散热胶装备";
  191. FunsEip.Add(GlobalContext.IsUsePLCNow,
  192. new Inovance_EIP(GlobalContext.PC3Address, GlobalContext.Machine3Address)); //OP30 点胶设备
  193. }
  194. if (GlobalContext.IsUsePLC4)
  195. {
  196. GlobalContext.IsUsePLCNow = 4;
  197. GlobalContext.IsUseStationName = "[OP40]胶线检测";
  198. FunsEip.Add(GlobalContext.IsUsePLCNow,
  199. new Inovance_EIP(GlobalContext.PC4Address, GlobalContext.Machine4Address)); //OP40 3D胶线检测
  200. }
  201. if (GlobalContext.IsUsePLC5)
  202. {
  203. GlobalContext.IsUsePLCNow = 5;
  204. GlobalContext.IsUseStationName = "[OP50]ADD板上料组装装备";
  205. FunsEip.Add(GlobalContext.IsUsePLCNow,
  206. new Inovance_EIP(GlobalContext.PC5Address, GlobalContext.Machine5Address)); //OP50 ADD PCB板上料
  207. }
  208. if (GlobalContext.IsUsePLC6)
  209. {
  210. GlobalContext.IsUsePLCNow = 6;
  211. GlobalContext.IsUseStationName = "[OP70]组上盖板";
  212. FunsEip.Add(GlobalContext.IsUsePLCNow,
  213. new Inovance_EIP(GlobalContext.PC6Address, GlobalContext.Machine6Address)); //OP60 顶盖装配
  214. }
  215. if (GlobalContext.IsUsePLC7)
  216. {
  217. GlobalContext.IsUsePLCNow = 7;
  218. GlobalContext.IsUseStationName = "[OP80]上盖板锁螺丝";
  219. FunsEip.Add(GlobalContext.IsUsePLCNow,
  220. new Inovance_EIP(GlobalContext.PC7Address, GlobalContext.Machine7Address)); //OP70 锁螺丝
  221. }
  222. if (GlobalContext.IsUsePLC8)
  223. {
  224. GlobalContext.IsUsePLCNow = 8;
  225. GlobalContext.IsUseStationName = "[OP90]NG下料";
  226. FunsEip.Add(GlobalContext.IsUsePLCNow,
  227. new Inovance_EIP(GlobalContext.PC8Address,
  228. GlobalContext.Machine8Address)); //OP80 3D螺丝高度检测,NG出料站
  229. }
  230. if (GlobalContext.IsUsePLC9)
  231. {
  232. GlobalContext.IsUsePLCNow = 9;
  233. GlobalContext.IsUseStationName = "[OP100]半成品下料";
  234. FunsEip.Add(GlobalContext.IsUsePLCNow,
  235. new Inovance_EIP(GlobalContext.PC9Address, GlobalContext.Machine9Address)); //OP90 下料站
  236. }
  237. (bool, string) DicResult = InitalDicAlarm(); // 实例化报警字典
  238. AddMessage(LogType.Info, DicResult.Item2);
  239. foreach (Inovance_EIP plcEIP in FunsEip.Values)
  240. {
  241. if (plcEIP != null)
  242. {
  243. try
  244. {
  245. (int, string) result = plcEIP.Connect();
  246. }
  247. catch (Exception ex)
  248. {
  249. MessageBox.Show($"PLC[{plcEIP._pcIPStr}]连接失败!失败信息:" + ex.Message,
  250. "PLC连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1,
  251. MessageBoxOptions.ServiceNotification);
  252. }
  253. }
  254. }
  255. // 采集任务
  256. Task TaskReadAlarm = new Task(ReadAlarmAllPLC); // 线程-获取线体报警数据
  257. List<Task> TaskReadProcess = new List<Task>(); // 线程-触发点位(PLC)的线程
  258. //TaskReadProcess.Add(new Task(() => { ReadStation_DownOrderInfo(1); })); // 下发机种
  259. if (GlobalContext.IsUsePLC1)
  260. TaskReadProcess.Add(new Task(() => { ReadStation_S1(1); })); //OP10 壳体清洁上料装备
  261. if (GlobalContext.IsUsePLC2)
  262. TaskReadProcess.Add(new Task(() => { ReadStation_S2(2); })); //OP20 顶盖上料设备
  263. if (GlobalContext.IsUsePLC3)
  264. TaskReadProcess.Add(new Task(() => { ReadStation_S3(3); })); //OP30 点胶设备
  265. if (GlobalContext.IsUsePLC4)
  266. TaskReadProcess.Add(new Task(() => { ReadStation_S4(4); })); //OP40 点胶检测设备
  267. if (GlobalContext.IsUsePLC5)
  268. TaskReadProcess.Add(new Task(() => { ReadStation_S5(5); })); //OP50 ADD PCB板上料设备
  269. if (GlobalContext.IsUsePLC6)
  270. TaskReadProcess.Add(new Task(() => { ReadStation_S6(6); })); //OP60 顶盖装配设备
  271. if (GlobalContext.IsUsePLC7)
  272. TaskReadProcess.Add(new Task(() => { ReadStation_S7(7); })); //OP70 锁螺丝设备
  273. if (GlobalContext.IsUsePLC8)
  274. TaskReadProcess.Add(new Task(() => { ReadStation_S8(8); })); //OP80 3D螺丝高度检测设备
  275. if (GlobalContext.IsUsePLC9)
  276. TaskReadProcess.Add(new Task(() => { ReadStation_S9(9); }));
  277. #region 初始化
  278. try
  279. {
  280. // 开启MES(Http)
  281. if (GlobalContext.IsUseMES)
  282. {
  283. bool mesret = HttpUitls.PingIP(GlobalContext.ServerIp);
  284. if (mesret)
  285. {
  286. picMESStatus.Image = imageListState.Images[1];
  287. GlobalContext.MESIsConnect = true;
  288. AddMessage(LogType.Info, "小米MES初始连接成功!");
  289. }
  290. else
  291. {
  292. picMESStatus.Image = imageListState.Images[0];
  293. GlobalContext.MESIsConnect = false;
  294. AddMessage(LogType.Info, $"小米MES[{GlobalContext.ServerHost}]初始连接失败!");
  295. }
  296. }
  297. // 开启IOT(MQTT)
  298. if (GlobalContext.IsUseIot)
  299. {
  300. string addr = GlobalContext.MQTTServerHost;
  301. int port = GlobalContext.MQTTServerPort;
  302. //生产环境需要修改
  303. (int, string) qmttResult = XiaomiMqttClient_Extend.OpenWithMqttServer("127.0.0.1", 6666,
  304. GlobalContext.MqttServerPath, GlobalContext.MqttServerName);
  305. XiaomiMqttResponse_ErrCode response_ErrCode = (XiaomiMqttResponse_ErrCode)qmttResult.Item1;
  306. if (response_ErrCode == XiaomiMqttResponse_ErrCode.OK)
  307. {
  308. picIot.Image = imageListState.Images[1];
  309. AddMessage(LogType.Info, "小米IOT MQTT初始连接成功!");
  310. // 设置回调函数
  311. //XiaomiMqttClient_Extend.SetCallbackWithDataId(CallbackWithDataId);
  312. // 配置参数
  313. XiaomiMqttLoginFunAndParam param = new XiaomiMqttLoginFunAndParam();
  314. // fds
  315. param.parameter.fds.address = GlobalContext.address;
  316. param.parameter.fds.appId = GlobalContext.appId;
  317. param.parameter.fds.appKey = GlobalContext.appKey;
  318. // mes
  319. param.parameter.mes.address = GlobalContext.ServerIp;
  320. param.parameter.mes.appId = GlobalContext.MESAppId;
  321. param.parameter.mes.appKey = GlobalContext.MESAppKey;
  322. // mqtt
  323. param.parameter.mqtt.address = GlobalContext.MQTTServerHost;
  324. param.parameter.mqtt.port = GlobalContext.MQTTServerPort;
  325. param.parameter.mqtt.username = GlobalContext.MQTTAppId;
  326. param.parameter.mqtt.password = GlobalContext.MQTTAppPwd;
  327. // 设备配置
  328. param.parameter.equipment.factoryCode = GlobalContext.Factory_Code;
  329. if (GlobalContext.IsUsePLC1)
  330. {
  331. param.parameter.equipment.deviceCode = GlobalContext.S1_device_code; // 装备编码
  332. param.parameter.equipment.stationCode = GlobalContext.S1_station; // ⼯位Id
  333. xiaomiParm.workstation = GlobalContext.S1_work_station; //工站
  334. }
  335. if (GlobalContext.IsUsePLC2)
  336. {
  337. param.parameter.equipment.deviceCode = GlobalContext.S2_device_code; // 装备编码
  338. param.parameter.equipment.stationCode = GlobalContext.S2_station; // ⼯位Id
  339. xiaomiParm.workstation = GlobalContext.S2_work_station; //工站
  340. }
  341. if (GlobalContext.IsUsePLC3)
  342. {
  343. param.parameter.equipment.deviceCode = GlobalContext.s3_1_device_code; // 装备编码
  344. //param.parameter.equipment.stationCode = GlobalContext.s3_1_station; // ⼯位Id
  345. }
  346. if (GlobalContext.IsUsePLC4)
  347. {
  348. param.parameter.equipment.deviceCode = GlobalContext.s4_device_code; // 装备编码
  349. param.parameter.equipment.stationCode = GlobalContext.s4_station; // ⼯位Id
  350. xiaomiParm.workstation = GlobalContext.s4_work_station; //工站
  351. }
  352. if (GlobalContext.IsUsePLC5)
  353. {
  354. param.parameter.equipment.deviceCode = GlobalContext.s5_device_code; // 装备编码
  355. param.parameter.equipment.stationCode = GlobalContext.s5_station; // ⼯位Id
  356. xiaomiParm.workstation = GlobalContext.s5_work_station; //工站
  357. }
  358. if (GlobalContext.IsUsePLC6)
  359. {
  360. param.parameter.equipment.deviceCode = GlobalContext.s6_device_code; // 装备编码
  361. param.parameter.equipment.stationCode = GlobalContext.s6_station; // ⼯位Id
  362. xiaomiParm.workstation = GlobalContext.s6_work_station; //工站
  363. }
  364. if (GlobalContext.IsUsePLC7)
  365. {
  366. param.parameter.equipment.deviceCode = GlobalContext.s7_1_device_code; // 装备编码
  367. //param.parameter.equipment.stationCode = GlobalContext.s7_1_station; // ⼯位Id
  368. xiaomiParm.stationCode = GlobalContext.s7_1_station;
  369. }
  370. if (GlobalContext.IsUsePLC8)
  371. {
  372. param.parameter.equipment.deviceCode = GlobalContext.s8_device_code; // 装备编码
  373. param.parameter.equipment.stationCode = GlobalContext.s8_station; // ⼯位Id
  374. xiaomiParm.workstation = GlobalContext.s8_work_station; //工站
  375. }
  376. if (GlobalContext.IsUsePLC9)
  377. {
  378. param.parameter.equipment.deviceCode = GlobalContext.s9_device_code; // 装备编码
  379. param.parameter.equipment.stationCode = GlobalContext.s9_station; // ⼯位Id
  380. xiaomiParm.workstation = GlobalContext.s9_work_station; //工站
  381. }
  382. param.parameter.equipment.project = GlobalContext.Project_Code;
  383. param.parameter.equipment.productMode = "debug";
  384. param.parameter.other.logLevel = 0;
  385. param.parameter.other.LogPath = GlobalContext.MqttLogDir;
  386. XiaomiMqttClient_Extend.ParameterConfig(param);
  387. //保存全局变量
  388. xiaomiParm.stationCode = param.parameter.equipment.stationCode;
  389. xiaomiParm.deviceCode = param.parameter.equipment.deviceCode;
  390. }
  391. else
  392. {
  393. picIot.Image = imageListState.Images[0];
  394. AddMessage(LogType.Info,
  395. $"小米IOT MQTT[{GlobalContext.MQTTServerHost}:{GlobalContext.MQTTServerPort}]初始连接失败!--- {response_ErrCode.ToString()}");
  396. }
  397. }
  398. // 开启AGV(Http与MQTT)
  399. if (GlobalContext.IsUseAGV)
  400. {
  401. // AGV HTTP
  402. bool mesret1 = HttpUitls.PingIP(GlobalContext.AGVHttpIp);
  403. if (mesret1)
  404. {
  405. picAgvHttp.Image = imageListState.Images[1];
  406. AddMessage(LogType.Info, "AGV Http初始连接成功!");
  407. }
  408. else
  409. {
  410. picAgvHttp.Image = imageListState.Images[0];
  411. AddMessage(LogType.Info, $"AGV Http[{GlobalContext.AGVHttpHost}]初始连接失败!");
  412. }
  413. string agvMqttIp = GlobalContext.MQTTServerHost;
  414. int agvMqttPort = GlobalContext.MQTTServerPort;
  415. Action<ResultData_MQTT> callback = AGVMqttShowLog;
  416. ResultData_MQTT result_MQTT = _MQTTHelper
  417. .CreateMQTTClientAndStart(agvMqttIp, agvMqttPort, null, null, callback).Result; // 连接MQTT服务器
  418. // AGV MQTT
  419. if (result_MQTT.ResultCode == 1)
  420. {
  421. picAgvMqtt.Image = imageListState.Images[1];
  422. GlobalContext.AGVMQTTIsConnect = true;
  423. AddMessage(LogType.Info, "小米AGV MQTT初始连接成功!");
  424. ResultData_MQTT result =
  425. XiaomiAGVMQTT_Base.DeviceTopicAGV(ref _MQTTHelper, GlobalContext.AGVMQTTDeviceCode);
  426. AddMessage(LogType.Info,
  427. $"小米AGV MQTT订阅{GlobalContext.AGVMQTTDeviceCode}--- [{result.ResultCode}]{result.ResultMsg}!");
  428. }
  429. else
  430. {
  431. picAgvMqtt.Image = imageListState.Images[0];
  432. GlobalContext.AGVMQTTIsConnect = false;
  433. AddMessage(LogType.Info,
  434. $"小米AGV MQTT[{GlobalContext.AGVMQTTHost}:{GlobalContext.AGVMQTTPort}]初始连接失败!--- [{result_MQTT.ResultCode}]{result_MQTT.ResultMsg}");
  435. }
  436. }
  437. // 持续监视MES、IOT、AGV HTTP、AGV MQTT连接状态
  438. Task.Run(MonitorMESConnect);
  439. // 查询PLC连接状态
  440. foreach (int plcNo in FunsEip.Keys)
  441. {
  442. bool connected = FunsEip[plcNo].IsConnected;
  443. if (connected)
  444. {
  445. string msg = plcNo.ToString() + "工位初始连接成功---" + FunsEip[plcNo]._pcIPStr;
  446. AddMessage(LogType.Info, msg);
  447. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI
  448. }
  449. else
  450. {
  451. string msg = plcNo.ToString() + "工位初始连接失败---" + FunsEip[plcNo]._pcIPStr;
  452. AddMessage(LogType.Info, msg);
  453. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  454. }
  455. }
  456. // PLC4时 初始化扫码器TCP
  457. //if (GlobalContext.IsUsePLC4)
  458. // HpTCPClientInit();
  459. // 开启PLC的业务处理线程-监听PLC点位+状态
  460. foreach (Task task in TaskReadProcess)
  461. {
  462. if (task != null)
  463. task.Start();
  464. }
  465. //// 开启iot的线程
  466. TaskReadAlarm.Start();
  467. ////下传MES信息给1工位(先判断下plc对象数量)
  468. //if (Funs.Count > 1)
  469. // DownLoadProductInfo(1);
  470. if (GlobalContext.IsUsePLC3 || GlobalContext.IsUsePLC7)
  471. {
  472. //state_l.Text = "设备状态(左):";
  473. //state_r.Text = "设备状态(右):";
  474. //state_r.Visible = true;
  475. //lblDeviceStates2.Visible = true;
  476. }
  477. //上传操作记录
  478. operateToIot("startup", "开启");
  479. //上传装备配置
  480. deviceConfigToIot("project_name", GlobalContext.Project_Code);
  481. AddMessage(LogType.Info, "程序初始化完成");
  482. }
  483. catch (Exception ex)
  484. {
  485. string str = ex.StackTrace;
  486. this.BeginInvoke(new Action(() =>
  487. {
  488. AddMessage(LogType.Error,
  489. "初始化PLC连接失败!异常信息:" + ex.Message + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  490. str.Length - str.LastIndexOf("\\") - 1));
  491. }));
  492. }
  493. #endregion
  494. }
  495. catch (Exception ex)
  496. {
  497. string str = ex.StackTrace;
  498. OnMessage(LogType.Info,
  499. "主窗体的首页初始化出错!异常位置:" +
  500. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1) + ";异常信息:" +
  501. ex.Message.ToString());
  502. if (ex.Message != null && ex.Message.Contains("timed out"))
  503. MessageBox.Show("主窗体的首页初始化出错!异常信息:PLC连接超时!" + ex.Message);
  504. else
  505. MessageBox.Show("主窗体的首页初始化出错!异常信息:" + ex.Message);
  506. }
  507. }
  508. /// <summary>
  509. /// 窗体关闭事件
  510. /// </summary>
  511. private void Form_Home_FormClosed(object sender, FormClosedEventArgs e)
  512. {
  513. Closed2();
  514. }
  515. public void Closed2()
  516. {
  517. try
  518. {
  519. IsRun = false;
  520. Thread.Sleep(IntervalReadPLC);
  521. // 断开TCP
  522. int count = _HPSocket_TcpClients.Count();
  523. for (int i = 0; i < count; i++)
  524. {
  525. try
  526. {
  527. if (_HPSocket_TcpClients[i] != null && _HPSocket_TcpClients[i]._client.IsConnected)
  528. {
  529. _HPSocket_TcpClients[i].Stop();
  530. _HPSocket_TcpClients[i]._client.OnPrepareConnect -= OnPrepareConnect; // 准备连接了事件
  531. _HPSocket_TcpClients[i]._client.OnConnect -= OnConnect; // 连接事件
  532. _HPSocket_TcpClients[i]._client.OnSend -= OnSend; // 数据包发送事件
  533. _HPSocket_TcpClients[i]._client.OnReceive -= OnReceive; // 数据包到达事件
  534. _HPSocket_TcpClients[i]._client.OnClose -= OnClose; // TCP连接关闭事件
  535. }
  536. }
  537. catch
  538. {
  539. }
  540. }
  541. // 关闭Iot
  542. try
  543. {
  544. XiaomiMqttClient_Extend.CloseWithMqttServer(GlobalContext.MqttServerPath,
  545. GlobalContext.MqttServerName);
  546. }
  547. catch
  548. {
  549. }
  550. // 关闭AGV Mqtt
  551. try
  552. {
  553. _MQTTHelper.DisconnectAsync_Client().Wait();
  554. }
  555. catch
  556. {
  557. }
  558. }
  559. catch
  560. {
  561. }
  562. }
  563. #endregion 窗体基础事件
  564. #region 监控MES状态
  565. /// <summary>
  566. /// 监控MES连接状态
  567. /// </summary>
  568. private void MonitorMESConnect()
  569. {
  570. while (IsRun) // 运行被控线程
  571. {
  572. try
  573. {
  574. // 开启MES(Http)
  575. if (GlobalContext.IsUseMES)
  576. {
  577. bool mesret = HttpUitls.PingIP(GlobalContext.ServerIp);
  578. if (mesret)
  579. {
  580. picMESStatus.Image = imageListState.Images[1];
  581. GlobalContext.MESIsConnect = true;
  582. }
  583. else
  584. {
  585. picMESStatus.Image = imageListState.Images[0];
  586. GlobalContext.MESIsConnect = false;
  587. OnMessage(LogType.Info, $"小米MES[{GlobalContext.ServerHost}]连接失败");
  588. }
  589. }
  590. // 开启IOT(MQTT)
  591. if (GlobalContext.IsUseIot)
  592. {
  593. bool iIot = XiaomiMqttClient.IsOpen;
  594. if (iIot)
  595. picIot.Image = imageListState.Images[1];
  596. else
  597. {
  598. picIot.Image = imageListState.Images[0];
  599. OnMessage(LogType.Info,
  600. $"小米IOT MQTT[{GlobalContext.MQTTServerHost}:{GlobalContext.MQTTServerPort}]连接失败");
  601. }
  602. }
  603. // 开启AGV(Http与MQTT)
  604. if (GlobalContext.IsUseAGV)
  605. {
  606. // AGV Http
  607. bool mesret1 = HttpUitls.PingIP(GlobalContext.AGVHttpIp);
  608. if (mesret1)
  609. picAgvHttp.Image = imageListState.Images[1];
  610. else
  611. {
  612. picAgvHttp.Image = imageListState.Images[0];
  613. OnMessage(LogType.Info, $"小米AGV Http[{GlobalContext.AGVHttpHost}]连接失败");
  614. }
  615. // AGV MQTT
  616. if (GlobalContext.AGVMQTTIsConnect)
  617. picAgvMqtt.Image = imageListState.Images[1];
  618. else
  619. {
  620. picAgvMqtt.Image = imageListState.Images[0];
  621. OnMessage(LogType.Info,
  622. $"小米AGV MQTT[{GlobalContext.AGVMQTTHost}:{GlobalContext.AGVMQTTPort}]连接失败");
  623. }
  624. }
  625. }
  626. catch (Exception ex)
  627. {
  628. string str = ex.StackTrace;
  629. AddMessage(LogType.Error,
  630. "监控MES心跳失败!异常信息:" + ex.Message + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  631. str.Length - str.LastIndexOf("\\") - 1));
  632. }
  633. Thread.Sleep(IntervalMonitorMES);
  634. }
  635. }
  636. #endregion 监控MES连接状态
  637. #region 采集设备状态、运行数据、报警数据
  638. /// <summary>
  639. /// 请求设备状态 5000
  640. /// </summary>
  641. /// <param name="no">1</param>
  642. /// <param name="stationNameStr"></param>
  643. /// <returns>0:证明未连接到PLC;1,代表设备控制状态处于运行状态;2,代表设备控制状态处于故障状态;3,代表设备控制状态处于缺料状态;4,代表设备控制状态处于待机状态;5,代表设备控制状态处于维修状态;</returns>
  644. public int GetDeviceStatus(int plcNo, string stationNameStr = "[S0]壳体上料")
  645. {
  646. try
  647. {
  648. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  649. {
  650. short result = Funs[plcNo].ReadHoldingRegisters<short>(5000); // 5000
  651. return result;
  652. }
  653. else
  654. {
  655. return 0;
  656. }
  657. }
  658. catch (Exception ex)
  659. {
  660. string str = ex.StackTrace;
  661. AddMessage_Station(stationNameStr, LogType.Error,
  662. "请求设备状态失败!" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  663. str.Length - str.LastIndexOf("\\") - 1));
  664. return 0;
  665. }
  666. }
  667. /// <summary>
  668. /// 检查是否可采集点检数据 - 不取新值
  669. /// 5000不为1时可点检
  670. /// </summary>
  671. /// <returns></returns>
  672. public bool CheckCanSpotcheck1(int deviceState)
  673. {
  674. //return true;
  675. //D5000 = 1,代表设备控制状态处于运行状态
  676. //D5000 = 2, 代表设备控制状态处于故障状态
  677. //D5000 = 3,代表设备控制状态处于缺料状态
  678. //D5000 = 4, 代表设备控制状态处于待机状态
  679. //D5000 = 5,代表设备控制状态处于维修状态
  680. return deviceState != 1;
  681. }
  682. /// <summary>
  683. /// 检查是否可采集产品数据 - 不取新值
  684. /// </summary>
  685. /// <returns></returns>
  686. public bool CheckCanCollData(int deviceState)
  687. {
  688. return deviceState == 0; // 点检时该值不为0
  689. }
  690. /// <summary>
  691. /// 采集到的设备状态
  692. /// </summary>
  693. private string _DeviceStates = "未知状态";
  694. private string _DeviceStates_Old = "未知状态";
  695. private string _DeviceStates2 = "未知状态";
  696. private string _DeviceStates_Old2 = "未知状态";
  697. private static string AlarmStateCode=""; //记录出发故障时的其中一笔警报编码,上传设备状态用
  698. private static string AlarmStateName = ""; //记录出发故障时的其中一笔警报名称,上传设备状态用
  699. private static string AlarmStateTime = ""; //记录出发故障时的其中一笔警报时间,上传设备状态用
  700. /// <summary>
  701. /// 获取设备报警数据与获取设备运行信息
  702. /// </summary>
  703. private async void ReadAlarmAllPLC()
  704. {
  705. /// 获取设备报警数据与状态信息
  706. string stationNameStr = "获取设备报警数据与状态信息";
  707. // 已连接到PLC
  708. while (IsRun)
  709. {
  710. try
  711. {
  712. #region 报警数据
  713. try
  714. {
  715. //_FaultDatas = new uint[] { 4, 0, 30, 10 };
  716. if (_FaultDatas.Length > 0)
  717. {
  718. ReadPLCAlarmToIot(_FaultDatas, _FaultDatas_Old, stationNameStr,"left");
  719. }
  720. else
  721. {
  722. AddMessage_Station(stationNameStr, LogType.Error, $"【报警日志】{stationNameStr}_获取报警数据出错!");
  723. }
  724. if (_FaultDatas2.Length > 0)
  725. {
  726. ReadPLCAlarmToIot(_FaultDatas2, _FaultDatas_Old2, stationNameStr,"right");
  727. }
  728. else
  729. {
  730. AddMessage_Station(stationNameStr, LogType.Error, $"【报警日志】{stationNameStr}_获取报警数据出错!");
  731. }
  732. }
  733. catch (Exception ex)
  734. {
  735. string str = ex.StackTrace;
  736. AddMessage_Station(stationNameStr, LogType.Error,
  737. $"【报警日志】{stationNameStr}_获取报警数据出错!错误信息:" + ex.Message.ToString() + "异常位置:" +
  738. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  739. }
  740. #endregion 报警数据
  741. #region 设备状态
  742. //if (!GlobalContext._IsCon_plc1Alarm)
  743. //{
  744. // UpdatePLCMonitor(1, -2, 0);
  745. // continue;
  746. //}
  747. foreach (Inovance_EIP plcEIP in FunsEip.Values)
  748. {
  749. if (plcEIP != null)
  750. {
  751. if (plcEIP.IsConnected)
  752. {
  753. #region 主页展示设备运行状态并上传到IOT中,有双工位left就是左工位,没有双工位left就是单工位
  754. switch (xmDeviceStateData.left)
  755. {
  756. case XiaomiDeviceState.Uninitialized: // 未初始化状态(未初始状态,需先初始化装备才能运行)
  757. _DeviceStates = "未初始化状态";
  758. lblDeviceStates.Text = _DeviceStates;
  759. break;
  760. case XiaomiDeviceState.Initializing: // 初始化状态(初始化进行中)
  761. _DeviceStates = "初始化状态";
  762. lblDeviceStates.Text = _DeviceStates;
  763. break;
  764. case XiaomiDeviceState.Initialized: // 初始化完成状态(初始化完成)
  765. _DeviceStates = "初始化完成状态";
  766. lblDeviceStates.Text = _DeviceStates;
  767. break;
  768. case XiaomiDeviceState.Running: // 运行状态(正常运行中)
  769. _DeviceStates = "运行状态";
  770. lblDeviceStates.Text = _DeviceStates;
  771. break;
  772. case XiaomiDeviceState.Paused: // 暂停状态(设备运行中人工操作暂停,进入此状态)
  773. _DeviceStates = "暂停状态";
  774. lblDeviceStates.Text = _DeviceStates;
  775. break;
  776. case XiaomiDeviceState.Fault: // 故障状态(发生故障后进入此状态,同时停止运行)
  777. _DeviceStates = "故障状态";
  778. lblDeviceStates.Text = _DeviceStates;
  779. break;
  780. case XiaomiDeviceState.Alarm: // 警报状态(产生报警后进入此状态,同时停止运行)
  781. _DeviceStates = "警报状态";
  782. lblDeviceStates.Text = _DeviceStates;
  783. break;
  784. }
  785. if (!_DeviceStates.Equals(_DeviceStates_Old))
  786. {
  787. var iotResult =
  788. SaveDeviceStateData(stationNameStr, xmDeviceStateData.left, "left"); // 上传+保存
  789. if (iotResult.Item1 == 1)
  790. {
  791. _DeviceStates_Old = _DeviceStates;
  792. AddMessage_Station(stationNameStr, LogType.Info,
  793. "【设备状态】" + stationNameStr + $"_上传设备状态到Iot成功!");
  794. }
  795. else
  796. AddMessage_Station(stationNameStr, LogType.Info,
  797. "【设备状态】" + stationNameStr +
  798. $"_上传设备状态到Iot失败!报错信息:[{iotResult.Item1}]_{iotResult.Item2}");
  799. }
  800. #endregion 主页展示设备运行状态并上传到IOT中
  801. #region 右工位
  802. //if (GlobalContext.IsUsePLC3 || GlobalContext.IsUsePLC7)
  803. //{
  804. // switch (xmDeviceStateData.right)
  805. // {
  806. // case XiaomiDeviceState.Uninitialized: // 未初始化状态(未初始状态,需先初始化装备才能运行)
  807. // _DeviceStates2 = "未初始化状态";
  808. // lblDeviceStates2.Text = _DeviceStates2;
  809. // break;
  810. // case XiaomiDeviceState.Initializing: // 初始化状态(初始化进行中)
  811. // _DeviceStates2 = "初始化状态";
  812. // lblDeviceStates2.Text = _DeviceStates2;
  813. // break;
  814. // case XiaomiDeviceState.Initialized: // 初始化完成状态(初始化完成)
  815. // _DeviceStates2 = "初始化完成状态";
  816. // lblDeviceStates2.Text = _DeviceStates2;
  817. // break;
  818. // case XiaomiDeviceState.Running: // 运行状态(正常运行中)
  819. // _DeviceStates2 = "运行状态";
  820. // lblDeviceStates2.Text = _DeviceStates2;
  821. // break;
  822. // case XiaomiDeviceState.Paused: // 暂停状态(设备运行中人工操作暂停,进入此状态)
  823. // _DeviceStates2 = "暂停状态";
  824. // lblDeviceStates2.Text = _DeviceStates2;
  825. // break;
  826. // case XiaomiDeviceState.Fault: // 故障状态(发生故障后进入此状态,同时停止运行)
  827. // _DeviceStates2 = "故障状态";
  828. // lblDeviceStates2.Text = _DeviceStates2;
  829. // break;
  830. // case XiaomiDeviceState.Alarm: // 警报状态(产生报警后进入此状态,同时停止运行)
  831. // _DeviceStates2 = "警报状态";
  832. // lblDeviceStates2.Text = _DeviceStates2;
  833. // break;
  834. // }
  835. // if (!_DeviceStates2.Equals(_DeviceStates_Old2))
  836. // {
  837. // var iotResult = SaveDeviceStateData(stationNameStr, xmDeviceStateData.left,
  838. // "right"); // 上传+保存
  839. // if (iotResult.Item1 == 1)
  840. // {
  841. // _DeviceStates_Old2 = _DeviceStates2;
  842. // AddMessage_Station(stationNameStr, LogType.Info,
  843. // "【设备状态】" + stationNameStr + $"_上传Iot成功!");
  844. // }
  845. // else
  846. // AddMessage_Station(stationNameStr, LogType.Info,
  847. // "【设备状态】" + stationNameStr +
  848. // $"_上传Iot失败!报错信息:[{iotResult.Item1}]_{iotResult.Item2}");
  849. // }
  850. //}
  851. #endregion 右工位
  852. }
  853. }
  854. }
  855. #endregion
  856. }
  857. catch (Exception ex)
  858. {
  859. //AddMessage_Station(stationNameStr, LogType.Error, $"PLC1_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  860. AddMessage_Station(stationNameStr, LogType.Error,
  861. $"PLC1_{stationNameStr}_采集运行数据与报警数据出错!错误信息:" + ex.Message.ToString());
  862. }
  863. Thread.Sleep(IntervalAlarm);
  864. }
  865. }
  866. #endregion 轮询PLC
  867. #region 下发订单信息
  868. ///// <summary>
  869. ///// 壳体上料(下发工单)的交互逻辑
  870. ///// </summary>
  871. ///// <param name="no"></param>
  872. ///// <exception cref="NotImplementedException"></exception>
  873. //private void ReadStation_DownOrderInfo(int plcNo)
  874. //{
  875. // // [S1] Tray盘上料装备(板测)
  876. // // [S2] FCT(板测)
  877. // // [S3] 值板机
  878. // // [S4] 取放桁架
  879. // // [S5] Tray盘下料装备
  880. // /// 上位机心跳
  881. // /// 获取设备报警数据与状态信息
  882. // string stationNameStr = "[S0]壳体上料";
  883. // while (IsRun)
  884. // {
  885. // try
  886. // {
  887. // if (!GlobalContext._IsCon_Funs1)
  888. // {
  889. // UpdatePLCMonitor(plcNo, 0);
  890. // continue;
  891. // }
  892. // if (Funs[plcNo].isConnected) // 检查PLC是否已连接上
  893. // {
  894. // #region 壳体上料(下发工单)
  895. // try
  896. // {
  897. // Funs[plcNo].Read_Int_Tag("500", 1, out short[] iiMes0);
  898. // Funs[plcNo].Read_Int_Tag("501", 1, out short[] iiPlc0);
  899. // bool mES_FLAG_1 = iiMes0[0] == 1 ? true : false; // MES_FLAG_1
  900. // bool pLC_Flag_1 = iiPlc0[0] == 1 ? true : false; // PLC_FLAG_1
  901. // // 重置数据和信号
  902. // if (mES_FLAG_1 && pLC_Flag_1) // 1 1
  903. // {
  904. // // 清空写给PLC的数据
  905. // int[] i497 = new int[1] { 0 };
  906. // Funs[plcNo].Write_DInt_Tag("497", 1, i497); // SN号(数字部分)重置信号
  907. // // MES_Flag重置为0
  908. // int[] i500 = new int[1] { 0 };
  909. // Funs[plcNo].Write_DInt_Tag("500", 1, i500); // MES_FLAG_1
  910. // }
  911. // }
  912. // catch (Exception ex)
  913. // {
  914. // string str = ex.StackTrace;
  915. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}下发订单信息运行出错!错误信息:" + ex.Message.ToString() + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  916. // }
  917. // #endregion 壳体上料(下发工单)
  918. // UpdatePLCMonitor(plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  919. // }
  920. // else
  921. // {
  922. // UpdatePLCMonitor(plcNo, 0); // 更新PLC状态的UI
  923. // AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  924. //
  925. // Funs[plcNo].Connect();
  926. // }
  927. // }
  928. // catch (Exception ex)
  929. // {
  930. // UpdatePLCMonitor(plcNo, 0); // 更新PLC状态的UI
  931. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  932. //
  933. // Funs[plcNo].ReConnect();
  934. // }
  935. // Thread.Sleep(IntervalReadPLC);
  936. // }
  937. //}
  938. ///// <summary>
  939. ///// 下发订单信息到PLC
  940. ///// </summary>
  941. ///// <param name="no">PLC编号</param>
  942. //private void DownLoadProductInfo(int plcNo, string stationNameStr = "[S0]壳体上料")
  943. //{
  944. // try
  945. // {
  946. // if (!string.IsNullOrEmpty(GlobalContext.Mtltmrk))
  947. // {
  948. // Funs[plcNo].Write_String_Tag("568", 1, GlobalContext.Mtltmrk); // 产品型号(mtltmrk)
  949. // WritePLCLog(LogType.Debug, GlobalContext.Mtltmrk);
  950. // }
  951. // Funs[plcNo].Write_DInt_Tag("500", 1, new Int32[1] { 1 }); // MES_FLAG_1
  952. // }
  953. // catch (Exception ex)
  954. // {
  955. // string str = ex.StackTrace;
  956. // AddMessage_Station(stationNameStr, LogType.Error, "下发订单信息到PLC失败!" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  957. // }
  958. //}
  959. /// <summary>
  960. /// 下发清料信号
  961. /// </summary>
  962. /// <param name="no">PLC编号</param>
  963. public bool ClearProducts(int plcNo, string stationNameStr = "[S0]壳体上料")
  964. {
  965. try
  966. {
  967. //Funs[plcNo].ReadHoldingRegisters<int>(496); //
  968. AddMessage_Station(stationNameStr, LogType.Info, "下发了清料信号!");
  969. return true;
  970. }
  971. catch (Exception ex)
  972. {
  973. string str = ex.StackTrace;
  974. AddMessage_Station(stationNameStr, LogType.Error,
  975. "下发清料信号失败!" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  976. str.Length - str.LastIndexOf("\\") - 1));
  977. return false;
  978. }
  979. }
  980. #endregion 下发订单信息
  981. #region Xiaomi 贲流
  982. #region 公共方法
  983. private static bool ProgressState = false;
  984. private static readonly object lockObj = new object(); // 锁对象
  985. private static bool isCollectingFlagLeft;
  986. private static bool isCollectingFlagRight;
  987. public static bool OpenDailogFalg = true; //是否开启扫码弹窗标识
  988. private static int res = 0;
  989. public static bool StopWhile =false; //二维码弹窗后停止循环
  990. public static bool inStationPass = true; //过站结果,保存进站结果
  991. public static string _strProductBarcode = "";
  992. public static string _strCarrierBarcode = "";
  993. public void ConnectToIOT()
  994. {
  995. XiaomiMqttLoginFunAndParam param = new XiaomiMqttLoginFunAndParam();
  996. // fds
  997. param.parameter.fds.address = GlobalContext.address;
  998. param.parameter.fds.appId = GlobalContext.appId;
  999. param.parameter.fds.appKey = GlobalContext.appKey;
  1000. // mes
  1001. param.parameter.mes.address = GlobalContext.ServerIp;
  1002. param.parameter.mes.appId = GlobalContext.MESAppId;
  1003. param.parameter.mes.appKey = GlobalContext.MESAppKey;
  1004. // mqtt
  1005. param.parameter.mqtt.address = GlobalContext.MQTTServerHost;
  1006. param.parameter.mqtt.port = GlobalContext.MQTTServerPort;
  1007. param.parameter.mqtt.username = GlobalContext.MQTTAppId;
  1008. param.parameter.mqtt.password = GlobalContext.MQTTAppPwd;
  1009. // 设备配置
  1010. param.parameter.equipment.factoryCode = GlobalContext.Factory_Code;
  1011. if (GlobalContext.IsUsePLC1)
  1012. {
  1013. param.parameter.equipment.deviceCode = GlobalContext.S1_device_code; // 装备编码
  1014. param.parameter.equipment.stationCode = GlobalContext.S1_station; // ⼯位Id
  1015. xiaomiParm.workstation = GlobalContext.S1_work_station; //工站
  1016. }
  1017. if (GlobalContext.IsUsePLC2)
  1018. {
  1019. param.parameter.equipment.deviceCode = GlobalContext.S2_device_code; // 装备编码
  1020. param.parameter.equipment.stationCode = GlobalContext.S2_station; // ⼯位Id
  1021. xiaomiParm.workstation = GlobalContext.S2_work_station; //工站
  1022. }
  1023. if (GlobalContext.IsUsePLC3)
  1024. {
  1025. param.parameter.equipment.deviceCode = GlobalContext.s3_1_device_code; // 装备编码
  1026. //param.parameter.equipment.stationCode = GlobalContext.s3_1_station; // ⼯位Id
  1027. }
  1028. if (GlobalContext.IsUsePLC4)
  1029. {
  1030. param.parameter.equipment.deviceCode = GlobalContext.s4_device_code; // 装备编码
  1031. param.parameter.equipment.stationCode = GlobalContext.s4_station; // ⼯位Id
  1032. xiaomiParm.workstation = GlobalContext.s4_work_station; //工站
  1033. }
  1034. if (GlobalContext.IsUsePLC5)
  1035. {
  1036. param.parameter.equipment.deviceCode = GlobalContext.s5_device_code; // 装备编码
  1037. param.parameter.equipment.stationCode = GlobalContext.s5_station; // ⼯位Id
  1038. xiaomiParm.workstation = GlobalContext.s5_work_station; //工站
  1039. }
  1040. if (GlobalContext.IsUsePLC6)
  1041. {
  1042. param.parameter.equipment.deviceCode = GlobalContext.s6_device_code; // 装备编码
  1043. param.parameter.equipment.stationCode = GlobalContext.s6_station; // ⼯位Id
  1044. xiaomiParm.workstation = GlobalContext.s6_work_station; //工站
  1045. }
  1046. if (GlobalContext.IsUsePLC7)
  1047. {
  1048. param.parameter.equipment.deviceCode = GlobalContext.s7_1_device_code; // 装备编码
  1049. //param.parameter.equipment.stationCode = GlobalContext.s7_1_station; // ⼯位Id
  1050. xiaomiParm.stationCode = GlobalContext.s7_1_station;
  1051. }
  1052. if (GlobalContext.IsUsePLC8)
  1053. {
  1054. param.parameter.equipment.deviceCode = GlobalContext.s8_device_code; // 装备编码
  1055. param.parameter.equipment.stationCode = GlobalContext.s8_station; // ⼯位Id
  1056. xiaomiParm.workstation = GlobalContext.s8_work_station; //工站
  1057. }
  1058. if (GlobalContext.IsUsePLC9)
  1059. {
  1060. param.parameter.equipment.deviceCode = GlobalContext.s9_device_code; // 装备编码
  1061. param.parameter.equipment.stationCode = GlobalContext.s9_station; // ⼯位Id
  1062. xiaomiParm.workstation = GlobalContext.s9_work_station; //工站
  1063. }
  1064. param.parameter.equipment.project = GlobalContext.Project_Code;
  1065. param.parameter.equipment.productMode = "debug";
  1066. param.parameter.other.logLevel = 0;
  1067. param.parameter.other.LogPath = GlobalContext.MqttLogDir;
  1068. XiaomiMqttClient_Extend.ParameterConfig(param);
  1069. }
  1070. /// <summary>
  1071. /// float[]转为string
  1072. /// </summary>
  1073. public string FloatArrayToString(float[] nScrewResults)
  1074. {
  1075. // 使用 "R" 格式说明符来保证浮点数的往返精度,不添加 'f' 后缀
  1076. return string.Join(",", Array.ConvertAll(nScrewResults, element => element.ToString("R")));
  1077. }
  1078. /// <summary>
  1079. /// short[]转为string
  1080. /// </summary>
  1081. public string ShortArrayToString(short[] nScrewResults)
  1082. {
  1083. // 使用 string.Join 来连接数组元素,并使用逗号作为分隔符
  1084. return string.Join(",", nScrewResults);
  1085. }
  1086. /// <summary>
  1087. /// 写入PLC重复三次
  1088. /// </summary>
  1089. public (int, string) WriteResultToPlc<T>(int plcNo, string stationNameStr, string strTagName, int nCount,
  1090. T inObj)
  1091. {
  1092. int i = 0;
  1093. int nRet = 0;
  1094. string strRet = "";
  1095. try
  1096. {
  1097. while (i < 3) // 最多上传三次
  1098. {
  1099. (nRet, strRet) = FunsEip[plcNo].Write_SingleTag<T>(strTagName, nCount, inObj);
  1100. if (nRet == 0) //成功
  1101. {
  1102. break;
  1103. }
  1104. else
  1105. {
  1106. AddMessage_Station(stationNameStr, LogType.Error,
  1107. $"PLC{plcNo}_{stationNameStr} 进站结果写入PLC出错!错误信息:" + strRet);
  1108. i++;
  1109. }
  1110. }
  1111. return (nRet, strRet);
  1112. }
  1113. catch (Exception ex)
  1114. {
  1115. return (1, ex.Message);
  1116. }
  1117. }
  1118. public (int, string) SaveScrewDataToTxt(string direction, string ProductBarcode, float[] fScrewTimes,
  1119. short[] nScrewOrders, short[] nScrewResults)
  1120. {
  1121. try
  1122. {
  1123. // 获取当前日期
  1124. string dateFolder = DateTime.Now.ToString("yyyyMMdd");
  1125. // 构建保存路径
  1126. string basePath = AppDomain.CurrentDomain.BaseDirectory; // 获取执行文件的目录
  1127. string savePath = Path.Combine(basePath, "screw", dateFolder, ProductBarcode, direction, "螺丝Mes数据");
  1128. // 确保目录存在
  1129. Directory.CreateDirectory(savePath);
  1130. // 文件名
  1131. string fileName = $"{ProductBarcode}_{DateTime.Now.ToString("HHmmss")}.txt";
  1132. string filePath = Path.Combine(savePath, fileName);
  1133. // 确保不会超出数组长度,只取前14个或数组的实际长度
  1134. int count = Math.Min(14, fScrewTimes.Length);
  1135. using (StreamWriter sw = new StreamWriter(filePath))
  1136. {
  1137. for (int i = 0; i < count; i++)
  1138. {
  1139. sw.WriteLine($"{ProductBarcode}{"_"}{i + 1}");
  1140. sw.WriteLine($"锁附时间:{fScrewTimes[i]}");
  1141. sw.WriteLine($"锁附顺序:{nScrewOrders[i]}");
  1142. sw.WriteLine($"锁附结果:{nScrewResults[i]}");
  1143. sw.WriteLine(); // 空行分隔不同螺丝的信息
  1144. }
  1145. }
  1146. return (0, "");
  1147. }
  1148. catch (Exception ex)
  1149. {
  1150. return (1, ex.Message);
  1151. }
  1152. }
  1153. /// <summary>
  1154. /// 解析三点激光存储的文本
  1155. /// </summary>
  1156. /// <param name="path">文本路径</param>
  1157. /// <returns></returns>
  1158. public string GetLastLineCompensation(string path)
  1159. {
  1160. string result = "";
  1161. try
  1162. {
  1163. // 获取当前日期并格式化为 "yyyy-MM-dd" 格式
  1164. string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
  1165. string filename = $"Laser-{currentDate}-W0.txt";
  1166. // 拼接完整路径
  1167. string fullPath = Path.Combine(path, filename);
  1168. string lastNonEmptyLine = "";
  1169. // 判断文件是否存在
  1170. if (File.Exists(fullPath))
  1171. {
  1172. //读取文件内容
  1173. string[] lines = File.ReadAllLines(fullPath);
  1174. // 获取最后一行数据(忽略标题行)
  1175. if (lines.Length > 1)
  1176. {
  1177. string lastLine = "";
  1178. for (int i = lines.Length - 1; i > 0; i--)
  1179. {
  1180. if (!string.IsNullOrEmpty(lines[i]))
  1181. {
  1182. lastLine = lines[i];
  1183. break;
  1184. }
  1185. }
  1186. // 将最后一行按逗号分隔
  1187. string[] values = lastLine.Split(',');
  1188. // 跳过前两个元素并转换为新的数组
  1189. string[] newValues = values.Skip(0).Skip(1).ToArray();
  1190. string value = string.Join(",", newValues); // 获取值并去除多余空格
  1191. value = value.Replace(" ", "").Replace("\t", "").TrimStart(',');
  1192. if (value.StartsWith(","))
  1193. {
  1194. value = value.Substring(1);
  1195. }
  1196. result = value;
  1197. }
  1198. }
  1199. else
  1200. {
  1201. Console.WriteLine($"文件不存在: {fullPath}");
  1202. }
  1203. }
  1204. catch (Exception ex)
  1205. {
  1206. // 捕获异常并输出错误信息
  1207. Console.WriteLine($"发生错误: {ex.Message}");
  1208. }
  1209. return result;
  1210. }
  1211. public int PCBStationOutData(BarcodeSet_t Barcode, IoT_DataSet_t iotData)
  1212. {
  1213. int res = 0;
  1214. string jsonstr1 = "";
  1215. try
  1216. {
  1217. XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
  1218. outRequest_Body.machineId = GlobalContext.S5_MachineId; // 装备id(可配置)
  1219. outRequest_Body.stationId = GlobalContext.s5_station; // ⼯位ID(可配置)
  1220. outRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
  1221. outRequest_Body.clientTime =
  1222. DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
  1223. outRequest_Body.unitSn = Barcode.strPCBBarcode; // 产品SN
  1224. int a1Result = (int)iotData.testStatus;
  1225. //bool pass = a1Result == 1;
  1226. //outRequest_Body.state = pass ? "PASS" : "FAIL"; ; // 出站条件 PASS或FAIL
  1227. outRequest_Body.state = "PASS";
  1228. outRequest_Body.userId = GlobalContext.MESUserId; // ⽤⼾ID
  1229. outRequest_Body.factoryId = GlobalContext.Factory_Code; // ⼯⼚id
  1230. XmStationOut_KeyMaterial keyMaterial = new XmStationOut_KeyMaterial();
  1231. keyMaterial.bindSort = 1;
  1232. keyMaterial.materialSn = Barcode.strProductBarcode;
  1233. outRequest_Body.unitData.keyMaterial.Add(keyMaterial); // 产品码
  1234. jsonstr1 = JsonConvert.SerializeObject(outRequest_Body);
  1235. XmMES_StationOutResponse response = new XmMES_StationOutResponse();
  1236. response = XiaomiMESHttp_StationOutbound.StationOut(outRequest_Body);
  1237. if (response != null && response.header.code == "200")
  1238. {
  1239. res = 1;
  1240. AddMessage(LogType.Info,
  1241. "上传PCB出站数据到MES服务器---成功!请求信息:" + jsonstr1 + ",返回信息:" +
  1242. JsonConvert.SerializeObject(response.body));
  1243. }
  1244. else
  1245. {
  1246. res = 0;
  1247. AddMessage(LogType.Error,
  1248. "上传PCB出站数据到MES服务器---失败!错误信息:" + response.header.desc + ",请求信息:" + jsonstr1 + ",返回信息:" +
  1249. JsonConvert.SerializeObject(response.body));
  1250. }
  1251. }
  1252. catch (Exception e)
  1253. {
  1254. res = 0;
  1255. AddMessage(LogType.Info, "上传PCB出站数据到MES服务器---失败!请求信息:" + jsonstr1 + ",返回信息:" + e.Message);
  1256. }
  1257. return res;
  1258. }
  1259. public int PCBStationInData(BarcodeSet_t Barcode, IoT_DataSet_t iotData)
  1260. {
  1261. int res = 0;
  1262. string json_Body = "";
  1263. try
  1264. {
  1265. XmMES_StationInRequest_Body inRequest_Body = new XmMES_StationInRequest_Body();
  1266. inRequest_Body.machineId = GlobalContext.S5_MachineId; // 装备ID(可配置)
  1267. inRequest_Body.stationId = GlobalContext.s5_station; // ⼯位ID(可配置)
  1268. inRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
  1269. inRequest_Body.clientTime =
  1270. DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
  1271. inRequest_Body.unitSn = Barcode.strPCBBarcode; // 产品SN
  1272. inRequest_Body.userId = GlobalContext.MESUserId; // 用户ID;
  1273. inRequest_Body.factoryId = GlobalContext.Factory_Code; // 工厂ID;
  1274. json_Body = JsonConvert.SerializeObject(inRequest_Body);
  1275. var response = XiaomiMESHttp_StationInbound.StationIn(inRequest_Body);
  1276. string resultJson = JsonConvert.SerializeObject(response);
  1277. if (response != null && response.header.code == "200")
  1278. {
  1279. res = 1;
  1280. AddMessage(LogType.Info,
  1281. "上传PCB进站数据到MES服务器---成功!请求信息:" + json_Body + ",返回信息:" +
  1282. JsonConvert.SerializeObject(response.body));
  1283. }
  1284. else
  1285. {
  1286. res = 0;
  1287. AddMessage(LogType.Error,
  1288. "上传PCB进站数据到MES服务器---失败!错误信息:" + response.header.desc + ",请求信息:" + json_Body + ",返回信息:" +
  1289. JsonConvert.SerializeObject(response.body));
  1290. }
  1291. }
  1292. catch (Exception e)
  1293. {
  1294. res = 0;
  1295. AddMessage(LogType.Info, "上传PCB进站数据到MES服务器---失败!请求信息:" + json_Body + ",返回信息:" + e.Message);
  1296. }
  1297. return res;
  1298. }
  1299. /// <summary>
  1300. /// 调用进站接口并保存进站数据
  1301. /// </summary>
  1302. /// <param name="stationNameStr">工站信息</param>
  1303. /// <param name="workorder_code">工单号</param>
  1304. /// <param name="mtltmrk">型号(物料号)</param>
  1305. /// <param name="sn">产品SN</param>
  1306. /// <param name="items">进站数据</param>
  1307. /// <returns>1成功;5MES报警;6上位机报警</returns>
  1308. public int SaveStationInData(string stationNameStr, string workorder_code, string mtltmrk, string sn,
  1309. List<TestItem> items, string MachineId, string StationId, bool pass, string slot)
  1310. {
  1311. int result = 0;
  1312. XmMES_StationInRequest_Body inRequest_Body = new XmMES_StationInRequest_Body();
  1313. inRequest_Body.machineId = MachineId; // 装备ID(可配置)
  1314. inRequest_Body.stationId = StationId; // ⼯位ID(可配置)
  1315. inRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
  1316. inRequest_Body.clientTime =
  1317. DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
  1318. inRequest_Body.unitSn = sn; // 产品SN
  1319. inRequest_Body.uuidInspection = uuid;
  1320. inRequest_Body.state = pass ? "PASS" : "FAIL";
  1321. inRequest_Body.userId = GlobalContext.MESUserId; // 用户ID;
  1322. inRequest_Body.factoryId = GlobalContext.Factory_Code; // 工厂ID;
  1323. string json_Body = JsonConvert.SerializeObject(inRequest_Body);
  1324. StationIn stationIn = new StationIn()
  1325. {
  1326. Workorder_code = workorder_code, // 车间订单号
  1327. Mtltmrk = mtltmrk, // 产品型号(物料号)
  1328. Sn = sn, // SN
  1329. StationIn_body = json_Body, // 进站接口Json数据 - Body
  1330. Parameter_values = items, // 进站数据
  1331. Write_user = inRequest_Body.userId, // 员工Id
  1332. Test_time = inRequest_Body.clientTime // 进站时间
  1333. };
  1334. // 本地数据
  1335. string sql = stationIn.ToStringInsert(0);
  1336. string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
  1337. result = ret == "成功" ? 1 : 6;
  1338. #region MES
  1339. if (GlobalContext.IsSendStationIn)
  1340. {
  1341. try
  1342. {
  1343. XmMES_StationInResponse response = new XmMES_StationInResponse();
  1344. string resultJson = "";
  1345. string mesRet = string.Empty;
  1346. int i = 0;
  1347. while (i < 2) // 1009会多次尝试上传
  1348. {
  1349. response = XiaomiMESHttp_StationInbound.StationIn(inRequest_Body);
  1350. resultJson = JsonConvert.SerializeObject(response);
  1351. if (response != null && response.header.code == "200")
  1352. break;
  1353. else if (!mesRet.Contains("1009")) // 1009是未知错误
  1354. i++;
  1355. i++;
  1356. mesRet = $"[{response?.header?.code}]{response?.header?.desc}";
  1357. // 记录失败原因
  1358. OnMessage(LogType.Error, $"上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:{mesRet},请求参数:{json_Body}");
  1359. }
  1360. if (response?.header?.code == "200")
  1361. {
  1362. inStationPass = true;//上传iot进站结果
  1363. string sql_Upd = stationIn.ToStringUpdateStatusByID(1);
  1364. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  1365. result = ret_Upd == "成功" ? 1 : 6;
  1366. AddMessage(LogType.Info,
  1367. $"【进站数据 SN {stationIn.Sn}】上传MES服务器---成功,返回参数:{resultJson},请求参数:{json_Body}");
  1368. }
  1369. else
  1370. {
  1371. inStationPass = false;//上传iot进站结果
  1372. result = 5;
  1373. AddMessage(LogType.Info,
  1374. $"【进站数据 SN {stationIn.Sn}】上传MES服务器---失败!接口报错信息: {mesRet},请求参数:{json_Body}");
  1375. }
  1376. string sql_response =
  1377. stationIn.ToStringUpdateStationInReturn_body(JsonConvert.SerializeObject(response));
  1378. SQLHelper_New.ExecuteNonQuery(sql_response, null);
  1379. }
  1380. catch (Exception ex)
  1381. {
  1382. inStationPass = false;//上传iot进站结果
  1383. result = 6;
  1384. string str = ex.StackTrace;
  1385. AddMessage_Station(stationNameStr, LogType.Error,
  1386. $"PLC上传进站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  1387. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1388. }
  1389. }
  1390. #endregion
  1391. #region IOT
  1392. //过站结果,出站传结果,这里注释掉
  1393. //if (GlobalContext.IsMqttSendProcessData)
  1394. //{
  1395. // PassStationResultRequest request = new PassStationResultRequest();
  1396. // request.project_code = GlobalContext.Project_Code; // 项⽬编码
  1397. // request.factory_code = GlobalContext.Factory_Code; // ⼯⼚Id
  1398. // request.process_section_code = GlobalContext.Process_Section_Code; // ⼯段编码
  1399. // request.line_code = GlobalContext.LineCode; // 线体编码
  1400. // request.work_station = xiaomiParm.workstation; // ⼯站ID
  1401. // request.device_code = xiaomiParm.deviceCode; // 装备编码
  1402. // request.station = xiaomiParm.stationCode;
  1403. // request.process_time =
  1404. // DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 节拍发⽣时间(2022-06-01 14:27:57.283)
  1405. // request.slot = slot; // 槽位编码
  1406. // request.sn = sn; // 产品SN
  1407. // // request.enter_status = inpass ? "PASS" : "FAIL"; // 进站状态
  1408. // request.enter_status = pass ? "PASS" : "FAIL"; // 进站状态
  1409. // request.result = ""; // 出站条件 PASS或FAIL; // 过站结果
  1410. // request.work_type = "OUT_STATION"; // 作业类型
  1411. // // 上传过站结果
  1412. // (int, string) iotResult = XiaomiMqttClient_Extend.Write_PassStationResult(request);
  1413. // if (iotResult.Item1 != 0)
  1414. // {
  1415. // OnMessage(LogType.Info,
  1416. // $"【IOT过站结果】上传失败!错误原因:{iotResult.Item2},过站结果;产品码[{sn}] 进站结果[{request.enter_status}] 出站结果[{request.result}]");
  1417. // }
  1418. //}
  1419. #endregion
  1420. return result;
  1421. }
  1422. /// <summary>
  1423. /// 选择如何记录出站数据
  1424. /// </summary>
  1425. /// <param name="items">出站数据</param>
  1426. /// <param name="equipmentCode">设备编号</param>
  1427. /// <param name="processItem">测试项目</param>
  1428. /// <param name="workorder_code">车间订单号</param>
  1429. /// <param name="batch_num">批次号</param>
  1430. /// <param name="mtltmrk">型号</param>
  1431. /// <param name="proDate">日期</param>
  1432. /// <param name="supplierCode">供应商代码</param>
  1433. /// <param name="sn_Number">产品序列号的 数字序列部分</param>
  1434. /// <returns>上传成功时返回1;失败返回0</returns>
  1435. private int SwitctProcessData(string stationNameStr, List<TestItem> items, string equipmentCode,
  1436. string processItem,
  1437. string workorder_code, string batch_num, string mtltmrk, string proDate,
  1438. string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string MachineId,
  1439. string StationId, string PartBarcode, string detailjson, XmStationOut_InspectionItemData inspectionItemData, string direction = "")
  1440. {
  1441. return SaveProcessDataByDB(stationNameStr, items, equipmentCode, processItem, workorder_code, batch_num,
  1442. mtltmrk,
  1443. proDate, supplierCode, sn, pass, vehicleSn, vehicleSlot, MachineId, StationId, PartBarcode, detailjson, inspectionItemData,
  1444. direction);
  1445. }
  1446. /// <summary>
  1447. /// 添加出站数据(提交到MES+本地保存到数据库)
  1448. /// </summary>
  1449. /// <param name="items">出站数据</param>
  1450. /// <param name="equipmentCode">设备编号</param>
  1451. /// <param name="processItem">测试项目</param>
  1452. /// <param name="workorder_code">车间订单号</param>
  1453. /// <param name="batch_num">批次号</param>
  1454. /// <param name="mtltmrk">型号</param>
  1455. /// <param name="proDate">日期</param>
  1456. /// <param name="supplierCode">供应商代码</param>
  1457. /// <param name="sn_Number">产品序列号的 数字序列部分</param>
  1458. /// <returns>上传成功时返回1;失败返回0</returns>
  1459. public int SaveProcessDataByDB(string stationNameStr, List<TestItem> items, string equipmentCode,
  1460. string processItem, string workorder_code, string batch_num, string mtltmrk,
  1461. string proDate, string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot,
  1462. string machineId, string stationId, string partBarcode, string detailjson, XmStationOut_InspectionItemData inspectionItemData, string direction = "")
  1463. {
  1464. int upload = 0;
  1465. int result = 0;
  1466. ProcessData processData = new ProcessData()
  1467. {
  1468. Equipment_code = equipmentCode,
  1469. Workorder_code = workorder_code,
  1470. Batch_number = batch_num,
  1471. Sn = sn, // SN
  1472. Testitem = processItem,
  1473. Parameter_values = items,
  1474. Write_user = GlobalContext.CurrentUser,
  1475. Test_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
  1476. };
  1477. // 本地数据
  1478. string sql = processData.ToStringInsert(upload);
  1479. string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
  1480. //AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地出站数据---" + ret));
  1481. #region MES
  1482. if (GlobalContext.IsSendProcessData)
  1483. {
  1484. try
  1485. {
  1486. string id = processData.ID.Copy();
  1487. XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
  1488. if (direction == "Right")
  1489. outRequest_Body.uuidInspection = uuid2;
  1490. else
  1491. outRequest_Body.uuidInspection = uuid;
  1492. outRequest_Body.machineId = machineId; // 装备id(可配置)
  1493. outRequest_Body.stationId = stationId; // ⼯位ID(可配置)
  1494. outRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
  1495. outRequest_Body.clientTime = processData.Test_time; // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
  1496. outRequest_Body.unitSn = sn; // 产品SN
  1497. outRequest_Body.state = pass ? "PASS" : "FAIL"; // 出站条件 PASS或FAIL
  1498. outRequest_Body.userId = GlobalContext.MESUserId; // ⽤⼾ID
  1499. outRequest_Body.factoryId = GlobalContext.Factory_Code; // ⼯⼚id
  1500. outRequest_Body.unitData.vehicleData.vehicleSn = vehicleSn;
  1501. outRequest_Body.unitData.vehicleData.vehicleType = string.Empty;
  1502. outRequest_Body.unitData.vehicleData.slot = vehicleSlot;
  1503. if (!string.IsNullOrEmpty(partBarcode))
  1504. {
  1505. outRequest_Body.unitData.keyMaterial.Add(
  1506. new XmMES_StationOutRequest_Body.XmStationOut_KeyMaterial()
  1507. {
  1508. bindSort = 1,
  1509. materialSn = partBarcode
  1510. }); // 设备数据 - 部件码
  1511. }
  1512. #region 过站明细
  1513. if (GlobalContext.IsSendProcessDetail)
  1514. {
  1515. if (detailjson.Length > 0)
  1516. {
  1517. //detailjson = "{\"fGlueSupplySpeed\":0.63,\"fAB_AirPress\":0.0,\"fAB_AirPressDiff\":0.0,\"fMesHeightInfos\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"fIntervalWeights\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"fRemainGlues\":[600.0,600.0]}";
  1518. // 解析JSON字符串为字典
  1519. detailjson = detailjson.Replace("[", "\"[");
  1520. detailjson = detailjson.Replace("]", "]\"");
  1521. var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(detailjson);
  1522. foreach (var kvp in dictionary)
  1523. {
  1524. outRequest_Body.unitData.processData.Add(
  1525. new XmMES_StationOutRequest_Body.XmStationOut_ProcessData()
  1526. {
  1527. dataName = kvp.Key.ToString(),
  1528. dataValue = string.IsNullOrEmpty(kvp.Value) ? "" : kvp.Value.ToString()
  1529. });
  1530. }
  1531. }
  1532. }
  1533. #endregion
  1534. #region 测试项
  1535. if (GlobalContext.IsSendTestData)
  1536. {
  1537. if (stationNameStr.Contains("OP31") || stationNameStr.Contains("OP32") || stationNameStr.Contains("OP40") || stationNameStr.Contains("OP50"))
  1538. {
  1539. outRequest_Body.unitData.inspectionItemData.Add(
  1540. new XmStationOut_InspectionItemData()
  1541. {
  1542. childUnitSn = inspectionItemData.childUnitSn,
  1543. childUnitState = inspectionItemData.childUnitState,
  1544. toolVersion = inspectionItemData.toolVersion,
  1545. dataItem = inspectionItemData.dataItem,
  1546. }
  1547. );
  1548. }
  1549. }
  1550. #endregion
  1551. #region OP30站读三点测高
  1552. if (stationNameStr.Contains("OP31") || stationNameStr.Contains("OP32"))
  1553. {
  1554. string path = "";
  1555. if (direction == "Left")
  1556. {
  1557. string pathStr = GlobalContext.MESLaserLPath;
  1558. path = DecFileName(pathStr);
  1559. }
  1560. else
  1561. {
  1562. string pathStr = GlobalContext.MESLaserRPath;
  1563. path = DecFileName(pathStr);
  1564. }
  1565. var item = outRequest_Body.unitData.processData.FirstOrDefault(data => data.dataName == "fMesHeightInfos");
  1566. if (item != null)
  1567. {
  1568. item.dataValue = GetLastLineCompensation(path);
  1569. }
  1570. //outRequest_Body.unitData.processData.Add(
  1571. // new XmMES_StationOutRequest_Body.XmStationOut_ProcessData()
  1572. // {
  1573. // dataName = "fMesHeightInfos",
  1574. // dataValue = GetLastLineCompensation(path)
  1575. // });
  1576. }
  1577. #endregion
  1578. #region 上传文件,添加附件uuid
  1579. if (GlobalContext.MESIsSendUpFile)
  1580. {
  1581. foreach (var item in fileUploadData.fileData)
  1582. {
  1583. if (!string.IsNullOrEmpty(item.FileName))
  1584. {
  1585. outRequest_Body.unitData.fileData.Add(
  1586. new XmStationOut_FileData()
  1587. {
  1588. fileName = item.FileName,
  1589. fileId = item.FileId,
  1590. bucket = item.Bucket
  1591. });
  1592. }
  1593. }
  1594. }
  1595. #endregion
  1596. #region 上传MES
  1597. string jsonstr1 = JsonConvert.SerializeObject(outRequest_Body);
  1598. if (GlobalContext.IsSendProcessData)
  1599. {
  1600. XmMES_StationOutResponse response = new XmMES_StationOutResponse();
  1601. string mesRet = string.Empty;
  1602. int i = 0;
  1603. while (i < 2) // 1009会多次尝试上传
  1604. {
  1605. response = XiaomiMESHttp_StationOutbound.StationOut(outRequest_Body);
  1606. if (response != null && response.header.code == "200")
  1607. {
  1608. OnMessage(LogType.Info,
  1609. $"【出站数据 SN {sn}】上传出站数据到MES服务器---成功!请求信息:" + jsonstr1 + "返回信息:" +
  1610. JsonConvert.SerializeObject(response.body));
  1611. break;
  1612. }
  1613. else if (!mesRet.Contains("1009")) // 1009是未知错误
  1614. i++;
  1615. i++;
  1616. mesRet = $"[{response?.header?.code}]{response?.header?.desc}";
  1617. // 记录失败原因
  1618. OnMessage(LogType.Error,
  1619. $"【出站数据 SN {sn}】上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:" + mesRet + "参数:" + jsonstr1);
  1620. }
  1621. if (response?.header?.code == "200")
  1622. {
  1623. string sql_Upd = ProcessData.ToStringUpdateStatusByID(1, id);
  1624. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  1625. result = 1;
  1626. //AddMessage_Station(stationNameStr, LogType.Info, $"更新【出站数据 id {id}】上传状态---" + ret_Upd);
  1627. AddMessage(LogType.Info, $"【出站数据 SN {sn}】上传MES服务器---成功");
  1628. }
  1629. else
  1630. {
  1631. AddMessage(LogType.Info, $"【出站数据 SN {sn}】上传MES服务器---失败!接口报错信息:" + mesRet);
  1632. }
  1633. fileUploadData.fileData.Clear();
  1634. string sql_UpStationout = ProcessData.ToStringUpdateStationOut_body(
  1635. JsonConvert.SerializeObject(outRequest_Body),
  1636. JsonConvert.SerializeObject(response), id);
  1637. SQLHelper_New.ExecuteNonQuery(sql_UpStationout, null);
  1638. }
  1639. #endregion
  1640. }
  1641. catch (Exception ex)
  1642. {
  1643. string str = ex.StackTrace;
  1644. AddMessage_Station(stationNameStr, LogType.Error,
  1645. $"PLC上传出站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  1646. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1647. }
  1648. }
  1649. #endregion
  1650. #region IOT
  1651. //过站明细
  1652. if (GlobalContext.IsMqttSendProcessData)
  1653. {
  1654. test_item_num = 0;
  1655. PassStationDetailRequest request = new PassStationDetailRequest();
  1656. if (direction == "Right")
  1657. request.pass_station_id = uuid2;
  1658. else
  1659. request.pass_station_id = uuid;
  1660. request.sn = sn; // 产品SN
  1661. request.slot = vehicleSlot; // 槽位编码
  1662. request.function_name = "Machine_加⼯模块";
  1663. request.status = "PASS";
  1664. (int, string) iotResult = (0, "");
  1665. if (detailjson.Length > 0)
  1666. {
  1667. // 解析JSON字符串为字典
  1668. var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(detailjson);
  1669. foreach (var kvp in dictionary)
  1670. {
  1671. test_item_num += 1;
  1672. request.test_item_num = test_item_num.ToString();
  1673. request.test_item = kvp.Key.ToString();
  1674. request.result_val = string.IsNullOrEmpty(kvp.Value) ? "" : kvp.Value.ToString();
  1675. request.description = request.test_item;
  1676. // 上传过站明细
  1677. iotResult = XiaomiMqttClient_Extend.Write_PassStationDetail(request);
  1678. if (iotResult.Item1 != 0)
  1679. {
  1680. OnMessage(LogType.Info,
  1681. $"【IOT过站明细】上传失败!错误原因:{iotResult.Item2},过站明细;产品码[{sn}] 测试项目[{request.test_item}] 测试值[{request.result_val}]");
  1682. }
  1683. }
  1684. }
  1685. }
  1686. //过站结果
  1687. if (GlobalContext.IsMqttSendProcessData)
  1688. {
  1689. PassStationResultRequest request = new PassStationResultRequest();
  1690. if (direction == "Right")
  1691. request.pass_station_id = uuid2;
  1692. else
  1693. request.pass_station_id = uuid;
  1694. request.project_code = GlobalContext.Project_Code; // 项⽬编码
  1695. request.factory_code = GlobalContext.Factory_Code; // ⼯⼚Id
  1696. request.process_section_code = GlobalContext.Process_Section_Code; // ⼯段编码
  1697. request.line_code = GlobalContext.LineCode; // 线体编码
  1698. request.work_station = xiaomiParm.workstation; // ⼯站ID
  1699. request.device_code = xiaomiParm.deviceCode; // 装备编码
  1700. request.station = xiaomiParm.stationCode;
  1701. request.process_time =
  1702. DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 节拍发⽣时间(2022-06-01 14:27:57.283)
  1703. request.slot = vehicleSlot; // 槽位编码
  1704. request.sn = sn; // 产品SN
  1705. // request.enter_status = inpass ? "PASS" : "FAIL"; // 进站状态
  1706. request.enter_status = inStationPass ? "PASS" : "FAIL";// 进站状态
  1707. request.result = pass ? "PASS" : "FAIL"; // 出站条件 PASS或FAIL; // 过站结果
  1708. request.work_type = "OUT_STATION"; // 作业类型
  1709. // 上传过站结果
  1710. (int, string) iotResult = XiaomiMqttClient_Extend.Write_PassStationResult(request);
  1711. if (iotResult.Item1 != 0)
  1712. {
  1713. OnMessage(LogType.Info,
  1714. $"【IOT过站结果】上传失败!错误原因:{iotResult.Item2},过站结果;产品码[{sn}] 进站结果[{request.enter_status}] 出站结果[{request.result}]");
  1715. }
  1716. }
  1717. #endregion
  1718. return result;
  1719. }
  1720. //private void CollectAndProcessDataLeft(string sn, string direction, string ip, string port, int connectTimeOut, int sendDataTimeOut)
  1721. //{
  1722. // Stopwatch stopwatch = new Stopwatch();
  1723. // stopwatch.Start();
  1724. // try
  1725. // {
  1726. // // 初始化 AtlasScrew 实例
  1727. // AtlasScrew atlasScrew1 = new AtlasScrew(ip, port, connectTimeOut, sendDataTimeOut);
  1728. // atlasScrew1.Initial();
  1729. // // 存储结果的列表
  1730. // List<(double Angle, double Torque, double StartTorque, double MaxTorque)> results = new List<(double, double, double, double)>();
  1731. // // 存储角度和扭力的字符串列表
  1732. // List<string> angleStrs = new List<string>();
  1733. // List<string> torqueStrs = new List<string>();
  1734. // // 上一次获取的数据
  1735. // (double JD_MEAN, double NL_MEAN) lastResult = (-1, -1);
  1736. // while (isExitAtlasLeft) // 检查是否收集数据
  1737. // {
  1738. // // 获取当前数据
  1739. // var currentResult = atlasScrew1.GetResults();
  1740. // // 判断是否为新数据
  1741. // if (currentResult.JD_MEAN != lastResult.JD_MEAN || currentResult.NL_MEAN != lastResult.NL_MEAN)
  1742. // {
  1743. // OnMessage(LogType.Info, $"检测到新数据: JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN}");
  1744. // // 更新角度和扭力的字符串列表
  1745. // angleStrs.Add(currentResult.JD_MEAN.ToString());
  1746. // torqueStrs.Add(currentResult.NL_MEAN.ToString());
  1747. // // 计算角度、扭力、起始扭力和最大扭力
  1748. // double[] angles = angleStrs.Select(a => double.Parse(a)).ToArray();
  1749. // double[] torques = torqueStrs.Select(a => double.Parse(a)).ToArray();
  1750. // double startTorque = torques.Length > 0 ? torques[0] : -1; // 起始扭力
  1751. // double maxTorque = torques.Length > 0 ? torques.Max() : -1; // 最大扭力
  1752. // // 将新数据添加到结果列表
  1753. // results.Add((angles.Last(), torques.Last(), startTorque, maxTorque));
  1754. // // 更新上一次获取的数据
  1755. // lastResult = currentResult;
  1756. // }
  1757. // // 等待一段时间后再次检查
  1758. // Thread.Sleep(20); // 轮询间隔时间
  1759. // // 如果触发了出站,则退出循环
  1760. // if (!isExitAtlasLeft)
  1761. // {
  1762. // break;
  1763. // }
  1764. // }
  1765. // // 生成文件名
  1766. // string fileName = $"{sn}_{direction}_{DateTime.Now:yyyyMMddHHmmss}.txt";
  1767. // // 写入数据到文件
  1768. // using (StreamWriter writer = new StreamWriter(fileName))
  1769. // {
  1770. // // 写入标题行
  1771. // writer.WriteLine("角度, 扭力, 起始扭力, 最大扭力");
  1772. // // 写入每一行数据
  1773. // foreach (var result in results)
  1774. // {
  1775. // writer.WriteLine($"{result.Angle}, {result.Torque}, {result.StartTorque}, {result.MaxTorque}");
  1776. // }
  1777. // }
  1778. // stopwatch.Stop();
  1779. // AddMessage(LogType.Info, $"数据采集完成并保存到文件 {fileName}; 总用时 {stopwatch.ElapsedMilliseconds}ms");
  1780. // }
  1781. // catch (Exception ex)
  1782. // {
  1783. // AddMessage(LogType.Error, $"数据采集过程中发生错误: {ex.Message}");
  1784. // }
  1785. // finally
  1786. // {
  1787. // // 重置标志变量
  1788. // isExitAtlasLeft = false;
  1789. // }
  1790. //}
  1791. //private void CollectAndProcessDataRight(string sn, string direction, string ip, string port, int connectTimeOut, int sendDataTimeOut)
  1792. //{
  1793. // Stopwatch stopwatch = new Stopwatch();
  1794. // stopwatch.Start();
  1795. // try
  1796. // {
  1797. // // 初始化 AtlasScrew 实例
  1798. // AtlasScrew atlasScrew2 = new AtlasScrew(ip, port, connectTimeOut, sendDataTimeOut);
  1799. // atlasScrew2.Initial();
  1800. // // 存储结果的列表
  1801. // List<(double JD_MEAN, double NL_MEAN)> results = new List<(double JD_MEAN, double NL_MEAN)>();
  1802. // // 上一次获取的数据
  1803. // (double JD_MEAN, double NL_MEAN) lastResult = (-1, -1);
  1804. // while (isExitAtlasRight) // 检查是否收集数据
  1805. // {
  1806. // // 获取当前数据
  1807. // var currentResult = atlasScrew2.GetResults();
  1808. // // 判断是否为新数据
  1809. // if (currentResult.JD_MEAN != lastResult.JD_MEAN || currentResult.NL_MEAN != lastResult.NL_MEAN)
  1810. // {
  1811. // AddMessage(LogType.Info, $"检测到新数据: JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN}");
  1812. // // 将新数据写入PLC
  1813. // //WriteDataToPlc(plcNo, stationNameStr, tagMesCommName, currentResult.JD_MEAN, currentResult.NL_MEAN);
  1814. // // 将新数据添加到结果列表
  1815. // results.Add(currentResult);
  1816. // // 更新上一次获取的数据
  1817. // lastResult = currentResult;
  1818. // }
  1819. // // 等待一段时间后再次检查
  1820. // Thread.Sleep(20); // 轮询间隔时间
  1821. // // 如果触发了出站,则退出循环
  1822. // if (!isExitAtlasRight)
  1823. // {
  1824. // break;
  1825. // }
  1826. // }
  1827. // // 将所有数据写入文件
  1828. // //WriteDataToFile(sn, direction, results);
  1829. // stopwatch.Stop();
  1830. // OnMessage(LogType.Info, $"螺丝数据采集完成;总用时{stopwatch.ElapsedMilliseconds}ms");
  1831. // }
  1832. // catch (Exception ex)
  1833. // {
  1834. // OnMessage(LogType.Error, $"螺丝数据采集过程中发生错误: {ex.Message}");
  1835. // }
  1836. // finally
  1837. // {
  1838. // // 重置标志变量
  1839. // isExitAtlasRight = false;
  1840. // }
  1841. //}
  1842. /// <summary>
  1843. ///字符串中文乱码解决
  1844. /// </summary>
  1845. /// <param name="str"></param>
  1846. /// <returns></returns>
  1847. public static string DecFileName(string str)
  1848. {
  1849. Encoding utf8 = Encoding.GetEncoding("gbk");
  1850. byte[] btArr = utf8.GetBytes(str);
  1851. return Encoding.UTF8.GetString(btArr);
  1852. }
  1853. private void CollectAndProcessDataLeft(AtlasScrew atlasScrew, string sn, string direction)
  1854. {
  1855. Stopwatch stopwatch = new Stopwatch();
  1856. stopwatch.Start();
  1857. int nRet = 0;
  1858. string strRet = "";
  1859. try
  1860. {
  1861. int fileCounter = 1; // 文件计数器,用于生成文件名中的序号
  1862. while (isCollectingFlagLeft)
  1863. {
  1864. // 从缓存中获取所有未处理的数据
  1865. var cachedData = atlasScrew.GetCachedDataLeft();
  1866. foreach (var currentResult in cachedData)
  1867. {
  1868. if (currentResult.JD_MEAN == 0 || currentResult.NL_MEAN == 0)
  1869. {
  1870. continue; // 跳过无效数据
  1871. }
  1872. OnMessage(LogType.Info,
  1873. $"检测到新数据: JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN}");
  1874. // 写入PLC
  1875. OP70_ScrewDataSet_t resultToPlC = new OP70_ScrewDataSet_t
  1876. {
  1877. fTorque = float.Parse(currentResult.NL_MEAN.ToString()),
  1878. fCircles = float.Parse(currentResult.JD_MEAN.ToString())
  1879. };
  1880. (nRet, strRet) = WriteResultToPlc(7, "", $"g_OP70_MES.{direction}.screwDriver", 1, resultToPlC);
  1881. if (nRet != 0)
  1882. {
  1883. OnMessage(LogType.Info,
  1884. $"SN:{sn}, JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN} 写入PLC失败");
  1885. }
  1886. else
  1887. {
  1888. OnMessage(LogType.Info,
  1889. $"SN:{sn}, JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN} 写入PLC成功");
  1890. }
  1891. // 构建保存路径
  1892. string dateFolder = DateTime.Now.ToString("yyyyMMdd");
  1893. string basePath = AppDomain.CurrentDomain.BaseDirectory;
  1894. string savePath = Path.Combine(basePath, "screw", dateFolder, sn, direction, "曲线");
  1895. Directory.CreateDirectory(savePath); // 确保目录存在
  1896. // 构建文件名(以 SN + 序号命名)
  1897. string fileName = $"{sn}_{fileCounter}.txt";
  1898. string filePath = Path.Combine(savePath, fileName);
  1899. // 写入文件
  1900. using (StreamWriter writer = new StreamWriter(filePath))
  1901. {
  1902. writer.WriteLine("精度, 扭力");
  1903. // 遍历 Pearkdegree 和 PearkTorque 的所有值
  1904. for (int i = 0;
  1905. i < currentResult.Pearkdegree.Length && i < currentResult.PearkTorque.Length;
  1906. i++)
  1907. {
  1908. double precision = Math.Round(currentResult.Pearkdegree[i]); // 精度
  1909. double torque = Math.Round(currentResult.PearkTorque[i], 2); // 扭力
  1910. writer.WriteLine($"{precision}, {torque}");
  1911. }
  1912. }
  1913. OnMessage(LogType.Info, $"保存文件成功: {filePath}");
  1914. // 增加文件计数器
  1915. fileCounter++;
  1916. }
  1917. // 如果没有更多数据,则短暂休眠以节省资源
  1918. if (!cachedData.Any())
  1919. {
  1920. Thread.Sleep(10); // 根据需要调整休眠时间
  1921. }
  1922. // 如果触发了出站,则退出循环
  1923. if (!isCollectingFlagLeft)
  1924. {
  1925. break;
  1926. }
  1927. }
  1928. stopwatch.Stop();
  1929. OnMessage(LogType.Info, $"数据采集完成; 总用时 {stopwatch.ElapsedMilliseconds}ms");
  1930. }
  1931. catch (Exception ex)
  1932. {
  1933. OnMessage(LogType.Error, $"数据采集过程中发生错误: {ex.Message}");
  1934. }
  1935. finally
  1936. {
  1937. isCollectingFlagLeft = false;
  1938. }
  1939. }
  1940. private void CollectAndProcessDataRight(AtlasScrew atlasScrew, string sn, string direction)
  1941. {
  1942. Stopwatch stopwatch = new Stopwatch();
  1943. stopwatch.Start();
  1944. int nRet = 0;
  1945. string strRet = "";
  1946. try
  1947. {
  1948. int fileCounter = 1; // 文件计数器,用于生成文件名中的序号
  1949. while (isCollectingFlagRight)
  1950. {
  1951. // 从缓存中获取所有未处理的数据
  1952. var cachedData = atlasScrew.GetCachedDataLeft();
  1953. foreach (var currentResult in cachedData)
  1954. {
  1955. if (currentResult.JD_MEAN == 0 || currentResult.NL_MEAN == 0)
  1956. {
  1957. continue; // 跳过无效数据
  1958. }
  1959. OnMessage(LogType.Info,
  1960. $"检测到新数据: JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN}");
  1961. // 写入PLC
  1962. OP70_ScrewDataSet_t resultToPlC = new OP70_ScrewDataSet_t
  1963. {
  1964. fTorque = float.Parse(currentResult.NL_MEAN.ToString()),
  1965. fCircles = float.Parse(currentResult.JD_MEAN.ToString())
  1966. };
  1967. (nRet, strRet) = WriteResultToPlc(7, "", $"g_OP70_MES.{direction}.screwDriver", 1, resultToPlC);
  1968. if (nRet != 0)
  1969. {
  1970. OnMessage(LogType.Info,
  1971. $"SN:{sn}, JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN} 写入PLC失败");
  1972. }
  1973. else
  1974. {
  1975. OnMessage(LogType.Info,
  1976. $"SN:{sn}, JD_MEAN={currentResult.JD_MEAN}, NL_MEAN={currentResult.NL_MEAN} 写入PLC成功");
  1977. }
  1978. // 构建保存路径
  1979. string dateFolder = DateTime.Now.ToString("yyyyMMdd");
  1980. string basePath = AppDomain.CurrentDomain.BaseDirectory;
  1981. string savePath = Path.Combine(basePath, "screw", dateFolder, sn, direction, "曲线");
  1982. Directory.CreateDirectory(savePath); // 确保目录存在
  1983. // 构建文件名(以 SN + 序号命名)
  1984. string fileName = $"{sn}_{fileCounter}.txt";
  1985. string filePath = Path.Combine(savePath, fileName);
  1986. // 写入文件
  1987. using (StreamWriter writer = new StreamWriter(filePath))
  1988. {
  1989. writer.WriteLine("精度, 扭力");
  1990. // 遍历 Pearkdegree 和 PearkTorque 的所有值
  1991. for (int i = 0;
  1992. i < currentResult.Pearkdegree.Length && i < currentResult.PearkTorque.Length;
  1993. i++)
  1994. {
  1995. double precision = Math.Round(currentResult.Pearkdegree[i]); // 精度
  1996. double torque = Math.Round(currentResult.PearkTorque[i], 2); // 扭力
  1997. writer.WriteLine($"{precision}, {torque}");
  1998. }
  1999. }
  2000. OnMessage(LogType.Info, $"保存文件成功: {filePath}");
  2001. // 增加文件计数器
  2002. fileCounter++;
  2003. }
  2004. // 如果没有更多数据,则短暂休眠以节省资源
  2005. if (!cachedData.Any())
  2006. {
  2007. Thread.Sleep(10); // 根据需要调整休眠时间
  2008. }
  2009. // 如果触发了出站,则退出循环
  2010. if (!isCollectingFlagRight)
  2011. {
  2012. break;
  2013. }
  2014. }
  2015. stopwatch.Stop();
  2016. OnMessage(LogType.Info, $"数据采集完成; 总用时 {stopwatch.ElapsedMilliseconds}ms");
  2017. }
  2018. catch (Exception ex)
  2019. {
  2020. OnMessage(LogType.Error, $"数据采集过程中发生错误: {ex.Message}");
  2021. }
  2022. finally
  2023. {
  2024. isCollectingFlagRight = false;
  2025. }
  2026. }
  2027. private void CopyFileToTempPath(string morepath,string temppath) {
  2028. string tempPath = GlobalContext.MqttFileTempDir; //临时存放图片的文件夹
  2029. var morePath = morepath.Split(",");
  2030. try
  2031. {
  2032. if (Directory.Exists(tempPath))
  2033. {
  2034. Directory.Delete(tempPath, recursive: true); // 清理临时目录
  2035. }
  2036. foreach (var item in morePath)
  2037. {
  2038. foreach (var file in Directory.GetFiles(item, "*.*", SearchOption.AllDirectories))
  2039. {
  2040. var relativePath = file.Substring(item.Length + 1);
  2041. var destFile = Path.Combine(temppath, relativePath);
  2042. Directory.CreateDirectory(Path.GetDirectoryName(destFile));
  2043. File.Copy(file, destFile, overwrite: true);
  2044. //删除文件
  2045. (bool, string) newResult = DeleteFile(file);
  2046. }
  2047. }
  2048. }
  2049. catch (Exception ex){
  2050. throw ex;
  2051. }
  2052. }
  2053. /// <summary>
  2054. /// 压缩文件
  2055. /// </summary>
  2056. /// <param name="folderPath">源文件地址</param>
  2057. /// <param name="zipFilePath">目标地址</param>
  2058. /// <returns></returns>
  2059. public static (int, string) CompressFolder(string folderPath, string zipFilePath)
  2060. {
  2061. try
  2062. {
  2063. // 创建zip文件,将指定文件夹内的所有内容压缩到这个zip文件中
  2064. System.IO.Compression.ZipFile.CreateFromDirectory(folderPath, zipFilePath);
  2065. return (1, "文件夹已成功压缩!");
  2066. }
  2067. catch (Exception ex)
  2068. {
  2069. return (0, "文件压缩出错!" + ex.Message);
  2070. }
  2071. }
  2072. /// <summary>
  2073. /// 上传文件
  2074. /// </summary>
  2075. /// <param name="BarcodeSet_t">条码集合</param>
  2076. /// <param name="stationCode">工站编号</param>
  2077. /// <param name="stationName">工站名称</param>
  2078. /// <param name="path">文件路径</param>
  2079. public async Task<(int, string)> SaveDBbyFileInfo(BarcodeSet_t BarcodeSet, string stationCode,
  2080. string stationName, int pass, string path, string guid = "")
  2081. {
  2082. string sql, filename = "";
  2083. int result = 0;
  2084. var formData = new MultipartFormDataContent();
  2085. string msg = "";
  2086. string file_category = "IMAGE"; //IMAGE 、TEXT 、UNKNOWN
  2087. string file_type = "IMAGE";
  2088. string project = GlobalContext.ProgramName;
  2089. string run_mode = GlobalContext.run_mode;
  2090. string product_mode = GlobalContext.product_mode;
  2091. string pass_result = (pass == 1 ? "PASS" : "Fail");
  2092. string device_code = xiaomiParm.deviceCode;
  2093. string sn = BarcodeSet.strProductBarcode;
  2094. string staion_id = xiaomiParm.stationCode;
  2095. string bucket =
  2096. $"{file_category}/{file_type}/{project}/{product_mode}/{run_mode}/{pass_result}/{device_code}/{sn}/{staion_id}";
  2097. // 获取所有图片文件
  2098. if (guid == "")
  2099. {
  2100. guid = Guid.NewGuid().ToString();
  2101. }
  2102. try
  2103. {
  2104. if (GlobalContext.MESIsSendUpFile)
  2105. {
  2106. List<string> imageFiles = GetAllImageFiles(path);
  2107. string toPath = GlobalContext.MqttFileBackupLogDir;
  2108. filename =
  2109. $"{xiaomiParm.workstation}_{file_type}_{sn}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.zip";
  2110. //string directoryPath = Path.GetDirectoryName(path);
  2111. string strFilePath = toPath + "\\" + filename;
  2112. if (imageFiles.Count > 0)
  2113. {
  2114. var r = CompressFolder(path, strFilePath);
  2115. if (r.Item1 == 0)
  2116. {
  2117. return (0, r.Item2);
  2118. }
  2119. else
  2120. {
  2121. msg = r.Item2 + "\r\n";
  2122. }
  2123. }
  2124. else
  2125. {
  2126. return (0, "文件不存在!");
  2127. }
  2128. FileUpload_X5 fileUpload_X5 = new FileUpload_X5();
  2129. fileUpload_X5.bucket = bucket;
  2130. fileUpload_X5.name = filename;
  2131. fileUpload_X5.uuid = guid.ToString();
  2132. ///需要上传文件
  2133. FileInfo file = new FileInfo(strFilePath);
  2134. string fileMd5Hex = GetMD5Hex(file);
  2135. fileUpload_X5.md5 = fileMd5Hex;
  2136. fileUpload_X5.uploadCloud = true;
  2137. fileUpload_X5.informMqtt = true;
  2138. FileMqttPayload fileMqttPayload = new FileMqttPayload();
  2139. fileMqttPayload.factory = GlobalContext.Factory_Code;
  2140. fileMqttPayload.project_name = GlobalContext.Project_Code;
  2141. fileMqttPayload.product_mode = GlobalContext.product_mode;
  2142. fileMqttPayload.line_no = GlobalContext.LineCode;
  2143. fileMqttPayload.work_station_no = xiaomiParm.workstation;
  2144. fileMqttPayload.equipment_no = xiaomiParm.deviceCode;
  2145. fileMqttPayload.station_no = xiaomiParm.stationCode;
  2146. fileMqttPayload.file_id = guid;
  2147. fileMqttPayload.file_name = filename;
  2148. fileMqttPayload.sn = BarcodeSet.strProductBarcode;
  2149. //fileMqttPayload.opt_time = "";
  2150. //fileMqttPayload.file_type = "";
  2151. //fileMqttPayload.file_category = "";
  2152. //fileMqttPayload.tag = "";
  2153. fileMqttPayload.reference_info.pass_station_id = uuid;
  2154. var fileresult = await
  2155. XiaomiMESHttp_UpLoadFile.FileUoladToMes(strFilePath, fileUpload_X5, fileMqttPayload);
  2156. if (fileresult.Item1 != 1)
  2157. {
  2158. return (0, msg + fileresult.Item2 + "\r\n");
  2159. }
  2160. else
  2161. {
  2162. msg = msg + fileresult.Item2 + "\r\n";
  2163. }
  2164. }
  2165. return (1, msg);
  2166. }
  2167. catch (Exception e)
  2168. {
  2169. return (0,
  2170. filename + $"文件上传错误!载具码:{BarcodeSet.strCarrierBarcode}产品码{BarcodeSet.strProductBarcode},错误原因:" +
  2171. e.Message);
  2172. }
  2173. }
  2174. /// <summary>
  2175. /// 获取路径下的所有图片
  2176. /// </summary>
  2177. /// <param name="directoryPath"></param>
  2178. /// <returns></returns>
  2179. public List<string> GetAllImageFiles(string directoryPath)
  2180. {
  2181. var imageExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
  2182. { ".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff" };
  2183. var imageFiles = new List<string>();
  2184. try
  2185. {
  2186. // 遍历目录及子目录中的所有文件
  2187. foreach (string file in Directory.EnumerateFiles(directoryPath, "*.*", SearchOption.AllDirectories))
  2188. {
  2189. // 获取文件扩展名并检查是否为图片格式
  2190. string extension = Path.GetExtension(file);
  2191. if (imageExtensions.Contains(extension))
  2192. {
  2193. imageFiles.Add(file);
  2194. }
  2195. }
  2196. }
  2197. catch (Exception ex)
  2198. {
  2199. OnMessage(LogType.Error, $"图片查询发生错误: {ex.Message}");
  2200. }
  2201. return imageFiles;
  2202. }
  2203. /// <summary>
  2204. /// 实例化报警字典
  2205. /// </summary>
  2206. private (bool, string) InitalDicAlarm()
  2207. {
  2208. #region 加载报警表
  2209. string excelPath = "";
  2210. switch (GlobalContext.IsUsePLCNow)
  2211. {
  2212. case 1:
  2213. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_10_壳体清洁上料.xlsx";
  2214. break;
  2215. case 2:
  2216. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_20_上盖板上料装备.xlsx";
  2217. break;
  2218. case 3:
  2219. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_30_点散热胶装备.xlsx";
  2220. break;
  2221. case 4:
  2222. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_40_胶线检测.xlsx";
  2223. break;
  2224. case 5:
  2225. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_50_ADD板上料组装装备.xlsx";
  2226. break;
  2227. case 6:
  2228. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_60_组上盖板.xlsx";
  2229. break;
  2230. case 7:
  2231. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_70_上盖板锁螺丝.xlsx";
  2232. break;
  2233. case 8:
  2234. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_80_NG下料.xlsx";
  2235. break;
  2236. case 9:
  2237. excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_90_半成品下料.xlsx";
  2238. break;
  2239. default:
  2240. return (false, $"不支持当前PLC[{GlobalContext.IsUsePLCNow}]的报警点位表!请在设置页切换到正确的plc后重启该软件!");
  2241. }
  2242. if (!File.Exists(excelPath))
  2243. return (false, $"未找到当前PLC[{GlobalContext.IsUsePLCNow}]的报警点位表!请检查文件路径:'{excelPath}'。");
  2244. DataTable DtModel = NPOIHelper.ReadExcel(excelPath);
  2245. if (DtModel == null || DtModel.Rows.Count < 1)
  2246. return (false, $"报警点位表未包含任何报警数据!请检查‘{excelPath}’文件!");
  2247. // 检查列名
  2248. List<string> isNeedParms = new List<string>()
  2249. {
  2250. "设备分类名称", "设备分类编码", "分类层级1", "分类层级2", "分类层级3", "分类层级4", "事件名称", "事件ID", "描述", "标签", "PLC地址", "工位"
  2251. }; // 必须要有的列
  2252. // 指定列名 + 检查列是否完整
  2253. DataRow dtRowName = DtModel.Rows[0];
  2254. int count = DtModel.Columns.Count;
  2255. for (int i = 0; i < count; i++)
  2256. {
  2257. string columeName = dtRowName[i]?.ToString();
  2258. if (!string.IsNullOrEmpty(columeName))
  2259. DtModel.Columns[i].ColumnName = columeName;
  2260. if ((!string.IsNullOrEmpty(columeName)) && isNeedParms.Count > 0 && isNeedParms.Contains(columeName))
  2261. isNeedParms.Remove(columeName);
  2262. }
  2263. DtModel.Rows.RemoveAt(0);
  2264. if (isNeedParms.Count > 0)
  2265. {
  2266. string msg1 = string.Join(",", isNeedParms);
  2267. return (false, $"报警点位表未包含列:{msg1}!请检查‘{excelPath}’文件!");
  2268. }
  2269. #endregion 加载报警表
  2270. List<Alarm> keyValues1 = new List<Alarm>();
  2271. for (int i = 0; i < DtModel.Rows.Count; i++)
  2272. {
  2273. Alarm alarm = new Alarm();
  2274. alarm.plcName = DtModel.Rows[i]["设备分类名称"]?.ToString(); // 设备名;
  2275. string type1Str = DtModel.Rows[i]["分类层级1"]?.ToString(); // 分类层级1;
  2276. alarm.type1CH = type1Str; // 分类层级1 中文
  2277. alarm.type1 = type1Str; // 分类层级1
  2278. if (!string.IsNullOrEmpty(type1Str) && type1Str.Contains("\n"))
  2279. {
  2280. string[] type1Strs = type1Str.Split('\n');
  2281. if (type1Strs.Length >= 2)
  2282. {
  2283. alarm.type1CH = type1Strs[0].Trim(); // 分类层级1 中文
  2284. alarm.type1 = type1Strs[1].Trim(); // 分类层级1
  2285. if (string.IsNullOrEmpty(alarm.type1))
  2286. alarm.type1 = alarm.type1CH;
  2287. }
  2288. }
  2289. string type2Str = DtModel.Rows[i]["分类层级2"]?.ToString(); // 分类层级2;电气控制 electric_control
  2290. alarm.type2CH = type2Str; // 分类层级2 中文
  2291. alarm.type2 = type2Str; // 分类层级2
  2292. if (!string.IsNullOrEmpty(type2Str) && type2Str.Contains("\n"))
  2293. {
  2294. string[] type2Strs = type2Str.Split('\n');
  2295. if (type2Strs.Length >= 2)
  2296. {
  2297. alarm.type2CH = type2Strs[0].Trim(); // 分类层级2 中文
  2298. alarm.type2 = type2Strs[1].Trim(); // 分类层级2
  2299. if (string.IsNullOrEmpty(alarm.type2))
  2300. alarm.type2 = alarm.type2CH;
  2301. }
  2302. }
  2303. string type3Str = DtModel.Rows[i]["分类层级3"]?.ToString(); // 分类层级3;故障 Fault
  2304. alarm.type3CH = type3Str; // 分类层级3 中文
  2305. alarm.type3 = type3Str; // 分类层级3
  2306. if (!string.IsNullOrEmpty(type3Str) && type3Str.Contains("\n"))
  2307. {
  2308. string[] type3Strs = type3Str.Split('\n');
  2309. if (type3Strs.Length >= 2)
  2310. {
  2311. alarm.type3CH = type3Strs[0].Trim(); // 分类层级3 中文
  2312. alarm.type3 = type3Strs[1].Trim(); // 分类层级3
  2313. if (string.IsNullOrEmpty(alarm.type3))
  2314. alarm.type3 = alarm.type3CH;
  2315. }
  2316. }
  2317. string faultStr = DtModel.Rows[i]["分类层级4"]?.ToString(); // 故障部件;overall_module
  2318. alarm.type4 = faultStr; // 分类层级4 中文
  2319. alarm.type4CH = faultStr; // 分类层级4
  2320. if (!string.IsNullOrEmpty(faultStr) && faultStr.Contains("\n"))
  2321. {
  2322. string[] faultStrs = faultStr.Split('\n');
  2323. if (faultStrs.Length >= 2)
  2324. {
  2325. alarm.type4CH = faultStrs[0].Trim(); // 故障部件;overall_module
  2326. alarm.type4 = faultStrs[1].Trim(); // 故障部件
  2327. if (string.IsNullOrEmpty(alarm.type4))
  2328. alarm.type4 = alarm.type4CH;
  2329. }
  2330. }
  2331. alarm.fault_code = DtModel.Rows[i]["事件ID"]?.ToString(); // 故障编码;A40001
  2332. alarm.fault_name = DtModel.Rows[i]["事件名称"]?.ToString(); // 故障名称;AL[1000]_系统_HMI急停故障
  2333. alarm.fault_desc = alarm.fault_name; // 故障描述;AL[1000]_系统_HMI急停故障
  2334. string plcAdress = DtModel.Rows[i]["PLC地址"]?.ToString();
  2335. alarm.PLC地址 = plcAdress;
  2336. plcAdress = plcAdress.Replace("fault_codes[", "");
  2337. plcAdress = plcAdress.Replace("]", "");
  2338. alarm.group_index = Convert.ToInt32(plcAdress.Split(".")[0]);
  2339. keyValues1.Add(alarm);
  2340. }
  2341. DicAlarms_Cur.Add(GlobalContext.IsUseStationName, keyValues1); // 这里使用线体代替工位
  2342. return (true, "报警字典表初始化成功!");
  2343. }
  2344. private async void ReadPLCAlarmToIot(uint[] FaultData, uint[] FaultDataOld, string stationNameStr,string flag)
  2345. {
  2346. DateTime dtNow = DateTime.Now;
  2347. try
  2348. {
  2349. List<DeviceAlarm_Cur> deviceAlarm_Curs = new List<DeviceAlarm_Cur>(); // 同步到报警页面用传输载体
  2350. List<(int, int)> AlarmIndexList = new List<(int, int)>(); //收集所有报警信息的位置
  2351. AlarmData alarmData = new AlarmData();
  2352. bool isNeedUpdUI = false; // 是否需要更新历史报警UI
  2353. bool isNoAlarm = false; //是否有报警
  2354. string binaryString = "";
  2355. bool isNoNewAlarm = false; //是否有新的报警
  2356. if (FaultData.Length > 0)
  2357. {
  2358. //foreach (var item in FaultData)
  2359. //{
  2360. // if (item > 0)
  2361. // {
  2362. // isNoAlarm = true;
  2363. // break;
  2364. // }
  2365. // else {
  2366. // isNoAlarm = false;
  2367. // }
  2368. //}
  2369. //如果警报都是0,则跳过解析
  2370. if (FaultData?.All(x => x == 0) ?? true)
  2371. {
  2372. if (flag == "left")
  2373. {
  2374. _FaultDatas_Old = FaultData.ToArray();
  2375. }
  2376. else
  2377. {
  2378. _FaultDatas_Old2 = FaultData.ToArray();
  2379. }
  2380. return;
  2381. }
  2382. if (!FaultData.SequenceEqual(FaultDataOld))
  2383. {
  2384. isNoNewAlarm = true;
  2385. isNeedUpdUI = true;
  2386. }
  2387. //if (FaultData.Length > 0 && isNoAlarm && isNoNewAlarm)
  2388. if (FaultData.Length > 0 && isNoNewAlarm)
  2389. {
  2390. //解析报警信息,分析当前报警在字典中的定位
  2391. for (int i = 0; i <= FaultData.Length - 1; i++)
  2392. {
  2393. var num = 0;
  2394. if (FaultData[i] > 0)
  2395. {
  2396. //转换二进制
  2397. binaryString = Convert.ToString(FaultData[i], 2);
  2398. for (int j = binaryString.Length - 1; j >= 0; j--)
  2399. {
  2400. num++;
  2401. char s = binaryString[j];
  2402. if (binaryString[j] == '1')
  2403. {
  2404. //记录1的位置
  2405. AlarmIndexList.Add((i, num - 1));
  2406. }
  2407. }
  2408. }
  2409. }
  2410. // 同步“设备报警信息”到“设备报警临时字典DicAlarms_Cur”
  2411. var dicAlarms_Cur_PLC1 = DicAlarms_Cur[GlobalContext.IsUseStationName];
  2412. foreach ((int index, int row) in AlarmIndexList)
  2413. {
  2414. var tempDic = dicAlarms_Cur_PLC1.Where(x => x.group_index == index).ToList();
  2415. for (int i = 0; i < tempDic.Count - 1; i++) // 读取
  2416. {
  2417. //若报警字典第[group_index]个数据,第[i]行与AlarmIndexList中的定位匹配,则添加进对应行的报警数据
  2418. if (tempDic[i].group_index == index && i == row)
  2419. {
  2420. dicAlarms_Cur_PLC1.Where(x => x.group_index == index).ToList()[row].报警数据 =
  2421. new AlarmData()
  2422. {
  2423. GUID = Guid.NewGuid().ToString(),
  2424. LineName = GlobalContext.IsUseStationName, // 工站
  2425. PlcStation = tempDic[i].plcName, // 工站全称;[S1]
  2426. Type1 = tempDic[i].type1, // 故障层级1
  2427. Type2 = tempDic[i].type2, // 故障层级2
  2428. Type3 = tempDic[i].type3, // 故障层级3
  2429. Type4 = tempDic[i].type4, // 故障层级4
  2430. AlarmType = tempDic[i].fault_code, // 报警类型
  2431. AlarmDesc = tempDic[i].fault_name, // 报警内容
  2432. StartTime = dtNow // 开始时间
  2433. };
  2434. // 传输到页面
  2435. deviceAlarm_Curs.Add(new DeviceAlarm_Cur()
  2436. {
  2437. 线体名称 = tempDic[i].plcName,
  2438. 报警类型 = tempDic[i].fault_code,
  2439. 报警内容 = tempDic[i].fault_name,
  2440. 开始时间 = dtNow
  2441. });
  2442. // 新增到数据库
  2443. //var data1 = dicAlarms_Cur_PLC1.Where(x => x.group_index == index).ToList()[row].报警数据;
  2444. //SaveAlarmDataByDB(stationNameStr, data1, false);
  2445. //OnMessage(LogType.Info, $"更新{BodyAlarm}完毕!");
  2446. }
  2447. }
  2448. }
  2449. //筛选含报警数据的字典
  2450. var dicAlarms_Cur = dicAlarms_Cur_PLC1.Where(x => x.报警数据 != null).ToList();
  2451. if (dicAlarms_Cur.Count > 0)
  2452. {
  2453. string stationId = "";
  2454. foreach (var item in dicAlarms_Cur)
  2455. {
  2456. if (!string.IsNullOrEmpty(xiaomiParm.stationCode))
  2457. {
  2458. stationId = xiaomiParm.stationCode;
  2459. //上传
  2460. SaveAlarmDataByDB(GlobalContext.IsUseStationName, stationId, item.报警数据, false);
  2461. }
  2462. else {
  2463. if (flag == "left")
  2464. {
  2465. if (GlobalContext.IsUsePLC3)
  2466. stationId = GlobalContext.s3_1_station;
  2467. if (GlobalContext.IsUsePLC7)
  2468. stationId = GlobalContext.s7_1_station;
  2469. //上传
  2470. SaveAlarmDataByDB(GlobalContext.IsUseStationName, stationId, item.报警数据, false);
  2471. }
  2472. else {
  2473. if (GlobalContext.IsUsePLC3)
  2474. stationId = GlobalContext.s3_2_station;
  2475. if (GlobalContext.IsUsePLC7)
  2476. stationId = GlobalContext.s7_2_station;
  2477. //上传
  2478. SaveAlarmDataByDB(GlobalContext.IsUseStationName, stationId, item.报警数据, false);
  2479. }
  2480. }
  2481. }
  2482. }
  2483. // 有新报警则更新
  2484. if (isNeedUpdUI)
  2485. // UI展示 - 展示到设备状态页
  2486. await Task.Run(() =>
  2487. {
  2488. try
  2489. {
  2490. if (Form_Main.formDevAlarm != null && !Form_Main.formDevAlarm.IsDisposed)
  2491. {
  2492. Form_Main.formDevAlarm.UpdDeviceAlarm_Cur(deviceAlarm_Curs); // 报警UI 更新
  2493. if (Form_Main.formDevAlarm.Visible)
  2494. Form_Main.formDevAlarm.UpdDeviceAlarm_History_48H(); // 历史报警UI 更新
  2495. }
  2496. }
  2497. catch
  2498. {
  2499. }
  2500. });
  2501. if (flag == "left")
  2502. {
  2503. _FaultDatas_Old = FaultData.ToArray();
  2504. }
  2505. else {
  2506. _FaultDatas_Old2 = FaultData.ToArray();
  2507. }
  2508. }
  2509. }
  2510. //FaultLogRequest request = new FaultLogRequest();
  2511. //request.station = mesStation; // 工位
  2512. //request.fault_name = xmFaultName; // 故障名称(同数据字典中的事件名称)
  2513. //request.fault_code = xmFaultCode2; // 故障编码(A,B,C,D,E)
  2514. //request.fault_cmpnt = xmFaultCmpnt; // 故障部件
  2515. //request.fault_desc = xmFaultDesc; // 故障描述
  2516. //request.fault_tm = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 故障发生时间 2022-06-01 14:27:57.283
  2517. // // 上传
  2518. //(int, string) iotResult = XiaomiMqttClient_Extend.Write_FaultLog(request, type1, type2, type3, request.fault_cmpnt, deciveCode);
  2519. }
  2520. catch (Exception ex)
  2521. {
  2522. string str = ex.StackTrace;
  2523. AddMessage_Station(stationNameStr, LogType.Error,
  2524. $"{stationNameStr}_获取报警数据出错!错误信息:" + ex.Message.ToString() + "异常位置:" +
  2525. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2526. }
  2527. }
  2528. public void operateToIot(string action, string stationNameStr)
  2529. {
  2530. OperateLogRequest request = new OperateLogRequest();
  2531. request.software_version = "V" + Application.ProductVersion; // 软件版本号;如:V1.2.4
  2532. request.operate_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 操作时间(2022-06-01 14:27:57.283)
  2533. request.operate_action = action; // 操作动作(对应软件开启/关闭/重新加载项⽬;startup、shutdown、reload)
  2534. //request.current_process = Process.GetCurrentProcess()?.Id.ToString(); // 当前进程;进程ID
  2535. request.current_process = Application.ProductName;
  2536. request.operate_desc = stationNameStr; // 操作描述;如:供应商软件开启/关闭/重新加载项⽬
  2537. request.operate_result = "success"; // 操作结果
  2538. request.operator_name = "default"; // 操作账号名;填当前操作⽤⼾,如⽆则填default
  2539. // 上传
  2540. (int, string) iotResult = XiaomiMqttClient_Extend.Write_OperateLog(request);
  2541. if (iotResult.Item1 != 0)
  2542. {
  2543. AddMessage(LogType.Info, "【操作记录】上传失败!错误原因:" + iotResult.Item2 + "操作状态:" + stationNameStr);
  2544. }
  2545. }
  2546. public void deviceConfigToIot(string id, string value)
  2547. {
  2548. DeviceConfigRequest request = new DeviceConfigRequest();
  2549. request.id = id; // 操作时间(2022-06-01 14:27:57.283)
  2550. request.value = value; // 操作动作(对应软件开启/关闭/重新加载项⽬;startup、shutdown、reload)
  2551. // 上传
  2552. (int, string) iotResult = XiaomiMqttClient_Extend.Write_deviceConfig(request);
  2553. if (iotResult.Item1 != 0)
  2554. {
  2555. AddMessage(LogType.Info, "【装备配置】上传失败!错误原因:" + iotResult.Item2 );
  2556. }
  2557. }
  2558. private static readonly object _oeeLock = new object();
  2559. private void 通用节拍接口(int plcNo, string stationNameStr, string tagMesCommName, string CarrierBarcode,
  2560. IoT_DataSet_t iot_data, out int res)
  2561. {
  2562. lock (_oeeLock) // 保证同一时间只有一个任务执行
  2563. {
  2564. Stopwatch stopwatch1 = new Stopwatch();
  2565. Stopwatch stopwatch2 = new Stopwatch();
  2566. string resultStr = string.Empty;
  2567. try
  2568. {
  2569. string oEEType = iot_data.beatAction.ToString(); // 节拍类型(plc写入)
  2570. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode); //产品SN
  2571. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  2572. (short, string) result = (0, "");
  2573. // 上传开始节拍 节拍只需要PLC传1、3、4、5
  2574. result = SaveOEEData(plcNo, stationNameStr, deviceOEE, strProductBarcode, CarrierBarcode);
  2575. //上传结束节拍
  2576. switch (oEEType)
  2577. {
  2578. case "1":
  2579. Enum.TryParse("2", out deviceOEE);
  2580. result = SaveOEEData(plcNo, stationNameStr, deviceOEE, strProductBarcode, CarrierBarcode);
  2581. break;
  2582. case "5":
  2583. Enum.TryParse("6", out deviceOEE);
  2584. result = SaveOEEData(plcNo, stationNameStr, deviceOEE, strProductBarcode, CarrierBarcode);
  2585. break;
  2586. }
  2587. if (result.Item1 == 1)
  2588. {
  2589. OnMessage(LogType.Info, $"PLC{plcNo}_{stationNameStr} 节拍[{deviceOEE}]上传成功!");
  2590. //写入PLC
  2591. IoT_DataSet_t iotData = new IoT_DataSet_t();
  2592. iotData.machineState = iot_data.machineState;
  2593. iotData.work_type = iot_data.work_type;
  2594. iotData.testStatus = iot_data.testStatus;
  2595. iotData.beatAction = 0;
  2596. iotData.beatReturn = 1; //OK
  2597. iotData.fault_codes = iot_data.fault_codes;
  2598. (int, string) PLCresult = WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, iotData);
  2599. if (PLCresult.Item1 == 0)
  2600. {
  2601. res = 1;
  2602. OnMessage(LogType.Info, $"PLC{plcNo}_{stationNameStr} 节拍[{deviceOEE}]写入成功!");
  2603. }
  2604. else
  2605. {
  2606. res = 0;
  2607. }
  2608. }
  2609. else
  2610. {
  2611. res = 0;
  2612. OnMessage(LogType.Info, $"PLC{plcNo}_{stationNameStr} 节拍[{deviceOEE}]接口出错!错误信息:" + result.Item2);
  2613. //写入PLC
  2614. IoT_DataSet_t iotData = new IoT_DataSet_t();
  2615. iotData.machineState = iot_data.machineState;
  2616. iotData.work_type = iot_data.work_type;
  2617. iotData.testStatus = iot_data.testStatus;
  2618. iotData.beatAction = 0;
  2619. iotData.beatReturn = 2; //NG
  2620. iotData.fault_codes = iot_data.fault_codes;
  2621. (int, string) PLCresult = WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, iotData);
  2622. }
  2623. }
  2624. catch (Exception ex)
  2625. {
  2626. res = 0;
  2627. string str = ex.StackTrace;
  2628. AddMessage_Station(stationNameStr, LogType.Error,
  2629. $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" +
  2630. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2631. //写入PLC
  2632. IoT_DataSet_t iotData = new IoT_DataSet_t();
  2633. iotData.machineState = iot_data.machineState;
  2634. iotData.work_type = iot_data.work_type;
  2635. iotData.testStatus = iot_data.testStatus;
  2636. iotData.beatAction = 0;
  2637. iotData.beatReturn = 2; //NG
  2638. iotData.fault_codes = iot_data.fault_codes;
  2639. (int, string) PLCresult = WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, iotData);
  2640. }
  2641. }
  2642. }
  2643. /// <summary>
  2644. /// 去除常见特殊字符,如 \r, \n, \t 等
  2645. /// </summary>
  2646. /// <param name="format"></param>
  2647. /// <returns></returns>
  2648. private static string FormatStrbyPLC(string format)
  2649. {
  2650. string cleanedString = "";
  2651. if (!string.IsNullOrEmpty(format))
  2652. {
  2653. cleanedString = Regex.Replace(format, @"[\r\n\t]", "");
  2654. }
  2655. return cleanedString;
  2656. }
  2657. private void S1_OpenDialog(int plcNo,string stationNameStr,string tagBaseName,string tagMesCommName) {
  2658. Task.Run(() =>
  2659. {
  2660. using (var dialog = new BandBarodeDialog_S1())
  2661. {
  2662. var rs = dialog.ShowDialog();
  2663. if (rs == DialogResult.OK)
  2664. {
  2665. //绑定载具和产品
  2666. ResponseMessage message = new ResponseMessage();
  2667. message = SQLHelper.InsertCarrierBind(_strCarrierBarcode, _strProductBarcode);
  2668. if (message.result == false)
  2669. {
  2670. AddMessage(LogType.Error, stationNameStr + "_载具码与产品码绑定失败,错误:" + message.text);
  2671. CommandFromPLC CommandToPlC = new CommandFromPLC();
  2672. CommandToPlC.cmd = 0;
  2673. CommandToPlC.cmdParam = 5;
  2674. CommandToPlC.cmdResult = 0;
  2675. WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, CommandToPlC);
  2676. return;
  2677. }
  2678. else
  2679. {
  2680. AddMessage(LogType.Error, stationNameStr + "_载具码与产品码绑定成功");
  2681. CommandFromPLC CommandToPlC = new CommandFromPLC();
  2682. CommandToPlC.cmd = 0;
  2683. CommandToPlC.cmdParam = 4;
  2684. CommandToPlC.cmdResult = 0;
  2685. WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, CommandToPlC);
  2686. }
  2687. AddMessage(LogType.Info, $"载具码:{_strCarrierBarcode},产品码:{_strProductBarcode}");
  2688. //StopWhile = false;//开启while循环
  2689. }
  2690. }
  2691. });
  2692. }
  2693. /// <summary>
  2694. /// 连接数组元素
  2695. /// </summary>
  2696. /// <param name="array"></param>
  2697. /// <returns></returns>
  2698. private static string ArrayToString(Array array)
  2699. {
  2700. // 使用 string.Join 连接数组元素
  2701. return string.Join(", ", array.Cast<object>().Select(x => x.ToString()));
  2702. }
  2703. #endregion
  2704. #region S1
  2705. /// <summary>
  2706. /// [S1] 壳体清洁上料装备(10扫码改造注释(临时))
  2707. /// </summary>
  2708. /// <param name="plcNo">PLC编号</param>
  2709. //private void ReadStation_S1(int plcNo)
  2710. //{
  2711. // string stationCode = "[OP10]";
  2712. // string stationName = "壳体清洁上料";
  2713. // string stationNameStr = stationCode + stationName;
  2714. // string tagBaseName = "g_OP10_MES"; //标签变量名称
  2715. // string tagMesCommName = "mesCommToPC"; //标签变量名称
  2716. // string tagAgvCommName = "agvCommFrmPC";
  2717. // string tagiotComnName = "iotData";
  2718. // string tagBarsetName = "BarcodeSet";
  2719. // string CarrierBarcode = "";
  2720. // string ProductBarcode = "";
  2721. // // 触发信号字典
  2722. // //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  2723. // s1PLCSignal_Old.Add("a1OEEType", 0); // 节拍类型(plc写入)
  2724. // // PLC数据字典 赋值
  2725. // s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  2726. // s1PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  2727. // OP10_MesData_t stPLC_MesData; //PLC的MES数据
  2728. // (int, string) result;
  2729. // while (true)
  2730. // {
  2731. // try
  2732. // {
  2733. // if (!GlobalContext._IsCon_Funs1)
  2734. // {
  2735. // UpdatePLCMonitor(1, plcNo, 0);
  2736. // continue;
  2737. // }
  2738. // if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  2739. // {
  2740. // Stopwatch stopwatch1 = new Stopwatch();
  2741. // Stopwatch stopwatch2 = new Stopwatch();
  2742. // stopwatch1.Start();
  2743. // stopwatch2.Start();
  2744. // #region 一次性读取所有数据
  2745. // // 一次性读取所有数据
  2746. // result = FunsEip[plcNo]
  2747. // .Read_SingleTag<OP10_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  2748. // if (result.Item1 != 0)
  2749. // {
  2750. // //richTextBox1.AppendText("\n" + strRet);
  2751. // }
  2752. // else
  2753. // {
  2754. // //richTextBox1.AppendText("\n" + "读取成功");
  2755. // stPLC_MesData.BarcodeSet.strProductBarcode =
  2756. // FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  2757. // stPLC_MesData.BarcodeSet.strPartBarcode =
  2758. // FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  2759. // stPLC_MesData.BarcodeSet.strCarrierBarcode =
  2760. // FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  2761. // stPLC_MesData.BarcodeSet.strPCBBarcode =
  2762. // FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  2763. // //设备状态
  2764. // int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  2765. // xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  2766. // ? XiaomiDeviceState.Unknown
  2767. // : (XiaomiDeviceState)xmDeviceStateInt;
  2768. // // 载具SN
  2769. // CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode.ToString();
  2770. // // 物料码(物料码还未绑定载具SN时必填)
  2771. // ProductBarcode = stPLC_MesData.BarcodeSet.strProductBarcode;
  2772. // // 节拍
  2773. // s1PLCData["a1OEEType"] = stPLC_MesData.iotData.beatAction;
  2774. // //报警信息
  2775. // _FaultDatas = stPLC_MesData.iotData.fault_codes;
  2776. // }
  2777. // #endregion 一次性读取所有数据
  2778. // stopwatch2.Stop();
  2779. // #region 进站
  2780. // try
  2781. // {
  2782. // if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  2783. // {
  2784. // lock (lockObj)
  2785. // {
  2786. // if (!ProgressState)
  2787. // {
  2788. // uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  2789. // ProgressState = true;
  2790. // Task.Run(() => S1进站(plcNo, stationNameStr, stPLC_MesData,
  2791. // tagBaseName + "." + tagMesCommName, out ProgressState));
  2792. // }
  2793. // }
  2794. // }
  2795. // }
  2796. // catch (Exception ex)
  2797. // {
  2798. // ProgressState = false;
  2799. // string str = ex.StackTrace;
  2800. // AddMessage_Station(stationNameStr, LogType.Error,
  2801. // $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  2802. // str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2803. // }
  2804. // #endregion 进站
  2805. // #region 出站
  2806. // try
  2807. // {
  2808. // if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  2809. // {
  2810. // lock (lockObj)
  2811. // {
  2812. // if (!ProgressState)
  2813. // {
  2814. // ProgressState = true;
  2815. // Task.Run(() => S1出站(plcNo, stationNameStr, stPLC_MesData,
  2816. // tagBaseName + "." + tagMesCommName, stationCode, stationName,
  2817. // out ProgressState));
  2818. // stPLC_MesData.mesCommFrmPLC.cmd = 0; //清除入站申请
  2819. // }
  2820. // }
  2821. // }
  2822. // }
  2823. // catch (Exception ex)
  2824. // {
  2825. // ProgressState = false;
  2826. // string str = ex.StackTrace;
  2827. // AddMessage_Station(stationNameStr, LogType.Error,
  2828. // $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  2829. // str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2830. // }
  2831. // #endregion 出站
  2832. // #region 节拍接口
  2833. // try
  2834. // {
  2835. // if (stPLC_MesData.iotData.beatAction > 0)
  2836. // {
  2837. // int a1OEEType = Convert.ToInt32(s1PLCData["a1OEEType"]);
  2838. // int a1OEETypeGOld = Convert.ToInt32(s1PLCSignal_Old["a1OEEType"]);
  2839. // if (a1OEEType != a1OEETypeGOld)
  2840. // {
  2841. // s1PLCData["OEETypeFlag"] = "1";
  2842. // }
  2843. // else
  2844. // {
  2845. // s1PLCData["OEETypeFlag"] = "0";
  2846. // }
  2847. // if (s1PLCData["OEETypeFlag"].ToString() == "1" && (a1OEEType == 1 || a1OEEType == 3 || a1OEEType == 4 || a1OEEType == 5))
  2848. // {
  2849. // 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName, CarrierBarcode, stPLC_MesData.iotData, out res);
  2850. // if (res == 1)
  2851. // {
  2852. // s1PLCSignal_Old["a1OEEType"] = s1PLCData["a1OEEType"];
  2853. // }
  2854. // else {
  2855. // s1PLCSignal_Old["a1OEEType"] = 0;
  2856. // }
  2857. // }
  2858. // }
  2859. // else {
  2860. // s1PLCSignal_Old["a1OEEType"] = 0;
  2861. // }
  2862. // }
  2863. // catch (Exception ex)
  2864. // {
  2865. // string str = ex.StackTrace;
  2866. // AddMessage_Station(stationNameStr, LogType.Error,
  2867. // $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  2868. // str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2869. // }
  2870. // #endregion
  2871. // UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  2872. // stopwatch1.Stop();
  2873. // //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  2874. // }
  2875. // else
  2876. // {
  2877. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  2878. // AddMessage_Station(stationNameStr, LogType.Info,
  2879. // "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  2880. // FunsEip[plcNo].Connect(); // 重连
  2881. // }
  2882. // }
  2883. // catch (Exception ex)
  2884. // {
  2885. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  2886. // AddMessage_Station(stationNameStr, LogType.Error,
  2887. // $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  2888. // }
  2889. // Thread.Sleep(IntervalReadPLC);
  2890. // }
  2891. //}
  2892. /// <summary>
  2893. /// [S1] 壳体清洁上料装备(10扫码改造注释(临时))
  2894. /// </summary>
  2895. /// <param name="plcNo">PLC编号</param>
  2896. private async void ReadStation_S1(int plcNo)
  2897. {
  2898. string stationCode = "[OP10]";
  2899. string stationName = "壳体清洁上料";
  2900. string stationNameStr = stationCode + stationName;
  2901. string tagBaseName = "g_OP10_MES"; //标签变量名称
  2902. string tagMesCommName = "mesCommToPC"; //标签变量名称
  2903. string tagAgvCommName = "agvCommFrmPC";
  2904. string tagiotComnName = "iotData";
  2905. string tagBarsetName = "BarcodeSet";
  2906. string CarrierBarcode = "";
  2907. string ProductBarcode = "";
  2908. // 触发信号字典
  2909. //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  2910. s1PLCSignal_Old.Add("a1OEEType", 0); // 节拍类型(plc写入)
  2911. // PLC数据字典 赋值
  2912. s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  2913. s1PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  2914. OP10_MesData_t stPLC_MesData; //PLC的MES数据
  2915. (int, string) result;
  2916. while (true)
  2917. {
  2918. try
  2919. {
  2920. if (!GlobalContext._IsCon_Funs1)
  2921. {
  2922. UpdatePLCMonitor(1, plcNo, 0);
  2923. continue;
  2924. }
  2925. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  2926. {
  2927. Stopwatch stopwatch1 = new Stopwatch();
  2928. Stopwatch stopwatch2 = new Stopwatch();
  2929. stopwatch1.Start();
  2930. stopwatch2.Start();
  2931. #region 一次性读取所有数据
  2932. // 一次性读取所有数据
  2933. result = FunsEip[plcNo]
  2934. .Read_SingleTag<OP10_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  2935. if (result.Item1 != 0)
  2936. {
  2937. //richTextBox1.AppendText("\n" + strRet);
  2938. }
  2939. else
  2940. {
  2941. //测试数据
  2942. //stPLC_MesData.mesCommFrmPLC.cmdParam = 1;
  2943. //richTextBox1.AppendText("\n" + "读取成功");
  2944. stPLC_MesData.BarcodeSet.strProductBarcode =
  2945. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  2946. stPLC_MesData.BarcodeSet.strPartBarcode =
  2947. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  2948. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  2949. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  2950. stPLC_MesData.BarcodeSet.strPCBBarcode =
  2951. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  2952. //设备状态
  2953. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  2954. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  2955. ? XiaomiDeviceState.Unknown
  2956. : (XiaomiDeviceState)xmDeviceStateInt;
  2957. // 载具SN
  2958. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode.ToString();
  2959. // 物料码(物料码还未绑定载具SN时必填)
  2960. ProductBarcode = stPLC_MesData.BarcodeSet.strProductBarcode;
  2961. // 节拍
  2962. s1PLCData["a1OEEType"] = stPLC_MesData.iotData.beatAction;
  2963. //报警信息
  2964. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  2965. //if (stPLC_MesData.mesCommFrmPLC.cmdParam == 2)
  2966. //{
  2967. // BandBarodeDialog_S1.isNoClose=true;
  2968. //}
  2969. }
  2970. #endregion 一次性读取所有数据
  2971. stopwatch2.Stop();
  2972. #region 扫码
  2973. //弹窗期间跳过循环
  2974. //if (StopWhile)
  2975. //{
  2976. // continue;
  2977. //}
  2978. if (stPLC_MesData.mesCommFrmPLC.cmdParam==1)
  2979. {
  2980. if (OpenDailogFalg)
  2981. {
  2982. //await S1_OpenDialog(plcNo, stationNameStr, tagBaseName, tagMesCommName);
  2983. S1_OpenDialog(plcNo, stationNameStr, tagBaseName, tagMesCommName);
  2984. }
  2985. //using (var dialog = new BandBarodeDialog_S1())
  2986. //{
  2987. // var rs = dialog.ShowDialog();
  2988. // if (rs == DialogResult.OK)
  2989. // {
  2990. // //绑定载具和产品
  2991. // ResponseMessage message = new ResponseMessage();
  2992. // message = SQLHelper.InsertCarrierBind(_strCarrierBarcode, _strProductBarcode);
  2993. // if (message.result == false)
  2994. // {
  2995. // AddMessage(LogType.Error, stationNameStr + "_载具码与产品码绑定失败,错误:" + message.text);
  2996. // CommandFromPLC CommandToPlC = new CommandFromPLC();
  2997. // CommandToPlC.cmd = 0;
  2998. // CommandToPlC.cmdParam = 5;
  2999. // CommandToPlC.cmdResult = 0;
  3000. // WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, CommandToPlC);
  3001. // return;
  3002. // }
  3003. // else
  3004. // {
  3005. // AddMessage(LogType.Error, stationNameStr + "_载具码与产品码绑定成功");
  3006. // CommandFromPLC CommandToPlC = new CommandFromPLC();
  3007. // CommandToPlC.cmd = 0;
  3008. // CommandToPlC.cmdParam = 4;
  3009. // CommandToPlC.cmdResult = 0;
  3010. // WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, CommandToPlC);
  3011. // }
  3012. // AddMessage(LogType.Info, $"载具码:{_strCarrierBarcode},产品码:{_strCarrierBarcode}");
  3013. // //StopWhile = false;//开启while循环
  3014. // }
  3015. //}
  3016. }
  3017. #endregion
  3018. #region 进站
  3019. try
  3020. {
  3021. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  3022. {
  3023. lock (lockObj)
  3024. {
  3025. if (!ProgressState)
  3026. {
  3027. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  3028. ProgressState = true;
  3029. Task.Run(() => S1进站(plcNo, stationNameStr, stPLC_MesData,
  3030. tagBaseName + "." + tagMesCommName, out ProgressState));
  3031. }
  3032. }
  3033. }
  3034. }
  3035. catch (Exception ex)
  3036. {
  3037. ProgressState = false;
  3038. string str = ex.StackTrace;
  3039. AddMessage_Station(stationNameStr, LogType.Error,
  3040. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3041. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3042. }
  3043. #endregion 进站
  3044. #region 出站
  3045. try
  3046. {
  3047. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  3048. {
  3049. lock (lockObj)
  3050. {
  3051. if (!ProgressState)
  3052. {
  3053. ProgressState = true;
  3054. Task.Run(() => S1出站(plcNo, stationNameStr, stPLC_MesData,
  3055. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  3056. out ProgressState));
  3057. stPLC_MesData.mesCommFrmPLC.cmd = 0; //清除入站申请
  3058. }
  3059. }
  3060. }
  3061. }
  3062. catch (Exception ex)
  3063. {
  3064. ProgressState = false;
  3065. string str = ex.StackTrace;
  3066. AddMessage_Station(stationNameStr, LogType.Error,
  3067. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3068. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3069. }
  3070. #endregion 出站
  3071. #region 节拍接口
  3072. try
  3073. {
  3074. if (stPLC_MesData.iotData.beatAction > 0)
  3075. {
  3076. int a1OEEType = Convert.ToInt32(s1PLCData["a1OEEType"]);
  3077. int a1OEETypeGOld = Convert.ToInt32(s1PLCSignal_Old["a1OEEType"]);
  3078. if (a1OEEType != a1OEETypeGOld)
  3079. {
  3080. s1PLCData["OEETypeFlag"] = "1";
  3081. }
  3082. else
  3083. {
  3084. s1PLCData["OEETypeFlag"] = "0";
  3085. }
  3086. if (s1PLCData["OEETypeFlag"].ToString() == "1" && (a1OEEType == 1 || a1OEEType == 3 || a1OEEType == 4 || a1OEEType == 5))
  3087. {
  3088. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName, CarrierBarcode, stPLC_MesData.iotData, out res);
  3089. if (res == 1)
  3090. {
  3091. s1PLCSignal_Old["a1OEEType"] = s1PLCData["a1OEEType"];
  3092. }
  3093. else
  3094. {
  3095. s1PLCSignal_Old["a1OEEType"] = 0;
  3096. }
  3097. }
  3098. }
  3099. else
  3100. {
  3101. s1PLCSignal_Old["a1OEEType"] = 0;
  3102. }
  3103. }
  3104. catch (Exception ex)
  3105. {
  3106. string str = ex.StackTrace;
  3107. AddMessage_Station(stationNameStr, LogType.Error,
  3108. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  3109. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3110. }
  3111. #endregion
  3112. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  3113. stopwatch1.Stop();
  3114. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  3115. }
  3116. else
  3117. {
  3118. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  3119. AddMessage_Station(stationNameStr, LogType.Info,
  3120. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  3121. FunsEip[plcNo].Connect(); // 重连
  3122. }
  3123. }
  3124. catch (Exception ex)
  3125. {
  3126. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  3127. AddMessage_Station(stationNameStr, LogType.Error,
  3128. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  3129. }
  3130. Thread.Sleep(IntervalReadPLC);
  3131. }
  3132. }
  3133. /// <summary>
  3134. /// [S1] 壳体清洁上料 - 进站
  3135. /// </summary>
  3136. /// <param name="plcNo">PLC编号</param>
  3137. /// <param name="stationNameStr">工站全称</param>
  3138. /// <param name="stPLC_MesData"></param>
  3139. /// <param name="tagMesCommName"></param>
  3140. private void S1进站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName,
  3141. out bool ProgressState)
  3142. {
  3143. Stopwatch stopwatch1 = new Stopwatch();
  3144. Stopwatch stopwatch2 = new Stopwatch();
  3145. try
  3146. {
  3147. stopwatch1.Start();
  3148. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  3149. //10扫码改造注释(临时)
  3150. //string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码),现在PLC只有OP10和OP50返回
  3151. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  3152. string sn = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  3153. string MachineId = GlobalContext.S1_MachineId; // 装备ID(可配置)
  3154. string StationId = GlobalContext.S1_StationId; // 工位ID(可配置)
  3155. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  3156. bool pass = a1Result == 1;
  3157. if (string.IsNullOrEmpty(sn))
  3158. {
  3159. ProgressState = false;
  3160. AddMessage(LogType.Error, $"{stationNameStr}_未能查到产品码");
  3161. Thread.Sleep(10000);
  3162. return;
  3163. }
  3164. //测试先用9码,正式直接用PLC得到的SN码,截取成9位码
  3165. // sn = sn.Substring(sn.Length - 11, 4) + sn.Substring(sn.Length - 5, 5);
  3166. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  3167. //绑定载具和产品
  3168. //测试注释(临时)
  3169. //ResponseMessage message = new ResponseMessage();
  3170. //message = SQLHelper.InsertCarrierBind(CarrierBarcode, sn);
  3171. //if (message.result == false)
  3172. //{
  3173. // AddMessage(LogType.Error, stationNameStr + "_载具码与产品码绑定失败,错误:" + message.text);
  3174. // ProgressState = false;
  3175. // Thread.Sleep(10000);
  3176. // return;
  3177. //}
  3178. // 产品SN进站
  3179. List<TestItem> item = new List<TestItem>();
  3180. stopwatch2.Start();
  3181. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  3182. item, MachineId, StationId, pass, "01-SLOT-01");
  3183. stopwatch2.Stop();
  3184. //指令执行结果 1:OK 110:失败
  3185. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  3186. if (mesResultFrmWeb == 1)
  3187. {
  3188. if (a1Result == 1)
  3189. {
  3190. mesResultFrmWeb = 1;
  3191. }
  3192. else
  3193. {
  3194. mesResultFrmWeb = 110;
  3195. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  3196. }
  3197. }
  3198. //进站结果写入PLC
  3199. CommandFromPLC resultToPlC = new CommandFromPLC();
  3200. resultToPlC.cmd = 0;
  3201. resultToPlC.cmdParam = 0;
  3202. resultToPlC.cmdResult = mesResultFrmWeb;
  3203. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3204. }
  3205. catch (Exception ex)
  3206. {
  3207. string str = ex.StackTrace;
  3208. AddMessage(LogType.Error,
  3209. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  3210. str.Length - str.LastIndexOf("\\") - 1));
  3211. CommandFromPLC resultToPlC = new CommandFromPLC();
  3212. resultToPlC.cmd = 0;
  3213. resultToPlC.cmdParam = 0; //指令参数
  3214. resultToPlC.cmdResult = 110;
  3215. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3216. }
  3217. stopwatch1.Stop();
  3218. AddMessage(LogType.Info, stationNameStr + "_进站结束");
  3219. AddMessage(LogType.Info,
  3220. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  3221. stopwatch2.ElapsedMilliseconds + "ms");
  3222. ProgressState = false;
  3223. }
  3224. /// <summary>
  3225. /// [S1] 壳体清洁上料 - 出站接口
  3226. /// </summary>
  3227. private void S1出站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName,
  3228. string stationCode, string stationName, out bool ProgressState)
  3229. {
  3230. Stopwatch stopwatch1 = new Stopwatch();
  3231. Stopwatch stopwatch2 = new Stopwatch();
  3232. try
  3233. {
  3234. stopwatch1.Start();
  3235. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  3236. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  3237. string processItem = stationName; // 项目
  3238. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  3239. string supplierCode = ""; // 供应商代码
  3240. string workorder_code = GlobalContext.WorkOrderCode; // 工单号 现在没用上
  3241. string batch_num = GlobalContext.BatchNumber; // 批次号 现在没用上
  3242. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号 现在没用上
  3243. string sn = string.Empty;
  3244. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  3245. string MachineId = GlobalContext.S1_MachineId; // 装备id(可配置)
  3246. string StationId = GlobalContext.S1_StationId; // ⼯位ID(可配置)
  3247. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  3248. //a1Result = 1;
  3249. bool pass = a1Result == 1;
  3250. //根据载具码获取产品码
  3251. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  3252. if (string.IsNullOrEmpty(strProductBarcode))
  3253. {
  3254. ProgressState = false;
  3255. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  3256. Thread.Sleep(10000);
  3257. return;
  3258. }
  3259. sn = strProductBarcode;
  3260. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  3261. List<TestItem> items = new List<TestItem>();
  3262. items.Add(new TestItem()
  3263. {
  3264. Parameter_name = "载具码",
  3265. Parameter_value = CarrierBarcode,
  3266. Parameter_unit = ""
  3267. });
  3268. items.Add(new TestItem()
  3269. {
  3270. Parameter_name = "产品码",
  3271. Parameter_value = sn,
  3272. Parameter_unit = ""
  3273. });
  3274. #region 转换过站明细字符串
  3275. //创建字典
  3276. var dic = new Dictionary<string, string>();
  3277. // 获取结构体类型
  3278. FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  3279. string resultString = "";
  3280. // 遍历变量名转换成字典描述
  3281. foreach (FieldInfo field in fields)
  3282. {
  3283. //获取枚举描述
  3284. string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  3285. typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  3286. //获取过站明细的值
  3287. object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  3288. // 检查是否为数组
  3289. if (valueObj.GetType().IsArray)
  3290. {
  3291. var array = valueObj as Array;
  3292. resultString = ArrayToString(array);
  3293. }
  3294. else
  3295. {
  3296. resultString = valueObj.ToString();
  3297. }
  3298. dic.Add(name, resultString);
  3299. }
  3300. string paramJson = JsonConvert.SerializeObject(dic);
  3301. #endregion
  3302. //出站接口
  3303. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  3304. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "01-SLOT-01",
  3305. MachineId, StationId, "", paramJson,new XmStationOut_InspectionItemData(), "");
  3306. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  3307. if (mesResultFrmWeb == 1)
  3308. {
  3309. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  3310. if (mesResultFrmWeb == 110)
  3311. {
  3312. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  3313. }
  3314. }
  3315. stopwatch2.Start();
  3316. //进站结果写入PLC
  3317. CommandFromPLC resultToPlC = new CommandFromPLC();
  3318. resultToPlC.cmd = 0;
  3319. resultToPlC.cmdParam = 0; //指令参数
  3320. resultToPlC.cmdResult = mesResultFrmWeb;
  3321. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3322. stopwatch2.Stop();
  3323. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  3324. //保存PLC返回MES数据到本地
  3325. ResponseMessage message = new ResponseMessage();
  3326. message = SQLHelper.InsertOp10Data(CarrierBarcode, sn, 1,
  3327. stPLC_MesData.mesData.nThrowCount, stPLC_MesData.mesData.fCleanAirPress,
  3328. stPLC_MesData.mesData.fCleanSpeed,
  3329. stPLC_MesData.mesData.fWindBladeHeight, stPLC_MesData.mesData.fCleanTime,
  3330. stPLC_MesData.mesData.nCleanCount,
  3331. stPLC_MesData.mesData.nRemainCount);
  3332. if (message.result == false)
  3333. {
  3334. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  3335. }
  3336. AddMessage(LogType.Info, stationNameStr + "_保存出站数据结束");
  3337. }
  3338. catch (Exception ex)
  3339. {
  3340. stopwatch2.Start();
  3341. CommandFromPLC resultToPlC = new CommandFromPLC();
  3342. resultToPlC.cmd = 0;
  3343. resultToPlC.cmdParam = 0; //指令参数
  3344. resultToPlC.cmdResult = 110;
  3345. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3346. stopwatch2.Stop();
  3347. string str = ex.StackTrace;
  3348. AddMessage(LogType.Error,
  3349. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  3350. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3351. }
  3352. stopwatch1.Stop();
  3353. AddMessage(LogType.Info,
  3354. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  3355. stopwatch2.ElapsedMilliseconds + "ms");
  3356. ProgressState = false;
  3357. uuid = "";
  3358. }
  3359. #endregion
  3360. #region S2
  3361. /// <summary>
  3362. /// [S2] 上盖板上料装备
  3363. /// </summary>
  3364. /// <param name="plcNo">PLC编号</param>
  3365. private void ReadStation_S2(int plcNo)
  3366. {
  3367. string stationCode = "[OP20]";
  3368. string stationName = "上盖板上料装备";
  3369. string stationNameStr = stationCode + stationName;
  3370. string tagBaseName = "g_OP20_MES"; //标签变量名称
  3371. string tagMesCommName = "mesCommToPC"; //标签变量名称
  3372. string tagAgvCommName = "agvCommFrmPC";
  3373. string tagiotComnName = "iotData";
  3374. string tagBarsetName = "BarcodeSet";
  3375. string CarrierBarcode = "";
  3376. // 触发信号字典
  3377. //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  3378. s2PLCSignal_Old.Add("a2OEEType", 0); // 节拍类型(plc写入)
  3379. // PLC数据字典 赋值
  3380. s2PLCData.Add("a2OEEType", 0); // 节拍类型(plc写入)
  3381. s2PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  3382. OP20_MesData_t stPLC_MesData; //PLC的MES数据
  3383. (int, string) result;
  3384. while (true)
  3385. {
  3386. try
  3387. {
  3388. if (!GlobalContext._IsCon_Funs2)
  3389. {
  3390. UpdatePLCMonitor(1, plcNo, 0);
  3391. continue;
  3392. }
  3393. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  3394. {
  3395. Stopwatch stopwatch1 = new Stopwatch();
  3396. Stopwatch stopwatch2 = new Stopwatch();
  3397. stopwatch1.Start();
  3398. stopwatch2.Start();
  3399. #region 一次性读取所有数据
  3400. // 一次性读取所有数据
  3401. result = FunsEip[plcNo]
  3402. .Read_SingleTag<OP20_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  3403. if (result.Item1 != 0)
  3404. {
  3405. //richTextBox1.AppendText("\n" + strRet);
  3406. }
  3407. else
  3408. {
  3409. //richTextBox1.AppendText("\n" + "读取成功");
  3410. stPLC_MesData.BarcodeSet.strProductBarcode =
  3411. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  3412. stPLC_MesData.BarcodeSet.strPartBarcode =
  3413. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  3414. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  3415. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  3416. stPLC_MesData.BarcodeSet.strPCBBarcode =
  3417. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  3418. //设备状态
  3419. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  3420. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  3421. ? XiaomiDeviceState.Unknown
  3422. : (XiaomiDeviceState)xmDeviceStateInt;
  3423. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具SN
  3424. s2PLCData["a2OEEType"] = stPLC_MesData.iotData.beatAction; // 节拍
  3425. //报警信息
  3426. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  3427. }
  3428. #endregion 一次性读取所有数据
  3429. stopwatch2.Stop();
  3430. #region 进站
  3431. try
  3432. {
  3433. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  3434. {
  3435. lock (lockObj)
  3436. {
  3437. if (!ProgressState)
  3438. {
  3439. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  3440. ProgressState = true;
  3441. Task.Run(() => S2进站(plcNo, stationNameStr, stPLC_MesData,
  3442. tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName,
  3443. out ProgressState));
  3444. }
  3445. }
  3446. }
  3447. }
  3448. catch (Exception ex)
  3449. {
  3450. ProgressState = false;
  3451. string str = ex.StackTrace;
  3452. AddMessage_Station(stationNameStr, LogType.Error,
  3453. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3454. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3455. }
  3456. #endregion 进站
  3457. #region 出站
  3458. try
  3459. {
  3460. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  3461. {
  3462. lock (lockObj)
  3463. {
  3464. if (!ProgressState)
  3465. {
  3466. ProgressState = true;
  3467. Task.Run(() => S2出站(plcNo, stationNameStr, stPLC_MesData,
  3468. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  3469. out ProgressState));
  3470. stPLC_MesData.mesCommFrmPLC.cmd = 0; //清除入站申请
  3471. }
  3472. }
  3473. }
  3474. }
  3475. catch (Exception ex)
  3476. {
  3477. ProgressState = false;
  3478. string str = ex.StackTrace;
  3479. AddMessage_Station(stationNameStr, LogType.Error,
  3480. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3481. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3482. }
  3483. #endregion 出站
  3484. #region 节拍接口
  3485. try
  3486. {
  3487. if (stPLC_MesData.iotData.beatAction > 0)
  3488. {
  3489. int a2OEEType = Convert.ToInt32(s2PLCData["a2OEEType"]);
  3490. int a2OEETypeGOld = Convert.ToInt32(s2PLCSignal_Old["a2OEEType"]);
  3491. if (a2OEEType != a2OEETypeGOld)
  3492. {
  3493. s2PLCData["OEETypeFlag"] = "1";
  3494. }
  3495. else
  3496. {
  3497. s2PLCData["OEETypeFlag"] = "0";
  3498. }
  3499. if (s2PLCData["OEETypeFlag"].ToString() == "1" && (a2OEEType == 1 || a2OEEType == 3 || a2OEEType == 4 || a2OEEType == 5))
  3500. {
  3501. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName, CarrierBarcode, stPLC_MesData.iotData, out res);
  3502. if (res == 1)
  3503. {
  3504. s2PLCSignal_Old["a2OEEType"] = s2PLCData["a2OEEType"];
  3505. }
  3506. else
  3507. {
  3508. s2PLCSignal_Old["a2OEEType"] = 0;
  3509. }
  3510. }
  3511. }
  3512. else {
  3513. s2PLCSignal_Old["a2OEEType"] = 0;
  3514. }
  3515. }
  3516. catch (Exception ex)
  3517. {
  3518. string str = ex.StackTrace;
  3519. AddMessage_Station(stationNameStr, LogType.Error,
  3520. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  3521. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3522. }
  3523. #endregion
  3524. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  3525. stopwatch1.Stop();
  3526. //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  3527. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  3528. }
  3529. else
  3530. {
  3531. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  3532. AddMessage_Station(stationNameStr, LogType.Info,
  3533. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  3534. FunsEip[plcNo].Connect();
  3535. }
  3536. }
  3537. catch (Exception ex)
  3538. {
  3539. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  3540. AddMessage_Station(stationNameStr, LogType.Error,
  3541. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  3542. //Funs[plcNo].ReConnect();
  3543. }
  3544. Thread.Sleep(IntervalReadPLC);
  3545. }
  3546. }
  3547. /// <summary>
  3548. /// [S2] 上盖板上料装备
  3549. /// </summary>
  3550. /// <param name="plcNo">PLC编号</param>
  3551. /// <param name="stationNameStr">工站全称</param>
  3552. private void S2进站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,
  3553. string tagBarsetName, out bool ProgressState)
  3554. {
  3555. Stopwatch stopwatch1 = new Stopwatch();
  3556. Stopwatch stopwatch2 = new Stopwatch();
  3557. try
  3558. {
  3559. stopwatch1.Start();
  3560. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  3561. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码),现在PLC只有10和50返回
  3562. //sn = sn.Substring(sn.Length - 11, 4) + sn.Substring(sn.Length - 5, 5);
  3563. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  3564. bool pass = a1Result == 1;
  3565. string MachineId = GlobalContext.S2_MachineId; // 装备ID(可配置)
  3566. string StationId = GlobalContext.S2_StationId; // 工位ID(可配置)
  3567. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  3568. //根据载具码获取产品码
  3569. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  3570. if (string.IsNullOrEmpty(strProductBarcode))
  3571. {
  3572. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  3573. ProgressState = false;
  3574. Thread.Sleep(10000);
  3575. return;
  3576. }
  3577. //这个地方之后PLC可能会返回SN码,到时用返回的和数据库中的比较下对错,结果faalse怎么办现在不知道
  3578. //if (sn != strProductBarcode)
  3579. //{
  3580. // AddMessage(LogType.Info, $"进站产品码错误!与载具绑定的产品码不匹配,进站产品码:{sn};载具绑定产品码:{strProductBarcode}");
  3581. //}
  3582. sn = strProductBarcode;
  3583. AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  3584. // 产品SN(物料码)校验
  3585. List<TestItem> item = new List<TestItem>();
  3586. stopwatch2.Start();
  3587. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  3588. item, MachineId, StationId, pass, "01-SLOT-01");
  3589. stopwatch2.Stop();
  3590. //指令执行结果 1:OK 110:失败
  3591. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  3592. if (mesResultFrmWeb == 1)
  3593. {
  3594. if (a1Result == 1)
  3595. {
  3596. mesResultFrmWeb = 1;
  3597. }
  3598. else
  3599. {
  3600. mesResultFrmWeb = 110;
  3601. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  3602. }
  3603. }
  3604. //进站结果写入PLC
  3605. CommandFromPLC resultToPlC = new CommandFromPLC();
  3606. resultToPlC.cmd = 0;
  3607. resultToPlC.cmdParam = 0; //指令参数
  3608. resultToPlC.cmdResult = mesResultFrmWeb;
  3609. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3610. }
  3611. catch (Exception ex)
  3612. {
  3613. string str = ex.StackTrace;
  3614. AddMessage(LogType.Error,
  3615. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  3616. str.Length - str.LastIndexOf("\\") - 1));
  3617. CommandFromPLC resultToPlC = new CommandFromPLC();
  3618. resultToPlC.cmd = 0;
  3619. resultToPlC.cmdParam = 0; //指令参数
  3620. resultToPlC.cmdResult = 110;
  3621. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3622. }
  3623. stopwatch1.Stop();
  3624. AddMessage(LogType.Info, stationNameStr + "_进站结束");
  3625. AddMessage(LogType.Info,
  3626. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  3627. stopwatch2.ElapsedMilliseconds + "ms");
  3628. ProgressState = false;
  3629. }
  3630. /// <summary>
  3631. /// [S2] 上盖板上料装备 - 出站接口
  3632. /// </summary>
  3633. private void S2出站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,
  3634. string stationCode, string stationName, out bool ProgressState)
  3635. {
  3636. Stopwatch stopwatch1 = new Stopwatch();
  3637. Stopwatch stopwatch2 = new Stopwatch();
  3638. try
  3639. {
  3640. stopwatch1.Start();
  3641. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  3642. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  3643. string processItem = stationName; // 测试项目
  3644. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  3645. string supplierCode = ""; // 供应商代码
  3646. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  3647. string batch_num = GlobalContext.BatchNumber; // 批次号
  3648. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  3649. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  3650. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  3651. string PartBarcode = (string)stPLC_MesData.BarcodeSet.strPartBarcode; //部件码
  3652. string MachineId = GlobalContext.S2_MachineId; // 装备id(可配置) // ZS
  3653. string StationId = GlobalContext.S2_StationId; // ⼯位ID(可配置) // ZS
  3654. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  3655. bool pass = a1Result == 1;
  3656. //根据载具码获取产品码
  3657. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  3658. if (string.IsNullOrEmpty(strProductBarcode))
  3659. {
  3660. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  3661. ProgressState = false;
  3662. Thread.Sleep(10000);
  3663. return;
  3664. }
  3665. sn = strProductBarcode;
  3666. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  3667. List<TestItem> items = new List<TestItem>();
  3668. items.Add(new TestItem()
  3669. {
  3670. Parameter_name = "载具码",
  3671. Parameter_value = CarrierBarcode,
  3672. Parameter_unit = ""
  3673. });
  3674. items.Add(new TestItem()
  3675. {
  3676. Parameter_name = "产品码",
  3677. Parameter_value = sn,
  3678. Parameter_unit = ""
  3679. });
  3680. items.Add(new TestItem()
  3681. {
  3682. Parameter_name = "部件码",
  3683. Parameter_value = PartBarcode,
  3684. Parameter_unit = ""
  3685. });
  3686. #region 转换过站明细字符串
  3687. ////创建字典
  3688. //var dic = new Dictionary<string, string>();
  3689. //// 获取结构体类型
  3690. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  3691. //string resultString = "";
  3692. //// 遍历变量名转换成字典描述
  3693. //foreach (FieldInfo field in fields)
  3694. //{
  3695. // //获取枚举描述
  3696. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  3697. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  3698. // //获取过站明细的值
  3699. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  3700. // // 检查是否为数组
  3701. // if (valueObj.GetType().IsArray)
  3702. // {
  3703. // var array = valueObj as Array;
  3704. // resultString = ArrayToString(array);
  3705. // }
  3706. // else
  3707. // {
  3708. // resultString = valueObj.ToString();
  3709. // }
  3710. // dic.Add(name, resultString);
  3711. //}
  3712. //string paramJson = JsonConvert.SerializeObject(dic);
  3713. #endregion
  3714. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);
  3715. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  3716. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "01-SLOT-01",
  3717. MachineId, StationId, PartBarcode, paramJson,new XmStationOut_InspectionItemData(), "");
  3718. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  3719. if (mesResultFrmWeb == 1)
  3720. {
  3721. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  3722. if (mesResultFrmWeb == 110)
  3723. {
  3724. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  3725. }
  3726. }
  3727. stopwatch2.Start();
  3728. //进站结果写入PLC
  3729. CommandFromPLC resultToPlC = new CommandFromPLC();
  3730. resultToPlC.cmd = 0;
  3731. resultToPlC.cmdParam = 0; //指令参数
  3732. resultToPlC.cmdResult = mesResultFrmWeb;
  3733. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3734. stopwatch2.Stop();
  3735. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  3736. //保存PLC返回MES数据到本地
  3737. ResponseMessage message = new ResponseMessage();
  3738. message = SQLHelper.InsertOp20Data(CarrierBarcode, sn, stPLC_MesData.mesData.nThrowCount,
  3739. stPLC_MesData.mesData.nRemainCount);
  3740. if (message.result == false)
  3741. {
  3742. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  3743. }
  3744. if (!string.IsNullOrEmpty(PartBarcode))
  3745. {
  3746. message = SQLHelper.InsertOp20Product(CarrierBarcode, sn, PartBarcode);
  3747. if (message.result == false)
  3748. {
  3749. AddMessage(LogType.Error, message.text);
  3750. }
  3751. }
  3752. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地成功");
  3753. }
  3754. catch (Exception ex)
  3755. {
  3756. stopwatch2.Start();
  3757. CommandFromPLC resultToPlC = new CommandFromPLC();
  3758. resultToPlC.cmd = 0;
  3759. resultToPlC.cmdParam = 0; //指令参数
  3760. resultToPlC.cmdResult = 110;
  3761. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  3762. stopwatch2.Stop();
  3763. string str = ex.StackTrace;
  3764. AddMessage(LogType.Error,
  3765. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  3766. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3767. }
  3768. stopwatch1.Stop();
  3769. AddMessage(LogType.Info,
  3770. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  3771. stopwatch2.ElapsedMilliseconds + "ms");
  3772. ProgressState = false;
  3773. uuid = "";
  3774. }
  3775. #endregion
  3776. #region S3
  3777. /// <summary>
  3778. /// [S3] 点散热胶装备
  3779. /// </summary>
  3780. /// <param name="plcNo">PLC编号</param>
  3781. private void ReadStation_S3(int plcNo)
  3782. {
  3783. string stationCode = "[OP30]";
  3784. string stationName = "点散热胶装备";
  3785. string stationNameStr = stationCode + stationName;
  3786. string tagBaseName = "g_OP30_MES"; //标签变量名称
  3787. string tagMesCommName = "mesCommToPC"; //标签变量名称
  3788. string tagAgvCommName = "agvCommFrmPC";
  3789. string tagiotComnName = "iotData";
  3790. string tagBarsetName = "BarcodeSet";
  3791. string CarrierBarcode_Left = "";
  3792. string CarrierBarcode_Right = "";
  3793. s3PLCSignal_Old.Add("a3OEEType_left", 0); // 节拍类型(plc写入)
  3794. s3PLCSignal_Old.Add("a3OEEType_right", 0); // 节拍类型(plc写入)
  3795. // PLC数据字典 赋值
  3796. s3PLCData.Add("a3OEEType_left", 0); // 节拍类型(plc写入)
  3797. s3PLCData.Add("a3OEEType_right", 0); // 节拍类型(plc写入)
  3798. s5PLCData.Add("OEETypeFlag_left", 0); // 节拍标识 0 不上传 ,1 上传
  3799. s5PLCData.Add("OEETypeFlag_right", 0); // 节拍标识 0 不上传 ,1 上传
  3800. OP30_MesData_t stPLC_MesData; //PLC的MES数据
  3801. (int, string) result;
  3802. while (true)
  3803. {
  3804. try
  3805. {
  3806. if (!GlobalContext._IsCon_Funs2)
  3807. {
  3808. UpdatePLCMonitor(1, plcNo, 0);
  3809. continue;
  3810. }
  3811. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  3812. {
  3813. Stopwatch stopwatch1 = new Stopwatch();
  3814. Stopwatch stopwatch2 = new Stopwatch();
  3815. stopwatch1.Start();
  3816. stopwatch2.Start();
  3817. #region 一次性读取所有数据
  3818. // 一次性读取所有数据
  3819. result = FunsEip[plcNo]
  3820. .Read_SingleTag<OP30_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  3821. if (result.Item1 != 0)
  3822. {
  3823. //richTextBox1.AppendText("\n" + strRet);
  3824. }
  3825. else
  3826. {
  3827. //测试数据
  3828. //stPLC_MesData.Left.mesCommFrmPLC.cmdParam = 1;
  3829. //stPLC_MesData.Left.BarcodeSet.strCarrierBarcode = "A123456";
  3830. //stPLC_MesData.Left.BarcodeSet.strPCBBarcode = "A1507V000239";
  3831. //stPLC_MesData.Left.iotData.beatAction = 1;
  3832. //stPLC_MesData.Left.iotData.beatAction = 2;
  3833. //stPLC_MesData.Left.BarcodeSet.strCarrierBarcode = "A123456";
  3834. //stPLC_MesData.Left.testData.fAB_AirPressDiff = 2.5f;
  3835. //stPLC_MesData.Left.testData.fAB_AirPressDiffMax = 2.5f;
  3836. //stPLC_MesData.Left.testData.fAB_AirPressDiffMin = 0;
  3837. //stPLC_MesData.Left.testData.fAB_AirPress = 0.1f;
  3838. //stPLC_MesData.Left.testData.fAB_AirPressMax = 0.2f;
  3839. //stPLC_MesData.Left.testData.fAB_AirPressMin = 0;
  3840. #region 去除扫码产生的特殊字符
  3841. stPLC_MesData.Left.BarcodeSet.strProductBarcode =
  3842. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strProductBarcode);
  3843. stPLC_MesData.Left.BarcodeSet.strPartBarcode =
  3844. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strPartBarcode);
  3845. stPLC_MesData.Left.BarcodeSet.strCarrierBarcode =
  3846. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strCarrierBarcode);
  3847. stPLC_MesData.Left.BarcodeSet.strPCBBarcode =
  3848. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strPCBBarcode);
  3849. stPLC_MesData.Right.BarcodeSet.strProductBarcode =
  3850. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strProductBarcode);
  3851. stPLC_MesData.Right.BarcodeSet.strPartBarcode =
  3852. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strPartBarcode);
  3853. stPLC_MesData.Right.BarcodeSet.strCarrierBarcode =
  3854. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strCarrierBarcode);
  3855. stPLC_MesData.Right.BarcodeSet.strPCBBarcode =
  3856. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strPCBBarcode);
  3857. #endregion
  3858. //richTextBox1.AppendText("\n" + "读取成功");
  3859. //设备状态
  3860. int xmDeviceStateInt_L = stPLC_MesData.Left.iotData.machineState;
  3861. int xmDeviceStateInt_R = stPLC_MesData.Right.iotData.machineState;
  3862. xmDeviceStateData.left = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
  3863. ? XiaomiDeviceState.Unknown
  3864. : (XiaomiDeviceState)xmDeviceStateInt_L;
  3865. xmDeviceStateData.right = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
  3866. ? XiaomiDeviceState.Unknown
  3867. : (XiaomiDeviceState)xmDeviceStateInt_R;
  3868. //载具SN
  3869. CarrierBarcode_Left = stPLC_MesData.Left.BarcodeSet.strCarrierBarcode;
  3870. CarrierBarcode_Right = stPLC_MesData.Right.BarcodeSet.strCarrierBarcode;
  3871. // 节拍
  3872. s3PLCData["a3OEEType_left"] = stPLC_MesData.Left.iotData.beatAction;
  3873. s3PLCData["a3OEEType_right"] = stPLC_MesData.Right.iotData.beatAction;
  3874. //报警信息
  3875. _FaultDatas = stPLC_MesData.Left.iotData.fault_codes;
  3876. _FaultDatas2 = stPLC_MesData.Right.iotData.fault_codes;
  3877. //_FaultDatas = new uint[] { 2, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
  3878. //_FaultDatas2 = new uint[] { 2, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
  3879. }
  3880. #endregion 一次性读取所有数据
  3881. stopwatch2.Stop();
  3882. #region 左边进站
  3883. try
  3884. {
  3885. if (stPLC_MesData.Left.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  3886. {
  3887. lock (lockObj)
  3888. {
  3889. if (!ProgressState)
  3890. {
  3891. stationCode = "[OP31]";
  3892. stationName = "点散热胶装备1";
  3893. stationNameStr = stationCode + stationName;
  3894. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  3895. ProgressState = true;
  3896. Task.Run(() => S3进站(plcNo, stationNameStr, stPLC_MesData.Left,
  3897. tagBaseName + ".Left." + tagMesCommName,
  3898. tagBaseName + ".Left." + tagBarsetName, "Left", out ProgressState));
  3899. }
  3900. }
  3901. }
  3902. }
  3903. catch (Exception ex)
  3904. {
  3905. ProgressState = false;
  3906. string str = ex.StackTrace;
  3907. AddMessage_Station(stationNameStr, LogType.Error,
  3908. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3909. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3910. }
  3911. #endregion 左边进站
  3912. #region 左边出站
  3913. try
  3914. {
  3915. if (stPLC_MesData.Left.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  3916. {
  3917. lock (lockObj)
  3918. {
  3919. if (!ProgressState)
  3920. {
  3921. stationCode = "[OP31]";
  3922. stationName = "点散热胶装备1";
  3923. stationNameStr = stationCode + stationName;
  3924. ProgressState = true;
  3925. Task.Run(() => S3出站(plcNo, stationNameStr, stPLC_MesData.Left,
  3926. tagBaseName + ".Left." + tagMesCommName, stationCode, stationName, "Left",
  3927. out ProgressState));
  3928. stPLC_MesData.Left.mesCommFrmPLC.cmd = 0;
  3929. }
  3930. }
  3931. }
  3932. }
  3933. catch (Exception ex)
  3934. {
  3935. ProgressState = false;
  3936. string str = ex.StackTrace;
  3937. AddMessage_Station(stationNameStr, LogType.Error,
  3938. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3939. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3940. }
  3941. #endregion 左边出站
  3942. #region 右边进站
  3943. try
  3944. {
  3945. if (stPLC_MesData.Right.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  3946. {
  3947. lock (lockObj)
  3948. {
  3949. if (!ProgressState)
  3950. {
  3951. uuid2 = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  3952. stationCode = "[OP32]";
  3953. stationName = "点散热胶装备2";
  3954. stationNameStr = stationCode + stationName;
  3955. ProgressState = true;
  3956. Task.Run(() => S3进站(plcNo, stationNameStr, stPLC_MesData.Right,
  3957. tagBaseName + ".Right." + tagMesCommName,
  3958. tagBaseName + ".Right." + tagBarsetName, "Right", out ProgressState));
  3959. }
  3960. }
  3961. }
  3962. }
  3963. catch (Exception ex)
  3964. {
  3965. ProgressState = false;
  3966. string str = ex.StackTrace;
  3967. AddMessage_Station(stationNameStr, LogType.Error,
  3968. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3969. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3970. }
  3971. #endregion 右边进站
  3972. #region 右边出站
  3973. try
  3974. {
  3975. if (stPLC_MesData.Right.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  3976. {
  3977. lock (lockObj)
  3978. {
  3979. if (!ProgressState)
  3980. {
  3981. stationCode = "[OP32]";
  3982. stationName = "点散热胶装备2";
  3983. stationNameStr = stationCode + stationName;
  3984. ProgressState = true;
  3985. Task.Run(() => S3出站(plcNo, stationNameStr, stPLC_MesData.Right,
  3986. tagBaseName + ".Right." + tagMesCommName, stationCode, stationName, "Right",
  3987. out ProgressState));
  3988. stPLC_MesData.Right.mesCommFrmPLC.cmd = 0;
  3989. }
  3990. }
  3991. }
  3992. }
  3993. catch (Exception ex)
  3994. {
  3995. string str = ex.StackTrace;
  3996. AddMessage_Station(stationNameStr, LogType.Error,
  3997. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  3998. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3999. }
  4000. #endregion 右边出站
  4001. #region 节拍接口
  4002. try
  4003. {
  4004. #region 左工位 节拍
  4005. if (stPLC_MesData.Left.iotData.beatAction > 0)
  4006. {
  4007. stationCode = "[OP31]";
  4008. stationName = "点散热胶装备1";
  4009. stationNameStr = stationCode + stationName;
  4010. int a3OEEType_left = Convert.ToInt32(s3PLCData["a3OEEType_left"]);
  4011. int a3OEETypeGOld_left = Convert.ToInt32(s3PLCSignal_Old["a3OEEType_left"]);
  4012. if (a3OEEType_left != a3OEETypeGOld_left)
  4013. {
  4014. s3PLCData["OEETypeFlag_left"] = "1";
  4015. }
  4016. else
  4017. {
  4018. s3PLCData["OEETypeFlag_left"] = "0";
  4019. }
  4020. if (s3PLCData["OEETypeFlag_left"].ToString() == "1" && (a3OEEType_left == 1 || a3OEEType_left == 3 || a3OEEType_left == 4 || a3OEEType_left == 5))
  4021. {
  4022. 通用节拍接口(plcNo, stationNameStr,
  4023. tagBaseName + ".Left." + tagiotComnName, CarrierBarcode_Left,
  4024. stPLC_MesData.Left.iotData, out res);
  4025. if (res == 1)
  4026. {
  4027. s3PLCSignal_Old["a3OEEType_left"] = a3OEEType_left;
  4028. }
  4029. else {
  4030. s3PLCSignal_Old["a3OEEType_left"] = 0;
  4031. }
  4032. }
  4033. }
  4034. else
  4035. {
  4036. s3PLCSignal_Old["a3OEEType_left"] = 0;
  4037. }
  4038. #endregion 左工位 节拍
  4039. #region 右工位 节拍
  4040. if (stPLC_MesData.Right.iotData.beatAction > 0)
  4041. {
  4042. stationCode = "[OP32]";
  4043. stationName = "点散热胶装备2";
  4044. stationNameStr = stationCode + stationName;
  4045. int a3OEEType_right = Convert.ToInt32(s3PLCData["a3OEEType_right"]);
  4046. int a3OEETypeGOld_right = Convert.ToInt32(s3PLCSignal_Old["a3OEEType_right"]);
  4047. if (a3OEEType_right != a3OEETypeGOld_right)
  4048. {
  4049. s3PLCData["OEETypeFlag_right"] = "1";
  4050. }
  4051. else
  4052. {
  4053. s3PLCData["OEETypeFlag_right"] = "0";
  4054. }
  4055. if (s3PLCData["OEETypeFlag_right"].ToString() == "1" && (a3OEEType_right == 1 || a3OEEType_right == 3 || a3OEEType_right == 4 || a3OEEType_right == 5))
  4056. {
  4057. 通用节拍接口(plcNo, stationNameStr,
  4058. tagBaseName + ".Right." + tagiotComnName, CarrierBarcode_Right,
  4059. stPLC_MesData.Right.iotData, out res);
  4060. if (res == 1)
  4061. {
  4062. s3PLCSignal_Old["a3OEEType_right"] = a3OEEType_right;
  4063. }
  4064. else {
  4065. s3PLCSignal_Old["a3OEEType_right"] = 0;
  4066. }
  4067. }
  4068. }
  4069. else
  4070. {
  4071. s3PLCSignal_Old["a3OEEType_right"] = 0;
  4072. }
  4073. #endregion 右工位 节拍
  4074. }
  4075. catch (Exception ex)
  4076. {
  4077. string str = ex.StackTrace;
  4078. AddMessage_Station(stationNameStr, LogType.Error,
  4079. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  4080. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4081. }
  4082. #endregion
  4083. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  4084. stopwatch1.Stop();
  4085. //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  4086. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  4087. }
  4088. else
  4089. {
  4090. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4091. AddMessage_Station(stationNameStr, LogType.Info,
  4092. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  4093. FunsEip[plcNo].Connect();
  4094. }
  4095. }
  4096. catch (Exception ex)
  4097. {
  4098. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4099. AddMessage_Station(stationNameStr, LogType.Error,
  4100. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  4101. //Funs[plcNo].ReConnect();
  4102. }
  4103. Thread.Sleep(IntervalReadPLC);
  4104. }
  4105. }
  4106. /// <summary>
  4107. /// [S3] 点散热胶装备 - 进站
  4108. /// </summary>
  4109. /// <param name="plcNo">PLC编号</param>
  4110. /// <param name="stationNameStr">工站全称</param>
  4111. private void S3进站(int plcNo, string stationNameStr, OP30_stnDataSet_t stPLC_MesData, string tagMesCommName,
  4112. string tagBarsetName, string direction, out bool ProgressState)
  4113. {
  4114. Stopwatch stopwatch1 = new Stopwatch();
  4115. Stopwatch stopwatch2 = new Stopwatch();
  4116. try
  4117. {
  4118. stopwatch1.Start();
  4119. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_进站开始");
  4120. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  4121. string MachineId = GlobalContext.S3_MachineId; // 装备ID(可配置)
  4122. string StationId = string.Empty;
  4123. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  4124. bool pass = a1Result == 1;
  4125. string slot = "";
  4126. if (direction == "Left")
  4127. {
  4128. StationId = GlobalContext.S3_StationId_1; // 工位ID(可配置)
  4129. slot = "01-SLOT-01";
  4130. }
  4131. if (direction == "Right")
  4132. {
  4133. StationId = GlobalContext.S3_StationId_2; // 工位ID(可配置)
  4134. slot = "01-SLOT-02";
  4135. }
  4136. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  4137. //载具码验证产品码
  4138. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  4139. if (string.IsNullOrEmpty(strProductBarcode))
  4140. {
  4141. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  4142. ProgressState = false;
  4143. Thread.Sleep(10000);
  4144. return;
  4145. }
  4146. sn = strProductBarcode;
  4147. AddMessage(LogType.Info, $"载具码:{strProductBarcode};产品码:{sn}");
  4148. // 产品SN(物料码)校验
  4149. List<TestItem> item = new List<TestItem>();
  4150. stopwatch2.Start();
  4151. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  4152. item, MachineId, StationId, pass, slot);
  4153. stopwatch2.Stop();
  4154. //指令执行结果 1:OK 110:失败
  4155. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  4156. if (mesResultFrmWeb == 1)
  4157. {
  4158. if (a1Result == 1)
  4159. {
  4160. mesResultFrmWeb = 1;
  4161. }
  4162. else
  4163. {
  4164. mesResultFrmWeb = 110;
  4165. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  4166. }
  4167. }
  4168. //进站结果写入PLC
  4169. CommandFromPLC resultToPlC = new CommandFromPLC();
  4170. resultToPlC.cmd = 0;
  4171. resultToPlC.cmdParam = 0; //指令参数
  4172. resultToPlC.cmdResult = mesResultFrmWeb;
  4173. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4174. }
  4175. catch (Exception ex)
  4176. {
  4177. string str = ex.StackTrace;
  4178. AddMessage(LogType.Error,
  4179. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  4180. str.Length - str.LastIndexOf("\\") - 1));
  4181. CommandFromPLC resultToPlC = new CommandFromPLC();
  4182. resultToPlC.cmd = 0;
  4183. resultToPlC.cmdParam = 0; //指令参数
  4184. resultToPlC.cmdResult = 110;
  4185. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4186. }
  4187. stopwatch1.Stop();
  4188. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_进站结束");
  4189. AddMessage(LogType.Info,
  4190. stationNameStr + "_" + direction + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  4191. stopwatch2.ElapsedMilliseconds + "ms");
  4192. ProgressState = false;
  4193. }
  4194. /// <summary>
  4195. /// [S3] 点散热胶装备 - 出站
  4196. /// </summary>
  4197. private void S3出站(int plcNo, string stationNameStr, OP30_stnDataSet_t stPLC_MesData, string tagMesCommName,
  4198. string stationCode, string stationName, string direction, out bool ProgressState)
  4199. {
  4200. Stopwatch stopwatch1 = new Stopwatch();
  4201. Stopwatch stopwatch2 = new Stopwatch();
  4202. try
  4203. {
  4204. stopwatch1.Start();
  4205. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_出站开始");
  4206. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  4207. string processItem = stationName; // 测试项目
  4208. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  4209. string supplierCode = ""; // 供应商代码
  4210. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  4211. string batch_num = GlobalContext.BatchNumber; // 批次号
  4212. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  4213. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  4214. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  4215. string MachineId = GlobalContext.S3_MachineId; // 装备id(可配置)
  4216. string StationId = string.Empty;
  4217. string slot = "";
  4218. if (direction == "Left")
  4219. {
  4220. StationId = GlobalContext.S3_StationId_1; // 工位ID(可配置)
  4221. slot = "01-SLOT-01";
  4222. }
  4223. if (direction == "Right")
  4224. {
  4225. StationId = GlobalContext.S3_StationId_2; // 工位ID(可配置)
  4226. slot = "01-SLOT-02";
  4227. }
  4228. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  4229. bool pass = a1Result == 1;
  4230. //根据载具码获取产品码
  4231. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  4232. if (string.IsNullOrEmpty(strProductBarcode))
  4233. {
  4234. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  4235. ProgressState = false;
  4236. Thread.Sleep(10000);
  4237. return;
  4238. }
  4239. Console.WriteLine($"异常1:{strProductBarcode}");
  4240. sn = strProductBarcode;
  4241. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  4242. List<TestItem> items = new List<TestItem>();
  4243. items.Add(new TestItem()
  4244. {
  4245. Parameter_name = "载具码",
  4246. Parameter_value = CarrierBarcode,
  4247. Parameter_unit = ""
  4248. });
  4249. items.Add(new TestItem()
  4250. {
  4251. Parameter_name = "产品码",
  4252. Parameter_value = sn,
  4253. Parameter_unit = ""
  4254. });
  4255. #region 转换过站明细字符串
  4256. ////创建字典
  4257. //var dic = new Dictionary<string, string>();
  4258. //// 获取结构体类型
  4259. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  4260. //string resultString = "";
  4261. //// 遍历变量名转换成字典描述
  4262. //foreach (FieldInfo field in fields)
  4263. //{
  4264. // //获取枚举描述
  4265. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  4266. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  4267. // //获取过站明细的值
  4268. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  4269. // // 检查是否为数组
  4270. // if (valueObj.GetType().IsArray)
  4271. // {
  4272. // var array = valueObj as Array;
  4273. // resultString = ArrayToString(array);
  4274. // }
  4275. // else
  4276. // {
  4277. // resultString = valueObj.ToString();
  4278. // }
  4279. // dic.Add(name, resultString);
  4280. //}
  4281. //string paramJson = JsonConvert.SerializeObject(dic);
  4282. #endregion
  4283. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);//过站生产数据
  4284. #region MAS测试项
  4285. XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
  4286. string passFlag = "";
  4287. string AllpassFlag = "PASS";
  4288. float fAB_AirPressDiff = stPLC_MesData.testData.fAB_AirPressDiff;
  4289. float fAB_AirPressDiffMax = stPLC_MesData.testData.fAB_AirPressDiffMax;
  4290. float fAB_AirPressDiffMin = stPLC_MesData.testData.fAB_AirPressDiffMin;
  4291. float fAB_AirPress = stPLC_MesData.testData.fAB_AirPress;
  4292. float fAB_AirPressMax = stPLC_MesData.testData.fAB_AirPressMax;
  4293. float fAB_AirPressMin = stPLC_MesData.testData.fAB_AirPressMin;
  4294. XmStationOut_InspectionItemData inspectionItemData = new XmStationOut_InspectionItemData();
  4295. if (fAB_AirPressDiffMax > fAB_AirPressDiffMin && (fAB_AirPressDiffMax != 0 || fAB_AirPressDiffMin != 0))
  4296. {
  4297. if (fAB_AirPressDiff > fAB_AirPressDiffMin && fAB_AirPressDiff <= fAB_AirPressDiffMax)
  4298. passFlag = "PASS";
  4299. else
  4300. passFlag = "FAIL";
  4301. if (passFlag == "FAIL") AllpassFlag = passFlag;
  4302. inspectionItemData.AddDataItem("AirPressure","AB管气压", fAB_AirPressDiff.ToString(), fAB_AirPressDiffMax.ToString(), fAB_AirPressDiffMin.ToString(), passFlag);
  4303. }
  4304. if (fAB_AirPressMax > fAB_AirPressMin && (fAB_AirPressMax != 0 || fAB_AirPressMin != 0))
  4305. {
  4306. if (fAB_AirPress > fAB_AirPressMin && fAB_AirPress <= fAB_AirPressMax)
  4307. passFlag = "PASS";
  4308. else
  4309. passFlag = "FAIL";
  4310. if (passFlag == "FAIL") AllpassFlag = passFlag;
  4311. inspectionItemData.AddDataItem("AirPressure","AB管气压差", fAB_AirPress.ToString(), fAB_AirPressMax.ToString(), fAB_AirPressMin.ToString(), passFlag);
  4312. }
  4313. inspectionItemData.childUnitSn = strProductBarcode;
  4314. inspectionItemData.childUnitState = AllpassFlag;
  4315. inspectionItemData.toolVersion = "1.0";
  4316. #endregion
  4317. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  4318. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, strProductBarcode, pass, CarrierBarcode,slot,
  4319. MachineId, StationId, "", paramJson, inspectionItemData, direction);
  4320. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  4321. if (mesResultFrmWeb == 1)
  4322. {
  4323. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  4324. if (mesResultFrmWeb == 110)
  4325. {
  4326. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  4327. }
  4328. }
  4329. stopwatch2.Start();
  4330. //进站结果写入PLC
  4331. CommandFromPLC resultToPlC = new CommandFromPLC();
  4332. resultToPlC.cmd = 0;
  4333. resultToPlC.cmdParam = 0; //指令参数
  4334. resultToPlC.cmdResult = mesResultFrmWeb;
  4335. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4336. stopwatch2.Stop();
  4337. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_出站结束");
  4338. //保存PLC返回MES数据到本地
  4339. ResponseMessage message = new ResponseMessage();
  4340. if (direction == "Left")
  4341. {
  4342. string strMesHeightInfos = FloatArrayToString(stPLC_MesData.mesData.fMesHeightInfos);
  4343. string strIntervalWeights = FloatArrayToString(stPLC_MesData.mesData.fIntervalWeights);
  4344. string strRemainGlues = FloatArrayToString(stPLC_MesData.mesData.fRemainGlues);
  4345. message = SQLHelper.InsertOp301Data(CarrierBarcode, sn, stPLC_MesData.mesData.fGlueSupplySpeed,
  4346. stPLC_MesData.mesData.fAB_AirPress, stPLC_MesData.mesData.fAB_AirPressDiff,
  4347. strMesHeightInfos, strIntervalWeights, strRemainGlues);
  4348. if (message.result == false)
  4349. {
  4350. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  4351. }
  4352. }
  4353. if (direction == "Right")
  4354. {
  4355. string strMesHeightInfos = FloatArrayToString(stPLC_MesData.mesData.fMesHeightInfos);
  4356. string strIntervalWeights = FloatArrayToString(stPLC_MesData.mesData.fIntervalWeights);
  4357. string strRemainGlues = FloatArrayToString(stPLC_MesData.mesData.fRemainGlues);
  4358. message = SQLHelper.InsertOp302Data(CarrierBarcode, sn, stPLC_MesData.mesData.fGlueSupplySpeed,
  4359. stPLC_MesData.mesData.fAB_AirPress, stPLC_MesData.mesData.fAB_AirPressDiff,
  4360. strMesHeightInfos, strIntervalWeights, strRemainGlues);
  4361. if (message.result == false)
  4362. {
  4363. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  4364. }
  4365. }
  4366. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地成功");
  4367. }
  4368. catch (Exception ex)
  4369. {
  4370. stopwatch2.Start();
  4371. CommandFromPLC resultToPlC = new CommandFromPLC();
  4372. resultToPlC.cmd = 0;
  4373. resultToPlC.cmdParam = 0; //指令参数
  4374. resultToPlC.cmdResult = 110;
  4375. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4376. stopwatch2.Stop();
  4377. string str = ex.StackTrace;
  4378. AddMessage(LogType.Error,
  4379. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  4380. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4381. }
  4382. stopwatch1.Stop();
  4383. AddMessage(LogType.Info,
  4384. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  4385. stopwatch2.ElapsedMilliseconds + "ms");
  4386. ProgressState = false;
  4387. if (direction == "Left") uuid = "";
  4388. if (direction == "Right") uuid2 = "";
  4389. }
  4390. #endregion S3
  4391. #region S4
  4392. /// <summary>
  4393. /// [S4] 点胶检测设备
  4394. /// </summary>
  4395. /// <param name="plcNo">PLC编号</param>
  4396. private void ReadStation_S4(int plcNo)
  4397. {
  4398. string stationCode = "[OP40]";
  4399. string stationName = "胶线检测";
  4400. string stationNameStr = stationCode + stationName;
  4401. string tagBaseName = "g_OP40_MES"; //标签变量名称
  4402. string tagMesCommName = "mesCommToPC"; //标签变量名称
  4403. string tagAgvCommName = "agvCommFrmPC";
  4404. string tagiotComnName = "iotData";
  4405. string tagBarsetName = "BarcodeSet";
  4406. string CarrierBarcode = "";
  4407. // 触发信号字典
  4408. //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4409. s4PLCSignal_Old.Add("a4OEEType", 0); // 节拍类型(plc写入)
  4410. // PLC数据字典 赋值
  4411. s4PLCData.Add("a4OEEType", 0); // 节拍类型(plc写入)
  4412. s4PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  4413. OP40_MesData_t stPLC_MesData; //PLC的MES数据
  4414. (int, string) result;
  4415. while (true)
  4416. {
  4417. try
  4418. {
  4419. if (!GlobalContext._IsCon_Funs1)
  4420. {
  4421. UpdatePLCMonitor(1, plcNo, 0);
  4422. continue;
  4423. }
  4424. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  4425. {
  4426. Stopwatch stopwatch1 = new Stopwatch();
  4427. Stopwatch stopwatch2 = new Stopwatch();
  4428. stopwatch1.Start();
  4429. stopwatch2.Start();
  4430. #region 一次性读取所有数据
  4431. // 一次性读取所有数据
  4432. result = FunsEip[plcNo]
  4433. .Read_SingleTag<OP40_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  4434. if (result.Item1 != 0)
  4435. {
  4436. //richTextBox1.AppendText("\n" + strRet);
  4437. }
  4438. else
  4439. {
  4440. //测试数据
  4441. //stPLC_MesData.mesCommFrmPLC.cmd = 2;
  4442. //stPLC_MesData.BarcodeSet.strCarrierBarcode = "A235461";
  4443. //stPLC_MesData.BarcodeSet.strPCBBarcode = "A1507V000239";
  4444. //stPLC_MesData.testData.fGlue_Areas = new float[] { 12, 22, 16 };
  4445. //stPLC_MesData.testData.fGlue_AreasMax = 20f;
  4446. //stPLC_MesData.testData.fGlue_AreasMin = 0;
  4447. //stPLC_MesData.testData.fGlue_Heights = new float[] { 5, 8, 6.6f };
  4448. //stPLC_MesData.testData.fGlue_HeightsMax = 10f;
  4449. //stPLC_MesData.testData.fGlue_HeightsMin = 0;
  4450. //去除扫码产生的特殊字符
  4451. stPLC_MesData.BarcodeSet.strProductBarcode =
  4452. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  4453. stPLC_MesData.BarcodeSet.strPartBarcode =
  4454. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  4455. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  4456. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  4457. stPLC_MesData.BarcodeSet.strPCBBarcode =
  4458. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  4459. //richTextBox1.AppendText("\n" + "读取成功");
  4460. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  4461. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  4462. ? XiaomiDeviceState.Unknown
  4463. : (XiaomiDeviceState)xmDeviceStateInt;
  4464. // 载具SN
  4465. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode;
  4466. // 节拍
  4467. s4PLCData["a4OEEType"] = stPLC_MesData.iotData.beatAction;
  4468. //报警信息
  4469. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  4470. }
  4471. #endregion 一次性读取所有数据
  4472. stopwatch2.Stop();
  4473. #region 进站
  4474. try
  4475. {
  4476. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  4477. {
  4478. lock (lockObj)
  4479. {
  4480. if (!ProgressState)
  4481. {
  4482. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  4483. ProgressState = true;
  4484. Task.Run(() => S4进站(plcNo, stationNameStr, stPLC_MesData,
  4485. tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName,
  4486. out ProgressState));
  4487. }
  4488. }
  4489. }
  4490. }
  4491. catch (Exception ex)
  4492. {
  4493. ProgressState = false;
  4494. string str = ex.StackTrace;
  4495. AddMessage_Station(stationNameStr, LogType.Error,
  4496. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  4497. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4498. }
  4499. #endregion 进站
  4500. #region 出站
  4501. try
  4502. {
  4503. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  4504. {
  4505. lock (lockObj)
  4506. {
  4507. if (!ProgressState)
  4508. {
  4509. ProgressState = true;
  4510. Task.Run(() => S4出站(plcNo, stationNameStr, stPLC_MesData,
  4511. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  4512. out ProgressState));
  4513. stPLC_MesData.mesCommFrmPLC.cmd = 0;
  4514. }
  4515. }
  4516. }
  4517. }
  4518. catch (Exception ex)
  4519. {
  4520. string str = ex.StackTrace;
  4521. AddMessage_Station(stationNameStr, LogType.Error,
  4522. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  4523. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4524. }
  4525. #endregion 出站
  4526. #region 节拍接口
  4527. try
  4528. {
  4529. if (stPLC_MesData.iotData.beatAction > 0)
  4530. {
  4531. int a4OEEType = Convert.ToInt32(s4PLCData["a4OEEType"]);
  4532. int a4OEETypeGOld = Convert.ToInt32(s4PLCSignal_Old["a4OEEType"]);
  4533. //若设备紧急复原后节拍重置
  4534. if (a4OEEType == 1)
  4535. {
  4536. a4OEETypeGOld = 0;
  4537. }
  4538. if (a4OEEType != a4OEETypeGOld)
  4539. {
  4540. s4PLCData["OEETypeFlag"] = "1";
  4541. }
  4542. else
  4543. {
  4544. s4PLCData["OEETypeFlag"] = "0";
  4545. }
  4546. if (s4PLCData["OEETypeFlag"].ToString() == "1" && (a4OEEType == 1 || a4OEEType == 3 || a4OEEType == 4 || a4OEEType == 5))
  4547. {
  4548. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName, CarrierBarcode, stPLC_MesData.iotData, out res);
  4549. if (res == 1)
  4550. {
  4551. s4PLCSignal_Old["a4OEEType"] = s4PLCData["a4OEEType"];
  4552. }
  4553. else
  4554. {
  4555. s4PLCSignal_Old["a4OEEType"] = 0;
  4556. }
  4557. }
  4558. }
  4559. else {
  4560. s4PLCSignal_Old["a4OEEType"] = 0;
  4561. }
  4562. }
  4563. catch (Exception ex)
  4564. {
  4565. string str = ex.StackTrace;
  4566. AddMessage_Station(stationNameStr, LogType.Error,
  4567. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  4568. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4569. }
  4570. #endregion
  4571. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  4572. stopwatch1.Stop();
  4573. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  4574. }
  4575. else
  4576. {
  4577. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4578. AddMessage_Station(stationNameStr, LogType.Info,
  4579. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  4580. FunsEip[plcNo].Connect(); // 重连
  4581. }
  4582. }
  4583. catch (Exception ex)
  4584. {
  4585. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4586. AddMessage_Station(stationNameStr, LogType.Error,
  4587. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  4588. }
  4589. Thread.Sleep(IntervalReadPLC);
  4590. }
  4591. }
  4592. /// <summary>
  4593. /// [S4] 点胶检测设备 - 进站
  4594. /// </summary>
  4595. /// <param name="plcNo">PLC编号</param>
  4596. /// <param name="stationNameStr">工站全称</param>
  4597. /// <param name="stPLC_MesData"></param>
  4598. /// <param name="tagMesCommName"></param>
  4599. private void S4进站(int plcNo, string stationNameStr, OP40_MesData_t stPLC_MesData, string tagMesCommName,
  4600. string tagBarsetName, out bool ProgressState)
  4601. {
  4602. Stopwatch stopwatch1 = new Stopwatch();
  4603. Stopwatch stopwatch2 = new Stopwatch();
  4604. try
  4605. {
  4606. stopwatch1.Start();
  4607. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  4608. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  4609. string MachineId = GlobalContext.S4_MachineId; // 装备ID(可配置)
  4610. string StationId = GlobalContext.S4_StationId; // 工位ID(可配置)
  4611. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  4612. bool pass = a1Result == 1;
  4613. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  4614. //载具码验证产品码
  4615. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  4616. if (string.IsNullOrEmpty(strProductBarcode))
  4617. {
  4618. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  4619. ProgressState = false;
  4620. Thread.Sleep(10000);
  4621. return;
  4622. }
  4623. sn = strProductBarcode;
  4624. AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  4625. // 产品SN(物料码)校验
  4626. List<TestItem> item = new List<TestItem>();
  4627. stopwatch2.Start();
  4628. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  4629. item, MachineId, StationId, pass, "01-SLOT-01");
  4630. stopwatch2.Stop();
  4631. //指令执行结果 1:OK 110:失败
  4632. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  4633. if (mesResultFrmWeb == 1)
  4634. {
  4635. if (a1Result == 1)
  4636. {
  4637. mesResultFrmWeb = 1;
  4638. }
  4639. else
  4640. {
  4641. mesResultFrmWeb = 110;
  4642. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  4643. }
  4644. }
  4645. //进站结果写入PLC
  4646. CommandFromPLC resultToPlC = new CommandFromPLC();
  4647. resultToPlC.cmd = 0;
  4648. resultToPlC.cmdParam = 0; //指令参数
  4649. resultToPlC.cmdResult = mesResultFrmWeb;
  4650. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4651. }
  4652. catch (Exception ex)
  4653. {
  4654. string str = ex.StackTrace;
  4655. AddMessage(LogType.Error,
  4656. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  4657. str.Length - str.LastIndexOf("\\") - 1));
  4658. CommandFromPLC resultToPlC = new CommandFromPLC();
  4659. resultToPlC.cmd = 0;
  4660. resultToPlC.cmdParam = 0; //指令参数
  4661. resultToPlC.cmdResult = 110;
  4662. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4663. }
  4664. stopwatch1.Stop();
  4665. AddMessage(LogType.Info, stationNameStr + "_进站结束");
  4666. AddMessage(LogType.Info,
  4667. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  4668. stopwatch2.ElapsedMilliseconds + "ms");
  4669. ProgressState = false;
  4670. }
  4671. /// <summary>
  4672. /// [S4] 点胶检测设备 - 出站接口
  4673. /// </summary>
  4674. private void S4出站(int plcNo, string stationNameStr, OP40_MesData_t stPLC_MesData, string tagMesCommName,
  4675. string stationCode, string stationName, out bool ProgressState)
  4676. {
  4677. Stopwatch stopwatch1 = new Stopwatch();
  4678. Stopwatch stopwatch2 = new Stopwatch();
  4679. try
  4680. {
  4681. stopwatch1.Start();
  4682. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  4683. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  4684. string processItem = stationName; // 测试项目
  4685. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  4686. string supplierCode = ""; // 供应商代码
  4687. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  4688. string batch_num = GlobalContext.BatchNumber; // 批次号
  4689. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  4690. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  4691. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  4692. string MachineId = GlobalContext.S4_MachineId; // 装备id(可配置) // ZS
  4693. string StationId = GlobalContext.S4_StationId; // ⼯位ID(可配置) // ZS
  4694. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  4695. bool pass = a1Result == 1;
  4696. //根据载具码获取产品码
  4697. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  4698. if (string.IsNullOrEmpty(strProductBarcode))
  4699. {
  4700. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  4701. ProgressState = false;
  4702. Thread.Sleep(10000);
  4703. return;
  4704. }
  4705. sn = strProductBarcode;
  4706. stPLC_MesData.BarcodeSet.strProductBarcode = strProductBarcode;
  4707. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  4708. List<TestItem> items = new List<TestItem>();
  4709. items.Add(new TestItem()
  4710. {
  4711. Parameter_name = "载具码",
  4712. Parameter_value = CarrierBarcode,
  4713. Parameter_unit = ""
  4714. });
  4715. items.Add(new TestItem()
  4716. {
  4717. Parameter_name = "产品码",
  4718. Parameter_value = sn,
  4719. Parameter_unit = ""
  4720. });
  4721. #region 上传图片
  4722. if (GlobalContext.MQTTIsSendUpFile)
  4723. {
  4724. CopyFileToTempPath(GlobalContext.UpFilePath,GlobalContext.MqttFileTempDir);
  4725. if (Directory.Exists(GlobalContext.MqttFileTempDir))
  4726. {
  4727. var result = SaveDBbyFileInfo(stPLC_MesData.BarcodeSet, stationCode, stationName, a1Result, GlobalContext.MqttFileTempDir, uuid).Result;
  4728. if (result.Item1==1)
  4729. {
  4730. OnMessage(LogType.Error, $"【文件上传】 产品码 [{sn}] " + result.Item2);
  4731. }
  4732. }
  4733. //string[] urlarry = GlobalContext.UpFilePath.Split(",");
  4734. //// fileUploadData.fileData.Clear();
  4735. //foreach (var item in urlarry)
  4736. //{
  4737. // if (!string.IsNullOrEmpty(item))
  4738. // {
  4739. // //上传图片
  4740. // var result = SaveDBbyFileInfo(stPLC_MesData.BarcodeSet, stationCode, stationName, a1Result,
  4741. // item, uuid).Result;
  4742. // OnMessage(LogType.Error, $"【文件上传】 产品码 [{sn}] " + result.Item2);
  4743. // }
  4744. //}
  4745. }
  4746. #endregion
  4747. #region 转换过站明细字符串
  4748. //创建字典
  4749. var dic = new Dictionary<string, string>();
  4750. // 获取结构体类型
  4751. FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  4752. string resultString = "";
  4753. // 遍历变量名转换成字典描述
  4754. foreach (FieldInfo field in fields)
  4755. {
  4756. //获取枚举描述
  4757. string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  4758. typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  4759. //获取过站明细的值
  4760. object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  4761. // 检查是否为数组
  4762. if (valueObj.GetType().IsArray)
  4763. {
  4764. var array = valueObj as Array;
  4765. resultString = ArrayToString(array);
  4766. }
  4767. else
  4768. {
  4769. resultString = valueObj.ToString();
  4770. }
  4771. dic.Add(name, resultString);
  4772. }
  4773. string paramJson = JsonConvert.SerializeObject(dic);
  4774. #endregion
  4775. //string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);//过站生产数据
  4776. #region MAS测试项
  4777. XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
  4778. string passFlag = "";
  4779. string AllpassFlag = "PASS";
  4780. //胶线面积
  4781. float[] fGlue_Areas = stPLC_MesData.testData.fGlue_Areas;
  4782. float fGlue_AreasMax = stPLC_MesData.testData.fGlue_AreasMax;
  4783. float fGlue_AreasMin = stPLC_MesData.testData.fGlue_AreasMin;
  4784. //胶线高度
  4785. float[] fGlue_Heights = stPLC_MesData.testData.fGlue_Heights;
  4786. float fGlue_HeightsMax = stPLC_MesData.testData.fGlue_HeightsMax;
  4787. float fGlue_HeightsMin = stPLC_MesData.testData.fGlue_HeightsMin;
  4788. XmStationOut_InspectionItemData inspectionItemData = new XmStationOut_InspectionItemData();
  4789. inspectionItemData.childUnitSn = strProductBarcode;
  4790. inspectionItemData.childUnitState = AllpassFlag;
  4791. inspectionItemData.toolVersion = "1.0";
  4792. if (fGlue_AreasMax > fGlue_AreasMin && (fGlue_AreasMax != 0 || fGlue_AreasMin != 0))
  4793. {
  4794. for (int i = 0; i < fGlue_Areas.Length -1 ; i++)
  4795. {
  4796. if (fGlue_Areas[i] > fGlue_AreasMin && fGlue_Areas[i] <= fGlue_AreasMax)
  4797. passFlag = "PASS";
  4798. else
  4799. passFlag = "FAIL";
  4800. if (passFlag == "FAIL") AllpassFlag = passFlag;
  4801. }
  4802. inspectionItemData.AddDataItem("GlueLine", "胶线面积", string.Join(",", fGlue_Areas), fGlue_AreasMax.ToString(), fGlue_AreasMin.ToString(), passFlag);
  4803. }
  4804. if (fGlue_HeightsMax > fGlue_HeightsMin && (fGlue_HeightsMax != 0 || fGlue_HeightsMin != 0))
  4805. {
  4806. for (int i = 0; i < fGlue_Heights.Length-1; i++)
  4807. {
  4808. if (fGlue_Heights[i] > fGlue_HeightsMin && fGlue_Heights[i] <= fGlue_HeightsMax)
  4809. passFlag = "PASS";
  4810. else
  4811. passFlag = "FAIL";
  4812. if (passFlag == "FAIL") AllpassFlag = passFlag;
  4813. }
  4814. inspectionItemData.AddDataItem("GlueLine", "胶线高度", string.Join(",", fGlue_Heights), fGlue_HeightsMax.ToString(), fGlue_HeightsMin.ToString(), passFlag);
  4815. }
  4816. #endregion
  4817. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  4818. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode,
  4819. "01-SLOT-01", MachineId, StationId, "", paramJson,new XmStationOut_InspectionItemData(), "");
  4820. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  4821. if (mesResultFrmWeb == 1)
  4822. {
  4823. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  4824. if (mesResultFrmWeb == 110)
  4825. {
  4826. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  4827. }
  4828. }
  4829. stopwatch2.Start();
  4830. //进站结果写入PLC
  4831. CommandFromPLC resultToPlC = new CommandFromPLC();
  4832. resultToPlC.cmd = 0;
  4833. resultToPlC.cmdParam = 0; //指令参数
  4834. resultToPlC.cmdResult = mesResultFrmWeb;
  4835. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4836. stopwatch2.Stop();
  4837. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  4838. //保存PLC返回MES数据到本地
  4839. ResponseMessage message = new ResponseMessage();
  4840. string strGluePosX = FloatArrayToString(stPLC_MesData.mesData.fGluePosX);
  4841. string strGluePosY = FloatArrayToString(stPLC_MesData.mesData.fGluePosY);
  4842. string strGlue_Areas = FloatArrayToString(stPLC_MesData.mesData.fGlue_Areas);
  4843. string strGlue_Heights = FloatArrayToString(stPLC_MesData.mesData.fGlue_Heights);
  4844. message = SQLHelper.InsertOp40Data(CarrierBarcode, sn, strGluePosX,
  4845. strGluePosY, strGlue_Areas, strGlue_Heights, stPLC_MesData.mesData.nResult, "");
  4846. if (message.result == false)
  4847. {
  4848. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  4849. }
  4850. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地成功");
  4851. }
  4852. catch (Exception ex)
  4853. {
  4854. stopwatch2.Start();
  4855. CommandFromPLC resultToPlC = new CommandFromPLC();
  4856. resultToPlC.cmd = 0;
  4857. resultToPlC.cmdParam = 0; //指令参数
  4858. resultToPlC.cmdResult = 110;
  4859. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4860. stopwatch2.Stop();
  4861. string str = ex.StackTrace;
  4862. AddMessage(LogType.Error,
  4863. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  4864. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4865. }
  4866. stopwatch1.Stop();
  4867. AddMessage(LogType.Info,
  4868. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  4869. stopwatch2.ElapsedMilliseconds + "ms");
  4870. ProgressState = false;
  4871. uuid = "";
  4872. }
  4873. #endregion
  4874. #region S5
  4875. private static bool isPCBStation = false; //控制PCB是否进出站的标识
  4876. /// <summary>
  4877. /// [S5] 点胶检测设备
  4878. /// </summary>
  4879. /// <param name="plcNo">PLC编号</param>
  4880. private void ReadStation_S5(int plcNo)
  4881. {
  4882. string stationCode = "[OP50]";
  4883. string stationName = "ADD板上料组装装备";
  4884. string stationNameStr = stationCode + stationName;
  4885. string tagBaseName = "g_OP50_MES"; //标签变量名称
  4886. string tagMesCommName = "mesCommToPC"; //标签变量名称
  4887. string tagAgvCommName = "agvCommFrmPC";
  4888. string tagiotComnName = "iotData";
  4889. string tagBarsetName = "BarcodeSet";
  4890. OP50_MesData_t stPLC_MesData; //PLC的MES数据
  4891. string CarrierBarcode = "";
  4892. // 触发信号字典
  4893. s5PLCSignal_Old.Add("a5OEEType", 0); // 节拍类型(plc写入)
  4894. // PLC数据字典 赋值
  4895. s5PLCData.Add("a5OEEType", 0); // 节拍类型(plc写入)
  4896. s5PLCData.Add("OEETypeFlag", 0); // 节拍标识 0 不上传 ,1 上传
  4897. (int, string) result;
  4898. while (true)
  4899. {
  4900. try
  4901. {
  4902. if (!GlobalContext._IsCon_Funs1)
  4903. {
  4904. UpdatePLCMonitor(1, plcNo, 0);
  4905. continue;
  4906. }
  4907. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  4908. {
  4909. Stopwatch stopwatch1 = new Stopwatch();
  4910. Stopwatch stopwatch2 = new Stopwatch();
  4911. stopwatch1.Start();
  4912. stopwatch2.Start();
  4913. #region 一次性读取所有数据
  4914. // 一次性读取所有数据
  4915. result = FunsEip[plcNo]
  4916. .Read_SingleTag<OP50_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  4917. if (result.Item1 != 0)
  4918. {
  4919. }
  4920. else
  4921. {
  4922. //测试数据
  4923. //stPLC_MesData.mesCommFrmPLC.cmd = 2;
  4924. //stPLC_MesData.BarcodeSet.strCarrierBarcode = "A235461";
  4925. //stPLC_MesData.BarcodeSet.strPCBBarcode = "A1507V000239";
  4926. //stPLC_MesData.iotData.beatAction = 1;
  4927. //stPLC_MesData.iotData.beatAction = 2;
  4928. //stPLC_MesData.iotData.beatAction = 3;
  4929. //stPLC_MesData.iotData.beatAction = 4;
  4930. //stPLC_MesData.iotData.beatAction = 5;
  4931. //stPLC_MesData.iotData.beatAction = 6;
  4932. //stPLC_MesData.BarcodeSet.strCarrierBarcode = "A123456";
  4933. #region 去除扫码产生的特殊字符
  4934. stPLC_MesData.BarcodeSet.strProductBarcode =
  4935. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  4936. stPLC_MesData.BarcodeSet.strPartBarcode =
  4937. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  4938. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  4939. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  4940. stPLC_MesData.BarcodeSet.strPCBBarcode =
  4941. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  4942. #endregion
  4943. //richTextBox1.AppendText("\n" + "读取成功");
  4944. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  4945. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  4946. ? XiaomiDeviceState.Unknown
  4947. : (XiaomiDeviceState)xmDeviceStateInt;
  4948. // 节拍
  4949. s5PLCData["a5OEEType"] = stPLC_MesData.iotData.beatAction;
  4950. //载具码
  4951. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode.ToString();
  4952. //报警信息
  4953. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  4954. }
  4955. #endregion 一次性读取所有数据
  4956. stopwatch2.Stop();
  4957. #region 进站
  4958. try
  4959. {
  4960. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  4961. {
  4962. lock (lockObj)
  4963. {
  4964. if (!ProgressState)
  4965. {
  4966. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  4967. ProgressState = true;
  4968. string PCBBarcode = stPLC_MesData.BarcodeSet.strPCBBarcode;
  4969. if (PCBBarcode != "ERROR" && !string.IsNullOrEmpty(PCBBarcode))
  4970. {
  4971. ProgressState = true;
  4972. Task.Run(() => S5进站(plcNo, stationNameStr, stPLC_MesData,
  4973. tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName,
  4974. out ProgressState));
  4975. }
  4976. }
  4977. }
  4978. }
  4979. }
  4980. catch (Exception ex)
  4981. {
  4982. ProgressState = false;
  4983. string str = ex.StackTrace;
  4984. AddMessage_Station(stationNameStr, LogType.Error,
  4985. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  4986. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4987. }
  4988. #endregion 进站
  4989. #region 出站
  4990. try
  4991. {
  4992. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  4993. {
  4994. lock (lockObj)
  4995. {
  4996. if (!ProgressState)
  4997. {
  4998. ProgressState = true;
  4999. Task.Run(() => S5出站(plcNo, stationNameStr, stPLC_MesData,
  5000. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  5001. out ProgressState));
  5002. stPLC_MesData.mesCommFrmPLC.cmd = 0;
  5003. }
  5004. }
  5005. }
  5006. }
  5007. catch (Exception ex)
  5008. {
  5009. ProgressState = false;
  5010. string str = ex.StackTrace;
  5011. AddMessage_Station(stationNameStr, LogType.Error,
  5012. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  5013. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5014. }
  5015. #endregion 出站
  5016. #region 节拍接口
  5017. try
  5018. {
  5019. if (stPLC_MesData.iotData.beatAction > 0)
  5020. {
  5021. int a5OEEType = Convert.ToInt32(s5PLCData["a5OEEType"]);
  5022. int a5OEETypeGOld = Convert.ToInt32(s5PLCSignal_Old["a5OEEType"]);
  5023. if (a5OEEType != a5OEETypeGOld)
  5024. {
  5025. s5PLCData["OEETypeFlag"] = "1";
  5026. }
  5027. else
  5028. {
  5029. s5PLCData["OEETypeFlag"] = "0";
  5030. }
  5031. if (s5PLCData["OEETypeFlag"].ToString() == "1" && (a5OEEType == 1 || a5OEEType == 3 || a5OEEType == 4 || a5OEEType == 5))
  5032. {
  5033. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName, CarrierBarcode, stPLC_MesData.iotData, out res);
  5034. if (res == 1)
  5035. {
  5036. s5PLCSignal_Old["a5OEEType"] = s5PLCData["a5OEEType"];
  5037. }
  5038. else {
  5039. s5PLCSignal_Old["a5OEEType"] = 0;
  5040. }
  5041. }
  5042. }
  5043. else {
  5044. s5PLCSignal_Old["a5OEEType"] = 0;
  5045. }
  5046. }
  5047. catch (Exception ex)
  5048. {
  5049. string str = ex.StackTrace;
  5050. AddMessage_Station(stationNameStr, LogType.Error,
  5051. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  5052. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5053. }
  5054. #endregion
  5055. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  5056. stopwatch1.Stop();
  5057. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  5058. }
  5059. else
  5060. {
  5061. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  5062. AddMessage_Station(stationNameStr, LogType.Info,
  5063. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  5064. FunsEip[plcNo].Connect(); // 重连
  5065. }
  5066. }
  5067. catch (Exception ex)
  5068. {
  5069. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  5070. AddMessage_Station(stationNameStr, LogType.Error,
  5071. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  5072. }
  5073. Thread.Sleep(IntervalReadPLC);
  5074. }
  5075. }
  5076. /// <summary>
  5077. /// [S5] 点胶检测设备 - 进站
  5078. /// </summary>
  5079. /// <param name="plcNo">PLC编号</param>
  5080. /// <param name="stationNameStr">工站全称</param>
  5081. /// <param name="stPLC_MesData"></param>
  5082. /// <param name="tagMesCommName"></param>
  5083. private void S5进站(int plcNo, string stationNameStr, OP50_MesData_t stPLC_MesData, string tagMesCommName,
  5084. string tagBarsetName, out bool ProgressState)
  5085. {
  5086. Stopwatch stopwatch1 = new Stopwatch();
  5087. Stopwatch stopwatch2 = new Stopwatch();
  5088. try
  5089. {
  5090. stopwatch1.Start();
  5091. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  5092. //string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  5093. //sn = sn.Substring(sn.Length - 11, 4) + sn.Substring(sn.Length - 5, 5);
  5094. string MachineId = GlobalContext.S5_MachineId; // 装备ID(可配置)
  5095. string StationId = GlobalContext.S5_StationId; // 工位ID(可配置)
  5096. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码
  5097. string pcbBarcode = (string)stPLC_MesData.BarcodeSet.strPCBBarcode;
  5098. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  5099. bool pass = a1Result == 1;
  5100. AddMessage(LogType.Info, $"ADD板编码(PCB码):{pcbBarcode}");
  5101. //绑定载具和产品
  5102. //ResponseMessage message = new ResponseMessage();
  5103. //message = SQLHelper.PCBCarrierBind(strCarrierBarcode, pcbBarcode);
  5104. //if (message.result == false)
  5105. //{
  5106. // AddMessage(LogType.Error, stationNameStr + "_载具码与产品码绑定失败,错误:" + message.text);
  5107. // ProgressState = false;
  5108. // Thread.Sleep(10000);
  5109. // return;
  5110. //}
  5111. //载具码验证产品码 //载具码验证产品码
  5112. //string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  5113. //if (string.IsNullOrEmpty(strProductBarcode))
  5114. //{
  5115. // AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  5116. //}
  5117. //sn = strProductBarcode;
  5118. //AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  5119. // 产品SN(物料码)校验
  5120. List<TestItem> item = new List<TestItem>();
  5121. stopwatch2.Start();
  5122. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  5123. pcbBarcode,
  5124. item, MachineId, StationId, pass, "01-SLOT-01");
  5125. stopwatch2.Stop();
  5126. //指令执行结果 1:OK 110:失败
  5127. byte mesResultFrmWeb = (byte)(result == 1 ? 2 : 120);
  5128. if (mesResultFrmWeb == 1)
  5129. {
  5130. if (a1Result == 1)
  5131. {
  5132. mesResultFrmWeb = 2;
  5133. }
  5134. else
  5135. {
  5136. mesResultFrmWeb = 120;
  5137. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  5138. }
  5139. }
  5140. //进站结果写入PLC
  5141. CommandFromPLC resultToPlC = new CommandFromPLC();
  5142. resultToPlC.cmd = 0;
  5143. resultToPlC.cmdParam = 0; //指令参数
  5144. resultToPlC.cmdResult = mesResultFrmWeb;
  5145. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5146. }
  5147. catch (Exception ex)
  5148. {
  5149. string str = ex.StackTrace;
  5150. AddMessage(LogType.Error,
  5151. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  5152. str.Length - str.LastIndexOf("\\") - 1));
  5153. CommandFromPLC resultToPlC = new CommandFromPLC();
  5154. resultToPlC.cmd = 0;
  5155. resultToPlC.cmdParam = 0; //指令参数
  5156. resultToPlC.cmdResult = 120;
  5157. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5158. }
  5159. stopwatch1.Stop();
  5160. AddMessage(LogType.Info, stationNameStr + "_进站结束");
  5161. AddMessage(LogType.Info,
  5162. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  5163. stopwatch2.ElapsedMilliseconds + "ms");
  5164. ProgressState = false;
  5165. }
  5166. /// <summary>
  5167. /// [S5] 点胶检测设备 - 出站接口
  5168. /// </summary>
  5169. private void S5出站(int plcNo, string stationNameStr, OP50_MesData_t stPLC_MesData, string tagMesCommName,
  5170. string stationCode, string stationName, out bool ProgressState)
  5171. {
  5172. Stopwatch stopwatch1 = new Stopwatch();
  5173. Stopwatch stopwatch2 = new Stopwatch();
  5174. try
  5175. {
  5176. stopwatch1.Start();
  5177. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  5178. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  5179. string processItem = stationName; // 测试项目
  5180. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  5181. string supplierCode = ""; // 供应商代码
  5182. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  5183. string batch_num = GlobalContext.BatchNumber; // 批次号
  5184. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  5185. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  5186. string PartBarcode = (string)stPLC_MesData.BarcodeSet.strPartBarcode; // 部件条码;
  5187. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  5188. string pcbBarcode = (string)stPLC_MesData.BarcodeSet.strPCBBarcode;
  5189. string MachineId = GlobalContext.S5_MachineId; // 装备id(可配置) // ZS
  5190. string StationId = GlobalContext.S5_StationId; // ⼯位ID(可配置) // ZS
  5191. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  5192. bool pass = a1Result == 1;
  5193. CommandFromPLC resultToPlC = new CommandFromPLC();
  5194. //根据载具码获取产品码
  5195. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  5196. if (string.IsNullOrEmpty(strProductBarcode))
  5197. {
  5198. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  5199. ProgressState = false;
  5200. Thread.Sleep(10000);
  5201. return;
  5202. }
  5203. stPLC_MesData.BarcodeSet.strProductBarcode = strProductBarcode;
  5204. sn = strProductBarcode;
  5205. //数据库绑定载具和PCB
  5206. ResponseMessage message = new ResponseMessage();
  5207. message = SQLHelper.PCBCarrierBind(CarrierBarcode, pcbBarcode);
  5208. if (message.result == false)
  5209. {
  5210. AddMessage(LogType.Error, stationNameStr + "_PCB码数据库绑定失败,错误:" + message.text);
  5211. ProgressState = true; //防止循环报错
  5212. return;
  5213. }
  5214. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn};PCB码:{pcbBarcode}");
  5215. List<TestItem> items = new List<TestItem>();
  5216. items.Add(new TestItem()
  5217. {
  5218. Parameter_name = "载具码",
  5219. Parameter_value = CarrierBarcode,
  5220. Parameter_unit = ""
  5221. });
  5222. items.Add(new TestItem()
  5223. {
  5224. Parameter_name = "产品码",
  5225. Parameter_value = sn,
  5226. Parameter_unit = ""
  5227. });
  5228. items.Add(new TestItem()
  5229. {
  5230. Parameter_name = "PCB码",
  5231. Parameter_value = pcbBarcode,
  5232. Parameter_unit = ""
  5233. });
  5234. #region 上传图片
  5235. if (GlobalContext.MQTTIsSendUpFile)
  5236. {
  5237. CopyFileToTempPath(GlobalContext.UpFilePath, GlobalContext.MqttFileTempDir);
  5238. if (Directory.Exists(GlobalContext.MqttFileTempDir))
  5239. {
  5240. var result = SaveDBbyFileInfo(stPLC_MesData.BarcodeSet, stationCode, stationName, a1Result, GlobalContext.MqttFileTempDir, uuid).Result;
  5241. if (result.Item1 == 1)
  5242. {
  5243. OnMessage(LogType.Error, $"【文件上传】 产品码 [{sn}] " + result.Item2);
  5244. }
  5245. }
  5246. //string[] urlarry = GlobalContext.UpFilePath.Split(",");
  5247. //// fileUploadData.fileData.Clear();
  5248. //foreach (var item in urlarry)
  5249. //{
  5250. // if (!string.IsNullOrEmpty(item))
  5251. // {
  5252. // //上传图片
  5253. // var result = SaveDBbyFileInfo(stPLC_MesData.BarcodeSet, stationCode, stationName, a1Result,
  5254. // item, uuid).Result;
  5255. // OnMessage(LogType.Error, $"【文件上传】 产品码 [{sn}] " + result.Item2);
  5256. // }
  5257. //}
  5258. }
  5259. #endregion
  5260. #region 转换过站明细字符串
  5261. ////创建字典
  5262. //var dic = new Dictionary<string, string>();
  5263. //// 获取结构体类型
  5264. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  5265. //string resultString = "";
  5266. //// 遍历变量名转换成字典描述
  5267. //foreach (FieldInfo field in fields)
  5268. //{
  5269. // //获取枚举描述
  5270. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  5271. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  5272. // //获取过站明细的值
  5273. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  5274. // // 检查是否为数组
  5275. // if (valueObj.GetType().IsArray)
  5276. // {
  5277. // var array = valueObj as Array;
  5278. // resultString = ArrayToString(array);
  5279. // }
  5280. // else
  5281. // {
  5282. // resultString = valueObj.ToString();
  5283. // }
  5284. // dic.Add(name, resultString);
  5285. //}
  5286. //string paramJson = JsonConvert.SerializeObject(dic);
  5287. #endregion
  5288. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);
  5289. #region MAS测试项
  5290. XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
  5291. string passFlag = "";
  5292. string AllpassFlag = "PASS";
  5293. //ADD板的压力
  5294. float fForceAddPCB = stPLC_MesData.testData.fForceAddPCB;
  5295. float fForceAddPCBMax = stPLC_MesData.testData.fForceAddPCBMax;
  5296. float fForceAddPCBMin = stPLC_MesData.testData.fForceAddPCBMin;
  5297. XmStationOut_InspectionItemData inspectionItemData = new XmStationOut_InspectionItemData();
  5298. if (fForceAddPCBMax > fForceAddPCBMin && (fForceAddPCBMax != 0 || fForceAddPCBMin != 0))
  5299. {
  5300. if (fForceAddPCB > fForceAddPCBMin && fForceAddPCB <= fForceAddPCBMax)
  5301. passFlag = "PASS";
  5302. else
  5303. passFlag = "FAIL";
  5304. if (passFlag == "FAIL") AllpassFlag = passFlag;
  5305. inspectionItemData.AddDataItem("AirPressure", "ADD板压力", fForceAddPCB.ToString(), fForceAddPCBMax.ToString(), fForceAddPCBMin.ToString(), passFlag);
  5306. }
  5307. inspectionItemData.childUnitSn = strProductBarcode;
  5308. inspectionItemData.childUnitState = AllpassFlag;
  5309. inspectionItemData.toolVersion = "1.0";
  5310. #endregion
  5311. int result1 = 0;
  5312. byte mesResultFrmWeb = 0;
  5313. if (stPLC_MesData.mesCommFrmPLC.cmdParam == 2)
  5314. {
  5315. result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem, workorder_code,
  5316. batch_num
  5317. , mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "01-SLOT-01", MachineId, StationId,
  5318. PartBarcode, paramJson,new XmStationOut_InspectionItemData(), "");
  5319. uuid = "";
  5320. }
  5321. else if (stPLC_MesData.mesCommFrmPLC.cmdParam == 1)
  5322. {
  5323. result1 = PCBStationOutData(stPLC_MesData.BarcodeSet, stPLC_MesData.iotData);
  5324. }
  5325. mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  5326. //进站结果写入PLC
  5327. resultToPlC.cmd = 0;
  5328. resultToPlC.cmdParam = 0; //指令参数
  5329. resultToPlC.cmdResult = mesResultFrmWeb;
  5330. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5331. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  5332. //保存PLC返回MES数据到本地
  5333. //ResponseMessage message = new ResponseMessage();
  5334. message = SQLHelper.InsertOp50Data(CarrierBarcode, sn, stPLC_MesData.mesData.nIsAddPCBAsmOK,
  5335. stPLC_MesData.mesData.nHaveAddPCB, stPLC_MesData.mesData.fForceAddPCB,
  5336. stPLC_MesData.mesData.nRemainCount, "");
  5337. if (message.result == false)
  5338. {
  5339. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  5340. }
  5341. //保存部件码信息
  5342. if (!string.IsNullOrEmpty(PartBarcode))
  5343. {
  5344. message = SQLHelper.InsertOp50Product(CarrierBarcode, sn, PartBarcode);
  5345. if (message.result == false)
  5346. {
  5347. AddMessage(LogType.Info, stationNameStr + "_保存部件码信息失败");
  5348. }
  5349. }
  5350. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地成功");
  5351. }
  5352. catch (Exception ex)
  5353. {
  5354. stopwatch2.Start();
  5355. CommandFromPLC resultToPlC = new CommandFromPLC();
  5356. resultToPlC.cmd = 0;
  5357. resultToPlC.cmdParam = 0; //指令参数
  5358. resultToPlC.cmdResult = 110;
  5359. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5360. stopwatch2.Stop();
  5361. string str = ex.StackTrace;
  5362. AddMessage(LogType.Error,
  5363. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  5364. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5365. }
  5366. stopwatch1.Stop();
  5367. AddMessage(LogType.Info,
  5368. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  5369. stopwatch2.ElapsedMilliseconds + "ms");
  5370. ProgressState = false;
  5371. }
  5372. private int S5_PCB进出站(OP50_MesData_t stPLC_MesData, int plcNo, string stationNameStr, string tagBaseName,
  5373. string tagMesCommName)
  5374. {
  5375. string PCBBarcode = stPLC_MesData.BarcodeSet.strPCBBarcode;
  5376. if (PCBBarcode != "ERROR" && !string.IsNullOrEmpty(PCBBarcode))
  5377. {
  5378. string strProductBarcode =
  5379. SQLHelper.GetProductBarcodeByCarrierCode(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  5380. stPLC_MesData.BarcodeSet.strProductBarcode = strProductBarcode;
  5381. CommandFromPLC resultToPlC = new CommandFromPLC();
  5382. resultToPlC.cmd = 0;
  5383. resultToPlC.cmdParam = 0; //指令参数
  5384. if (GlobalContext.IsSendStationIn)
  5385. {
  5386. #region 进站
  5387. //int res1 = PCBStationInData(stPLC_MesData.BarcodeSet, stPLC_MesData.iotData);
  5388. //if (res1 == 1)
  5389. //{
  5390. // resultToPlC.cmdResult = 2;//OK
  5391. // WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, resultToPlC);
  5392. //}
  5393. //else
  5394. //{
  5395. // resultToPlC.cmdResult = 120;
  5396. // WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, resultToPlC);
  5397. // return 2;
  5398. //}
  5399. #endregion
  5400. #region 出站
  5401. int res2 = PCBStationOutData(stPLC_MesData.BarcodeSet, stPLC_MesData.iotData);
  5402. if (res2 == 1)
  5403. {
  5404. resultToPlC.cmdResult = 2; //OK
  5405. WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, resultToPlC);
  5406. return 1;
  5407. }
  5408. else
  5409. {
  5410. resultToPlC.cmdResult = 120;
  5411. WriteResultToPlc(plcNo, stationNameStr, tagBaseName + "." + tagMesCommName, 1, resultToPlC);
  5412. return 2;
  5413. }
  5414. #endregion
  5415. }
  5416. else
  5417. {
  5418. return 2;
  5419. }
  5420. }
  5421. else
  5422. {
  5423. return 2;
  5424. }
  5425. }
  5426. #endregion
  5427. #region S6
  5428. private Dictionary<string, object> s6PLCData = new Dictionary<string, object>();
  5429. private Dictionary<string, object> s6PLCSignal_Old = new Dictionary<string, object>();
  5430. /// <summary>
  5431. /// [S6] 顶盖装配设备
  5432. /// </summary>
  5433. /// <param name="plcNo">PLC编号</param>
  5434. public void ReadStation_S6(int plcNo)
  5435. {
  5436. string stationCode = "[OP70]";
  5437. string stationName = "组上盖板";
  5438. string stationNameStr = stationCode + stationName;
  5439. string tagBaseName = "g_OP60_MES"; //标签变量名称
  5440. string tagMesCommName = "mesCommToPC"; //标签变量名称
  5441. string tagAgvCommName = "agvCommFrmPC";
  5442. string tagiotComnName = "iotData";
  5443. string tagBarsetName = "BarcodeSet";
  5444. string CarrierBarcode = "";
  5445. // 触发信号字典
  5446. s6PLCSignal_Old.Add("a6OEEType", 0); // 节拍类型(plc写入)
  5447. // PLC数据字典 赋值
  5448. s6PLCData.Add("a6OEEType", 0); // 节拍类型(plc写入)
  5449. s6PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  5450. OP60_MesData_t stPLC_MesData; //PLC的MES数据
  5451. (int, string) result;
  5452. while (true)
  5453. {
  5454. try
  5455. {
  5456. if (!GlobalContext._IsCon_Funs1)
  5457. {
  5458. UpdatePLCMonitor(1, plcNo, 0);
  5459. continue;
  5460. }
  5461. if (StopWhile)
  5462. {
  5463. continue;
  5464. }
  5465. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  5466. {
  5467. Stopwatch stopwatch1 = new Stopwatch();
  5468. Stopwatch stopwatch2 = new Stopwatch();
  5469. stopwatch1.Start();
  5470. stopwatch2.Start();
  5471. #region 一次性读取所有数据
  5472. // 一次性读取所有数据
  5473. result = FunsEip[plcNo]
  5474. .Read_SingleTag<OP60_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  5475. if (result.Item1 != 0)
  5476. {
  5477. //richTextBox1.AppendText("\n" + strRet);
  5478. }
  5479. else
  5480. {
  5481. //测试
  5482. //stPLC_MesData.BarcodeSet.strCarrierBarcode = "A123456";
  5483. //stPLC_MesData.mesCommFrmPLC.cmd = 1;
  5484. //去除扫码产生的特殊字符
  5485. stPLC_MesData.BarcodeSet.strProductBarcode =
  5486. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  5487. stPLC_MesData.BarcodeSet.strPartBarcode =
  5488. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  5489. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  5490. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  5491. stPLC_MesData.BarcodeSet.strPCBBarcode =
  5492. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  5493. //richTextBox1.AppendText("\n" + "读取成功");
  5494. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  5495. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  5496. ? XiaomiDeviceState.Unknown
  5497. : (XiaomiDeviceState)xmDeviceStateInt;
  5498. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具SN
  5499. s6PLCData["a6OEEType"] = stPLC_MesData.iotData.beatAction; // 节拍
  5500. //报警信息
  5501. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  5502. }
  5503. #endregion 一次性读取所有数据
  5504. stopwatch2.Stop();
  5505. #region 进站
  5506. try
  5507. {
  5508. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  5509. {
  5510. lock (lockObj)
  5511. {
  5512. if (!ProgressState)
  5513. {
  5514. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  5515. ProgressState = true;
  5516. //载具码验证产品码
  5517. Task.Run(() => S6进站(plcNo, stationNameStr, stPLC_MesData,
  5518. tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName,
  5519. out ProgressState));
  5520. }
  5521. }
  5522. }
  5523. }
  5524. catch (Exception ex)
  5525. {
  5526. ProgressState = false;
  5527. string str = ex.StackTrace;
  5528. AddMessage_Station(stationNameStr, LogType.Error,
  5529. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  5530. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5531. }
  5532. #endregion 进站
  5533. #region 出站
  5534. try
  5535. {
  5536. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  5537. {
  5538. lock (lockObj)
  5539. {
  5540. if (!ProgressState)
  5541. {
  5542. ProgressState = true;
  5543. Task.Run(() => S6出站(plcNo, stationNameStr, stPLC_MesData,
  5544. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  5545. out ProgressState));
  5546. stPLC_MesData.mesCommFrmPLC.cmd = 0;
  5547. }
  5548. }
  5549. }
  5550. }
  5551. catch (Exception ex)
  5552. {
  5553. ProgressState = false;
  5554. string str = ex.StackTrace;
  5555. AddMessage_Station(stationNameStr, LogType.Error,
  5556. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  5557. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5558. }
  5559. #endregion 出站
  5560. #region 节拍接口
  5561. try
  5562. {
  5563. if (stPLC_MesData.iotData.beatAction > 0)
  5564. {
  5565. int a6OEEType = Convert.ToInt32(s6PLCData["a6OEEType"]);
  5566. int a6OEETypeGOld = Convert.ToInt32(s6PLCSignal_Old["a6OEEType"]);
  5567. if (a6OEEType != a6OEETypeGOld)
  5568. {
  5569. s6PLCData["OEETypeFlag"] = "1";
  5570. }
  5571. else
  5572. {
  5573. s6PLCData["OEETypeFlag"] = "0";
  5574. }
  5575. if (s6PLCData["OEETypeFlag"].ToString() == "1" && (a6OEEType == 1 || a6OEEType == 3 || a6OEEType == 4 || a6OEEType == 5))
  5576. {
  5577. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName, CarrierBarcode, stPLC_MesData.iotData, out res);
  5578. if (res == 1)
  5579. {
  5580. s6PLCSignal_Old["a6OEEType"] = s6PLCData["a6OEEType"];
  5581. }
  5582. else
  5583. {
  5584. s6PLCSignal_Old["a6OEEType"] = 0;
  5585. }
  5586. }
  5587. }
  5588. else {
  5589. s6PLCSignal_Old["a6OEEType"] = 0;
  5590. }
  5591. }
  5592. catch (Exception ex)
  5593. {
  5594. string str = ex.StackTrace;
  5595. AddMessage_Station(stationNameStr, LogType.Error,
  5596. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  5597. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5598. }
  5599. #endregion
  5600. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  5601. stopwatch1.Stop();
  5602. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  5603. }
  5604. else
  5605. {
  5606. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  5607. AddMessage_Station(stationNameStr, LogType.Info,
  5608. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  5609. FunsEip[plcNo].Connect(); // 重连
  5610. }
  5611. }
  5612. catch (Exception ex)
  5613. {
  5614. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  5615. AddMessage_Station(stationNameStr, LogType.Error,
  5616. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  5617. }
  5618. Thread.Sleep(IntervalReadPLC);
  5619. }
  5620. }
  5621. /// <summary>
  5622. /// [S6] 顶盖装配设备 - 进站
  5623. /// </summary>
  5624. /// <param name="plcNo">PLC编号</param>
  5625. /// <param name="stationNameStr">工站全称</param>
  5626. /// <param name="stPLC_MesData"></param>
  5627. /// <param name="tagMesCommName"></param>
  5628. private void S6进站(int plcNo, string stationNameStr, OP60_MesData_t stPLC_MesData, string tagMesCommName,
  5629. string tagBarsetName, out bool ProgressState)
  5630. {
  5631. Stopwatch stopwatch1 = new Stopwatch();
  5632. Stopwatch stopwatch2 = new Stopwatch();
  5633. try
  5634. {
  5635. stopwatch1.Start();
  5636. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  5637. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  5638. string MachineId = GlobalContext.S6_MachineId; // 装备ID(可配置)
  5639. string StationId = GlobalContext.S6_StationId; // 工位ID(可配置)
  5640. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  5641. bool pass = a1Result == 1;
  5642. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  5643. string ProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  5644. string PCBBarcode = SQLHelper.GetPCBBarcodeByCarrierCode(strCarrierBarcode);
  5645. //strCarrierBarcode = "N801A-003";
  5646. //载具码验证产品码
  5647. if (string.IsNullOrEmpty(ProductBarcode))
  5648. {
  5649. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  5650. ProgressState = false;
  5651. Thread.Sleep(10000);
  5652. return;
  5653. }
  5654. sn = ProductBarcode;
  5655. AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  5656. if (ProductBarcode != "")
  5657. {
  5658. MessageBox.Show($"产品码:{sn}线外螺丝机过站后点击确认", "提示",
  5659. MessageBoxButtons.OK,
  5660. MessageBoxIcon.Information);
  5661. }
  5662. // 产品SN(物料码)校验
  5663. List<TestItem> item = new List<TestItem>();
  5664. stopwatch2.Start();
  5665. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  5666. item, MachineId, StationId, pass, "01-SLOT-01");
  5667. stopwatch2.Stop();
  5668. //指令执行结果 1:OK 110:失败
  5669. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  5670. if (mesResultFrmWeb == 1)
  5671. {
  5672. if (a1Result == 1)
  5673. {
  5674. mesResultFrmWeb = 1;
  5675. if (OpenDailogFalg)
  5676. {
  5677. using (var dialog = new BandBarodeDialog(strCarrierBarcode, ProductBarcode, PCBBarcode))
  5678. {
  5679. var rs = dialog.ShowDialog();
  5680. if (rs == DialogResult.OK)
  5681. {
  5682. AddMessage(LogType.Info, $"扫码校验通过,载具码:{strCarrierBarcode}");
  5683. OpenDailogFalg = false; //关闭扫码
  5684. StopWhile = false;//开启while循环
  5685. }
  5686. else
  5687. {
  5688. ProgressState = false;
  5689. return;
  5690. }
  5691. }
  5692. }
  5693. }
  5694. else
  5695. {
  5696. mesResultFrmWeb = 110;
  5697. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  5698. }
  5699. }
  5700. //进站结果写入PLC
  5701. CommandFromPLC resultToPlC = new CommandFromPLC();
  5702. resultToPlC.cmd = 0;
  5703. resultToPlC.cmdParam = 0; //指令参数
  5704. resultToPlC.cmdResult = mesResultFrmWeb;
  5705. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5706. }
  5707. catch (Exception ex)
  5708. {
  5709. string str = ex.StackTrace;
  5710. AddMessage(LogType.Error,
  5711. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  5712. str.Length - str.LastIndexOf("\\") - 1));
  5713. CommandFromPLC resultToPlC = new CommandFromPLC();
  5714. resultToPlC.cmd = 0;
  5715. resultToPlC.cmdParam = 0; //指令参数
  5716. resultToPlC.cmdResult = 110;
  5717. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5718. }
  5719. stopwatch1.Stop();
  5720. AddMessage(LogType.Info, stationNameStr + "_进站结束");
  5721. AddMessage(LogType.Info,
  5722. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  5723. stopwatch2.ElapsedMilliseconds + "ms");
  5724. ProgressState = false;
  5725. }
  5726. /// <summary>
  5727. /// [S6] 顶盖装配设备 - 出站接口
  5728. /// </summary>
  5729. private void S6出站(int plcNo, string stationNameStr, OP60_MesData_t stPLC_MesData, string tagMesCommName,
  5730. string stationCode, string stationName, out bool ProgressState)
  5731. {
  5732. Stopwatch stopwatch1 = new Stopwatch();
  5733. Stopwatch stopwatch2 = new Stopwatch();
  5734. try
  5735. {
  5736. stopwatch1.Start();
  5737. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  5738. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  5739. string processItem = stationName; // 测试项目
  5740. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  5741. string supplierCode = ""; // 供应商代码
  5742. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  5743. string batch_num = GlobalContext.BatchNumber; // 批次号
  5744. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  5745. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  5746. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  5747. string MachineId = GlobalContext.S6_MachineId; // 装备id(可配置) // ZS
  5748. string StationId = GlobalContext.S6_StationId; // ⼯位ID(可配置) // ZS
  5749. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  5750. bool pass = a1Result == 1;
  5751. //根据载具码获取产品码
  5752. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  5753. if (string.IsNullOrEmpty(strProductBarcode))
  5754. {
  5755. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  5756. ProgressState = false;
  5757. Thread.Sleep(10000);
  5758. return;
  5759. }
  5760. sn = strProductBarcode;
  5761. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  5762. List<TestItem> items = new List<TestItem>();
  5763. items.Add(new TestItem()
  5764. {
  5765. Parameter_name = "载具码",
  5766. Parameter_value = CarrierBarcode,
  5767. Parameter_unit = ""
  5768. });
  5769. items.Add(new TestItem()
  5770. {
  5771. Parameter_name = "产品码",
  5772. Parameter_value = sn,
  5773. Parameter_unit = ""
  5774. });
  5775. #region 转换过站明细字符串
  5776. ////创建字典
  5777. //var dic = new Dictionary<string, string>();
  5778. //// 获取结构体类型
  5779. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  5780. //string resultString = "";
  5781. //// 遍历变量名转换成字典描述
  5782. //foreach (FieldInfo field in fields)
  5783. //{
  5784. // //获取枚举描述
  5785. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  5786. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  5787. // //获取过站明细的值
  5788. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  5789. // // 检查是否为数组
  5790. // if (valueObj.GetType().IsArray)
  5791. // {
  5792. // var array = valueObj as Array;
  5793. // resultString = ArrayToString(array);
  5794. // }
  5795. // else
  5796. // {
  5797. // resultString = valueObj.ToString();
  5798. // }
  5799. // dic.Add(name, resultString);
  5800. //}
  5801. //string paramJson = JsonConvert.SerializeObject(dic);
  5802. #endregion
  5803. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);
  5804. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  5805. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "01-SLOT-01",
  5806. MachineId, StationId, "", paramJson,new XmStationOut_InspectionItemData(), "");
  5807. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  5808. if (mesResultFrmWeb == 1)
  5809. {
  5810. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  5811. if (mesResultFrmWeb==110)
  5812. {
  5813. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  5814. }
  5815. }
  5816. stopwatch2.Start();
  5817. //进站结果写入PLC
  5818. CommandFromPLC resultToPlC = new CommandFromPLC();
  5819. resultToPlC.cmd = 0;
  5820. resultToPlC.cmdParam = 0; //指令参数
  5821. resultToPlC.cmdResult = mesResultFrmWeb;
  5822. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5823. stopwatch2.Stop();
  5824. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  5825. //保存PLC返回MES数据到本地
  5826. ResponseMessage message = new ResponseMessage();
  5827. message = SQLHelper.InsertOp60Data(CarrierBarcode, sn, stPLC_MesData.mesData.nIsTopCoverAsmOK,
  5828. stPLC_MesData.mesData.nHaveTopCover, stPLC_MesData.mesData.fForceTopCover, "");
  5829. }
  5830. catch (Exception ex)
  5831. {
  5832. stopwatch2.Start();
  5833. CommandFromPLC resultToPlC = new CommandFromPLC();
  5834. resultToPlC.cmd = 0;
  5835. resultToPlC.cmdParam = 0; //指令参数
  5836. resultToPlC.cmdResult = 110;
  5837. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5838. stopwatch2.Stop();
  5839. string str = ex.StackTrace;
  5840. AddMessage(LogType.Error,
  5841. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  5842. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5843. }
  5844. stopwatch1.Stop();
  5845. AddMessage(LogType.Info,
  5846. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  5847. stopwatch2.ElapsedMilliseconds + "ms");
  5848. ProgressState = false;
  5849. uuid = "";
  5850. OpenDailogFalg = true; //开启下一个物料的扫码
  5851. }
  5852. #endregion
  5853. #region S7
  5854. private Dictionary<string, object> s7PLCSignal_Old = new Dictionary<string, object>();
  5855. private Dictionary<string, object> s7PLCData = new Dictionary<string, object>();
  5856. /// <summary>
  5857. /// [S7] 锁螺丝设备
  5858. /// </summary>
  5859. /// <param name="plcNo">PLC编号</param>
  5860. private void ReadStation_S7(int plcNo)
  5861. {
  5862. string stationCode = "[OP80]";
  5863. string stationName = "上盖板锁螺丝";
  5864. string stationNameStr = stationCode + stationName;
  5865. string tagBaseName = "g_OP70_MES"; //标签变量名称
  5866. string tagMesCommName = "mesCommToPC"; //标签变量名称
  5867. string tagAgvCommName = "agvCommFrmPC";
  5868. string tagBarsetName = "BarcodeSet";
  5869. string tagiotComnName = "iotData";
  5870. string tagScrewDataset = "screwDataset";
  5871. string CarrierBarcode_Left = "";
  5872. string CarrierBarcode_Right = "";
  5873. s7PLCSignal_Old.Add("a7OEEType_left", 0); // 节拍类型(plc写入)
  5874. s7PLCSignal_Old.Add("a7OEEType_right", 0); // 节拍类型(plc写入)
  5875. // PLC数据字典 赋值
  5876. s7PLCData.Add("a7OEEType_left", 0); // 节拍类型(plc写入)
  5877. s7PLCData.Add("a7OEEType_right", 0); // 节拍类型(plc写入)
  5878. s5PLCData.Add("OEETypeFlag_left", 0); // 节拍标识 0 不上传 ,1 上传
  5879. s5PLCData.Add("OEETypeFlag_right", 0); // 节拍标识 0 不上传 ,1 上传
  5880. OP70_MesData_t stPLC_MesData; //PLC的MES数据
  5881. (int, string) result;
  5882. AtlasScrew atlasScrewLeft = new AtlasScrew(GlobalContext.AtlasAddressLeft, GlobalContext.AtlasAddressPort,
  5883. 3000, 3000, "Left");
  5884. atlasScrewLeft.Initial();
  5885. AtlasScrew atlasScrewRight = new AtlasScrew(GlobalContext.AtlasAddressRight, GlobalContext.AtlasAddressPort,
  5886. 3000, 3000, "Right");
  5887. atlasScrewRight.Initial();
  5888. while (true)
  5889. {
  5890. try
  5891. {
  5892. if (!GlobalContext._IsCon_Funs1)
  5893. {
  5894. UpdatePLCMonitor(1, plcNo, 0);
  5895. continue;
  5896. }
  5897. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  5898. {
  5899. Stopwatch stopwatch1 = new Stopwatch();
  5900. Stopwatch stopwatch2 = new Stopwatch();
  5901. stopwatch1.Start();
  5902. stopwatch2.Start();
  5903. #region 一次性读取所有数据
  5904. // 一次性读取所有数据
  5905. result = FunsEip[plcNo]
  5906. .Read_SingleTag<OP70_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  5907. if (result.Item1 != 0)
  5908. {
  5909. //richTextBox1.AppendText("\n" + strRet);
  5910. }
  5911. else
  5912. {
  5913. #region 去除扫码产生的特殊字符
  5914. stPLC_MesData.Left.BarcodeSet.strProductBarcode =
  5915. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strProductBarcode);
  5916. stPLC_MesData.Left.BarcodeSet.strPartBarcode =
  5917. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strPartBarcode);
  5918. stPLC_MesData.Left.BarcodeSet.strCarrierBarcode =
  5919. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strCarrierBarcode);
  5920. stPLC_MesData.Left.BarcodeSet.strPCBBarcode =
  5921. FormatStrbyPLC(stPLC_MesData.Left.BarcodeSet.strPCBBarcode);
  5922. stPLC_MesData.Right.BarcodeSet.strProductBarcode =
  5923. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strProductBarcode);
  5924. stPLC_MesData.Right.BarcodeSet.strPartBarcode =
  5925. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strPartBarcode);
  5926. stPLC_MesData.Right.BarcodeSet.strCarrierBarcode =
  5927. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strCarrierBarcode);
  5928. stPLC_MesData.Right.BarcodeSet.strPCBBarcode =
  5929. FormatStrbyPLC(stPLC_MesData.Right.BarcodeSet.strPCBBarcode);
  5930. #endregion
  5931. int xmDeviceStateInt_L = stPLC_MesData.Left.iotData.machineState;
  5932. int xmDeviceStateInt_R = stPLC_MesData.Right.iotData.machineState;
  5933. xmDeviceStateData.left = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
  5934. ? XiaomiDeviceState.Unknown
  5935. : (XiaomiDeviceState)xmDeviceStateInt_L;
  5936. xmDeviceStateData.right = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
  5937. ? XiaomiDeviceState.Unknown
  5938. : (XiaomiDeviceState)xmDeviceStateInt_R;
  5939. s7PLCData["a7OEEPartNo"] =
  5940. stPLC_MesData.Left.BarcodeSet.strProductBarcode; // 物料码(物料码还未绑定载具SN时必填)
  5941. // 载具SN
  5942. CarrierBarcode_Left = stPLC_MesData.Left.BarcodeSet.strCarrierBarcode;
  5943. CarrierBarcode_Right = stPLC_MesData.Right.BarcodeSet.strCarrierBarcode;
  5944. // 节拍
  5945. s7PLCData["a7OEEType"] = stPLC_MesData.Left.iotData.beatAction;
  5946. s7PLCData["a7OEEType_left"] = stPLC_MesData.Left .iotData.beatAction;
  5947. s7PLCData["a7OEEType_right"] = stPLC_MesData.Right.iotData.beatAction;
  5948. //报警信息
  5949. _FaultDatas = stPLC_MesData.Left.iotData.fault_codes;
  5950. _FaultDatas2 = stPLC_MesData.Right.iotData.fault_codes;
  5951. }
  5952. #endregion 一次性读取所有数据
  5953. stopwatch2.Stop();
  5954. #region 左边进站
  5955. try
  5956. {
  5957. if (stPLC_MesData.Left.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  5958. {
  5959. lock (lockObj)
  5960. {
  5961. if (!ProgressState)
  5962. {
  5963. stationCode = "[OP81]";
  5964. stationName = "上盖板锁螺丝1";
  5965. stationNameStr = stationCode + stationName;
  5966. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  5967. ProgressState = true;
  5968. Task.Run(() => S7进站(plcNo, stationNameStr, stPLC_MesData.Left,
  5969. tagBaseName + ".Left." + tagMesCommName,
  5970. tagBaseName + ".Left." + tagBarsetName, "Left", out ProgressState,
  5971. atlasScrewLeft));
  5972. }
  5973. }
  5974. }
  5975. }
  5976. catch (Exception ex)
  5977. {
  5978. ProgressState = false;
  5979. string str = ex.StackTrace;
  5980. AddMessage_Station(stationNameStr, LogType.Error,
  5981. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  5982. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5983. }
  5984. #endregion 左边进站
  5985. #region 左边出站
  5986. try
  5987. {
  5988. if (stPLC_MesData.Left.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  5989. {
  5990. lock (lockObj)
  5991. {
  5992. if (!ProgressState)
  5993. {
  5994. stationCode = "[OP81]";
  5995. stationName = "上盖板锁螺丝1";
  5996. stationNameStr = stationCode + stationName;
  5997. ProgressState = true;
  5998. Task.Run(() => S7出站(plcNo, stationNameStr, stPLC_MesData.Left,
  5999. tagBaseName + ".Left." + tagMesCommName, stationCode, stationName, "Left",
  6000. out ProgressState));
  6001. stPLC_MesData.Left.mesCommFrmPLC.cmd = 0;
  6002. }
  6003. }
  6004. }
  6005. }
  6006. catch (Exception ex)
  6007. {
  6008. ProgressState = false;
  6009. string str = ex.StackTrace;
  6010. AddMessage_Station(stationNameStr, LogType.Error,
  6011. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  6012. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6013. }
  6014. #endregion 左边出站
  6015. #region 右边进站
  6016. try
  6017. {
  6018. if (stPLC_MesData.Right.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  6019. {
  6020. lock (lockObj)
  6021. {
  6022. if (!ProgressState)
  6023. {
  6024. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  6025. stationCode = "[OP82]";
  6026. stationName = "上盖板锁螺丝2";
  6027. stationNameStr = stationCode + stationName;
  6028. ProgressState = true;
  6029. Task.Run(() => S7进站(plcNo, stationNameStr, stPLC_MesData.Right,
  6030. tagBaseName + ".Right." + tagMesCommName,
  6031. tagBaseName + ".Right" + tagBarsetName, "Right", out ProgressState,
  6032. atlasScrewRight));
  6033. }
  6034. }
  6035. }
  6036. }
  6037. catch (Exception ex)
  6038. {
  6039. ProgressState = false;
  6040. string str = ex.StackTrace;
  6041. AddMessage_Station(stationNameStr, LogType.Error,
  6042. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  6043. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6044. }
  6045. #endregion 右边进站
  6046. #region 右边出站
  6047. try
  6048. {
  6049. if (stPLC_MesData.Right.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  6050. {
  6051. lock (lockObj)
  6052. {
  6053. if (!ProgressState)
  6054. {
  6055. stationCode = "[OP82]";
  6056. stationName = "上盖板锁螺丝2";
  6057. stationNameStr = stationCode + stationName;
  6058. ProgressState = true;
  6059. Task.Run(() => S7出站(plcNo, stationNameStr, stPLC_MesData.Right,
  6060. tagBaseName + ".Right." + tagMesCommName, stationCode, stationName, "Right",
  6061. out ProgressState));
  6062. stPLC_MesData.Right.mesCommFrmPLC.cmd = 0;
  6063. }
  6064. }
  6065. }
  6066. }
  6067. catch (Exception ex)
  6068. {
  6069. ProgressState = false;
  6070. string str = ex.StackTrace;
  6071. AddMessage_Station(stationNameStr, LogType.Error,
  6072. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  6073. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6074. }
  6075. #endregion 右边出站
  6076. #region 节拍接口
  6077. try
  6078. {
  6079. #region 左工位 节拍
  6080. if (stPLC_MesData.Left.iotData.beatAction > 0)
  6081. {
  6082. stationCode = "[OP81]";
  6083. stationName = "上盖板锁螺丝1";
  6084. stationNameStr = stationCode + stationName;
  6085. int a7OEEType_left = Convert.ToInt32(s7PLCData["a7OEEType_left"]);
  6086. int a7OEETypeGOld_left = Convert.ToInt32(s7PLCSignal_Old["a7OEEType_left"]);
  6087. if (a7OEEType_left != a7OEETypeGOld_left)
  6088. {
  6089. if (a7OEEType_left != a7OEETypeGOld_left)
  6090. s7PLCData["OEETypeFlag_left"] = "1";
  6091. else
  6092. s7PLCData["OEETypeFlag_left"] = "0";
  6093. if (s7PLCData["OEETypeFlag_left"].ToString() == "1" && (a7OEEType_left == 1 || a7OEEType_left == 3 || a7OEEType_left == 4 || a7OEEType_left == 5))
  6094. {
  6095. int res = 0;
  6096. 通用节拍接口(plcNo, stationNameStr, tagBaseName + ".Left." + tagiotComnName, CarrierBarcode_Left,
  6097. stPLC_MesData.Left.iotData, out res);
  6098. if (res == 1)
  6099. {
  6100. s7PLCSignal_Old["a7OEEType_left"] = s7PLCData["a7OEEType_left"];
  6101. }
  6102. else {
  6103. s7PLCSignal_Old["a7OEEType_left"] = 0;
  6104. }
  6105. }
  6106. }
  6107. }
  6108. else
  6109. {
  6110. s7PLCSignal_Old["a7OEEType_left"] = 0;
  6111. }
  6112. #endregion 左工位 节拍
  6113. #region 右工位 节拍
  6114. if (stPLC_MesData.Right.iotData.beatAction > 0)
  6115. {
  6116. stationCode = "[OP82]";
  6117. stationName = "上盖板锁螺丝2";
  6118. stationNameStr = stationCode + stationName;
  6119. int a7OEEType_right = Convert.ToInt32(s7PLCData["a7OEEType_right"]);
  6120. int a7OEETypeGOld_right = Convert.ToInt32(s7PLCSignal_Old["a7OEEType_right"]);
  6121. if (a7OEEType_right != a7OEETypeGOld_right)
  6122. {
  6123. if (a7OEEType_right != a7OEETypeGOld_right)
  6124. s7PLCData["a7OEEType_right"] = "1";
  6125. else
  6126. s7PLCData["a7OEEType_right"] = "0";
  6127. if (s7PLCData["a7OEEType_right"].ToString() == "1" && (a7OEEType_right == 1 || a7OEEType_right == 3 || a7OEEType_right == 4 || a7OEEType_right == 5))
  6128. {
  6129. 通用节拍接口(plcNo, stationNameStr, tagBaseName + ".Right." + tagiotComnName, CarrierBarcode_Left,
  6130. stPLC_MesData.Right.iotData, out res);
  6131. if (res == 1)
  6132. {
  6133. s7PLCSignal_Old["a7OEEType_right"] = s7PLCData["a7OEEType_right"];
  6134. }
  6135. else {
  6136. s7PLCSignal_Old["a7OEEType_right"] = 0;
  6137. }
  6138. }
  6139. }
  6140. }
  6141. else
  6142. {
  6143. s7PLCSignal_Old["a7OEEType_right"] = 0;
  6144. }
  6145. #endregion 右工位 节拍
  6146. }
  6147. catch (Exception ex)
  6148. {
  6149. string str = ex.StackTrace;
  6150. AddMessage_Station(stationNameStr, LogType.Error,
  6151. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  6152. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6153. }
  6154. #endregion
  6155. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  6156. stopwatch1.Stop();
  6157. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  6158. }
  6159. else
  6160. {
  6161. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  6162. AddMessage_Station(stationNameStr, LogType.Info,
  6163. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  6164. FunsEip[plcNo].Connect(); // 重连
  6165. }
  6166. }
  6167. catch (Exception ex)
  6168. {
  6169. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  6170. AddMessage_Station(stationNameStr, LogType.Error,
  6171. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  6172. }
  6173. Thread.Sleep(IntervalReadPLC);
  6174. }
  6175. }
  6176. /// <summary>
  6177. /// [S7] 锁螺丝设备 - 进站
  6178. /// </summary>
  6179. /// <param name="plcNo">PLC编号</param>
  6180. /// <param name="stationNameStr">工站全称</param>
  6181. /// <param name="stPLC_MesData"></param>
  6182. /// <param name="tagMesCommName"></param>
  6183. private void S7进站(int plcNo, string stationNameStr, OP70_stnDataSet_t stPLC_MesData, string tagMesCommName,
  6184. string tagBarsetName, string direction, out bool ProgressState, AtlasScrew atlasScrew)
  6185. {
  6186. Stopwatch stopwatch1 = new Stopwatch();
  6187. Stopwatch stopwatch2 = new Stopwatch();
  6188. string atlasSn = string.Empty;
  6189. try
  6190. {
  6191. stopwatch1.Start();
  6192. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_进站开始");
  6193. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  6194. string MachineId = GlobalContext.S7_MachineId; // 装备ID(可配置)
  6195. string StationId = string.Empty; // 工位ID(可配置)
  6196. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  6197. bool pass = a1Result == 1;
  6198. if (direction == "Left")
  6199. {
  6200. StationId = GlobalContext.S7_StationId_1;
  6201. }
  6202. if (direction == "Right")
  6203. {
  6204. StationId = GlobalContext.S7_StationId_2;
  6205. }
  6206. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  6207. //载具码验证产品码
  6208. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  6209. if (string.IsNullOrEmpty(strProductBarcode))
  6210. {
  6211. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  6212. ProgressState = false;
  6213. Thread.Sleep(10000);
  6214. return;
  6215. }
  6216. sn = strProductBarcode;
  6217. atlasSn = strProductBarcode;
  6218. AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  6219. string slot = "";
  6220. if (direction == "Left")
  6221. {
  6222. isCollectingFlagLeft = false; //采集螺丝数据结束
  6223. slot = "01-SLOT-01";
  6224. }
  6225. if (direction == "Right")
  6226. {
  6227. isCollectingFlagRight = false; //采集螺丝数据结束
  6228. slot = "01-SLOT-02";
  6229. }
  6230. // 产品SN(物料码)校验
  6231. List<TestItem> item = new List<TestItem>();
  6232. stopwatch2.Start();
  6233. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  6234. item, MachineId, StationId, pass, slot);
  6235. stopwatch2.Stop();
  6236. //指令执行结果 1:OK 110:失败
  6237. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  6238. if (mesResultFrmWeb == 1)
  6239. {
  6240. if (a1Result == 1)
  6241. {
  6242. mesResultFrmWeb = 1;
  6243. }
  6244. else
  6245. {
  6246. mesResultFrmWeb = 110;
  6247. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  6248. }
  6249. }
  6250. //进站结果写入PLC
  6251. CommandFromPLC resultToPlC = new CommandFromPLC();
  6252. resultToPlC.cmd = 0;
  6253. resultToPlC.cmdParam = 0; //指令参数
  6254. resultToPlC.cmdResult = mesResultFrmWeb;
  6255. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6256. }
  6257. catch (Exception ex)
  6258. {
  6259. string str = ex.StackTrace;
  6260. AddMessage(LogType.Error,
  6261. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  6262. str.Length - str.LastIndexOf("\\") - 1));
  6263. CommandFromPLC resultToPlC = new CommandFromPLC();
  6264. resultToPlC.cmd = 0;
  6265. resultToPlC.cmdParam = 0; //指令参数
  6266. resultToPlC.cmdResult = 110;
  6267. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6268. }
  6269. stopwatch1.Stop();
  6270. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_进站结束");
  6271. AddMessage(LogType.Info,
  6272. stationNameStr + "_" + direction + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  6273. stopwatch2.ElapsedMilliseconds + "ms");
  6274. ProgressState = false;
  6275. //开始采集螺丝数据
  6276. if (direction == "Left")
  6277. {
  6278. isCollectingFlagLeft = true;
  6279. CollectAndProcessDataLeft(atlasScrew, atlasSn, direction);
  6280. }
  6281. if (direction == "Right")
  6282. {
  6283. isCollectingFlagRight = true;
  6284. CollectAndProcessDataRight(atlasScrew, atlasSn, direction);
  6285. }
  6286. }
  6287. /// <summary>
  6288. /// [S7] 锁螺丝设备 - 出站
  6289. /// </summary>
  6290. private void S7出站(int plcNo, string stationNameStr, OP70_stnDataSet_t stPLC_MesData, string tagMesCommName,
  6291. string stationCode, string stationName, string direction, out bool ProgressState)
  6292. {
  6293. Stopwatch stopwatch1 = new Stopwatch();
  6294. Stopwatch stopwatch2 = new Stopwatch();
  6295. try
  6296. {
  6297. stopwatch1.Start();
  6298. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_出站开始");
  6299. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  6300. string processItem = stationName; // 测试项目
  6301. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  6302. string supplierCode = ""; // 供应商代码
  6303. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  6304. string batch_num = GlobalContext.BatchNumber; // 批次号
  6305. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  6306. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  6307. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  6308. string MachineId = GlobalContext.S7_MachineId; // 装备id(可配置)
  6309. string StationId = string.Empty; // 工位ID(可配置)
  6310. string slot = "";//iot槽位
  6311. if (direction == "Left")
  6312. {
  6313. StationId = GlobalContext.S7_StationId_1;
  6314. slot = "01-SLOT-01";
  6315. }
  6316. if (direction == "Right")
  6317. {
  6318. StationId = GlobalContext.S7_StationId_2;
  6319. slot = "01-SLOT-02";
  6320. }
  6321. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  6322. //a1Result = 1;
  6323. bool pass = a1Result == 1;
  6324. //根据载具码获取产品码
  6325. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  6326. if (string.IsNullOrEmpty(strProductBarcode))
  6327. {
  6328. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  6329. ProgressState = false;
  6330. Thread.Sleep(10000);
  6331. return;
  6332. }
  6333. sn = strProductBarcode;
  6334. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  6335. List<TestItem> items = new List<TestItem>();
  6336. items.Add(new TestItem()
  6337. {
  6338. Parameter_name = "载具码",
  6339. Parameter_value = CarrierBarcode,
  6340. Parameter_unit = ""
  6341. });
  6342. items.Add(new TestItem()
  6343. {
  6344. Parameter_name = "产品码",
  6345. Parameter_value = sn,
  6346. Parameter_unit = ""
  6347. });
  6348. #region 转换过站明细字符串
  6349. ////创建字典
  6350. //var dic = new Dictionary<string, string>();
  6351. //// 获取结构体类型
  6352. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  6353. //string resultString = "";
  6354. //// 遍历变量名转换成字典描述
  6355. //foreach (FieldInfo field in fields)
  6356. //{
  6357. // //获取枚举描述
  6358. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  6359. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  6360. // //获取过站明细的值
  6361. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  6362. // // 检查是否为数组
  6363. // if (valueObj.GetType().IsArray)
  6364. // {
  6365. // var array = valueObj as Array;
  6366. // resultString = ArrayToString(array);
  6367. // }
  6368. // else
  6369. // {
  6370. // resultString = valueObj.ToString();
  6371. // }
  6372. // dic.Add(name, resultString);
  6373. //}
  6374. //string paramJson = JsonConvert.SerializeObject(dic);
  6375. #endregion
  6376. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);
  6377. //if (direction == "Right")
  6378. //{
  6379. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem, workorder_code,
  6380. batch_num, mtltmrk, plcDate_YMD, supplierCode
  6381. , sn, pass, CarrierBarcode, slot, MachineId, StationId, "", paramJson,new XmStationOut_InspectionItemData(), "");
  6382. //}
  6383. //if (direction == "Left")
  6384. //{
  6385. // isCollectingFlagLeft = false;//采集螺丝数据结束
  6386. //}
  6387. //if (direction == "Right")
  6388. //{
  6389. // isCollectingFlagRight = false;//采集螺丝数据结束
  6390. //}
  6391. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  6392. if (mesResultFrmWeb == 1)
  6393. {
  6394. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  6395. if (mesResultFrmWeb == 110)
  6396. {
  6397. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  6398. }
  6399. }
  6400. stopwatch2.Start();
  6401. //进站结果写入PLC
  6402. CommandFromPLC resultToPlC = new CommandFromPLC();
  6403. resultToPlC.cmd = 0;
  6404. resultToPlC.cmdParam = 0; //指令参数
  6405. resultToPlC.cmdResult = mesResultFrmWeb;
  6406. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6407. stopwatch2.Stop();
  6408. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_出站结束");
  6409. //保存PLC返回MES数据到本地
  6410. ResponseMessage message = new ResponseMessage();
  6411. if (direction == "Left")
  6412. {
  6413. string strMesHeightInfos = FloatArrayToString(stPLC_MesData.mesData.fScrewTimes);
  6414. string strScrewOrders = ShortArrayToString(stPLC_MesData.mesData.nScrewOrders);
  6415. string strScrewResults = ShortArrayToString(stPLC_MesData.mesData.nScrewResults);
  6416. message = SQLHelper.InsertOp701Data(CarrierBarcode, sn, strMesHeightInfos,
  6417. strScrewOrders, strScrewResults, stPLC_MesData.mesData.nRemainCount);
  6418. //if (message.result == false)
  6419. //{
  6420. // AddMessage(LogType.Info, stationNameStr + "_Left_保存加工数据失败");
  6421. //}
  6422. }
  6423. if (direction == "Right")
  6424. {
  6425. string strMesHeightInfos = FloatArrayToString(stPLC_MesData.mesData.fScrewTimes);
  6426. string strScrewOrders = ShortArrayToString(stPLC_MesData.mesData.nScrewOrders);
  6427. string strScrewResults = ShortArrayToString(stPLC_MesData.mesData.nScrewResults);
  6428. message = SQLHelper.InsertOp702Data(CarrierBarcode, sn, strMesHeightInfos,
  6429. strScrewOrders, strScrewResults, stPLC_MesData.mesData.nRemainCount);
  6430. //if (message.result == false)
  6431. //{
  6432. // AddMessage(LogType.Info, stationNameStr + "__Right_保存加工数据失败");
  6433. //}
  6434. }
  6435. //保存螺丝数据到txt
  6436. (int, string) result = SaveScrewDataToTxt(direction, sn, stPLC_MesData.mesData.fScrewTimes,
  6437. stPLC_MesData.mesData.nScrewOrders, stPLC_MesData.mesData.nScrewResults);
  6438. if (result.Item1 != 0)
  6439. {
  6440. AddMessage(LogType.Error, $"{stationNameStr}螺丝数据保存失败 " + message.text);
  6441. }
  6442. AddMessage(LogType.Info, stationNameStr + "_" + direction + "_保存加工数据到本地成功");
  6443. }
  6444. catch (Exception ex)
  6445. {
  6446. stopwatch2.Start();
  6447. CommandFromPLC resultToPlC = new CommandFromPLC();
  6448. resultToPlC.cmd = 0;
  6449. resultToPlC.cmdParam = 0; //指令参数
  6450. resultToPlC.cmdResult = 110;
  6451. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6452. stopwatch2.Stop();
  6453. string str = ex.StackTrace;
  6454. AddMessage(LogType.Error,
  6455. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  6456. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6457. }
  6458. stopwatch1.Stop();
  6459. AddMessage(LogType.Info,
  6460. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  6461. stopwatch2.ElapsedMilliseconds + "ms");
  6462. ProgressState = false;
  6463. if (direction == "Left") uuid = "";
  6464. if (direction == "Right") uuid2 = "";
  6465. }
  6466. #endregion
  6467. #region S8
  6468. private Dictionary<string, object> s8PLCData = new Dictionary<string, object>();
  6469. private Dictionary<string, object> s8PLCSignal_Old = new Dictionary<string, object>();
  6470. /// <summary>
  6471. /// [S8] 3D螺丝高度检测设备
  6472. /// </summary>
  6473. /// <param name="plcNo">PLC编号</param>
  6474. private void ReadStation_S8(int plcNo)
  6475. {
  6476. string stationCode = "[OP90]";
  6477. string stationName = "NG下料";
  6478. string stationNameStr = stationCode + stationName;
  6479. string tagBaseName = "g_OP80_MES"; //标签变量名称
  6480. string tagMesCommName = "mesCommToPC"; //标签变量名称
  6481. string tagAgvCommName = "agvCommFrmPC";
  6482. string tagiotComnName = "iotData";
  6483. string tagBarsetName = "BarcodeSet";
  6484. string CarrierBarcode = "";
  6485. // 触发信号字典
  6486. //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  6487. s8PLCSignal_Old.Add("a8OEEType", 0); // 节拍类型(plc写入)
  6488. // PLC数据字典 赋值
  6489. s8PLCData.Add("a8OEEType", 0); // 节拍类型(plc写入)
  6490. s8PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  6491. OP80_MesData_t stPLC_MesData; //PLC的MES数据
  6492. (int, string) result;
  6493. while (true)
  6494. {
  6495. try
  6496. {
  6497. if (!GlobalContext._IsCon_Funs1)
  6498. {
  6499. UpdatePLCMonitor(1, plcNo, 0);
  6500. continue;
  6501. }
  6502. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  6503. {
  6504. Stopwatch stopwatch1 = new Stopwatch();
  6505. Stopwatch stopwatch2 = new Stopwatch();
  6506. stopwatch1.Start();
  6507. stopwatch2.Start();
  6508. #region 一次性读取所有数据
  6509. // 一次性读取所有数据
  6510. result = FunsEip[plcNo]
  6511. .Read_SingleTag<OP80_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  6512. if (result.Item1 != 0)
  6513. {
  6514. //richTextBox1.AppendText("\n" + strRet);
  6515. }
  6516. else
  6517. {
  6518. //去除扫码产生的特殊字符
  6519. stPLC_MesData.BarcodeSet.strProductBarcode =
  6520. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  6521. stPLC_MesData.BarcodeSet.strPartBarcode =
  6522. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  6523. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  6524. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  6525. stPLC_MesData.BarcodeSet.strPCBBarcode =
  6526. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  6527. }
  6528. #endregion 一次性读取所有数据
  6529. stopwatch2.Stop();
  6530. //richTextBox1.AppendText("\n" + "读取成功");
  6531. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  6532. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  6533. ? XiaomiDeviceState.Unknown
  6534. : (XiaomiDeviceState)xmDeviceStateInt;
  6535. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具SN
  6536. s8PLCData["a8OEEType"] = stPLC_MesData.iotData.beatAction; // 节拍
  6537. //报警信息
  6538. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  6539. stopwatch2.Stop();
  6540. #region 进站
  6541. try
  6542. {
  6543. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  6544. {
  6545. lock (lockObj)
  6546. {
  6547. if (!ProgressState)
  6548. {
  6549. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  6550. ProgressState = true;
  6551. Task.Run(() => S8进站(plcNo, stationNameStr, stPLC_MesData,
  6552. tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName,
  6553. out ProgressState));
  6554. }
  6555. }
  6556. }
  6557. }
  6558. catch (Exception ex)
  6559. {
  6560. ProgressState = false;
  6561. string str = ex.StackTrace;
  6562. AddMessage_Station(stationNameStr, LogType.Error,
  6563. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  6564. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6565. }
  6566. #endregion 进站
  6567. #region 出站
  6568. try
  6569. {
  6570. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  6571. {
  6572. lock (lockObj)
  6573. {
  6574. if (!ProgressState)
  6575. {
  6576. ProgressState = true;
  6577. Task.Run(() => S8出站(plcNo, stationNameStr, stPLC_MesData,
  6578. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  6579. out ProgressState));
  6580. stPLC_MesData.mesCommFrmPLC.cmd = 0;
  6581. }
  6582. }
  6583. }
  6584. }
  6585. catch (Exception ex)
  6586. {
  6587. ProgressState = false;
  6588. string str = ex.StackTrace;
  6589. AddMessage_Station(stationNameStr, LogType.Error,
  6590. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  6591. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6592. }
  6593. #endregion 出站
  6594. #region 节拍接口
  6595. try
  6596. {
  6597. int a8OEEType = Convert.ToInt32(s8PLCData["a8OEEType"]);
  6598. int a8OEETypeGOld = Convert.ToInt32(s8PLCSignal_Old["a8OEEType"]);
  6599. if (stPLC_MesData.iotData.beatAction > 0)
  6600. {
  6601. if (a8OEEType != a8OEETypeGOld)
  6602. {
  6603. s8PLCData["OEETypeFlag"] = "1";
  6604. }
  6605. else
  6606. {
  6607. s8PLCData["OEETypeFlag"] = "0";
  6608. }
  6609. if (s8PLCData["OEETypeFlag"].ToString() == "1" && (a8OEEType == 1 || a8OEEType == 3 || a8OEEType == 4 || a8OEEType == 5))
  6610. {
  6611. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName,
  6612. CarrierBarcode, stPLC_MesData.iotData, out res);
  6613. if (res == 1)
  6614. {
  6615. s8PLCSignal_Old["a8OEEType"] = s8PLCData["a8OEEType"];
  6616. }
  6617. else
  6618. {
  6619. s8PLCSignal_Old["a8OEEType"] = 0;
  6620. }
  6621. }
  6622. }
  6623. else {
  6624. s8PLCSignal_Old["a8OEEType"] = 0;
  6625. }
  6626. }
  6627. catch (Exception ex)
  6628. {
  6629. string str = ex.StackTrace;
  6630. AddMessage_Station(stationNameStr, LogType.Error,
  6631. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  6632. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6633. }
  6634. #endregion
  6635. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  6636. stopwatch1.Stop();
  6637. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  6638. }
  6639. else
  6640. {
  6641. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  6642. AddMessage_Station(stationNameStr, LogType.Info,
  6643. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  6644. FunsEip[plcNo].Connect(); // 重连
  6645. }
  6646. }
  6647. catch (Exception ex)
  6648. {
  6649. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  6650. AddMessage_Station(stationNameStr, LogType.Error,
  6651. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  6652. }
  6653. Thread.Sleep(IntervalReadPLC);
  6654. }
  6655. }
  6656. /// <summary>
  6657. /// [S8] 3D螺丝高度检测设备 - 进站
  6658. /// </summary>
  6659. /// <param name="plcNo">PLC编号</param>
  6660. /// <param name="stationNameStr">工站全称</param>
  6661. /// <param name="stPLC_MesData"></param>
  6662. /// <param name="tagMesCommName"></param>
  6663. private void S8进站(int plcNo, string stationNameStr, OP80_MesData_t stPLC_MesData, string tagMesCommName,
  6664. string tagBarsetName, out bool ProgressState)
  6665. {
  6666. Stopwatch stopwatch1 = new Stopwatch();
  6667. Stopwatch stopwatch2 = new Stopwatch();
  6668. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  6669. bool pass = a1Result == 1;
  6670. try
  6671. {
  6672. stopwatch1.Start();
  6673. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  6674. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  6675. string MachineId = GlobalContext.S8_MachineId; // 装备ID(可配置)
  6676. string StationId = GlobalContext.S8_StationId; // 工位ID(可配置)
  6677. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  6678. //载具码验证产品码
  6679. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  6680. if (string.IsNullOrEmpty(strProductBarcode))
  6681. {
  6682. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  6683. ProgressState = false;
  6684. Thread.Sleep(10000);
  6685. return;
  6686. }
  6687. sn = strProductBarcode;
  6688. AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  6689. // 产品SN(物料码)校验
  6690. List<TestItem> item = new List<TestItem>();
  6691. stopwatch2.Start();
  6692. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  6693. sn,
  6694. item, MachineId, StationId, pass, "01-SLOT-01");
  6695. stopwatch2.Stop();
  6696. //指令执行结果 1:OK 110:失败
  6697. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  6698. if (mesResultFrmWeb == 1)
  6699. {
  6700. if (a1Result == 1)
  6701. {
  6702. mesResultFrmWeb = 1;
  6703. }
  6704. else
  6705. {
  6706. mesResultFrmWeb = 110;
  6707. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  6708. }
  6709. }
  6710. //进站结果写入PLC
  6711. CommandFromPLC resultToPlC = new CommandFromPLC();
  6712. resultToPlC.cmd = 0;
  6713. resultToPlC.cmdParam = 0; //指令参数
  6714. resultToPlC.cmdResult = mesResultFrmWeb;
  6715. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6716. }
  6717. catch (Exception ex)
  6718. {
  6719. string str = ex.StackTrace;
  6720. AddMessage(LogType.Error,
  6721. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(
  6722. str.LastIndexOf("\\") + 1,
  6723. str.Length - str.LastIndexOf("\\") - 1));
  6724. CommandFromPLC resultToPlC = new CommandFromPLC();
  6725. resultToPlC.cmd = 0;
  6726. resultToPlC.cmdParam = 0; //指令参数
  6727. resultToPlC.cmdResult = 110;
  6728. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6729. }
  6730. stopwatch1.Stop();
  6731. AddMessage(LogType.Info,
  6732. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  6733. stopwatch2.ElapsedMilliseconds + "ms");
  6734. ProgressState = false;
  6735. }
  6736. /// <summary>
  6737. /// [S8] 3D螺丝高度检测设备 - 出站接口
  6738. /// </summary>
  6739. private void S8出站(int plcNo, string stationNameStr, OP80_MesData_t stPLC_MesData, string tagMesCommName,
  6740. string stationCode, string stationName, out bool ProgressState)
  6741. {
  6742. Stopwatch stopwatch1 = new Stopwatch();
  6743. Stopwatch stopwatch2 = new Stopwatch();
  6744. try
  6745. {
  6746. stopwatch1.Start();
  6747. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  6748. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  6749. string processItem = stationName; // 测试项目
  6750. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  6751. string supplierCode = ""; // 供应商代码
  6752. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  6753. string batch_num = GlobalContext.BatchNumber; // 批次号
  6754. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  6755. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  6756. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  6757. string MachineId = GlobalContext.S8_MachineId; // 装备id(可配置) // ZS
  6758. string StationId = GlobalContext.S8_StationId; // ⼯位ID(可配置) // ZS
  6759. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  6760. bool pass = a1Result == 1;
  6761. //根据载具码获取产品码
  6762. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  6763. if (string.IsNullOrEmpty(strProductBarcode))
  6764. {
  6765. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  6766. ProgressState = false;
  6767. Thread.Sleep(10000);
  6768. return;
  6769. }
  6770. sn = strProductBarcode;
  6771. stPLC_MesData.BarcodeSet.strProductBarcode = strProductBarcode;
  6772. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  6773. List<TestItem> items = new List<TestItem>();
  6774. items.Add(new TestItem()
  6775. {
  6776. Parameter_name = "载具码",
  6777. Parameter_value = CarrierBarcode,
  6778. Parameter_unit = ""
  6779. });
  6780. items.Add(new TestItem()
  6781. {
  6782. Parameter_name = "产品码",
  6783. Parameter_value = sn,
  6784. Parameter_unit = ""
  6785. });
  6786. #region 上传图片
  6787. if (GlobalContext.MQTTIsSendUpFile)
  6788. {
  6789. CopyFileToTempPath(GlobalContext.UpFilePath, GlobalContext.MqttFileTempDir);
  6790. if (Directory.Exists(GlobalContext.MqttFileTempDir))
  6791. {
  6792. var result = SaveDBbyFileInfo(stPLC_MesData.BarcodeSet, stationCode, stationName, a1Result, GlobalContext.MqttFileTempDir, uuid).Result;
  6793. if (result.Item1 == 1)
  6794. {
  6795. OnMessage(LogType.Error, $"【文件上传】 产品码 [{sn}] " + result.Item2);
  6796. }
  6797. }
  6798. //string[] urlarry = GlobalContext.UpFilePath.Split(",");
  6799. //// fileUploadData.fileData.Clear();
  6800. //foreach (var item in urlarry)
  6801. //{
  6802. // if (!string.IsNullOrEmpty(item))
  6803. // {
  6804. // //上传图片
  6805. // var result = SaveDBbyFileInfo(stPLC_MesData.BarcodeSet, stationCode, stationName,
  6806. // a1Result, item, uuid).Result;
  6807. // OnMessage(LogType.Error, $"【文件上传】 产品码 [{sn}] " + result.Item2);
  6808. // }
  6809. //}
  6810. }
  6811. #endregion
  6812. #region 转换过站明细字符串
  6813. ////创建字典
  6814. //var dic = new Dictionary<string, string>();
  6815. //// 获取结构体类型
  6816. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  6817. //string resultString = "";
  6818. //// 遍历变量名转换成字典描述
  6819. //foreach (FieldInfo field in fields)
  6820. //{
  6821. // //获取枚举描述
  6822. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  6823. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  6824. // //获取过站明细的值
  6825. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  6826. // // 检查是否为数组
  6827. // if (valueObj.GetType().IsArray)
  6828. // {
  6829. // var array = valueObj as Array;
  6830. // resultString = ArrayToString(array);
  6831. // }
  6832. // else
  6833. // {
  6834. // resultString = valueObj.ToString();
  6835. // }
  6836. // dic.Add(name, resultString);
  6837. //}
  6838. //string paramJson = JsonConvert.SerializeObject(dic);
  6839. #endregion
  6840. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);
  6841. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  6842. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "01-SLOT-01",
  6843. MachineId, StationId, "", paramJson,new XmStationOut_InspectionItemData(), "");
  6844. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  6845. if (mesResultFrmWeb == 1)
  6846. {
  6847. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  6848. if (mesResultFrmWeb == 110)
  6849. {
  6850. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  6851. }
  6852. }
  6853. stopwatch2.Start();
  6854. //进站结果写入PLC
  6855. CommandFromPLC resultToPlC = new CommandFromPLC();
  6856. resultToPlC.cmd = 0;
  6857. resultToPlC.cmdParam = 0; //指令参数
  6858. resultToPlC.cmdResult = mesResultFrmWeb;
  6859. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6860. stopwatch2.Stop();
  6861. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  6862. //保存PLC返回MES数据到本地
  6863. ResponseMessage message = new ResponseMessage();
  6864. string strScrewHeights = FloatArrayToString(stPLC_MesData.mesData.fScrewHeights);
  6865. string strScrewResults = ShortArrayToString(stPLC_MesData.mesData.nScrewResults);
  6866. message = SQLHelper.InsertOp80Data(CarrierBarcode, sn, strScrewHeights, strScrewResults);
  6867. if (message.result == false)
  6868. {
  6869. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  6870. }
  6871. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地成功");
  6872. }
  6873. catch (Exception ex)
  6874. {
  6875. stopwatch2.Start();
  6876. CommandFromPLC resultToPlC = new CommandFromPLC();
  6877. resultToPlC.cmd = 0;
  6878. resultToPlC.cmdParam = 0; //指令参数
  6879. resultToPlC.cmdResult = 110;
  6880. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  6881. stopwatch2.Stop();
  6882. string str = ex.StackTrace;
  6883. AddMessage(LogType.Error,
  6884. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  6885. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6886. }
  6887. stopwatch1.Stop();
  6888. AddMessage(LogType.Info,
  6889. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  6890. stopwatch2.ElapsedMilliseconds + "ms");
  6891. ProgressState = false;
  6892. uuid = "";
  6893. }
  6894. #endregion
  6895. #region S9
  6896. private Dictionary<string, object> s9PLCData = new Dictionary<string, object>();
  6897. private Dictionary<string, object> s9PLCSignal_Old = new Dictionary<string, object>();
  6898. /// <summary>
  6899. /// [S9] 下料设备
  6900. /// </summary>
  6901. /// <param name="plcNo">PLC编号</param>
  6902. private void ReadStation_S9(int plcNo)
  6903. {
  6904. string stationCode = "[OP100]";
  6905. string stationName = "半成品下料";
  6906. string stationNameStr = stationCode + stationName;
  6907. string tagBaseName = "g_OP90_MES"; //标签变量名称
  6908. string tagMesCommName = "mesCommToPC"; //标签变量名称
  6909. string tagAgvCommName = "agvCommFrmPC";
  6910. string tagiotComnName = "iotData";
  6911. string tagBarsetName = "BarcodeSet";
  6912. string CarrierBarcode = "";
  6913. // 触发信号字典
  6914. //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  6915. s9PLCSignal_Old.Add("a9OEEType", 0); // 节拍类型(plc写入)
  6916. // PLC数据字典 赋值
  6917. s9PLCData.Add("a9OEEType", 0); // 节拍类型(plc写入)
  6918. s9PLCData.Add("OEETypeFlag", 0); // 节拍类型(plc写入)
  6919. OP90_MesData_t stPLC_MesData; //PLC的MES数据
  6920. (int, string) result;
  6921. while (true)
  6922. {
  6923. try
  6924. {
  6925. if (!GlobalContext._IsCon_Funs1)
  6926. {
  6927. UpdatePLCMonitor(1, plcNo, 0);
  6928. continue;
  6929. }
  6930. if (FunsEip[plcNo].IsConnected) // 检查PLC是否已连接上
  6931. {
  6932. Stopwatch stopwatch1 = new Stopwatch();
  6933. Stopwatch stopwatch2 = new Stopwatch();
  6934. stopwatch1.Start();
  6935. stopwatch2.Start();
  6936. #region 一次性读取所有数据
  6937. // 一次性读取所有数据
  6938. result = FunsEip[plcNo]
  6939. .Read_SingleTag<OP90_MesData_t>(tagBaseName, 1, out stPLC_MesData, this); //读取单个结构体数据
  6940. if (result.Item1 != 0)
  6941. {
  6942. //richTextBox1.AppendText("\n" + strRet);
  6943. }
  6944. else
  6945. {
  6946. //去除扫码产生的特殊字符
  6947. stPLC_MesData.BarcodeSet.strProductBarcode =
  6948. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strProductBarcode);
  6949. stPLC_MesData.BarcodeSet.strPartBarcode =
  6950. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPartBarcode);
  6951. stPLC_MesData.BarcodeSet.strCarrierBarcode =
  6952. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strCarrierBarcode);
  6953. stPLC_MesData.BarcodeSet.strPCBBarcode =
  6954. FormatStrbyPLC(stPLC_MesData.BarcodeSet.strPCBBarcode);
  6955. //richTextBox1.AppendText("\n" + "读取成功");
  6956. int xmDeviceStateInt = stPLC_MesData.iotData.machineState;
  6957. xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
  6958. ? XiaomiDeviceState.Unknown
  6959. : (XiaomiDeviceState)xmDeviceStateInt;
  6960. CarrierBarcode = stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具SN
  6961. s9PLCData["a9OEEType"] = stPLC_MesData.iotData.beatAction; // 节拍
  6962. //报警信息
  6963. _FaultDatas = stPLC_MesData.iotData.fault_codes;
  6964. }
  6965. #endregion 一次性读取所有数据
  6966. stopwatch2.Stop();
  6967. #region 进站
  6968. try
  6969. {
  6970. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
  6971. {
  6972. lock (lockObj)
  6973. {
  6974. if (!ProgressState)
  6975. {
  6976. uuid = Guid.NewGuid().ToString(); //创建贯穿进出站的uuid
  6977. ProgressState = true;
  6978. Task.Run(() => S9进站(plcNo, stationNameStr, stPLC_MesData,
  6979. tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName,
  6980. out ProgressState));
  6981. }
  6982. }
  6983. }
  6984. }
  6985. catch (Exception ex)
  6986. {
  6987. ProgressState = false;
  6988. string str = ex.StackTrace;
  6989. AddMessage_Station(stationNameStr, LogType.Error,
  6990. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  6991. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  6992. }
  6993. #endregion 进站
  6994. #region 出站
  6995. try
  6996. {
  6997. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  6998. {
  6999. lock (lockObj)
  7000. {
  7001. if (!ProgressState)
  7002. {
  7003. ProgressState = true;
  7004. Task.Run(() => S9出站(plcNo, stationNameStr, stPLC_MesData,
  7005. tagBaseName + "." + tagMesCommName, stationCode, stationName,
  7006. out ProgressState));
  7007. stPLC_MesData.mesCommFrmPLC.cmd = 0;
  7008. }
  7009. }
  7010. }
  7011. }
  7012. catch (Exception ex)
  7013. {
  7014. ProgressState = false;
  7015. string str = ex.StackTrace;
  7016. AddMessage_Station(stationNameStr, LogType.Error,
  7017. $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" +
  7018. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7019. }
  7020. #endregion 出站
  7021. #region 节拍接口
  7022. try
  7023. {
  7024. if (stPLC_MesData.iotData.beatAction > 0)
  7025. {
  7026. int a9OEEType = Convert.ToInt32(s9PLCData["a9OEEType"]);
  7027. int a9OEETypeGOld = Convert.ToInt32(s9PLCSignal_Old["a9OEEType"]);
  7028. if (a9OEEType != a9OEETypeGOld)
  7029. {
  7030. s9PLCData["OEETypeFlag"] = "1";
  7031. }
  7032. else
  7033. {
  7034. s9PLCData["OEETypeFlag"] = "0";
  7035. }
  7036. if (s9PLCData["OEETypeFlag"].ToString() == "1" && (a9OEEType == 1 || a9OEEType == 3 || a9OEEType == 4 || a9OEEType == 5))
  7037. {
  7038. 通用节拍接口(plcNo, stationNameStr, tagBaseName + "." + tagiotComnName,
  7039. CarrierBarcode, stPLC_MesData.iotData, out res);
  7040. if (res == 1)
  7041. {
  7042. s9PLCSignal_Old["a9OEEType"] = s9PLCData["a9OEEType"];
  7043. }
  7044. else
  7045. {
  7046. s9PLCSignal_Old["a9OEEType"] = 0;
  7047. }
  7048. }
  7049. }
  7050. else {
  7051. s9PLCSignal_Old["a9OEEType"] = 0;
  7052. }
  7053. }
  7054. catch (Exception ex)
  7055. {
  7056. string str = ex.StackTrace;
  7057. AddMessage_Station(stationNameStr, LogType.Error,
  7058. $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" +
  7059. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7060. }
  7061. #endregion
  7062. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  7063. stopwatch1.Stop();
  7064. //OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  7065. }
  7066. else
  7067. {
  7068. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  7069. AddMessage_Station(stationNameStr, LogType.Info,
  7070. "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  7071. FunsEip[plcNo].Connect(); // 重连
  7072. }
  7073. }
  7074. catch (Exception ex)
  7075. {
  7076. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  7077. AddMessage_Station(stationNameStr, LogType.Error,
  7078. $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  7079. }
  7080. Thread.Sleep(IntervalReadPLC);
  7081. }
  7082. }
  7083. /// <summary>
  7084. /// [S9] 下料设备 - 进站
  7085. /// </summary>
  7086. /// <param name="plcNo">PLC编号</param>
  7087. /// <param name="stationNameStr">工站全称</param>
  7088. /// <param name="stPLC_MesData"></param>
  7089. /// <param name="tagMesCommName"></param>
  7090. private void S9进站(int plcNo, string stationNameStr, OP90_MesData_t stPLC_MesData, string tagMesCommName,
  7091. string tagBarsetName, out bool ProgressState)
  7092. {
  7093. Stopwatch stopwatch1 = new Stopwatch();
  7094. Stopwatch stopwatch2 = new Stopwatch();
  7095. try
  7096. {
  7097. stopwatch1.Start();
  7098. AddMessage(LogType.Info, stationNameStr + "_进站开始");
  7099. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  7100. string MachineId = GlobalContext.S9_MachineId; // 装备ID(可配置)
  7101. string StationId = GlobalContext.S9_StationId; // 工位ID(可配置)
  7102. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  7103. bool pass = a1Result == 1;
  7104. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  7105. //载具码验证产品码
  7106. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  7107. if (string.IsNullOrEmpty(strProductBarcode))
  7108. {
  7109. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  7110. ProgressState = false;
  7111. Thread.Sleep(10000);
  7112. return;
  7113. }
  7114. sn = strProductBarcode;
  7115. AddMessage(LogType.Info, $"载具码:{strCarrierBarcode};产品码:{sn}");
  7116. // 产品SN(物料码)校验
  7117. List<TestItem> item = new List<TestItem>();
  7118. stopwatch2.Start();
  7119. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  7120. item, MachineId, StationId, pass, "01-SLOT-01");
  7121. stopwatch2.Stop();
  7122. //指令执行结果 1:OK 110:失败
  7123. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  7124. if (mesResultFrmWeb == 1)
  7125. {
  7126. if (a1Result == 1)
  7127. {
  7128. mesResultFrmWeb = 1;
  7129. }
  7130. else
  7131. {
  7132. mesResultFrmWeb = 110;
  7133. AddMessage(LogType.Info, stationNameStr + "_进站检测结果:FAIL");
  7134. }
  7135. }
  7136. //进站结果写入PLC
  7137. CommandFromPLC resultToPlC = new CommandFromPLC();
  7138. resultToPlC.cmd = 0;
  7139. resultToPlC.cmdParam = 0; //指令参数
  7140. resultToPlC.cmdResult = mesResultFrmWeb;
  7141. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  7142. }
  7143. catch (Exception ex)
  7144. {
  7145. string str = ex.StackTrace;
  7146. AddMessage(LogType.Error,
  7147. $"{stationNameStr}_上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1,
  7148. str.Length - str.LastIndexOf("\\") - 1));
  7149. CommandFromPLC resultToPlC = new CommandFromPLC();
  7150. resultToPlC.cmd = 0;
  7151. resultToPlC.cmdParam = 0; //指令参数
  7152. resultToPlC.cmdResult = 110;
  7153. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  7154. }
  7155. stopwatch1.Stop();
  7156. AddMessage(LogType.Info, stationNameStr + "_进站结束");
  7157. AddMessage(LogType.Info,
  7158. stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  7159. stopwatch2.ElapsedMilliseconds + "ms");
  7160. ProgressState = false;
  7161. }
  7162. /// <summary>
  7163. /// [S9] 下料设备 - 出站接口
  7164. /// </summary>
  7165. private void S9出站(int plcNo, string stationNameStr, OP90_MesData_t stPLC_MesData, string tagMesCommName,
  7166. string stationCode, string stationName, out bool ProgressState)
  7167. {
  7168. Stopwatch stopwatch1 = new Stopwatch();
  7169. Stopwatch stopwatch2 = new Stopwatch();
  7170. try
  7171. {
  7172. stopwatch1.Start();
  7173. AddMessage(LogType.Info, stationNameStr + "_出站开始");
  7174. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  7175. string processItem = stationName; // 测试项目
  7176. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  7177. string supplierCode = ""; // 供应商代码
  7178. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  7179. string batch_num = GlobalContext.BatchNumber; // 批次号
  7180. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  7181. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  7182. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  7183. string MachineId = GlobalContext.S9_MachineId; // 装备id(可配置) // ZS
  7184. string StationId = GlobalContext.S9_StationId; // ⼯位ID(可配置) // ZS
  7185. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  7186. bool pass = a1Result == 1;
  7187. //根据载具码获取产品码
  7188. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(CarrierBarcode);
  7189. if (string.IsNullOrEmpty(strProductBarcode))
  7190. {
  7191. AddMessage(LogType.Error, $"{stationNameStr}_数据库未查询到该载具绑定信息!");
  7192. ProgressState = false;
  7193. Thread.Sleep(10000);
  7194. return;
  7195. }
  7196. sn = strProductBarcode;
  7197. AddMessage(LogType.Info, $"载具码:{CarrierBarcode};产品码:{sn}");
  7198. List<TestItem> items = new List<TestItem>();
  7199. items.Add(new TestItem()
  7200. {
  7201. Parameter_name = "载具码",
  7202. Parameter_value = CarrierBarcode,
  7203. Parameter_unit = ""
  7204. });
  7205. items.Add(new TestItem()
  7206. {
  7207. Parameter_name = "产品码",
  7208. Parameter_value = sn,
  7209. Parameter_unit = ""
  7210. });
  7211. #region 转换过站明细字符串
  7212. ////创建字典
  7213. //var dic = new Dictionary<string, string>();
  7214. //// 获取结构体类型
  7215. //FieldInfo[] fields = typeof(OP40_DataSet_t).GetFields();
  7216. //string resultString = "";
  7217. //// 遍历变量名转换成字典描述
  7218. //foreach (FieldInfo field in fields)
  7219. //{
  7220. // //获取枚举描述
  7221. // string name = XiaomiMESEnumMethod.GetEnumDescriptionByName(field.Name,
  7222. // typeof(XiaomiMESEnum_ProcessData.Enum_40_ProcessData));
  7223. // //获取过站明细的值
  7224. // object valueObj = field.GetValue(stPLC_MesData.mesData) ?? 0;
  7225. // // 检查是否为数组
  7226. // if (valueObj.GetType().IsArray)
  7227. // {
  7228. // var array = valueObj as Array;
  7229. // resultString = ArrayToString(array);
  7230. // }
  7231. // else
  7232. // {
  7233. // resultString = valueObj.ToString();
  7234. // }
  7235. // dic.Add(name, resultString);
  7236. //}
  7237. //string paramJson = JsonConvert.SerializeObject(dic);
  7238. #endregion
  7239. string paramJson = JsonConvert.SerializeObject(stPLC_MesData.mesData);
  7240. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  7241. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "01-SLOT-01",
  7242. MachineId, StationId, "", paramJson,new XmStationOut_InspectionItemData(), "");
  7243. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  7244. if (mesResultFrmWeb == 1)
  7245. {
  7246. mesResultFrmWeb = (byte)(a1Result == 1 ? 1 : 110); //检测NG
  7247. if (mesResultFrmWeb == 110)
  7248. {
  7249. AddMessage(LogType.Info, stationNameStr + "_出站PLC检测结果:FAIL");
  7250. }
  7251. }
  7252. stopwatch2.Start();
  7253. //进站结果写入PLC
  7254. CommandFromPLC resultToPlC = new CommandFromPLC();
  7255. resultToPlC.cmd = 0;
  7256. resultToPlC.cmdParam = 0; //指令参数
  7257. resultToPlC.cmdResult = mesResultFrmWeb;
  7258. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  7259. stopwatch2.Stop();
  7260. AddMessage(LogType.Info, stationNameStr + "_出站结束");
  7261. //保存PLC返回MES数据到本地
  7262. ResponseMessage message = new ResponseMessage();
  7263. message = SQLHelper.InsertOp90Data(CarrierBarcode, sn, stPLC_MesData.mesData.nThrowCount,
  7264. stPLC_MesData.mesData.nRemainCount);
  7265. if (message.result == false)
  7266. {
  7267. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地失败");
  7268. }
  7269. AddMessage(LogType.Info, stationNameStr + "_保存加工数据到本地成功");
  7270. if (result1 == 1)
  7271. {
  7272. //载具码解除绑定
  7273. message = SQLHelper.DelCarrierBind(CarrierBarcode);
  7274. if (message.result == false)
  7275. {
  7276. AddMessage(LogType.Error, message.text);
  7277. }
  7278. }
  7279. }
  7280. catch (Exception ex)
  7281. {
  7282. stopwatch2.Start();
  7283. CommandFromPLC resultToPlC = new CommandFromPLC();
  7284. resultToPlC.cmd = 0;
  7285. resultToPlC.cmdParam = 0; //指令参数
  7286. resultToPlC.cmdResult = 110;
  7287. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  7288. stopwatch2.Stop();
  7289. string str = ex.StackTrace;
  7290. AddMessage(LogType.Error,
  7291. $"{stationNameStr}_上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  7292. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7293. }
  7294. stopwatch1.Stop();
  7295. AddMessage(LogType.Info,
  7296. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  7297. stopwatch2.ElapsedMilliseconds + "ms");
  7298. ProgressState = false;
  7299. uuid = "";
  7300. }
  7301. #endregion
  7302. #endregion Xiaomi
  7303. #region PLC1 张超凡
  7304. #region [S1] Tray盘上料装备(板测)
  7305. /// <summary>
  7306. /// S1工位的数据- 触发信号上次的值
  7307. /// </summary>
  7308. private Dictionary<string, object> s1PLCSignal_Old = new Dictionary<string, object>();
  7309. /// <summary>
  7310. /// S1工位的数据(含触发信号)
  7311. /// </summary>
  7312. private Dictionary<string, object> s1PLCData = new Dictionary<string, object>();
  7313. /// <summary>
  7314. /// S1工位的数据- 回写点位
  7315. /// </summary>
  7316. private Dictionary<string, WriteToPLC_Flag> s1PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  7317. ///// <summary>
  7318. ///// 触发信号
  7319. ///// </summary>
  7320. //private ManualResetEvent[] MreTasks;
  7321. /// <summary>
  7322. /// [S1] Tray盘上料装备(板测)
  7323. /// </summary>
  7324. /// <param name="plcNo">PLC编号</param>
  7325. //private void ReadStation_S1(int plcNo)
  7326. //{
  7327. // // [S1] Tray盘上料装备
  7328. // // [S2] FCT
  7329. // // [S3] 值板机
  7330. // // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  7331. // // [S5] Tray盘下料装备
  7332. // string stationCode = "[S1]";
  7333. // string stationName = "Tray盘上料装备";
  7334. // string stationNameStr = stationCode + stationName;
  7335. // #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  7336. // // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  7337. // s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  7338. // s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  7339. // s1PLCSignal_Old.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  7340. // s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  7341. // s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  7342. // s1PLCSignal_Old.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  7343. // s1PLCSignal_Old.Add("a1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  7344. // s1PLCSignal_Old.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  7345. // s1PLCSignal_Old.Add("a1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  7346. // // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  7347. // s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  7348. // s1PLCData.Add("a1MES_FLAG_VehicleStates", 0); // MES_FLAG
  7349. // s1PLCData.Add("a1ProductSN_VehicleStates", ""); // 产品SN(载具码)
  7350. // s1PLCData.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  7351. // s1PLCData.Add("a1MES_FLAG_Check", 0); // MES_FLAG
  7352. // s1PLCData.Add("a1ProductSN_Check", ""); // 产品SN(物料码)
  7353. // s1PLCData.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  7354. // s1PLCData.Add("a1MES_FLAG", 0); // MES_FLAG
  7355. // s1PLCData.Add("a1ProductSN", ""); // 产品SN(载具SN)
  7356. // s1PLCData.Add("a1PartNo1", ""); // 物料码1(穴位1)
  7357. // s1PLCData.Add("a1PartNo2", ""); // 物料码2(穴位2)
  7358. // s1PLCData.Add("a1Result", 0); // 产品结果
  7359. // s1PLCData.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  7360. // s1PLCData.Add("a1MES_FLAG_ICT", 0); // MES_FLAG
  7361. // s1PLCData.Add("a1ProductSN_ICT", ""); // 产品SN(载具SN)
  7362. // s1PLCData.Add("a1PartNo1_ICT", ""); // 物料码1(穴位1)
  7363. // s1PLCData.Add("a1PartNo2_ICT", ""); // 物料码2(穴位2)
  7364. // s1PLCData.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  7365. // s1PLCData.Add("a1OEEMES_FLAG", 0); // MES_FLAG
  7366. // s1PLCData.Add("a1OEEPartNo", ""); // 物料码(物料码还未绑定载具SN时必填)
  7367. // s1PLCData.Add("a1OEEVehicleCode", ""); // 载具SN
  7368. // s1PLCData.Add("a1OEEPartNum", 0); // 穴位号
  7369. // s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  7370. // s1PLCData.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  7371. // s1PLCData.Add("a1AGVUpStart", 0); // AGV上料开始信号
  7372. // s1PLCData.Add("a1AGVUpEnd", 0); // AGV上料完成信号
  7373. // s1PLCData.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  7374. // s1PLCData.Add("a1AGVDownStart", 0); // AGV下料开始信号
  7375. // s1PLCData.Add("a1AGVDownEnd", 0); // AGV下料完成信号
  7376. // #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  7377. // while (IsRun)
  7378. // {
  7379. // try
  7380. // {
  7381. // if (!GlobalContext._IsCon_Funs1)
  7382. // {
  7383. // UpdatePLCMonitor(1, plcNo, 0);
  7384. // continue;
  7385. // }
  7386. // if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  7387. // {
  7388. // Stopwatch stopwatch1 = new Stopwatch();
  7389. // Stopwatch stopwatch2 = new Stopwatch();
  7390. // stopwatch1.Start();
  7391. // stopwatch2.Start();
  7392. // #region 一次性读取所有数据
  7393. // // 一次性读取所有数据
  7394. // int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100);
  7395. // int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 100);
  7396. // int[] data3 = Funs[plcNo].ReadHoldingRegisters(2200, 100);
  7397. // int[] data4 = Funs[plcNo].ReadHoldingRegisters(2300, 33);
  7398. // int[] datas = data1.Concat(data2).ToArray();
  7399. // datas = datas.Concat(data3).ToArray();
  7400. // datas = datas.Concat(data4).ToArray();
  7401. // s1PLCData["a1PLC_FLAG_VehicleStates"] = datas[2]; // 载具进站查询状态
  7402. // s1PLCData["a1MES_FLAG_VehicleStates"] = datas[3];
  7403. // int[] a1ProductSN_VehicleStatesData = datas.Skip(4).Take(20).ToArray();
  7404. // s1PLCData["a1ProductSN_VehicleStates"] = ModbusClient.ConvertRegistersToString(a1ProductSN_VehicleStatesData, 0, 40);
  7405. // s1PLCData["a1PLC_FLAG_Check"] = datas[76]; // 上料进站校验
  7406. // s1PLCData["a1MES_FLAG_Check"] = datas[77];
  7407. // int[] a1ProductSN_CheckData = datas.Skip(78).Take(20).ToArray();
  7408. // s1PLCData["a1ProductSN_Check"] = ModbusClient.ConvertRegistersToString(a1ProductSN_CheckData, 0, 40);
  7409. // s1PLCData["a1PLC_FLAG"] = datas[108]; // 出站接口
  7410. // s1PLCData["a1MES_FLAG"] = datas[109];
  7411. // int[] a1ProductSNData = datas.Skip(110).Take(20).ToArray();
  7412. // s1PLCData["a1ProductSN"] = ModbusClient.ConvertRegistersToString(a1ProductSNData, 0, 40);
  7413. // int[] a1PartNo1Data = datas.Skip(130).Take(20).ToArray();
  7414. // s1PLCData["a1PartNo1"] = ModbusClient.ConvertRegistersToString(a1PartNo1Data, 0, 40);
  7415. // int[] a1PartNo2Data = datas.Skip(150).Take(20).ToArray();
  7416. // s1PLCData["a1PartNo2"] = ModbusClient.ConvertRegistersToString(a1PartNo2Data, 0, 40);
  7417. // s1PLCData["a1Result"] = datas[170];
  7418. // s1PLCData["a1PLC_FLAG_ICT"] = datas[181]; // 将SN发给ICT标机(串口)
  7419. // s1PLCData["a1MES_FLAG_ICT"] = datas[182];
  7420. // int[] a1ProductSN_ICTData = datas.Skip(183).Take(20).ToArray();
  7421. // s1PLCData["a1ProductSN_ICT"] = ModbusClient.ConvertRegistersToString(a1ProductSN_ICTData, 0, 40);
  7422. // int[] a1PartNo1_ICTData = datas.Skip(203).Take(20).ToArray();
  7423. // s1PLCData["a1PartNo1_ICT"] = ModbusClient.ConvertRegistersToString(a1PartNo1_ICTData, 0, 40);
  7424. // int[] a1PartNo2_ICTData = datas.Skip(223).Take(20).ToArray();
  7425. // s1PLCData["a1PartNo2_ICT"] = ModbusClient.ConvertRegistersToString(a1PartNo2_ICTData, 0, 40);
  7426. // s1PLCData["a1OEEPLC_FLAG"] = datas[253]; // 节拍接口
  7427. // s1PLCData["a1OEEMES_FLAG"] = datas[254];
  7428. // int[] a1OEEPartNoData = datas.Skip(255).Take(20).ToArray();
  7429. // s1PLCData["a1OEEPartNo"] = ModbusClient.ConvertRegistersToString(a1OEEPartNoData, 0, 40); // 物料码(物料码还未绑定载具SN时必填)
  7430. // int[] a1OEEVehicleCodeData = datas.Skip(275).Take(20).ToArray();
  7431. // s1PLCData["a1OEEVehicleCode"] = ModbusClient.ConvertRegistersToString(a1OEEVehicleCodeData, 0, 40); // 载具SN
  7432. // s1PLCData["a1OEEPartNum"] = datas[295]; // 穴位号
  7433. // s1PLCData["a1OEEType"] = datas[296]; // 节拍类型(plc写入)
  7434. // s1PLCData["a1AGVUpCall"] = datas[307]; // AGV上料
  7435. // s1PLCData["a1AGVUpStart"] = datas[308];
  7436. // s1PLCData["a1AGVUpEnd"] = datas[309];
  7437. // s1PLCData["a1AGVDownCall"] = datas[320]; // AGV下料
  7438. // s1PLCData["a1AGVDownStart"] = datas[321];
  7439. // s1PLCData["a1AGVDownEnd"] = datas[322];
  7440. // #endregion 一次性读取所有数据
  7441. // stopwatch2.Stop();
  7442. // #region 回写操作,写后清空flag
  7443. // PLCWriteData(Funs[plcNo], ref s1PLCData, ref s1PLCWriteData);
  7444. // #endregion 回写操作,写后清空flag
  7445. // #region 载具进站查询状态(有假产品的拿下来,有产品的穴位不放产品)
  7446. // try
  7447. // {
  7448. // int a1PLC_FLAG_VehicleStates = (int)s1PLCData["a1PLC_FLAG_VehicleStates"];
  7449. // int a1MES_FLAG_VehicleStates = (int)s1PLCData["a1MES_FLAG_VehicleStates"];
  7450. // int a1PLC_FLAG_VehicleStatesOld = (int)s1PLCSignal_Old["a1PLC_FLAG_VehicleStates"];
  7451. // if (a1PLC_FLAG_VehicleStates != a1PLC_FLAG_VehicleStatesOld)
  7452. // {
  7453. // if (a1PLC_FLAG_VehicleStates == 1 && a1MES_FLAG_VehicleStates == 0) // 0->1
  7454. // Task.Run(() => S1载具进站查询状态(plcNo, stationNameStr)); // MreTasks[1].Set();
  7455. // else if (a1PLC_FLAG_VehicleStates == 0 && a1MES_FLAG_VehicleStates != 0)
  7456. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)0);
  7457. // s1PLCSignal_Old["a1PLC_FLAG_VehicleStates"] = s1PLCData["a1PLC_FLAG_VehicleStates"];
  7458. // }
  7459. // }
  7460. // catch (Exception ex)
  7461. // {
  7462. // // 6代表上位机报警
  7463. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6);
  7464. // string str = ex.StackTrace;
  7465. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 载具进站查询状态出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7466. // }
  7467. // #endregion 载具进站查询状态(有假产品的拿下来,有产品的穴位不放产品)
  7468. // #region 上料进站校验
  7469. // try
  7470. // {
  7471. // int a1PLC_FLAG_Check = (int)s1PLCData["a1PLC_FLAG_Check"];
  7472. // int a1MES_FLAG_Check = (int)s1PLCData["a1MES_FLAG_Check"];
  7473. // int a1PLC_FLAG_CheckOld = (int)s1PLCSignal_Old["a1PLC_FLAG_Check"];
  7474. // if (a1PLC_FLAG_Check != a1PLC_FLAG_CheckOld)
  7475. // {
  7476. // if (a1PLC_FLAG_Check == 1 && a1MES_FLAG_Check == 0) // 0->1
  7477. // Task.Run(() => S1上料进站校验(plcNo, stationNameStr)); // MreTasks[2].Set();
  7478. // else if (a1PLC_FLAG_Check == 0 && a1MES_FLAG_Check != 0)
  7479. // Funs[plcNo].WriteMultipleRegisters<short>(2077, (short)0);
  7480. // s1PLCSignal_Old["a1PLC_FLAG_Check"] = s1PLCData["a1PLC_FLAG_Check"];
  7481. // }
  7482. // }
  7483. // catch (Exception ex)
  7484. // {
  7485. // Funs[plcNo].WriteMultipleRegisters<short>(2077, (short)6); // 6代表上位机报警
  7486. // string str = ex.StackTrace;
  7487. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7488. // }
  7489. // #endregion 上料进站校验
  7490. // #region Tray盘上料装备-出站接口
  7491. // try
  7492. // {
  7493. // int a1PLC_FLAG = (int)s1PLCData["a1PLC_FLAG"];
  7494. // int a1MES_FLAG = (int)s1PLCData["a1MES_FLAG"];
  7495. // int a1PLC_FLAGOld = (int)s1PLCSignal_Old["a1PLC_FLAG"];
  7496. // if (a1PLC_FLAG != a1PLC_FLAGOld)
  7497. // {
  7498. // if (a1PLC_FLAG == 1 && a1MES_FLAG == 0) // 0->1
  7499. // Task.Run(() => S1出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  7500. // else if (a1PLC_FLAG == 0 && a1MES_FLAG != 0)
  7501. // Funs[plcNo].WriteMultipleRegisters<short>(2109, (short)0);
  7502. // s1PLCSignal_Old["a1PLC_FLAG"] = s1PLCData["a1PLC_FLAG"];
  7503. // }
  7504. // }
  7505. // catch (Exception ex)
  7506. // {
  7507. // Funs[plcNo].WriteMultipleRegisters<short>(2109, (short)6); // 6代表上位机报警
  7508. // string str = ex.StackTrace;
  7509. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传出站数据出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7510. // }
  7511. // #endregion Tray盘上料装备-出站接口
  7512. // #region Tray盘上料装备-将SN发给ICT标机
  7513. // try
  7514. // {
  7515. // int a1PLC_FLAG_ICT = (int)s1PLCData["a1PLC_FLAG_ICT"];
  7516. // int a1MES_FLAG_ICT = (int)s1PLCData["a1MES_FLAG_ICT"];
  7517. // int a1PLC_FLAG_ICTOld = (int)s1PLCSignal_Old["a1PLC_FLAG_ICT"];
  7518. // if (a1PLC_FLAG_ICT != a1PLC_FLAG_ICTOld)
  7519. // {
  7520. // if (a1PLC_FLAG_ICT == 1 && a1MES_FLAG_ICT == 0) // 0->1
  7521. // Task.Run(() => S1将SN发给ICT标机(plcNo, stationNameStr)); // MreTasks[3].Set();
  7522. // else if (a1PLC_FLAG_ICT == 0 && a1MES_FLAG_ICT != 0)
  7523. // Funs[plcNo].WriteMultipleRegisters<short>(2182, (short)0);
  7524. // s1PLCSignal_Old["a1PLC_FLAG_ICT"] = s1PLCData["a1PLC_FLAG_ICT"];
  7525. // }
  7526. // }
  7527. // catch (Exception ex)
  7528. // {
  7529. // Funs[plcNo].WriteMultipleRegisters<short>(2182, (short)4); // 4代表上位机报警
  7530. // string str = ex.StackTrace;
  7531. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 将SN发给ICT标机出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7532. // }
  7533. // #endregion Tray盘上料装备-将SN发给ICT标机
  7534. // #region Tray盘上料装备-点检数据
  7535. // //try
  7536. // //{
  7537. // // Funs[plcNo].Read_Int_Tag("828", 1, out short[] iPLC_Flag); // PLC_Flag
  7538. // // Funs[plcNo].Read_Int_Tag("829", 1, out short[] iMES_Flag); // MES_Flag
  7539. // // bool pLC_Flag = iPLC_Flag[0] == 1 ? true : false; // PLC_Flag
  7540. // // bool mES_Flag = iMES_Flag[0] == 1 ? true : false; // MES_Flag
  7541. // // if (pLC_Flag && !mES_Flag) // 1 0
  7542. // // {
  7543. // // AddMessage_Station(stationNameStr, LogType.Info, Head + stationNameStr + BodyCheck);
  7544. // // await Task.Run(() => { DoOneCheckData_Tray盘上料装备(plcNo, stationCode, stationName); });
  7545. // // AddMessage_Station(stationNameStr, LogType.Info, stationNameStr + BodyCheck + Tail);
  7546. // // }
  7547. // // else if (!pLC_Flag && mES_Flag) // 0 1
  7548. // // {
  7549. // // // 清空写给PLC的数据
  7550. // // // MES_Flag重置为0
  7551. // // Funs[plcNo].Write_DInt_Tag("829", 1, new Int32[1] { 0 });
  7552. // // }
  7553. // //}
  7554. // //catch (Exception ex)
  7555. // //{
  7556. // // // MES_Flag 为2上位机报错
  7557. // // Funs[plcNo].Write_DInt_Tag("829", 1, new Int32[1] { 2 });
  7558. // // string str = ex.StackTrace;
  7559. // // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}点检运行出错!错误信息:" + ex.Message + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7560. // //}
  7561. // #endregion Tray盘上料装备-点检数据
  7562. // #region 节拍接口
  7563. // try
  7564. // {
  7565. // int a1OEEPLC_FLAG = (int)s1PLCData["a1OEEPLC_FLAG"];
  7566. // int a1OEEMES_FLAG = (int)s1PLCData["a1OEEMES_FLAG"];
  7567. // int a1OEEPLC_FLAGOld = (int)s1PLCSignal_Old["a1OEEPLC_FLAG"];
  7568. // if (a1OEEPLC_FLAG != a1OEEPLC_FLAGOld)
  7569. // {
  7570. // if (a1OEEPLC_FLAG == 1 && a1OEEMES_FLAG == 0) // 0->1
  7571. // Task.Run(() => S1节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  7572. // else if (a1OEEPLC_FLAG == 0 && a1OEEMES_FLAG != 0)
  7573. // Funs[plcNo].WriteMultipleRegisters<short>(2254, (short)0); //
  7574. // s1PLCSignal_Old["a1OEEPLC_FLAG"] = s1PLCData["a1OEEPLC_FLAG"];
  7575. // }
  7576. // }
  7577. // catch (Exception ex)
  7578. // {
  7579. // Funs[plcNo].WriteMultipleRegisters<short>(2254, (short)4); // 4代表上位机报警
  7580. // string str = ex.StackTrace;
  7581. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7582. // }
  7583. // #endregion 节拍接口
  7584. // #region AGV上料
  7585. // // AGV上料叫AGV信号
  7586. // try
  7587. // {
  7588. // int a1AGVUpCall = (int)s1PLCData["a1AGVUpCall"];
  7589. // int a1AGVUpCallOld = (int)s1PLCSignal_Old["a1AGVUpCall"];
  7590. // if (a1AGVUpCall != a1AGVUpCallOld)
  7591. // {
  7592. // if (a1AGVUpCall == 1) // 0->1
  7593. // Task.Run(() => S1AGV上料叫agv(plcNo, stationNameStr)); // MreTasks[5].Set();
  7594. // s1PLCSignal_Old["a1AGVUpCall"] = s1PLCData["a1AGVUpCall"];
  7595. // }
  7596. // }
  7597. // catch (Exception ex)
  7598. // {
  7599. // Funs[plcNo].WriteMultipleRegisters<short>(2307, (short)4); // 4代表上位机报警
  7600. // string str = ex.StackTrace;
  7601. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7602. // }
  7603. // // AGV上料完成信号
  7604. // try
  7605. // {
  7606. // int a1AGVUpEnd = (int)s1PLCData["a1AGVUpEnd"];
  7607. // int a1AGVUpEndOld = (int)s1PLCSignal_Old["a1AGVUpEnd"];
  7608. // if (a1AGVUpEnd != a1AGVUpEndOld)
  7609. // {
  7610. // if (a1AGVUpEnd == 1) // 0->1
  7611. // Task.Run(() => S1AGV上料完成(plcNo, stationNameStr)); // MreTasks[6].Set();
  7612. // s1PLCSignal_Old["a1AGVUpEnd"] = s1PLCData["a1AGVUpEnd"];
  7613. // }
  7614. // }
  7615. // catch (Exception ex)
  7616. // {
  7617. // Funs[plcNo].WriteMultipleRegisters<short>(2309, (short)4); // 4代表上位机报警
  7618. // string str = ex.StackTrace;
  7619. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料完成信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7620. // }
  7621. // #endregion AGV上料
  7622. // #region AGV下料
  7623. // // AGV下料叫agv信号
  7624. // try
  7625. // {
  7626. // int a1AGVDownCall = (int)s1PLCData["a1AGVDownCall"];
  7627. // int a1AGVDownCallOld = (int)s1PLCSignal_Old["a1AGVDownCall"];
  7628. // if (a1AGVDownCall != a1AGVDownCallOld)
  7629. // {
  7630. // if (a1AGVDownCall == 1) // 0->1
  7631. // Task.Run(() => S1AGV下料叫agv(plcNo, stationNameStr)); // MreTasks[7].Set();
  7632. // s1PLCSignal_Old["a1AGVDownCall"] = s1PLCData["a1AGVDownCall"];
  7633. // }
  7634. // }
  7635. // catch (Exception ex)
  7636. // {
  7637. // Funs[plcNo].WriteMultipleRegisters<short>(2320, (short)4); // 4代表上位机报警
  7638. // string str = ex.StackTrace;
  7639. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料叫agv信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7640. // }
  7641. // // AGV下料完成信号
  7642. // try
  7643. // {
  7644. // int a1AGVDownEnd = (int)s1PLCData["a1AGVDownEnd"];
  7645. // int a1AGVDownEndOld = (int)s1PLCSignal_Old["a1AGVDownEnd"];
  7646. // if (a1AGVDownEnd != a1AGVDownEndOld)
  7647. // {
  7648. // if (a1AGVDownEnd == 1) // 0->1
  7649. // Task.Run(() => S1AGV下料完成(plcNo, stationNameStr)); // MreTasks[8].Set();
  7650. // s1PLCSignal_Old["a1AGVDownEnd"] = s1PLCData["a1AGVDownEnd"];
  7651. // }
  7652. // }
  7653. // catch (Exception ex)
  7654. // {
  7655. // Funs[plcNo].WriteMultipleRegisters<short>(2322, (short)4); // 4代表上位机报警
  7656. // string str = ex.StackTrace;
  7657. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料完成信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7658. // }
  7659. // #endregion AGV下料
  7660. // #region 心跳
  7661. // try
  7662. // {
  7663. // short states = 0;
  7664. // Funs[plcNo].WriteMultipleRegisters<short>(2000, states);
  7665. // }
  7666. // catch (Exception ex)
  7667. // {
  7668. // string str = ex.StackTrace;
  7669. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上位机心跳写入出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7670. // }
  7671. // #endregion 心跳
  7672. // UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  7673. // stopwatch1.Stop();
  7674. // //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  7675. // OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  7676. // }
  7677. // else
  7678. // {
  7679. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  7680. // AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  7681. // Funs[plcNo].Connect(); // 重连
  7682. // }
  7683. // }
  7684. // catch (Exception ex)
  7685. // {
  7686. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  7687. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  7688. // Funs[plcNo].ReConnect();
  7689. // }
  7690. // Thread.Sleep(IntervalReadPLC);
  7691. // }
  7692. //}
  7693. /// <summary>
  7694. /// [S1] Tray盘上料装备(板测)- 载具进站查询状态
  7695. /// </summary>
  7696. /// <param name="plcNo">PLC编号</param>
  7697. /// <param name="stationNameStr">工站全称</param>
  7698. private void S1载具进站查询状态(int plcNo, string stationNameStr)
  7699. {
  7700. Stopwatch stopwatch1 = new Stopwatch();
  7701. Stopwatch stopwatch2 = new Stopwatch();
  7702. try
  7703. {
  7704. stopwatch1.Start();
  7705. string sn = (string)s1PLCData["a1ProductSN_VehicleStates"]; // 产品SN(载具码)
  7706. sn = sn.Replace("\0", "");
  7707. #region 查询载具上的产品信息
  7708. string cavityData = string.Empty;
  7709. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref cavityData);
  7710. if (string.IsNullOrEmpty(cavityData))
  7711. cavityData = "";
  7712. if (snResult != 0)
  7713. {
  7714. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  7715. writeToPLC_Flag1.Name = "a1MES_FLAG_VehicleStates";
  7716. writeToPLC_Flag1.Adress = 2003;
  7717. writeToPLC_Flag1.Value = (short)6;
  7718. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_VehicleStates", writeToPLC_Flag1);
  7719. stopwatch1.Stop();
  7720. AddMessage(LogType.Info,
  7721. stationNameStr + $"_载具进站查询状态失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  7722. "ms");
  7723. return;
  7724. }
  7725. #endregion 查询载具上的产品信息
  7726. string[] cavitySNs = cavityData.Split('.');
  7727. string a1CavitySN1_VehicleStates = ""; // 穴位1物料SN(上位机写入)
  7728. string a1CavitySN2_VehicleStates = ""; // 穴位2物料SN(上位机写入)
  7729. short a1CavityResult1_VehicleStates = 1; // 1空;2ng;3假产品;
  7730. short a1CavityResult2_VehicleStates = 1; // 1空;2ng;3假产品;
  7731. if (cavitySNs != null && cavitySNs.Length >= 2)
  7732. {
  7733. a1CavitySN1_VehicleStates = cavitySNs[0];
  7734. a1CavitySN2_VehicleStates = cavitySNs[1];
  7735. a1CavityResult1_VehicleStates = 2;
  7736. a1CavityResult2_VehicleStates = 2;
  7737. }
  7738. if (a1CavitySN1_VehicleStates == "假产品")
  7739. a1CavityResult1_VehicleStates = 3;
  7740. if (a1CavitySN2_VehicleStates == "假产品")
  7741. a1CavityResult2_VehicleStates = 3;
  7742. short mES_Flag = 1; // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  7743. // 回写
  7744. stopwatch2.Start();
  7745. //Funs[plcNo].WriteMultipleRegisters<string>(2024, a1CavitySN1_VehicleStates, 20);
  7746. //Funs[plcNo].WriteMultipleRegisters<string>(2044, a1CavitySN2_VehicleStates, 20);
  7747. //Funs[plcNo].WriteMultipleRegisters<short>(2064, a1CavityResult1_VehicleStates);
  7748. //Funs[plcNo].WriteMultipleRegisters<short>(2065, a1CavityResult2_VehicleStates);
  7749. //// MES_Flag
  7750. //Funs[plcNo].WriteMultipleRegisters<short>(2003, mES_Flag);
  7751. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  7752. writeToPLC_Flag.Name = "a1MES_FLAG_VehicleStates";
  7753. writeToPLC_Flag.Adress = 2003;
  7754. writeToPLC_Flag.Value = mES_Flag;
  7755. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 穴位1物料SN(上位机写入)
  7756. {
  7757. Name = "a1CavitySN1_VehicleStates",
  7758. Adress = 2024,
  7759. ValueType = PLCValueType.String,
  7760. ValueTypeStrLength = 20,
  7761. Value = a1CavitySN1_VehicleStates
  7762. });
  7763. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 穴位2物料SN(上位机写入)
  7764. {
  7765. Name = "a1CavitySN2_VehicleStates",
  7766. Adress = 2044,
  7767. ValueType = PLCValueType.String,
  7768. ValueTypeStrLength = 20,
  7769. Value = a1CavitySN2_VehicleStates
  7770. });
  7771. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  7772. {
  7773. Name = "a1CavityResult1_VehicleStates",
  7774. Adress = 2064,
  7775. ValueType = PLCValueType.Short,
  7776. Value = a1CavityResult1_VehicleStates
  7777. });
  7778. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  7779. {
  7780. Name = "a1CavityResult2_VehicleStates",
  7781. Adress = 2065,
  7782. ValueType = PLCValueType.Short,
  7783. Value = a1CavityResult2_VehicleStates
  7784. });
  7785. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_VehicleStates", writeToPLC_Flag);
  7786. stopwatch2.Stop();
  7787. }
  7788. catch (Exception ex)
  7789. {
  7790. string str = ex.StackTrace;
  7791. AddMessage_Station(stationNameStr, LogType.Error,
  7792. $"PLC{plcNo}_{stationNameStr} 载具进站查询状态出错!错误信息:" + ex.Message + "异常位置:" +
  7793. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7794. // MES_Flag
  7795. stopwatch2.Start();
  7796. //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  7797. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  7798. writeToPLC_Flag.Name = "a1MES_FLAG_VehicleStates";
  7799. writeToPLC_Flag.Adress = 2003;
  7800. writeToPLC_Flag.Value = (short)6;
  7801. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_VehicleStates", writeToPLC_Flag);
  7802. stopwatch2.Stop();
  7803. }
  7804. stopwatch1.Stop();
  7805. AddMessage(LogType.Info,
  7806. stationNameStr + "_载具进站查询状态;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  7807. stopwatch2.ElapsedMilliseconds + "ms");
  7808. }
  7809. /// <summary>
  7810. /// [S1] Tray盘上料装备(板测)- 上料进站校验
  7811. /// </summary>
  7812. /// <param name="plcNo">PLC编号</param>
  7813. /// <param name="stationNameStr">工站全称</param>
  7814. private void S1上料进站校验(int plcNo, string stationNameStr)
  7815. {
  7816. Stopwatch stopwatch1 = new Stopwatch();
  7817. Stopwatch stopwatch2 = new Stopwatch();
  7818. try
  7819. {
  7820. stopwatch1.Start();
  7821. string sn = (string)s1PLCData["a1ProductSN_Check"]; // 产品SN(物料码)
  7822. sn = sn.Replace("\0", "");
  7823. // 保存进站数据+调用进站MES接口
  7824. List<TestItem> item = new List<TestItem>();
  7825. stopwatch2.Start();
  7826. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn,
  7827. item, out string errorMsg);
  7828. stopwatch2.Stop();
  7829. short a1MES_FLAG_Check = (short)result;
  7830. //Funs[plcNo].WriteMultipleRegisters<short>(2077, a1MES_FLAG_Check); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  7831. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  7832. writeToPLC_Flag.Name = "a1MES_FLAG_Check";
  7833. writeToPLC_Flag.Adress = 2077;
  7834. writeToPLC_Flag.Value = a1MES_FLAG_Check;
  7835. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_Check", writeToPLC_Flag);
  7836. }
  7837. catch (Exception ex)
  7838. {
  7839. string str = ex.StackTrace;
  7840. AddMessage_Station(stationNameStr, LogType.Error,
  7841. $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" +
  7842. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7843. // MES_Flag
  7844. //Funs[plcNo].WriteMultipleRegisters<short>(2077, (short)6); // 6代表上位机报警
  7845. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  7846. writeToPLC_Flag.Name = "a1MES_FLAG_Check";
  7847. writeToPLC_Flag.Adress = 2077;
  7848. writeToPLC_Flag.Value = (short)6;
  7849. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_Check", writeToPLC_Flag);
  7850. }
  7851. stopwatch1.Stop();
  7852. AddMessage(LogType.Info,
  7853. stationNameStr + "_上料进站校验;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  7854. stopwatch2.ElapsedMilliseconds + "ms");
  7855. }
  7856. /// <summary>
  7857. /// [S1] Tray盘上料装备(板测)- 出站接口
  7858. /// </summary>
  7859. /// <param name="plcNo"></param>
  7860. /// <param name="stationCode"></param>
  7861. /// <param name="stationName"></param>
  7862. private void S1出站接口(int plcNo, string stationCode, string stationName)
  7863. {
  7864. Stopwatch stopwatch1 = new Stopwatch();
  7865. Stopwatch stopwatch2 = new Stopwatch();
  7866. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  7867. string stationNameStr = stationCode + stationName;
  7868. string processItem = stationName; // 测试项目
  7869. try
  7870. {
  7871. stopwatch1.Start();
  7872. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  7873. //string batch_num = GlobalContext.BatchNumber; // 批次号
  7874. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  7875. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  7876. string sn = (string)s1PLCData["a1ProductSN"]; // 产品SN(载具SN码)
  7877. sn = sn.Replace("\0", "");
  7878. string partNo1 = (string)s1PLCData["a1PartNo1"]; // 物料码1(穴位1)
  7879. partNo1 = partNo1.Replace("\0", "");
  7880. string partNo2 = (string)s1PLCData["a1PartNo2"]; // 物料码2(穴位2)
  7881. partNo2 = partNo2.Replace("\0", "");
  7882. int a1Result = (int)s1PLCData["a1Result"]; // 产品结果
  7883. bool pass = a1Result == 1;
  7884. stopwatch2.Start();
  7885. // 产品1
  7886. List<TestItem> items = new List<TestItem>();
  7887. items.Add(new TestItem()
  7888. {
  7889. Parameter_name = "载具码",
  7890. Parameter_value = sn,
  7891. Parameter_unit = ""
  7892. });
  7893. items.Add(new TestItem()
  7894. {
  7895. Parameter_name = "载具穴号",
  7896. Parameter_value = "1",
  7897. Parameter_unit = ""
  7898. });
  7899. items.Add(new TestItem()
  7900. {
  7901. Parameter_name = "产品结果",
  7902. Parameter_value = a1Result == 1 ? "OK" : "NG",
  7903. Parameter_unit = ""
  7904. });
  7905. int result1 = SwitctProcessData_old(stationNameStr, items, equipmentCode, processItem
  7906. , workorder_code, mtltmrk, partNo1, pass, sn, "01-SLOT-01");
  7907. // 产品2
  7908. items = new List<TestItem>();
  7909. items.Add(new TestItem()
  7910. {
  7911. Parameter_name = "载具码",
  7912. Parameter_value = sn,
  7913. Parameter_unit = ""
  7914. });
  7915. items.Add(new TestItem()
  7916. {
  7917. Parameter_name = "载具穴号",
  7918. Parameter_value = "2",
  7919. Parameter_unit = ""
  7920. });
  7921. items.Add(new TestItem()
  7922. {
  7923. Parameter_name = "产品结果",
  7924. Parameter_value = a1Result == 1 ? "OK" : "NG",
  7925. Parameter_unit = ""
  7926. });
  7927. int result2 = SwitctProcessData_old(stationNameStr, items, equipmentCode, processItem
  7928. , workorder_code, mtltmrk, partNo2, pass, sn, "2");
  7929. short result = 0;
  7930. List<int> results = new List<int>() { result1, result2 };
  7931. if (result1 == 1 && result2 == 1)
  7932. result = 1;
  7933. else if (results.Contains(3))
  7934. result = 3;
  7935. else if (results.Contains(2))
  7936. result = 2;
  7937. else if (results.Contains(4))
  7938. result = 4;
  7939. else
  7940. result = 4;
  7941. stopwatch2.Stop();
  7942. #region 存储绑定数据到 边线MES系统中
  7943. if (result == 1)
  7944. {
  7945. string data = string.Concat(partNo1, ".", partNo2);
  7946. int resultMesR = XiaomiMES_RouteCommunication.SNBindData(sn, data);
  7947. if (resultMesR != 0)
  7948. {
  7949. result = 4;
  7950. AddMessage_Station(stationNameStr, LogType.Error,
  7951. $"PLC{plcNo}_[{equipmentCode}]{processItem}过站失败!MES边线程序返回:{resultMesR}");
  7952. }
  7953. }
  7954. #endregion 存储绑定数据到 边线MES系统中
  7955. // MES_Flag 为MES报错
  7956. // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  7957. //Funs[plcNo].WriteMultipleRegisters<short>(2109, result); // 4代表上位机报警
  7958. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  7959. writeToPLC_Flag.Name = "a1MES_FLAG";
  7960. writeToPLC_Flag.Adress = 2109;
  7961. writeToPLC_Flag.Value = result;
  7962. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG", writeToPLC_Flag);
  7963. OnMessage(LogType.Debug,
  7964. $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  7965. }
  7966. catch (Exception ex)
  7967. {
  7968. stopwatch2.Restart();
  7969. // MES_Flag 为4上位机报错
  7970. //Funs[plcNo].WriteMultipleRegisters<short>(2109, (short)4); // 4代表上位机报警
  7971. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  7972. writeToPLC_Flag.Name = "a1MES_FLAG";
  7973. writeToPLC_Flag.Adress = 2109;
  7974. writeToPLC_Flag.Value = (short)4;
  7975. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG", writeToPLC_Flag);
  7976. stopwatch2.Stop();
  7977. string str = ex.StackTrace;
  7978. AddMessage_Station(stationNameStr, LogType.Error,
  7979. $"PLC{plcNo}_[{equipmentCode}]{processItem}上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  7980. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  7981. }
  7982. stopwatch1.Stop();
  7983. AddMessage(LogType.Info,
  7984. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  7985. stopwatch2.ElapsedMilliseconds + "ms");
  7986. }
  7987. //// 上传点检数据_ [S1] Tray盘上料装备(板测)
  7988. //private void DoOneCheckData_Tray盘上料装备(int plcNo, string stationCode, string stationName)
  7989. //{
  7990. // string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  7991. // string stationNameStr = stationCode + stationName;
  7992. // string processItem = stationName; // 测试项目
  7993. // try
  7994. // {
  7995. // string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  7996. // string accno = "1"; // 工序编号
  7997. // Funs[plcNo].Read_Real_Tag("896", 1, out float[] float0);
  7998. // float travelLimitUp = float0[0]; // 胶圈装配行程设定上限
  7999. // List<OneCheckItem> items = new List<OneCheckItem>()
  8000. // {
  8001. // new OneCheckItem()
  8002. // {
  8003. // Onecheck_name="胶圈装配行程设定上限",
  8004. // Onecheck_content="上限值",
  8005. // Onecheck_result=$"正常|胶圈装配行程设定上限{travelLimitUp} mm"
  8006. // },
  8007. // };
  8008. // OneCheckData oneCheckData = new OneCheckData()
  8009. // {
  8010. // Line_code = GlobalContext.LineCode,
  8011. // Line_name = GlobalContext.LineName,
  8012. // Equipment_code = equipmentCode,
  8013. // Equipment_name = equipmentCode,
  8014. // Workorder_code = workorder_code,
  8015. // Procedure_code = accno,
  8016. // Procedure_name = processItem,
  8017. // Oneckeck_values = items,
  8018. // Onecheck_empcode = "",
  8019. // Onecheck_empname = "",
  8020. // Onecheck_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
  8021. // };
  8022. // int result1 = SaveOneCheckDataByDBAndSubmit(oneCheckData, equipmentCode, processItem);
  8023. // //int result = result1 == 1 ? 1 : (GlobalContext.IsSendCheckOneData ? 4 : 1);
  8024. // short result = result1 == 1 ? (short)1 : (short)2;
  8025. // // MES_Flag 为4MES报错
  8026. // Funs[plcNo].Write_DInt_Tag("829", 1, new Int32[1] { result });
  8027. // WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  8028. // }
  8029. // catch (Exception ex)
  8030. // {
  8031. // // MES_Flag 为2上位机报错
  8032. // Funs[plcNo].Write_DInt_Tag("829", 1, new Int32[1] { 2 });
  8033. // string str = ex.StackTrace;
  8034. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}点检报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8035. // }
  8036. //}
  8037. // ReadStation_S1_2 节拍接口+AGV
  8038. /// <summary>
  8039. /// [S1] Tray盘上料装备(板测)- 将SN发给ICT标机(串口)
  8040. /// </summary>
  8041. /// <param name="plcNo">PLC编号</param>
  8042. /// <param name="stationNameStr">工站全称</param>
  8043. private void S1将SN发给ICT标机(int plcNo, string stationNameStr)
  8044. {
  8045. Stopwatch stopwatch1 = new Stopwatch();
  8046. Stopwatch stopwatch2 = new Stopwatch();
  8047. try
  8048. {
  8049. stopwatch1.Start();
  8050. string a1ProductSN_ICT = (string)s1PLCData["a1ProductSN_ICT"]; // 产品SN(载具SN)
  8051. a1ProductSN_ICT = a1ProductSN_ICT.Replace("\0", "");
  8052. string a1PartNo1_ICT = (string)s1PLCData["a1PartNo1_ICT"]; // 物料码1(穴位1)
  8053. a1PartNo1_ICT = a1PartNo1_ICT.Replace("\0", "");
  8054. string a1PartNo2_ICT = (string)s1PLCData["a1PartNo2_ICT"]; // 物料码2(穴位2)
  8055. a1PartNo2_ICT = a1PartNo2_ICT.Replace("\0", "");
  8056. // ZS 将SN发给ICT标机(串口)
  8057. short a1MES_FLAG_ICT = 1;
  8058. stopwatch2.Start();
  8059. // MES_Flag
  8060. //Funs[plcNo].WriteMultipleRegisters<short>(2182, a1MES_FLAG_ICT); // 上位机发送1代表OK;2代表失败;4代表上位机报警;
  8061. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8062. writeToPLC_Flag.Name = "a1MES_FLAG_ICT";
  8063. writeToPLC_Flag.Adress = 2182;
  8064. writeToPLC_Flag.Value = a1MES_FLAG_ICT;
  8065. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_ICT", writeToPLC_Flag);
  8066. stopwatch2.Stop();
  8067. }
  8068. catch (Exception ex)
  8069. {
  8070. string str = ex.StackTrace;
  8071. AddMessage_Station(stationNameStr, LogType.Error,
  8072. $"PLC{plcNo}_{stationNameStr} 将SN发给ICT标机出错!错误信息:" + ex.Message + "异常位置:" +
  8073. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8074. stopwatch2.Start();
  8075. // MES_Flag
  8076. //Funs[plcNo].WriteMultipleRegisters<short>(2182, (short)4); // 4代表上位机报警
  8077. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8078. writeToPLC_Flag.Name = "a1MES_FLAG_ICT";
  8079. writeToPLC_Flag.Adress = 2182;
  8080. writeToPLC_Flag.Value = (short)4;
  8081. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_ICT", writeToPLC_Flag);
  8082. stopwatch2.Stop();
  8083. }
  8084. stopwatch1.Stop();
  8085. AddMessage(LogType.Info,
  8086. stationNameStr + "_将SN发给ICT标机;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  8087. stopwatch2.ElapsedMilliseconds + "ms");
  8088. }
  8089. /// <summary>
  8090. /// [S1] Tray盘上料装备(板测)- AGV上料叫agv
  8091. /// </summary>
  8092. /// <param name="plcNo">PLC编号</param>
  8093. /// <param name="stationNameStr">工站全称</param>
  8094. private void S1AGV上料叫agv(int plcNo, string stationNameStr)
  8095. {
  8096. Stopwatch stopwatch1 = new Stopwatch();
  8097. Stopwatch stopwatch2 = new Stopwatch();
  8098. try
  8099. {
  8100. stopwatch1.Start();
  8101. // ZS 呼叫AGV
  8102. short a1AGVUpCall = 2;
  8103. stopwatch2.Start();
  8104. // a1AGVUpCall
  8105. //Funs[plcNo].WriteMultipleRegisters<short>(2307, a1AGVUpCall); // 1:plc请求上料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  8106. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8107. writeToPLC_Flag.Name = "a1AGVUpCall";
  8108. writeToPLC_Flag.Adress = 2307;
  8109. writeToPLC_Flag.Value = a1AGVUpCall;
  8110. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpCall", writeToPLC_Flag);
  8111. stopwatch2.Stop();
  8112. }
  8113. catch (Exception ex)
  8114. {
  8115. string str = ex.StackTrace;
  8116. AddMessage_Station(stationNameStr, LogType.Error,
  8117. $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" +
  8118. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8119. // a1AGVUpCall
  8120. stopwatch2.Start();
  8121. //Funs[plcNo].WriteMultipleRegisters<short>(2307, (short)4); // 4代表上位机报警
  8122. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8123. writeToPLC_Flag.Name = "a1AGVUpCall";
  8124. writeToPLC_Flag.Adress = 2307;
  8125. writeToPLC_Flag.Value = (short)4;
  8126. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpCall", writeToPLC_Flag);
  8127. stopwatch2.Stop();
  8128. }
  8129. stopwatch1.Stop();
  8130. AddMessage(LogType.Info,
  8131. stationNameStr + "_AGV上料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  8132. stopwatch2.ElapsedMilliseconds + "ms");
  8133. }
  8134. /// <summary>
  8135. /// [S1] Tray盘上料装备(板测)- AGV上料完成
  8136. /// </summary>
  8137. /// <param name="plcNo">PLC编号</param>
  8138. /// <param name="stationNameStr">工站全称</param>
  8139. private void S1AGV上料完成(int plcNo, string stationNameStr)
  8140. {
  8141. Stopwatch stopwatch1 = new Stopwatch();
  8142. Stopwatch stopwatch2 = new Stopwatch();
  8143. try
  8144. {
  8145. stopwatch1.Start();
  8146. // ZS AGV上料完成,让小车离开
  8147. short a1AGVUpEnd = 2;
  8148. stopwatch2.Start();
  8149. // a1AGVUpEnd
  8150. //Funs[plcNo].WriteMultipleRegisters<short>(2309, a1AGVUpEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  8151. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8152. writeToPLC_Flag.Name = "a1AGVUpEnd";
  8153. writeToPLC_Flag.Adress = 2309;
  8154. writeToPLC_Flag.Value = a1AGVUpEnd;
  8155. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpEnd", writeToPLC_Flag);
  8156. stopwatch2.Stop();
  8157. }
  8158. catch (Exception ex)
  8159. {
  8160. string str = ex.StackTrace;
  8161. AddMessage_Station(stationNameStr, LogType.Error,
  8162. $"PLC{plcNo}_{stationNameStr} AGV上料完成出错!错误信息:" + ex.Message + "异常位置:" +
  8163. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8164. // a1AGVUpEnd
  8165. stopwatch2.Start();
  8166. //Funs[plcNo].WriteMultipleRegisters<short>(2309, (short)4); // 4代表上位机报警
  8167. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8168. writeToPLC_Flag.Name = "a1AGVUpEnd";
  8169. writeToPLC_Flag.Adress = 2309;
  8170. writeToPLC_Flag.Value = (short)4;
  8171. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpEnd", writeToPLC_Flag);
  8172. stopwatch2.Stop();
  8173. }
  8174. stopwatch1.Stop();
  8175. AddMessage(LogType.Info,
  8176. stationNameStr + "_AGV上料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  8177. stopwatch2.ElapsedMilliseconds + "ms");
  8178. }
  8179. /// <summary>
  8180. /// [S1] Tray盘上料装备(板测)- AGV下料叫agv
  8181. /// </summary>
  8182. /// <param name="plcNo">PLC编号</param>
  8183. /// <param name="stationNameStr">工站全称</param>
  8184. private void S1AGV下料叫agv(int plcNo, string stationNameStr)
  8185. {
  8186. Stopwatch stopwatch1 = new Stopwatch();
  8187. Stopwatch stopwatch2 = new Stopwatch();
  8188. try
  8189. {
  8190. stopwatch1.Start();
  8191. // ZS 呼叫AGV
  8192. short a1AGVDownCall = 2;
  8193. stopwatch2.Start();
  8194. // a1AGVDownCall
  8195. //Funs[plcNo].WriteMultipleRegisters<short>(2320, a1AGVDownCall); // 1:plc请求下料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  8196. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8197. writeToPLC_Flag.Name = "a1AGVDownCall";
  8198. writeToPLC_Flag.Adress = 2320;
  8199. writeToPLC_Flag.Value = a1AGVDownCall;
  8200. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownCall", writeToPLC_Flag);
  8201. stopwatch2.Stop();
  8202. }
  8203. catch (Exception ex)
  8204. {
  8205. string str = ex.StackTrace;
  8206. AddMessage_Station(stationNameStr, LogType.Error,
  8207. $"PLC{plcNo}_{stationNameStr} AGV下料叫agv出错!错误信息:" + ex.Message + "异常位置:" +
  8208. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8209. // a1AGVDownCall
  8210. stopwatch2.Start();
  8211. //Funs[plcNo].WriteMultipleRegisters<short>(2320, (short)4); // 4代表上位机报警
  8212. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8213. writeToPLC_Flag.Name = "a1AGVDownCall";
  8214. writeToPLC_Flag.Adress = 2320;
  8215. writeToPLC_Flag.Value = (short)4;
  8216. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownCall", writeToPLC_Flag);
  8217. stopwatch2.Stop();
  8218. }
  8219. stopwatch1.Stop();
  8220. AddMessage(LogType.Info,
  8221. stationNameStr + "_AGV下料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  8222. stopwatch2.ElapsedMilliseconds + "ms");
  8223. }
  8224. /// <summary>
  8225. /// [S1] Tray盘上料装备(板测)- AGV下料完成
  8226. /// </summary>
  8227. /// <param name="plcNo">PLC编号</param>
  8228. /// <param name="stationNameStr">工站全称</param>
  8229. private void S1AGV下料完成(int plcNo, string stationNameStr)
  8230. {
  8231. Stopwatch stopwatch1 = new Stopwatch();
  8232. Stopwatch stopwatch2 = new Stopwatch();
  8233. try
  8234. {
  8235. stopwatch1.Start();
  8236. // ZS AGV上料完成,让小车离开
  8237. short a1AGVDownEnd = 2;
  8238. stopwatch2.Start();
  8239. // a1AGVDownEnd
  8240. //Funs[plcNo].WriteMultipleRegisters<short>(2322, a1AGVDownEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  8241. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8242. writeToPLC_Flag.Name = "a1AGVDownEnd";
  8243. writeToPLC_Flag.Adress = 2322;
  8244. writeToPLC_Flag.Value = a1AGVDownEnd;
  8245. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownEnd", writeToPLC_Flag);
  8246. stopwatch2.Stop();
  8247. }
  8248. catch (Exception ex)
  8249. {
  8250. string str = ex.StackTrace;
  8251. AddMessage_Station(stationNameStr, LogType.Error,
  8252. $"PLC{plcNo}_{stationNameStr} AGV下料完成出错!错误信息:" + ex.Message + "异常位置:" +
  8253. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8254. // a1AGVDownEnd
  8255. stopwatch2.Start();
  8256. //Funs[plcNo].WriteMultipleRegisters<short>(2322, (short)4); // 4代表上位机报警
  8257. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8258. writeToPLC_Flag.Name = "a1AGVDownEnd";
  8259. writeToPLC_Flag.Adress = 2322;
  8260. writeToPLC_Flag.Value = (short)4;
  8261. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownEnd", writeToPLC_Flag);
  8262. stopwatch2.Stop();
  8263. }
  8264. stopwatch1.Stop();
  8265. AddMessage(LogType.Info,
  8266. stationNameStr + "_AGV下料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  8267. stopwatch2.ElapsedMilliseconds + "ms");
  8268. }
  8269. #endregion [S1] Tray盘上料装备(板测)
  8270. #endregion PLC1 张超凡
  8271. #region PLC2 李晓奇
  8272. #region [S2] FCT(板测)
  8273. /// <summary>
  8274. /// S2工位的数据- 触发信号上次的值
  8275. /// </summary>
  8276. private Dictionary<string, object> s2PLCSignal_Old = new Dictionary<string, object>();
  8277. /// <summary>
  8278. /// S2工位的数据(含触发信号)
  8279. /// </summary>
  8280. private Dictionary<string, object> s2PLCData = new Dictionary<string, object>();
  8281. /// <summary>
  8282. /// S2工位的数据- 回写点位
  8283. /// </summary>
  8284. private Dictionary<string, WriteToPLC_Flag> s2PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  8285. /// <summary>
  8286. /// [S2] FCT(板测)
  8287. /// </summary>
  8288. /// <param name="plcNo">PLC编号</param>
  8289. //private void ReadStation_S2(int plcNo)
  8290. //{
  8291. // // [S1] Tray盘上料装备
  8292. // // [S2] FCT
  8293. // // [S3] 值板机
  8294. // // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  8295. // // [S5] Tray盘下料装备
  8296. // /// 上位机心跳
  8297. // /// 获取设备报警数据与状态信息
  8298. // string stationCode = "[S2]";
  8299. // string stationName = "FCT";
  8300. // string stationNameStr = stationCode + stationName;
  8301. // #region 创建字典
  8302. // // 触发信号字典 赋值
  8303. // s2PLCSignal_Old.Add("b1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  8304. // s2PLCSignal_Old.Add("b1PLC_FLAG_Unbind", 0); // PLC_FLAG 二穴载具解绑/绑定(产品换载具)
  8305. // s2PLCSignal_Old.Add("b1PLC_FLAG", 0); // PLC_FLAG 出站接口
  8306. // s2PLCSignal_Old.Add("b1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  8307. // // PLC数据字典 赋值
  8308. // s2PLCData.Add("b1PLC_FLAG_Check", 0); // 进站校验
  8309. // s2PLCData.Add("b1MES_FLAG_Check", 0);
  8310. // s2PLCData.Add("b1ProductSN_Check", 0);
  8311. // s2PLCData.Add("b1PLC_FLAG_Unbind", 0); // 二穴载具解绑/绑定(产品换载具)
  8312. // s2PLCData.Add("b1MES_FLAG_Unbind", 0);
  8313. // s2PLCData.Add("b1ProductSN_Unbind", "");
  8314. // s2PLCData.Add("b1ProductSN_Bind", "");
  8315. // s2PLCData.Add("b1Part1SN_Bind", "");
  8316. // s2PLCData.Add("b1Part2SN_Bind", "");
  8317. // s2PLCData.Add("b1PLC_FLAG", 0); // 出站接口
  8318. // s2PLCData.Add("b1MES_FLAG", 0);
  8319. // s2PLCData.Add("b1ProductSN", 0);
  8320. // s2PLCData.Add("b1Part1Result", 0);
  8321. // s2PLCData.Add("b1Part2Result", 0);
  8322. // s2PLCData.Add("b1OEEPLC_FLAG", 0); // 节拍接口
  8323. // s2PLCData.Add("b1OEEMES_FLAG", 0);
  8324. // s2PLCData.Add("b1OEEProductSN", "");
  8325. // s2PLCData.Add("b1OEEType", 0);
  8326. // #endregion 创建字典
  8327. // while (IsRun)
  8328. // {
  8329. // try
  8330. // {
  8331. // if (!GlobalContext._IsCon_Funs2)
  8332. // {
  8333. // UpdatePLCMonitor(1, plcNo, 0);
  8334. // continue;
  8335. // }
  8336. // if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  8337. // {
  8338. // Stopwatch stopwatch1 = new Stopwatch();
  8339. // Stopwatch stopwatch2 = new Stopwatch();
  8340. // stopwatch1.Start();
  8341. // stopwatch2.Start();
  8342. // #region 一次性读取所有数据
  8343. // // 一次性读取所有数据
  8344. // int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100); //
  8345. // int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 100); //
  8346. // int[] data3 = Funs[plcNo].ReadHoldingRegisters(2200, 35); //
  8347. // int[] datas = data1.Concat(data2).ToArray();
  8348. // datas = datas.Concat(data3).ToArray();
  8349. // s2PLCData["b1PLC_FLAG_Check"] = datas[2]; // 进站校验
  8350. // s2PLCData["b1MES_FLAG_Check"] = datas[3];
  8351. // int[] b1ProductSN_CheckData = datas.Skip(4).Take(20).ToArray();
  8352. // s2PLCData["b1ProductSN_Check"] = ModbusClient.ConvertRegistersToString(b1ProductSN_CheckData, 0, 40);
  8353. // s2PLCData["b1PLC_FLAG_Unbind"] = datas[76]; // 二穴载具解绑/绑定(产品换载具)
  8354. // s2PLCData["b1MES_FLAG_Unbind"] = datas[77];
  8355. // int[] b1ProductSN_UnbindData = datas.Skip(78).Take(20).ToArray();
  8356. // s2PLCData["b1ProductSN_Unbind"] = ModbusClient.ConvertRegistersToString(b1ProductSN_UnbindData, 0, 40);
  8357. // int[] b1ProductSN_BindData = datas.Skip(98).Take(20).ToArray();
  8358. // s2PLCData["b1ProductSN_Bind"] = ModbusClient.ConvertRegistersToString(b1ProductSN_BindData, 0, 40);
  8359. // int[] b1Part1SN_BindData = datas.Skip(118).Take(20).ToArray();
  8360. // s2PLCData["b1Part1SN_Bind"] = ModbusClient.ConvertRegistersToString(b1Part1SN_BindData, 0, 40);
  8361. // int[] b1Part2SN_BindData = datas.Skip(138).Take(20).ToArray();
  8362. // s2PLCData["b1Part2SN_Bind"] = ModbusClient.ConvertRegistersToString(b1Part2SN_BindData, 0, 40);
  8363. // s2PLCData["b1PLC_FLAG"] = datas[168]; // 出站接口
  8364. // s2PLCData["b1MES_FLAG"] = datas[169];
  8365. // int[] b1ProductSNData = datas.Skip(170).Take(20).ToArray();
  8366. // s2PLCData["b1ProductSN"] = ModbusClient.ConvertRegistersToString(b1ProductSNData, 0, 40);
  8367. // s2PLCData["b1Part1Result"] = datas[190];
  8368. // s2PLCData["b1Part2Result"] = datas[191];
  8369. // s2PLCData["b1OEEPLC_FLAG"] = datas[202]; // 节拍接口
  8370. // s2PLCData["b1OEEMES_FLAG"] = datas[203];
  8371. // int[] b1OEEProductSNData = datas.Skip(204).Take(20).ToArray();
  8372. // s2PLCData["b1OEEProductSN"] = ModbusClient.ConvertRegistersToString(b1OEEProductSNData, 0, 40);
  8373. // s2PLCData["b1OEEType"] = datas[224];
  8374. // #endregion 一次性读取所有数据
  8375. // stopwatch2.Stop();
  8376. // #region 回写操作,写后清空flag
  8377. // PLCWriteData(Funs[plcNo], ref s2PLCData, ref s2PLCWriteData);
  8378. // #endregion 回写操作,写后清空flag
  8379. // #region 进站校验
  8380. // try
  8381. // {
  8382. // int b1PLC_FLAG_Check = (int)s2PLCData["b1PLC_FLAG_Check"];
  8383. // int b1MES_FLAG_Check = (int)s2PLCData["b1MES_FLAG_Check"];
  8384. // int b1PLC_FLAG_CheckOld = (int)s2PLCSignal_Old["b1PLC_FLAG_Check"];
  8385. // if (b1PLC_FLAG_Check != b1PLC_FLAG_CheckOld)
  8386. // {
  8387. // if (b1PLC_FLAG_Check == 1 && b1MES_FLAG_Check == 0) // 0->1
  8388. // Task.Run(() => S2进站校验(plcNo, stationNameStr)); // MreTasks[2].Set();
  8389. // else if (b1PLC_FLAG_Check == 0 && b1MES_FLAG_Check != 0)
  8390. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)0);
  8391. // s2PLCSignal_Old["b1PLC_FLAG_Check"] = s2PLCData["b1PLC_FLAG_Check"];
  8392. // }
  8393. // }
  8394. // catch (Exception ex)
  8395. // {
  8396. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  8397. // string str = ex.StackTrace;
  8398. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8399. // }
  8400. // #endregion 进站校验
  8401. // #region 二穴载具解绑/绑定(产品换载具)
  8402. // try
  8403. // {
  8404. // int b1PLC_FLAG_Unbind = (int)s2PLCData["b1PLC_FLAG_Unbind"];
  8405. // int b1MES_FLAG_Check = (int)s2PLCData["b1MES_FLAG_Check"];
  8406. // int b1PLC_FLAG_UnbindOld = (int)s2PLCSignal_Old["b1PLC_FLAG_Unbind"];
  8407. // if (b1PLC_FLAG_Unbind != b1PLC_FLAG_UnbindOld)
  8408. // {
  8409. // if (b1PLC_FLAG_Unbind == 1 && b1MES_FLAG_Check == 0) // 0->1
  8410. // Task.Run(() => S2二穴载具解绑绑定(plcNo, stationNameStr)); // MreTasks[2].Set();
  8411. // else if (b1PLC_FLAG_Unbind == 0 && b1MES_FLAG_Check != 0)
  8412. // Funs[plcNo].WriteMultipleRegisters<short>(2077, (short)0);
  8413. // s2PLCSignal_Old["b1PLC_FLAG_Unbind"] = s2PLCData["b1PLC_FLAG_Unbind"];
  8414. // }
  8415. // }
  8416. // catch (Exception ex)
  8417. // {
  8418. // Funs[plcNo].WriteMultipleRegisters<short>(2077, (short)6); // 6代表上位机报警
  8419. // string str = ex.StackTrace;
  8420. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 二穴载具解绑/绑定出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8421. // }
  8422. // #endregion 二穴载具解绑/绑定(产品换载具)
  8423. // #region FCT-出站接口
  8424. // try
  8425. // {
  8426. // int b1PLC_FLAG = (int)s2PLCData["b1PLC_FLAG"];
  8427. // int b1MES_FLAG = (int)s2PLCData["b1MES_FLAG"];
  8428. // int b1PLC_FLAGOld = (int)s2PLCSignal_Old["b1PLC_FLAG"];
  8429. // if (b1PLC_FLAG != b1PLC_FLAGOld)
  8430. // {
  8431. // if (b1PLC_FLAG == 1 && b1MES_FLAG == 0) // 0->1
  8432. // Task.Run(() => S2出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  8433. // else if (b1PLC_FLAG == 0 && b1MES_FLAG != 0)
  8434. // Funs[plcNo].WriteMultipleRegisters<short>(2169, (short)0);
  8435. // }
  8436. // }
  8437. // catch (Exception ex)
  8438. // {
  8439. // // MES_Flag 为6上位机报错
  8440. // Funs[plcNo].WriteMultipleRegisters<short>(2169, (short)6); // 6代表上位机报警
  8441. // string str = ex.StackTrace;
  8442. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}上传出站数据出错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8443. // }
  8444. // #endregion FCT-出站接口
  8445. // #region 节拍接口
  8446. // try
  8447. // {
  8448. // int b1OEEPLC_FLAG = (int)s2PLCData["b1OEEPLC_FLAG"];
  8449. // int b1OEEMES_FLAG = (int)s2PLCData["b1OEEMES_FLAG"];
  8450. // int b1OEEPLC_FLAGOld = (int)s2PLCSignal_Old["b1OEEPLC_FLAG"];
  8451. // if (b1OEEPLC_FLAG != b1OEEPLC_FLAGOld)
  8452. // {
  8453. // if (b1OEEPLC_FLAG == 1 && b1OEEMES_FLAG == 0) // 0->1
  8454. // Task.Run(() => S2节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  8455. // else if (b1OEEPLC_FLAG == 0 && b1OEEMES_FLAG != 0)
  8456. // Funs[plcNo].WriteMultipleRegisters<short>(2203, (short)0);
  8457. // s2PLCSignal_Old["b1OEEPLC_FLAG"] = s2PLCData["b1OEEPLC_FLAG"];
  8458. // }
  8459. // }
  8460. // catch (Exception ex)
  8461. // {
  8462. // Funs[plcNo].WriteMultipleRegisters<short>(2203, (short)4); // 4代表上位机报警
  8463. // string str = ex.StackTrace;
  8464. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8465. // }
  8466. // #endregion 节拍接口
  8467. // #region 心跳
  8468. // try
  8469. // {
  8470. // short states = 0;
  8471. // Funs[plcNo].WriteMultipleRegisters<short>(2000, states);
  8472. // }
  8473. // catch (Exception ex)
  8474. // {
  8475. // string str = ex.StackTrace;
  8476. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上位机心跳写入出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8477. // }
  8478. // #endregion 心跳
  8479. // UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  8480. // stopwatch1.Stop();
  8481. // //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  8482. // OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  8483. // }
  8484. // else
  8485. // {
  8486. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  8487. // AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  8488. // Funs[plcNo].Connect();
  8489. // }
  8490. // }
  8491. // catch (Exception ex)
  8492. // {
  8493. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  8494. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  8495. // Funs[plcNo].ReConnect();
  8496. // }
  8497. // Thread.Sleep(IntervalReadPLC);
  8498. // }
  8499. //}
  8500. /// <summary>
  8501. /// [S2] FCT(板测)- 进站校验
  8502. /// </summary>
  8503. /// <param name="plcNo">PLC编号</param>
  8504. /// <param name="stationNameStr">工站全称</param>
  8505. private void S2进站校验(int plcNo, string stationNameStr)
  8506. {
  8507. Stopwatch stopwatch1 = new Stopwatch();
  8508. Stopwatch stopwatch2 = new Stopwatch();
  8509. try
  8510. {
  8511. stopwatch1.Start();
  8512. string sn = (string)s2PLCData["b1ProductSN_Check"]; // 产品SN(载具码)
  8513. sn = sn.Replace("\0", "");
  8514. #region 查询载具上的产品信息(查询物料码By载具码,并判断是不是假产品)
  8515. // 查询物料码By载具码 并判断是不是假产品
  8516. string cavityData = string.Empty;
  8517. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref cavityData);
  8518. if (string.IsNullOrEmpty(cavityData))
  8519. cavityData = "";
  8520. if (snResult != 0)
  8521. {
  8522. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  8523. writeToPLC_Flag1.Name = "b1MES_FLAG_Check";
  8524. writeToPLC_Flag1.Adress = 2003;
  8525. writeToPLC_Flag1.Value = (short)6;
  8526. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Check", writeToPLC_Flag1);
  8527. stopwatch1.Stop();
  8528. AddMessage(LogType.Info,
  8529. stationNameStr + $"_进站校验失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  8530. return;
  8531. }
  8532. #endregion 查询载具上的产品信息(查询物料码By载具码,并判断是不是假产品)
  8533. string[] cavitySNs = cavityData.Split('.');
  8534. string b1Part1SN_Check = ""; // 穴位1物料SN(上位机写入)
  8535. string b1Part2SN_Check = ""; // 穴位2物料SN(上位机写入)
  8536. short b1Part1Result_Check = 1; // 穴位1产品结果(上位机写入);1ok;2ng;3假产品
  8537. short b1Part2Result_Check = 1; // 穴位2产品结果(上位机写入);1ok;2ng;3假产品
  8538. if (cavitySNs != null && cavitySNs.Length >= 2)
  8539. {
  8540. b1Part1SN_Check = cavitySNs[0];
  8541. b1Part2SN_Check = cavitySNs[1];
  8542. b1Part1Result_Check = 2;
  8543. b1Part2Result_Check = 2;
  8544. }
  8545. if (b1Part1SN_Check == "假产品")
  8546. b1Part1Result_Check = 3;
  8547. if (b1Part2SN_Check == "假产品")
  8548. b1Part2Result_Check = 3;
  8549. // 调用MES进站
  8550. stopwatch2.Start();
  8551. // 调用MES进站 - 产品1
  8552. List<TestItem> item;
  8553. int result1 = b1Part1Result_Check;
  8554. if (result1 != 3)
  8555. {
  8556. item = new List<TestItem>();
  8557. item.Add(new TestItem()
  8558. {
  8559. Parameter_name = "载具码",
  8560. Parameter_value = sn,
  8561. });
  8562. item.Add(new TestItem()
  8563. {
  8564. Parameter_name = "载具穴号",
  8565. Parameter_value = "1",
  8566. });
  8567. result1 = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  8568. b1Part1SN_Check, item, out string errorMsg);
  8569. }
  8570. // 调用MES进站 - 产品2
  8571. int result2 = b1Part2Result_Check;
  8572. if (result2 != 3)
  8573. {
  8574. item = new List<TestItem>();
  8575. item.Add(new TestItem()
  8576. {
  8577. Parameter_name = "载具码",
  8578. Parameter_value = sn,
  8579. });
  8580. item.Add(new TestItem()
  8581. {
  8582. Parameter_name = "载具穴号",
  8583. Parameter_value = "2",
  8584. });
  8585. result2 = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  8586. b1Part2SN_Check, item, out string errorMsg);
  8587. }
  8588. stopwatch2.Stop();
  8589. b1Part1Result_Check = result1 == 1 ? (short)1 : (short)2; // 穴位1产品结果(上位机写入);1ok;2ng;3假产品
  8590. b1Part2Result_Check = result2 == 1 ? (short)1 : (short)2; // 穴位2产品结果(上位机写入);1ok;2ng;3假产品
  8591. int result = result1;
  8592. if (result == 1)
  8593. result = result2;
  8594. short b1MES_FLAG_Check = (short)result;
  8595. //Funs[plcNo].WriteMultipleRegisters<string>(2024, b1Part1SN_Check, 20);
  8596. //Funs[plcNo].WriteMultipleRegisters<string>(2044, b1Part2SN_Check, 20);
  8597. //Funs[plcNo].WriteMultipleRegisters<short>(2064, b1Part1Result_Check);
  8598. //Funs[plcNo].WriteMultipleRegisters<short>(2065, b1Part2Result_Check);
  8599. //// MES_Flag
  8600. //Funs[plcNo].WriteMultipleRegisters<short>(2003, b1MES_FLAG_Check); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  8601. WriteToPLC_Flag
  8602. writeToPLC_Flag = new WriteToPLC_Flag(); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  8603. writeToPLC_Flag.Name = "b1MES_FLAG_Check";
  8604. writeToPLC_Flag.Adress = 2003;
  8605. writeToPLC_Flag.Value = b1MES_FLAG_Check;
  8606. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  8607. {
  8608. Name = "b1Part1SN_Check",
  8609. Adress = 2024,
  8610. ValueType = PLCValueType.String,
  8611. ValueTypeStrLength = 20,
  8612. Value = b1Part1SN_Check
  8613. });
  8614. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  8615. {
  8616. Name = "b1Part2SN_Check",
  8617. Adress = 2044,
  8618. ValueType = PLCValueType.String,
  8619. ValueTypeStrLength = 20,
  8620. Value = b1Part2SN_Check
  8621. });
  8622. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  8623. {
  8624. Name = "b1Part1Result_Check",
  8625. Adress = 2064,
  8626. ValueType = PLCValueType.Short,
  8627. Value = b1Part1Result_Check
  8628. });
  8629. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  8630. {
  8631. Name = "b1Part2Result_Check",
  8632. Adress = 2065,
  8633. ValueType = PLCValueType.Short,
  8634. Value = b1Part2Result_Check
  8635. });
  8636. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Check", writeToPLC_Flag);
  8637. }
  8638. catch (Exception ex)
  8639. {
  8640. string str = ex.StackTrace;
  8641. AddMessage_Station(stationNameStr, LogType.Error,
  8642. $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" +
  8643. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8644. // MES_Flag
  8645. //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  8646. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8647. writeToPLC_Flag.Name = "b1MES_FLAG_Check";
  8648. writeToPLC_Flag.Adress = 2003;
  8649. writeToPLC_Flag.Value = (short)6;
  8650. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Check", writeToPLC_Flag);
  8651. }
  8652. stopwatch1.Stop();
  8653. AddMessage(LogType.Info,
  8654. stationNameStr + "_上料进站校验;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  8655. stopwatch2.ElapsedMilliseconds + "ms");
  8656. }
  8657. /// <summary>
  8658. /// [S2] FCT(板测)- 二穴载具解绑绑定
  8659. /// </summary>
  8660. /// <param name="plcNo">PLC编号</param>
  8661. /// <param name="stationNameStr">工站全称</param>
  8662. private void S2二穴载具解绑绑定(int plcNo, string stationNameStr)
  8663. {
  8664. Stopwatch stopwatch1 = new Stopwatch();
  8665. Stopwatch stopwatch2 = new Stopwatch();
  8666. try
  8667. {
  8668. stopwatch1.Start();
  8669. // 产品换载具
  8670. string b1ProductSN_Unbind = (string)s2PLCData["b1ProductSN_Unbind"]; // 原二穴载具SN(需要解绑的)
  8671. b1ProductSN_Unbind = b1ProductSN_Unbind.Replace("\0", "");
  8672. string b1ProductSN_Bind = (string)s2PLCData["b1ProductSN_Bind"]; // 新二穴载具SN(需要绑定的)
  8673. b1ProductSN_Bind = b1ProductSN_Bind.Replace("\0", "");
  8674. string b1Part1SN_Bind = (string)s2PLCData["b1Part1SN_Bind"]; // 穴位1物料SN(plc写入)
  8675. b1Part1SN_Bind = b1Part1SN_Bind.Replace("\0", "");
  8676. string b1Part2SN_Bind = (string)s2PLCData["b1Part2SN_Bind"]; // 穴位2物料SN(plc写入)
  8677. b1Part2SN_Bind = b1Part2SN_Bind.Replace("\0", "");
  8678. stopwatch2.Start();
  8679. #region 查询载具上的产品信息
  8680. //string cavityData = string.Empty;
  8681. //int snResult = XiaomiMES_RouteCommunication.SNQueryData(b1ProductSN_Unbind, ref cavityData);
  8682. //if (string.IsNullOrEmpty(cavityData))
  8683. // cavityData = "";
  8684. //if (snResult != 0)
  8685. //{
  8686. // WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8687. // writeToPLC_Flag.Name = "b1MES_FLAG_Unbind";
  8688. // writeToPLC_Flag.Adress = 2077;
  8689. // writeToPLC_Flag.Value = (short)6;
  8690. // SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Unbind", writeToPLC_Flag);
  8691. // stopwatch1.Stop();
  8692. // AddMessage(LogType.Info, stationNameStr + $"_二穴载具解绑绑定失败!MES边线软件_二穴载具查询返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  8693. // return;
  8694. //}
  8695. #endregion 查询载具上的产品信息
  8696. #region 解绑(边线MES系统)
  8697. int snResult = XiaomiMES_RouteCommunication.SNDeleteData(b1ProductSN_Unbind);
  8698. if (snResult != 0)
  8699. {
  8700. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  8701. writeToPLC_Flag1.Name = "b1MES_FLAG_Unbind";
  8702. writeToPLC_Flag1.Adress = 2077;
  8703. writeToPLC_Flag1.Value = (short)6;
  8704. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Unbind", writeToPLC_Flag1);
  8705. stopwatch1.Stop();
  8706. AddMessage(LogType.Info,
  8707. stationNameStr + $"_二穴载具解绑失败!MES边线软件_二穴载具[{b1ProductSN_Unbind}]解绑返回结果{snResult};总用时" +
  8708. stopwatch1.ElapsedMilliseconds + "ms");
  8709. return;
  8710. }
  8711. #endregion 解绑(边线MES系统)
  8712. #region 存储绑定数据到 边线MES系统中
  8713. string data = string.Concat(b1Part1SN_Bind, ".", b1Part2SN_Bind);
  8714. snResult = XiaomiMES_RouteCommunication.SNBindData(b1ProductSN_Bind, data);
  8715. if (snResult != 0)
  8716. {
  8717. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  8718. writeToPLC_Flag1.Name = "b1MES_FLAG_Unbind";
  8719. writeToPLC_Flag1.Adress = 2077;
  8720. writeToPLC_Flag1.Value = (short)6;
  8721. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Unbind", writeToPLC_Flag1);
  8722. stopwatch1.Stop();
  8723. AddMessage(LogType.Info,
  8724. stationNameStr + $"_二穴载具绑定失败!MES边线软件_二穴载具[{b1ProductSN_Bind}]绑定[{data}]返回结果{snResult};总用时" +
  8725. stopwatch1.ElapsedMilliseconds + "ms");
  8726. return;
  8727. }
  8728. #endregion 存储绑定数据到 边线MES系统中
  8729. stopwatch2.Stop();
  8730. short b1MES_FLAG_Unbind = 1;
  8731. // MES_Flag
  8732. //Funs[plcNo].WriteMultipleRegisters<short>(2077, b1MES_FLAG_Unbind); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  8733. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8734. writeToPLC_Flag.Name = "b1MES_FLAG_Unbind";
  8735. writeToPLC_Flag.Adress = 2077;
  8736. writeToPLC_Flag.Value = b1MES_FLAG_Unbind;
  8737. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Unbind", writeToPLC_Flag);
  8738. }
  8739. catch (Exception ex)
  8740. {
  8741. string str = ex.StackTrace;
  8742. AddMessage_Station(stationNameStr, LogType.Error,
  8743. $"PLC{plcNo}_{stationNameStr} 二穴载具解绑绑定出错!错误信息:" + ex.Message + "异常位置:" +
  8744. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8745. // MES_Flag
  8746. stopwatch2.Start();
  8747. //Funs[plcNo].WriteMultipleRegisters<short>(2077, (short)6); // 6代表上位机报警
  8748. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8749. writeToPLC_Flag.Name = "b1MES_FLAG_Unbind";
  8750. writeToPLC_Flag.Adress = 2077;
  8751. writeToPLC_Flag.Value = (short)6;
  8752. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG_Unbind", writeToPLC_Flag);
  8753. stopwatch2.Stop();
  8754. }
  8755. stopwatch1.Stop();
  8756. AddMessage(LogType.Info,
  8757. stationNameStr + "_二穴载具解绑绑定;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  8758. stopwatch2.ElapsedMilliseconds + "ms");
  8759. }
  8760. //// 上次采集到的SN
  8761. //private string sn_FCT = string.Empty;
  8762. /// <summary>
  8763. /// [S2] FCT(板测)- 出站数据
  8764. /// </summary>
  8765. private void S2出站接口(int plcNo, string stationCode, string stationName)
  8766. {
  8767. Stopwatch stopwatch1 = new Stopwatch();
  8768. Stopwatch stopwatch2 = new Stopwatch();
  8769. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  8770. string stationNameStr = stationCode + stationName;
  8771. string processItem = stationName; // 测试项目
  8772. try
  8773. {
  8774. stopwatch1.Start();
  8775. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  8776. //string batch_num = GlobalContext.BatchNumber; // 批次号
  8777. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  8778. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  8779. string b1ProductSN = (string)s2PLCData["b1ProductSN"]; // 产品SN(载具SN)
  8780. int b1Part1Result = (int)s2PLCData["b1Part1Result"]; // 产品1结果
  8781. int b1Part2Result = (int)s2PLCData["b1Part2Result"]; // 产品2结果
  8782. bool pass1 = b1Part1Result == 1;
  8783. bool pass2 = b1Part2Result == 1;
  8784. #region 根据 载具SN 查 物料SN
  8785. string cavityData = string.Empty;
  8786. int snResult = XiaomiMES_RouteCommunication.SNQueryData(b1ProductSN, ref cavityData);
  8787. if (string.IsNullOrEmpty(cavityData))
  8788. cavityData = "";
  8789. if (snResult != 0)
  8790. {
  8791. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  8792. writeToPLC_Flag1.Name = "b1MES_FLAG";
  8793. writeToPLC_Flag1.Adress = 2169;
  8794. writeToPLC_Flag1.Value = (short)4;
  8795. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG", writeToPLC_Flag1);
  8796. stopwatch1.Stop();
  8797. AddMessage(LogType.Info,
  8798. stationNameStr + $"_上传出站数据失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  8799. "ms");
  8800. return;
  8801. }
  8802. #endregion 根据 载具SN 查 物料SN
  8803. string[] cavitySNs = cavityData.Split('.');
  8804. string b1ProductSN1 = string.Empty;
  8805. string b1ProductSN2 = string.Empty;
  8806. if (cavitySNs != null && cavitySNs.Length >= 2)
  8807. {
  8808. b1ProductSN1 = cavitySNs[0];
  8809. b1ProductSN2 = cavitySNs[1];
  8810. }
  8811. stopwatch2.Start();
  8812. // 产品1
  8813. int result1 = 0;
  8814. if (b1ProductSN1 == "假产品")
  8815. result1 = 1;
  8816. else
  8817. {
  8818. List<TestItem> items1 = new List<TestItem>();
  8819. items1.Add(new TestItem()
  8820. {
  8821. Parameter_name = "载具码",
  8822. Parameter_value = b1ProductSN.ToString(),
  8823. Parameter_unit = ""
  8824. });
  8825. items1.Add(new TestItem()
  8826. {
  8827. Parameter_name = "载具穴号",
  8828. Parameter_value = "1",
  8829. Parameter_unit = ""
  8830. });
  8831. items1.Add(new TestItem()
  8832. {
  8833. Parameter_name = "产品结果",
  8834. Parameter_value = b1Part1Result == 1 ? "OK" : "NG",
  8835. Parameter_unit = ""
  8836. });
  8837. result1 = SwitctProcessData_old(stationNameStr, items1, equipmentCode, processItem
  8838. , workorder_code, mtltmrk, b1ProductSN1, pass1, b1ProductSN, "1");
  8839. }
  8840. // 产品2
  8841. int result2 = 0;
  8842. if (b1ProductSN1 == "假产品")
  8843. result2 = 1;
  8844. else
  8845. {
  8846. List<TestItem> items2 = new List<TestItem>();
  8847. items2.Add(new TestItem()
  8848. {
  8849. Parameter_name = "载具码",
  8850. Parameter_value = b1ProductSN.ToString(),
  8851. Parameter_unit = ""
  8852. });
  8853. items2.Add(new TestItem()
  8854. {
  8855. Parameter_name = "载具穴号",
  8856. Parameter_value = "2",
  8857. Parameter_unit = ""
  8858. });
  8859. items2.Add(new TestItem()
  8860. {
  8861. Parameter_name = "产品结果",
  8862. Parameter_value = b1Part2Result == 1 ? "OK" : "NG",
  8863. Parameter_unit = ""
  8864. });
  8865. result2 = SwitctProcessData_old(stationNameStr, items2, equipmentCode, processItem
  8866. , workorder_code, mtltmrk, b1ProductSN2, pass2, b1ProductSN, "2");
  8867. }
  8868. short result = 0;
  8869. List<int> results = new List<int>() { result1, result2 };
  8870. if (result1 == 1 && result2 == 1)
  8871. result = 1;
  8872. else if (results.Contains(3))
  8873. result = 3;
  8874. else if (results.Contains(2))
  8875. result = 2;
  8876. else if (results.Contains(4))
  8877. result = 4;
  8878. else
  8879. result = 4;
  8880. stopwatch2.Stop();
  8881. //Funs[plcNo].WriteMultipleRegisters<short>(2169, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  8882. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8883. writeToPLC_Flag.Name = "b1MES_FLAG";
  8884. writeToPLC_Flag.Adress = 2169;
  8885. writeToPLC_Flag.Value = result;
  8886. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG", writeToPLC_Flag);
  8887. OnMessage(LogType.Debug,
  8888. $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  8889. }
  8890. catch (Exception ex)
  8891. {
  8892. stopwatch2.Restart();
  8893. // MES_Flag 为4上位机报错
  8894. //Funs[plcNo].WriteMultipleRegisters<short>(2169, (short)4); // 4代表上位机报警
  8895. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  8896. writeToPLC_Flag.Name = "b1MES_FLAG";
  8897. writeToPLC_Flag.Adress = 2169;
  8898. writeToPLC_Flag.Value = (short)4;
  8899. SxPLCWriteData_Add(ref s2PLCWriteData, "b1MES_FLAG", writeToPLC_Flag);
  8900. stopwatch2.Stop();
  8901. string str = ex.StackTrace;
  8902. AddMessage_Station(stationNameStr, LogType.Error,
  8903. $"PLC{plcNo}_[{equipmentCode}]{processItem}出站数据报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  8904. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  8905. }
  8906. stopwatch1.Stop();
  8907. AddMessage(LogType.Info,
  8908. stationNameStr + "_出站数据;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  8909. stopwatch2.ElapsedMilliseconds + "ms");
  8910. }
  8911. #endregion [S2] FCT(板测)
  8912. #endregion PLC2 李晓奇
  8913. #region PLC3 刘永村
  8914. #region [S3] 值板机
  8915. /// <summary>
  8916. /// S3工位的数据- 触发信号上次的值
  8917. /// </summary>
  8918. private Dictionary<string, object> s3PLCSignal_Old = new Dictionary<string, object>();
  8919. /// <summary>
  8920. /// S3工位的数据(含触发信号)
  8921. /// </summary>
  8922. private Dictionary<string, object> s3PLCData = new Dictionary<string, object>();
  8923. /// <summary>
  8924. /// S3工位的数据- 回写点位
  8925. /// </summary>
  8926. private Dictionary<string, WriteToPLC_Flag> s3PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  8927. /// <summary>
  8928. /// [S3] 值板机
  8929. /// </summary>
  8930. /// <param name="plcNo">PLC编号</param>
  8931. //private void ReadStation_S3(int plcNo)
  8932. //{
  8933. // // [S1] Tray盘上料装备
  8934. // // [S2] FCT
  8935. // // [S3] 值板机
  8936. // // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  8937. // // [S5] Tray盘下料装备
  8938. // /// 上位机心跳
  8939. // /// 获取设备报警数据与状态信息
  8940. // string stationCode = "[S3]";
  8941. // string stationName = "值板机";
  8942. // string stationNameStr = stationCode + stationName;
  8943. // #region 创建字典
  8944. // // 触发信号字典 赋值
  8945. // s3PLCSignal_Old.Add("c1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  8946. // s3PLCSignal_Old.Add("c1PLC_FLAG_Unbind", 0); // PLC_FLAG 二穴载具解绑
  8947. // s3PLCSignal_Old.Add("c1PLC_FLAG_Bind", 0); // PLC_FLAG 二穴载具绑定
  8948. // s3PLCSignal_Old.Add("c1PLC_FLAG", 0); // PLC_FLAG 出站接口
  8949. // s3PLCSignal_Old.Add("c1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  8950. // // PLC数据字典 赋值
  8951. // s3PLCData.Add("c1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  8952. // s3PLCData.Add("c1MES_FLAG_Check", 0); // MES_FLAG
  8953. // s3PLCData.Add("c1ProductSN_Check", ""); // 产品SN(二穴载具SN)
  8954. // s3PLCData.Add("c1PLC_FLAG_Unbind", 0); // PLC_FLAG 二穴载具解绑
  8955. // s3PLCData.Add("c1MES_FLAG_Unbind", 0); // MES_FLAG
  8956. // //s3PLCData.Add("c1ProductSN_Check", ""); // 产品SN(二穴载具SN)
  8957. // s3PLCData.Add("c1VehicleCavity_Unbind", 0); // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  8958. // s3PLCData.Add("c1PLC_FLAG_Bind", 0); // PLC_FLAG 二穴载具绑定
  8959. // s3PLCData.Add("c1MES_FLAG_Bind", 0); // MES_FLAG
  8960. // //s3PLCData.Add("c1ProductSN_Check", ""); // 产品SN(二穴载具SN)
  8961. // s3PLCData.Add("c1CavityReverse_Bind", 0); // 是否是两个穴位交换
  8962. // s3PLCData.Add("c1VehicleCavityFr_Bind", 0); // 来源穴位号(产品取自二穴载具哪个穴位)
  8963. // s3PLCData.Add("c1VehicleCavityTo_Bind", 0); // 目标载具穴位号(产品放到二穴载具哪个穴位)
  8964. // s3PLCData.Add("c1PLC_FLAG", 0); // PLC_FLAG 出站接口
  8965. // s3PLCData.Add("c1MES_FLAG", 0); // MES_FLAG
  8966. // s3PLCData.Add("c1ProductSN", ""); // 产品SN(一穴载具SN)
  8967. // //s3PLCData.Add("c1ProductSN_Check", ""); // 二穴载具SN(产品取自哪个二穴载具)
  8968. // s3PLCData.Add("c1VehicleCavity", 0); // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  8969. // s3PLCData.Add("c1Result", 0); // 产品结果
  8970. // s3PLCData.Add("c1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  8971. // s3PLCData.Add("c1OEEMES_FLAG", 0); // MES_FLAG
  8972. // s3PLCData.Add("c1OEEProductSN", "");// 产品SN(载具SN)
  8973. // s3PLCData.Add("c1OEEType", 0); // 节拍类型(plc写入)
  8974. // #endregion 创建字典
  8975. // while (IsRun)
  8976. // {
  8977. // try
  8978. // {
  8979. // if (!GlobalContext._IsCon_Funs3)
  8980. // {
  8981. // UpdatePLCMonitor(1, plcNo, 0);
  8982. // continue;
  8983. // }
  8984. // if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  8985. // {
  8986. // Stopwatch stopwatch1 = new Stopwatch();
  8987. // Stopwatch stopwatch2 = new Stopwatch();
  8988. // stopwatch1.Start();
  8989. // stopwatch2.Start();
  8990. // #region 一次性读取所有数据
  8991. // // 一次性读取所有数据
  8992. // ModbusClientHelper modbusClientHelper = Funs[plcNo];
  8993. // int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100);
  8994. // int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 100);
  8995. // int[] data3 = Funs[plcNo].ReadHoldingRegisters(2200, 36);
  8996. // int[] datas = data1.Concat(data2).ToArray();
  8997. // datas = datas.Concat(data3).ToArray();
  8998. // s3PLCData["c1PLC_FLAG_Check"] = datas[2]; // PLC_FLAG 进站校验
  8999. // s3PLCData["c1MES_FLAG_Check"] = datas[3]; // MES_FLAG
  9000. // int[] c1ProductSN_CheckData = datas.Skip(4).Take(20).ToArray();
  9001. // s3PLCData["c1ProductSN_Check"] = ModbusClient.ConvertRegistersToString(c1ProductSN_CheckData, 0, 40); // 产品SN(二穴载具SN)
  9002. // s3PLCData["c1PLC_FLAG_Unbind"] = datas[81]; // PLC_FLAG 二穴载具解绑
  9003. // s3PLCData["c1MES_FLAG_Unbind"] = datas[82]; // MES_FLAG
  9004. // s3PLCData["c1VehicleCavity_Unbind"] = datas[103]; // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  9005. // s3PLCData["c1PLC_FLAG_Bind"] = datas[114]; // PLC_FLAG 二穴载具绑定
  9006. // s3PLCData["c1MES_FLAG_Bind"] = datas[115]; // MES_FLAG
  9007. // s3PLCData["c1CavityReverse_Bind"] = datas[136]; // 是否是两个穴位交换
  9008. // s3PLCData["c1VehicleCavityFr_Bind"] = datas[137]; // 来源穴位号(产品取自二穴载具哪个穴位)
  9009. // s3PLCData["c1VehicleCavityTo_Bind"] = datas[138]; // 目标载具穴位号(产品放到二穴载具哪个穴位)
  9010. // s3PLCData["c1PLC_FLAG"] = datas[149]; // PLC_FLAG 出站接口
  9011. // s3PLCData["c1MES_FLAG"] = datas[150]; // MES_FLAG
  9012. // int[] c1ProductSNData = datas.Skip(151).Take(20).ToArray();
  9013. // s3PLCData["c1ProductSN"] = ModbusClient.ConvertRegistersToString(c1ProductSNData, 0, 40); // 产品SN(一穴载具SN)
  9014. // s3PLCData["c1VehicleCavity"] = datas[191]; // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  9015. // s3PLCData["c1Result"] = datas[192]; // 产品结果
  9016. // s3PLCData["c1OEEPLC_FLAG"] = datas[203]; // PLC_FLAG 节拍接口
  9017. // s3PLCData["c1OEEMES_FLAG"] = datas[204]; // MES_FLAG
  9018. // int[] c1OEEProductSNData = datas.Skip(205).Take(20).ToArray();
  9019. // s3PLCData["c1OEEProductSN"] = ModbusClient.ConvertRegistersToString(c1OEEProductSNData, 0, 40); // 产品SN(载具SN)
  9020. // s3PLCData["c1OEEType"] = datas[225]; // 节拍类型(plc写入)
  9021. // #endregion 一次性读取所有数据
  9022. // stopwatch2.Stop();
  9023. // #region 回写操作,写后清空flag
  9024. // PLCWriteData(Funs[plcNo], ref s3PLCData, ref s3PLCWriteData);
  9025. // #endregion 回写操作,写后清空flag
  9026. // #region S3进站校验
  9027. // try
  9028. // {
  9029. // int c1PLC_FLAG_Check = (int)s3PLCData["c1PLC_FLAG_Check"];
  9030. // int c1MES_FLAG_Check = (int)s3PLCData["c1MES_FLAG_Check"];
  9031. // int c1PLC_FLAG_CheckOld = (int)s3PLCSignal_Old["c1PLC_FLAG_Check"];
  9032. // if (c1PLC_FLAG_Check != c1PLC_FLAG_CheckOld)
  9033. // {
  9034. // if (c1PLC_FLAG_Check == 1 && c1MES_FLAG_Check == 0) // 0->1
  9035. // Task.Run(() => S3进站校验(plcNo, stationNameStr)); // MreTasks[2].Set();
  9036. // else if (c1PLC_FLAG_Check == 0 && c1MES_FLAG_Check != 0)
  9037. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)0);
  9038. // s3PLCSignal_Old["c1PLC_FLAG_Check"] = s3PLCData["c1PLC_FLAG_Check"];
  9039. // }
  9040. // }
  9041. // catch (Exception ex)
  9042. // {
  9043. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  9044. // string str = ex.StackTrace;
  9045. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9046. // }
  9047. // #endregion S3进站校验
  9048. // #region S3二穴载具解绑
  9049. // try
  9050. // {
  9051. // int c1PLC_FLAG_Unbind = (int)s3PLCData["c1PLC_FLAG_Unbind"];
  9052. // int c1MES_FLAG_Bind = (int)s3PLCData["c1MES_FLAG_Unbind"];
  9053. // int c1PLC_FLAG_UnbindOld = (int)s3PLCSignal_Old["c1PLC_FLAG_Unbind"];
  9054. // if (c1PLC_FLAG_Unbind != c1PLC_FLAG_UnbindOld)
  9055. // {
  9056. // if (c1PLC_FLAG_Unbind == 1 && c1MES_FLAG_Bind == 0) // 0->1
  9057. // Task.Run(() => S3二穴载具解绑(plcNo, stationNameStr)); // MreTasks[2].Set();
  9058. // else if (c1PLC_FLAG_Unbind == 0 && c1MES_FLAG_Bind != 0)
  9059. // Funs[plcNo].WriteMultipleRegisters<short>(2082, (short)0);
  9060. // s3PLCSignal_Old["c1PLC_FLAG_Unbind"] = s3PLCData["c1PLC_FLAG_Unbind"];
  9061. // }
  9062. // }
  9063. // catch (Exception ex)
  9064. // {
  9065. // Funs[plcNo].WriteMultipleRegisters<short>(2083, (short)6); // 6代表上位机报警
  9066. // string str = ex.StackTrace;
  9067. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 二穴载具解绑/绑定出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9068. // }
  9069. // #endregion S3二穴载具解绑
  9070. // #region S3二穴载具绑定
  9071. // try
  9072. // {
  9073. // int c1PLC_FLAG_Bind = (int)s3PLCData["c1PLC_FLAG_Bind"];
  9074. // int c1MES_FLAG_Bind = (int)s3PLCData["c1MES_FLAG_Bind"];
  9075. // int c1PLC_FLAG_BindOld = (int)s3PLCSignal_Old["c1PLC_FLAG_Bind"];
  9076. // if (c1PLC_FLAG_Bind != c1PLC_FLAG_BindOld)
  9077. // {
  9078. // if (c1PLC_FLAG_Bind == 1 && c1MES_FLAG_Bind == 0) // 0->1
  9079. // Task.Run(() => S3二穴载具绑定(plcNo, stationNameStr)); // MreTasks[2].Set();
  9080. // else if (c1PLC_FLAG_Bind == 0 && c1MES_FLAG_Bind != 0)
  9081. // Funs[plcNo].WriteMultipleRegisters<short>(2115, (short)0);
  9082. // s3PLCSignal_Old["c1PLC_FLAG_Bind"] = s3PLCData["c1PLC_FLAG_Bind"];
  9083. // }
  9084. // }
  9085. // catch (Exception ex)
  9086. // {
  9087. // Funs[plcNo].WriteMultipleRegisters<short>(2115, (short)6); // 6代表上位机报警
  9088. // string str = ex.StackTrace;
  9089. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 二穴载具绑定出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9090. // }
  9091. // #endregion S3二穴载具绑定
  9092. // #region S3出站接口(+一穴载具绑定)
  9093. // try
  9094. // {
  9095. // int c1PLC_FLAG = (int)s3PLCData["c1PLC_FLAG"];
  9096. // int c1MES_FLAG = (int)s3PLCData["c1MES_FLAG"];
  9097. // int c1PLC_FLAGOld = (int)s3PLCSignal_Old["c1PLC_FLAG"];
  9098. // if (c1PLC_FLAG != c1PLC_FLAGOld)
  9099. // {
  9100. // if (c1PLC_FLAG == 1 && c1MES_FLAG == 0) // 0->1
  9101. // Task.Run(() => S3出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  9102. // else if (c1PLC_FLAG == 0 && c1MES_FLAG != 0)
  9103. // Funs[plcNo].WriteMultipleRegisters<short>(2150, (short)0);
  9104. // s3PLCSignal_Old["c1PLC_FLAG"] = s3PLCData["c1PLC_FLAG"];
  9105. // }
  9106. // }
  9107. // catch (Exception ex)
  9108. // {
  9109. // Funs[plcNo].WriteMultipleRegisters<short>(2150, (short)6); // 6代表上位机报警
  9110. // string str = ex.StackTrace;
  9111. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9112. // }
  9113. // #endregion S3出站接口(+一穴载具绑定)
  9114. // #region S3节拍接口
  9115. // try
  9116. // {
  9117. // int c1OEEPLC_FLAG = (int)s3PLCData["c1OEEPLC_FLAG"];
  9118. // int c1OEEMES_FLAG = (int)s3PLCData["c1OEEMES_FLAG"];
  9119. // int c1OEEPLC_FLAGOld = (int)s3PLCSignal_Old["c1OEEPLC_FLAG"];
  9120. // if (c1OEEPLC_FLAG != c1OEEPLC_FLAGOld)
  9121. // {
  9122. // if (c1OEEPLC_FLAG == 1 && c1OEEMES_FLAG == 0) // 0->1
  9123. // Task.Run(() => S3节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  9124. // else if (c1OEEPLC_FLAG == 0 && c1OEEMES_FLAG != 0)
  9125. // Funs[plcNo].WriteMultipleRegisters<short>(2204, (short)0);
  9126. // s3PLCSignal_Old["c1OEEPLC_FLAG"] = s3PLCData["c1OEEPLC_FLAG"];
  9127. // }
  9128. // }
  9129. // catch (Exception ex)
  9130. // {
  9131. // Funs[plcNo].WriteMultipleRegisters<short>(2204, (short)4); // 4代表上位机报警
  9132. // string str = ex.StackTrace;
  9133. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9134. // }
  9135. // #endregion S3节拍接口
  9136. // #region 心跳
  9137. // try
  9138. // {
  9139. // short states = 0;
  9140. // Funs[plcNo].WriteMultipleRegisters<short>(2000, states);
  9141. // }
  9142. // catch (Exception ex)
  9143. // {
  9144. // string str = ex.StackTrace;
  9145. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上位机心跳写入出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9146. // }
  9147. // #endregion 心跳
  9148. // UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  9149. // stopwatch1.Stop();
  9150. // //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  9151. // OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  9152. // }
  9153. // else
  9154. // {
  9155. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  9156. // AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  9157. // Funs[plcNo].Connect();
  9158. // }
  9159. // }
  9160. // catch (Exception ex)
  9161. // {
  9162. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  9163. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  9164. // Funs[plcNo].ReConnect();
  9165. // }
  9166. // Thread.Sleep(IntervalReadPLC);
  9167. // }
  9168. //}
  9169. /// <summary>
  9170. /// [S3] 值板机- 进站校验
  9171. /// </summary>
  9172. /// <param name="plcNo">PLC编号</param>
  9173. /// <param name="stationNameStr">工站全称</param>
  9174. private void S3进站校验(int plcNo, string stationNameStr)
  9175. {
  9176. Stopwatch stopwatch1 = new Stopwatch();
  9177. Stopwatch stopwatch2 = new Stopwatch();
  9178. try
  9179. {
  9180. stopwatch1.Start();
  9181. string sn = (string)s3PLCData["c1ProductSN_Check"]; // 产品SN(载具码)
  9182. sn = sn.Replace("\0", "");
  9183. #region 查询载具上的产品信息
  9184. string cavityData = string.Empty;
  9185. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref cavityData);
  9186. if (string.IsNullOrEmpty(cavityData))
  9187. cavityData = "";
  9188. if (snResult != 0)
  9189. {
  9190. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  9191. writeToPLC_Flag1.Name = "c1MES_FLAG_Check";
  9192. writeToPLC_Flag1.Adress = 2003;
  9193. writeToPLC_Flag1.Value = (short)6;
  9194. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Check", writeToPLC_Flag1);
  9195. stopwatch1.Stop();
  9196. AddMessage(LogType.Info,
  9197. stationNameStr + $"_进站校验失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  9198. return;
  9199. }
  9200. #endregion 查询载具上的产品信息
  9201. string[] cavitySNs = cavityData.Split('.');
  9202. string part1Str = ""; // 产品1的SN码
  9203. string part2Str = ""; // 产品2的SN码
  9204. short c1Part1Result_Check = 1; // 穴位1产品结果(上位机写入);1ok;2ng;3假产品
  9205. short c1Part2Result_Check = 1; // 穴位2产品结果(上位机写入);1ok;2ng;3假产品
  9206. if (cavitySNs != null && cavitySNs.Length >= 2)
  9207. {
  9208. part1Str = cavitySNs[0];
  9209. part2Str = cavitySNs[1];
  9210. c1Part1Result_Check = 2;
  9211. c1Part2Result_Check = 2;
  9212. }
  9213. if (part1Str == "假产品")
  9214. c1Part1Result_Check = 3;
  9215. if (part2Str == "假产品")
  9216. c1Part2Result_Check = 3;
  9217. // 调用MES进站
  9218. stopwatch2.Start();
  9219. // 调用MES进站 - 产品1
  9220. List<TestItem> item;
  9221. int result1 = c1Part1Result_Check;
  9222. if (result1 != 3)
  9223. {
  9224. item = new List<TestItem>();
  9225. item.Add(new TestItem()
  9226. {
  9227. Parameter_name = "载具码",
  9228. Parameter_value = sn,
  9229. });
  9230. item.Add(new TestItem()
  9231. {
  9232. Parameter_name = "载具穴号",
  9233. Parameter_value = "1",
  9234. });
  9235. result1 = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  9236. part1Str, item, out string errorMsg);
  9237. }
  9238. // 调用MES进站 - 产品2
  9239. int result2 = c1Part2Result_Check;
  9240. if (result2 != 3)
  9241. {
  9242. item = new List<TestItem>();
  9243. item.Add(new TestItem()
  9244. {
  9245. Parameter_name = "载具码",
  9246. Parameter_value = sn,
  9247. });
  9248. item.Add(new TestItem()
  9249. {
  9250. Parameter_name = "载具穴号",
  9251. Parameter_value = "2",
  9252. });
  9253. result2 = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  9254. part2Str, item, out string errorMsg);
  9255. }
  9256. stopwatch2.Stop();
  9257. if (result1 == 2)
  9258. c1Part1Result_Check = 2;
  9259. if (result2 == 2)
  9260. c1Part2Result_Check = 2;
  9261. int result = result1;
  9262. if (result == 1)
  9263. result = result2;
  9264. short c1Part1Num_Check = 0; // 穴位1产品返修次数(上位机写入)
  9265. short c1Part2Num_Check = 0; // 穴位2产品返修次数(上位机写入)
  9266. short c1MES_FLAG_Check = (short)result;
  9267. //Funs[plcNo].WriteMultipleRegisters<short>(2024, c1Part1Result_Check);
  9268. //Funs[plcNo].WriteMultipleRegisters<short>(2025, c1Part2Result_Check);
  9269. //Funs[plcNo].WriteMultipleRegisters<short>(2026, c1Part1Num_Check);
  9270. //Funs[plcNo].WriteMultipleRegisters<short>(2027, c1Part2Num_Check);
  9271. //// MES_Flag
  9272. //Funs[plcNo].WriteMultipleRegisters<short>(2003, c1MES_FLAG_Check); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  9273. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9274. writeToPLC_Flag.Name = "c1MES_FLAG_Check";
  9275. writeToPLC_Flag.Adress = 2003;
  9276. writeToPLC_Flag.Value = c1MES_FLAG_Check;
  9277. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  9278. {
  9279. Name = "c1Part1Result_Check",
  9280. Adress = 2024,
  9281. ValueType = PLCValueType.Short,
  9282. Value = c1Part1Result_Check
  9283. });
  9284. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  9285. {
  9286. Name = "c1Part2Result_Check",
  9287. Adress = 2025,
  9288. ValueType = PLCValueType.Short,
  9289. Value = c1Part2Result_Check
  9290. });
  9291. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  9292. {
  9293. Name = "c1Part1Num_Check",
  9294. Adress = 2026,
  9295. ValueType = PLCValueType.Short,
  9296. Value = c1Part1Num_Check
  9297. });
  9298. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  9299. {
  9300. Name = "c1Part2Num_Check",
  9301. Adress = 2027,
  9302. ValueType = PLCValueType.Short,
  9303. Value = c1Part2Num_Check
  9304. });
  9305. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Check", writeToPLC_Flag);
  9306. }
  9307. catch (Exception ex)
  9308. {
  9309. string str = ex.StackTrace;
  9310. AddMessage_Station(stationNameStr, LogType.Error,
  9311. $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" +
  9312. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9313. // MES_Flag
  9314. //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  9315. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9316. writeToPLC_Flag.Name = "c1MES_FLAG_Check";
  9317. writeToPLC_Flag.Adress = 2003;
  9318. writeToPLC_Flag.Value = (short)6;
  9319. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Check", writeToPLC_Flag);
  9320. }
  9321. stopwatch1.Stop();
  9322. AddMessage(LogType.Info,
  9323. stationNameStr + "_进站校验;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  9324. stopwatch2.ElapsedMilliseconds + "ms");
  9325. }
  9326. /// <summary>
  9327. /// [S3] 值板机 - 二穴载具解绑
  9328. /// </summary>
  9329. /// <param name="plcNo">PLC编号</param>
  9330. /// <param name="stationNameStr">工站全称</param>
  9331. private void S3二穴载具解绑(int plcNo, string stationNameStr)
  9332. {
  9333. Stopwatch stopwatch1 = new Stopwatch();
  9334. Stopwatch stopwatch2 = new Stopwatch();
  9335. try
  9336. {
  9337. stopwatch1.Start();
  9338. string c1ProductSN_Check = (string)s3PLCData["c1ProductSN_Check"]; // 产品SN(二穴载具SN)
  9339. c1ProductSN_Check = c1ProductSN_Check.Replace("\0", "");
  9340. int c1VehicleCavity_Unbind = (int)s3PLCData["c1VehicleCavity_Unbind"]; // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  9341. // 解绑
  9342. #region 查询载具上的产品信息
  9343. string cavityData = string.Empty;
  9344. int snResult = XiaomiMES_RouteCommunication.SNQueryData(c1ProductSN_Check, ref cavityData);
  9345. if (string.IsNullOrEmpty(cavityData))
  9346. cavityData = "";
  9347. if (snResult != 0)
  9348. {
  9349. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  9350. writeToPLC_Flag1.Name = "c1MES_FLAG_Unbind";
  9351. writeToPLC_Flag1.Adress = 2082;
  9352. writeToPLC_Flag1.Value = (short)6;
  9353. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Unbind", writeToPLC_Flag1);
  9354. stopwatch1.Stop();
  9355. AddMessage(LogType.Info,
  9356. stationNameStr + $"_二穴载具解绑失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  9357. "ms");
  9358. return;
  9359. }
  9360. #endregion 查询载具上的产品信息
  9361. string[] cavitySNs = cavityData.Split('.'); // 产品信息【产品1.产品2】
  9362. #region 解绑
  9363. if (cavitySNs.All(a => string.IsNullOrEmpty(a)))
  9364. {
  9365. // 删除
  9366. int res1 = XiaomiMES_RouteCommunication.SNDeleteData(c1ProductSN_Check);
  9367. OnMessage(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-二穴载具解绑SN{c1ProductSN_Check}---{res1}");
  9368. }
  9369. else
  9370. {
  9371. string data_new = string.Join(".", cavitySNs);
  9372. // 删除再插入
  9373. int res2 = XiaomiMES_RouteCommunication.SNDeleteData(c1ProductSN_Check);
  9374. int res3 = XiaomiMES_RouteCommunication.SNBindData(c1ProductSN_Check, data_new);
  9375. OnMessage(LogType.Debug,
  9376. $"PLC{plcNo}_[{stationNameStr}]-二穴载具解绑SN{c1ProductSN_Check}---{res2},{res3}");
  9377. }
  9378. #endregion 解绑
  9379. short c1MES_FLAG_Unbind = 1;
  9380. stopwatch2.Start();
  9381. // MES_Flag
  9382. //Funs[plcNo].WriteMultipleRegisters<short>(2082, c1MES_FLAG_Unbind); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  9383. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9384. writeToPLC_Flag.Name = "c1MES_FLAG_Unbind";
  9385. writeToPLC_Flag.Adress = 2082;
  9386. writeToPLC_Flag.Value = c1MES_FLAG_Unbind;
  9387. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Unbind", writeToPLC_Flag);
  9388. stopwatch2.Stop();
  9389. }
  9390. catch (Exception ex)
  9391. {
  9392. string str = ex.StackTrace;
  9393. AddMessage_Station(stationNameStr, LogType.Error,
  9394. $"PLC{plcNo}_{stationNameStr} 二穴载具解绑出错!错误信息:" + ex.Message + "异常位置:" +
  9395. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9396. // MES_Flag
  9397. stopwatch2.Start();
  9398. //Funs[plcNo].WriteMultipleRegisters<short>(2082, (short)6); // 6代表上位机报警
  9399. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9400. writeToPLC_Flag.Name = "c1MES_FLAG_Unbind";
  9401. writeToPLC_Flag.Adress = 2082;
  9402. writeToPLC_Flag.Value = (short)6;
  9403. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Unbind", writeToPLC_Flag);
  9404. stopwatch2.Stop();
  9405. }
  9406. stopwatch1.Stop();
  9407. AddMessage(LogType.Info,
  9408. stationNameStr + "_二穴载具解绑;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  9409. stopwatch2.ElapsedMilliseconds + "ms");
  9410. }
  9411. /// <summary>
  9412. /// [S3] 值板机 - 二穴载具绑定
  9413. /// </summary>
  9414. /// <param name="plcNo">PLC编号</param>
  9415. /// <param name="stationNameStr">工站全称</param>
  9416. private void S3二穴载具绑定(int plcNo, string stationNameStr)
  9417. {
  9418. Stopwatch stopwatch1 = new Stopwatch();
  9419. Stopwatch stopwatch2 = new Stopwatch();
  9420. try
  9421. {
  9422. stopwatch1.Start();
  9423. string c1ProductSN_Check = (string)s3PLCData["c1ProductSN_Check"]; // 产品SN(二穴载具SN)
  9424. c1ProductSN_Check = c1ProductSN_Check.Replace("\0", "");
  9425. int c1CavityReverse_Bind = (int)s3PLCData["c1CavityReverse_Bind"]; // 是否是两个穴位交换
  9426. int c1VehicleCavityFr_Bind = (int)s3PLCData["c1VehicleCavityFr_Bind"]; // 来源穴位号(产品取自二穴载具哪个穴位)
  9427. int c1VehicleCavityTo_Bind = (int)s3PLCData["c1VehicleCavityTo_Bind"]; // 目标载具穴位号(产品放到二穴载具哪个穴位)
  9428. stopwatch2.Start();
  9429. #region 查询载具上的产品信息
  9430. string cavityData = string.Empty;
  9431. int snResult = XiaomiMES_RouteCommunication.SNQueryData(c1ProductSN_Check, ref cavityData);
  9432. if (string.IsNullOrEmpty(cavityData))
  9433. cavityData = "";
  9434. if (snResult != 0)
  9435. {
  9436. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  9437. writeToPLC_Flag1.Name = "c1MES_FLAG_Bind";
  9438. writeToPLC_Flag1.Adress = 2115;
  9439. writeToPLC_Flag1.Value = (short)6;
  9440. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Bind", writeToPLC_Flag1);
  9441. stopwatch1.Stop();
  9442. AddMessage(LogType.Info,
  9443. stationNameStr + $"_二穴载具绑定失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  9444. "ms");
  9445. return;
  9446. }
  9447. #endregion 查询载具上的产品信息
  9448. // 产品换载具
  9449. string[] cavitySNs = cavityData.Split('.'); // 产品信息【产品1.产品2】
  9450. string partSn1 = "";
  9451. string partSn2 = "";
  9452. if (cavitySNs != null && cavitySNs.Length >= 2)
  9453. {
  9454. partSn1 = cavitySNs[0];
  9455. partSn2 = cavitySNs[1];
  9456. }
  9457. string data_new = string.Empty;
  9458. // 是否是两个穴位交换
  9459. if (c1CavityReverse_Bind == 1)
  9460. {
  9461. // 交换
  9462. data_new = string.Concat(partSn2, ".", partSn1);
  9463. }
  9464. else
  9465. {
  9466. // 不交换
  9467. string sn = string.Copy(cavitySNs[c1VehicleCavityFr_Bind]);
  9468. cavitySNs[c1VehicleCavityTo_Bind] = sn;
  9469. cavitySNs[c1VehicleCavityFr_Bind] = "";
  9470. data_new = string.Join(".", cavitySNs);
  9471. }
  9472. // 删除再插入
  9473. int res1 = XiaomiMES_RouteCommunication.SNDeleteData(c1ProductSN_Check);
  9474. int res2 = XiaomiMES_RouteCommunication.SNBindData(c1ProductSN_Check, data_new);
  9475. OnMessage(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-_二穴载具绑定SN{c1ProductSN_Check}---{res1},{res2}");
  9476. stopwatch2.Stop();
  9477. short c1MES_FLAG_Bind = 1;
  9478. // MES_Flag
  9479. //Funs[plcNo].WriteMultipleRegisters<short>(2115, c1MES_FLAG_Bind); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  9480. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9481. writeToPLC_Flag.Name = "c1MES_FLAG_Bind";
  9482. writeToPLC_Flag.Adress = 2115;
  9483. writeToPLC_Flag.Value = c1MES_FLAG_Bind;
  9484. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Bind", writeToPLC_Flag);
  9485. }
  9486. catch (Exception ex)
  9487. {
  9488. string str = ex.StackTrace;
  9489. AddMessage_Station(stationNameStr, LogType.Error,
  9490. $"PLC{plcNo}_{stationNameStr} 二穴载具绑定出错!错误信息:" + ex.Message + "异常位置:" +
  9491. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9492. // MES_Flag
  9493. stopwatch2.Start();
  9494. //Funs[plcNo].WriteMultipleRegisters<short>(2115, (short)6); // 6代表上位机报警
  9495. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9496. writeToPLC_Flag.Name = "c1MES_FLAG_Bind";
  9497. writeToPLC_Flag.Adress = 2115;
  9498. writeToPLC_Flag.Value = (short)6;
  9499. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG_Bind", writeToPLC_Flag);
  9500. stopwatch2.Stop();
  9501. }
  9502. stopwatch1.Stop();
  9503. AddMessage(LogType.Info,
  9504. stationNameStr + "_二穴载具绑定;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  9505. stopwatch2.ElapsedMilliseconds + "ms");
  9506. }
  9507. //// 上次采集到的SN
  9508. //private string sn_值板机 = string.Empty;
  9509. /// <summary>
  9510. /// [S3] 值板机 - 出站接口
  9511. /// </summary>
  9512. /// <param name="plcNo">PLC编号</param>
  9513. private void S3出站接口(int plcNo, string stationCode, string stationName)
  9514. {
  9515. Stopwatch stopwatch1 = new Stopwatch();
  9516. Stopwatch stopwatch2 = new Stopwatch();
  9517. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  9518. string stationNameStr = stationCode + stationName;
  9519. string processItem = stationName; // 测试项目
  9520. try
  9521. {
  9522. stopwatch1.Start();
  9523. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  9524. //string batch_num = GlobalContext.BatchNumber; // 批次号
  9525. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  9526. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  9527. string sn = (string)s3PLCData["c1ProductSN"]; // 产品SN(一穴载具SN)
  9528. sn = sn.Replace("\0", "");
  9529. string c1ProductSN_Check = (string)s3PLCData["c1ProductSN_Check"]; // 二穴载具SN(产品取自哪个二穴载具)
  9530. c1ProductSN_Check = c1ProductSN_Check.Replace("\0", "");
  9531. int c1VehicleCavity = (int)s3PLCData["c1VehicleCavity"]; // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  9532. int c1Result = (int)s3PLCData["c1Result"]; // 产品结果
  9533. bool pass = c1Result == 1;
  9534. // 查sn
  9535. #region 查询载具上的产品信息
  9536. string cavityData = string.Empty;
  9537. int snResult = XiaomiMES_RouteCommunication.SNQueryData(c1ProductSN_Check, ref cavityData);
  9538. if (string.IsNullOrEmpty(cavityData))
  9539. cavityData = "";
  9540. if (snResult != 0)
  9541. {
  9542. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  9543. writeToPLC_Flag1.Name = "c1MES_FLAG";
  9544. writeToPLC_Flag1.Adress = 2150;
  9545. writeToPLC_Flag1.Value = (short)4;
  9546. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG", writeToPLC_Flag1);
  9547. stopwatch1.Stop();
  9548. AddMessage(LogType.Info,
  9549. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  9550. return;
  9551. }
  9552. #endregion 查询载具上的产品信息
  9553. string[] cavitySNs = cavityData.Split('.');
  9554. string productSN = "";
  9555. if (cavitySNs != null && cavitySNs.Length >= 2)
  9556. {
  9557. productSN = cavitySNs[c1VehicleCavity];
  9558. cavitySNs[c1VehicleCavity] = "";
  9559. }
  9560. stopwatch2.Start();
  9561. List<TestItem> items = new List<TestItem>();
  9562. items.Add(new TestItem()
  9563. {
  9564. Parameter_name = "二穴载具码",
  9565. Parameter_value = c1ProductSN_Check,
  9566. Parameter_unit = ""
  9567. });
  9568. items.Add(new TestItem()
  9569. {
  9570. Parameter_name = "二穴载具穴号",
  9571. Parameter_value = c1VehicleCavity.ToString(),
  9572. Parameter_unit = ""
  9573. });
  9574. items.Add(new TestItem()
  9575. {
  9576. Parameter_name = "一穴载具码",
  9577. Parameter_value = sn,
  9578. Parameter_unit = ""
  9579. });
  9580. items.Add(new TestItem()
  9581. {
  9582. Parameter_name = "一穴载具穴号",
  9583. Parameter_value = "1",
  9584. Parameter_unit = ""
  9585. });
  9586. items.Add(new TestItem()
  9587. {
  9588. Parameter_name = "产品结果",
  9589. Parameter_value = c1Result == 1 ? "OK" : "NG",
  9590. Parameter_unit = ""
  9591. });
  9592. int result1 = SwitctProcessData_old(stationNameStr, items, equipmentCode, processItem
  9593. , workorder_code, mtltmrk, productSN, pass, sn, "1");
  9594. short result = (short)result1;
  9595. stopwatch2.Stop();
  9596. #region 存储绑定数据到 边线MES系统中
  9597. if (result == 1)
  9598. {
  9599. string data = string.Concat(productSN);
  9600. int resultMesR = XiaomiMES_RouteCommunication.SNBindData(sn, data);
  9601. if (resultMesR != 0)
  9602. {
  9603. result = 4;
  9604. AddMessage_Station(stationNameStr, LogType.Error,
  9605. $"PLC{plcNo}_[{equipmentCode}]{processItem}过站失败!MES边线程序返回:{resultMesR}");
  9606. }
  9607. }
  9608. #endregion 存储绑定数据到 边线MES系统中
  9609. #region 产品从 来源载具(二穴载具)中删除
  9610. if (cavitySNs.All(a => string.IsNullOrEmpty(a)))
  9611. {
  9612. // 删除
  9613. int res1 = XiaomiMES_RouteCommunication.SNDeleteData(c1ProductSN_Check);
  9614. OnMessage(LogType.Debug,
  9615. $"PLC{plcNo}_[{equipmentCode}]{processItem}-出站解绑SN{c1ProductSN_Check}---{res1}");
  9616. }
  9617. else
  9618. {
  9619. string data_new = string.Join(".", cavitySNs);
  9620. // 删除再插入
  9621. int res2 = XiaomiMES_RouteCommunication.SNDeleteData(c1ProductSN_Check);
  9622. int res3 = XiaomiMES_RouteCommunication.SNBindData(c1ProductSN_Check, data_new);
  9623. OnMessage(LogType.Debug,
  9624. $"PLC{plcNo}_[{equipmentCode}]{processItem}-出站解绑SN{c1ProductSN_Check}---{res2},{res3}");
  9625. }
  9626. #endregion 产品从 来源载具(二穴载具)中删除
  9627. // MES_Flag 为MES报错
  9628. // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  9629. //Funs[plcNo].WriteMultipleRegisters<short>(2150, result); // 4代表上位机报警
  9630. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9631. writeToPLC_Flag.Name = "c1MES_FLAG";
  9632. writeToPLC_Flag.Adress = 2150;
  9633. writeToPLC_Flag.Value = result;
  9634. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG", writeToPLC_Flag);
  9635. OnMessage(LogType.Debug,
  9636. $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  9637. }
  9638. catch (Exception ex)
  9639. {
  9640. stopwatch2.Restart();
  9641. // MES_Flag 为4上位机报错
  9642. //Funs[plcNo].WriteMultipleRegisters<short>(2150, (short)4); // 4代表上位机报警
  9643. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  9644. writeToPLC_Flag.Name = "c1MES_FLAG";
  9645. writeToPLC_Flag.Adress = 2150;
  9646. writeToPLC_Flag.Value = (short)4;
  9647. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG", writeToPLC_Flag);
  9648. stopwatch2.Stop();
  9649. string str = ex.StackTrace;
  9650. AddMessage_Station(stationNameStr, LogType.Error,
  9651. $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  9652. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9653. }
  9654. stopwatch1.Stop();
  9655. AddMessage(LogType.Info,
  9656. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  9657. stopwatch2.ElapsedMilliseconds + "ms");
  9658. }
  9659. #endregion [S3] 值板机
  9660. #endregion PLC3 刘永村
  9661. #region PLC4 刘果段
  9662. #region [S4] 取放桁架
  9663. /// <summary>
  9664. /// S4工位的数据- 触发信号上次的值
  9665. /// </summary>
  9666. private Dictionary<string, object> s4PLCSignal_Old = new Dictionary<string, object>();
  9667. /// <summary>
  9668. /// S4工位的数据(含触发信号)
  9669. /// </summary>
  9670. private Dictionary<string, object> s4PLCData = new Dictionary<string, object>();
  9671. /// <summary>
  9672. /// S4工位的数据- 回写点位
  9673. /// </summary>
  9674. private Dictionary<string, WriteToPLC_Flag> s4PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  9675. /// <summary>
  9676. /// [S4] 取放桁架
  9677. /// </summary>
  9678. /// <param name="plcNo">PLC编号</param>
  9679. //private void ReadStation_S4(int plcNo)
  9680. //{
  9681. // // [S1] Tray盘上料装备
  9682. // // [S2] FCT
  9683. // // [S3] 值板机
  9684. // // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  9685. // // [S5] Tray盘下料装备
  9686. // /// 上位机心跳
  9687. // /// 获取设备报警数据与状态信息
  9688. // string stationCode = "[S4_1]";
  9689. // string stationName = "载具下线装备";
  9690. // string stationNameStr = stationCode + stationName;
  9691. // string stationCode2 = "[S4_2]";
  9692. // string stationName2 = "桁架";
  9693. // string stationNameStr2 = stationCode2 + stationName2;
  9694. // string stationCode3 = "[S4_3]";
  9695. // string stationName3 = "提升机1";
  9696. // string stationNameStr3 = stationCode3 + stationName3;
  9697. // string stationCode4 = "[S4_4]";
  9698. // string stationName4 = "提升机2";
  9699. // string stationNameStr4 = stationCode4 + stationName4;
  9700. // string stationCode5 = "[S4_5]";
  9701. // string stationName5 = "载具上线装备";
  9702. // string stationNameStr5 = stationCode5 + stationName5;
  9703. // #region 创建字典
  9704. // // 触发信号字典 赋值
  9705. // s4PLCSignal_Old.Add("d1BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  9706. // s4PLCSignal_Old.Add("d1VehicleScanCode", 0); // 扫码信号 载具扫码
  9707. // s4PLCSignal_Old.Add("d1PLC_FLAG", 0); // PLC_FLAG 出站接口
  9708. // s4PLCSignal_Old.Add("d1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  9709. // s4PLCSignal_Old.Add("d2BulletclipScanCode", 0); // 扫码信号 查询标机中弹夹的状态
  9710. // s4PLCSignal_Old.Add("d3PLC_FLAG", 0); // PLC_FLAG 真空标机1出站接口
  9711. // s4PLCSignal_Old.Add("d4PLC_FLAG", 0); // PLC_FLAG 真空标机2出站接口
  9712. // s4PLCSignal_Old.Add("d5BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  9713. // s4PLCSignal_Old.Add("d5VehicleScanCode", 0); // 扫码信号 载具扫码
  9714. // s4PLCSignal_Old.Add("d5PLC_FLAG", 0); // PLC_FLAG 出站接口
  9715. // s4PLCSignal_Old.Add("d5OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  9716. // // PLC数据字典 赋值
  9717. // // 载具下线装备(弹夹上线)
  9718. // s4PLCData.Add("d1BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  9719. // s4PLCData.Add("d1BulletclipCode", ""); // 扫到的码
  9720. // s4PLCData.Add("d1VehicleScanCode", 0); // 扫码信号 载具扫码
  9721. // s4PLCData.Add("d1VehicleCode", ""); // 扫到的码
  9722. // s4PLCData.Add("d1PLC_FLAG", 0); // PLC_FLAG 出站接口
  9723. // s4PLCData.Add("d1MES_FLAG", 0); // MES_FLAG
  9724. // s4PLCData.Add("d1ProductSN", ""); // 产品SN(弹夹码)
  9725. // s4PLCData.Add("d1VehicleCode1", ""); // 载具1码(弹夹穴位1)
  9726. // s4PLCData.Add("d1VehicleCode2", ""); // 载具2码(弹夹穴位2)
  9727. // s4PLCData.Add("d1VehicleCode3", ""); // 载具3码(弹夹穴位3)
  9728. // s4PLCData.Add("d1VehicleCode4", ""); // 载具4码(弹夹穴位4)
  9729. // s4PLCData.Add("d1VehicleCode5", ""); // 载具5码(弹夹穴位5)
  9730. // s4PLCData.Add("d1VehicleCode6", ""); // 载具6码(弹夹穴位6)
  9731. // s4PLCData.Add("d1VehicleCode7", ""); // 载具7码(弹夹穴位7)
  9732. // s4PLCData.Add("d1VehicleCode8", ""); // 载具8码(弹夹穴位8)
  9733. // s4PLCData.Add("d1VehicleCode9", ""); // 载具9码(弹夹穴位9)
  9734. // s4PLCData.Add("d1VehicleCode10", ""); // 载具10码(弹夹穴位10)
  9735. // s4PLCData.Add("d1Result", 0); // 产品结果
  9736. // s4PLCData.Add("d1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  9737. // s4PLCData.Add("d1OEEMES_FLAG", 0); // MES_FLAG
  9738. // s4PLCData.Add("d1OEEProductSN", "");// 产品SN(载具SN)
  9739. // s4PLCData.Add("d1OEEType", 0); // 节拍类型(plc写入)
  9740. // s4PLCData.Add("d2BulletclipScanCode", 0); // 扫码信号 查询标机中弹夹的状态
  9741. // s4PLCData.Add("d2BulletclipStates", 0); // 弹夹状态
  9742. // s4PLCData.Add("d2BulletclipCode", ""); // 扫到的码
  9743. // // 真空标机(提升机)
  9744. // s4PLCData.Add("d3PLC_FLAG", 0); // PLC_FLAG 真空标机1出站接口
  9745. // s4PLCData.Add("d3MES_FLAG", 0); // MES_FLAG
  9746. // s4PLCData.Add("d3Type", 0); // 进站还是出站
  9747. // s4PLCData.Add("d3ProductSN", ""); // 产品SN(弹夹码)
  9748. // s4PLCData.Add("d3Result", 0); // 产品结果
  9749. // s4PLCData.Add("d4PLC_FLAG", 0); // PLC_FLAG 真空标机2出站接口
  9750. // s4PLCData.Add("d4MES_FLAG", 0); // MES_FLAG
  9751. // s4PLCData.Add("d4Type", 0); // 进站还是出站
  9752. // s4PLCData.Add("d4ProductSN", ""); // 产品SN(弹夹码)
  9753. // s4PLCData.Add("d4Result", 0); // 产品结果
  9754. // // 载具上线装备(弹夹下线)
  9755. // s4PLCData.Add("d5BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  9756. // s4PLCData.Add("d5BulletclipCode", ""); // 扫到的码
  9757. // s4PLCData.Add("d5VehicleScanCode", 0); // 扫码信号 载具扫码
  9758. // s4PLCData.Add("d5VehicleCode", ""); // 扫到的码
  9759. // s4PLCData.Add("d5PLC_FLAG", 0); // PLC_FLAG 出站接口
  9760. // s4PLCData.Add("d5MES_FLAG", 0); // MES_FLAG
  9761. // s4PLCData.Add("d5ProductSN", ""); // 产品SN(弹夹码)
  9762. // s4PLCData.Add("d5VehicleCode1", ""); // 载具1码(弹夹穴位1)
  9763. // s4PLCData.Add("d5VehicleCode2", ""); // 载具2码(弹夹穴位2)
  9764. // s4PLCData.Add("d5VehicleCode3", ""); // 载具3码(弹夹穴位3)
  9765. // s4PLCData.Add("d5VehicleCode4", ""); // 载具4码(弹夹穴位4)
  9766. // s4PLCData.Add("d5VehicleCode5", ""); // 载具5码(弹夹穴位5)
  9767. // s4PLCData.Add("d5VehicleCode6", ""); // 载具6码(弹夹穴位6)
  9768. // s4PLCData.Add("d5VehicleCode7", ""); // 载具7码(弹夹穴位7)
  9769. // s4PLCData.Add("d5VehicleCode8", ""); // 载具8码(弹夹穴位8)
  9770. // s4PLCData.Add("d5VehicleCode9", ""); // 载具9码(弹夹穴位9)
  9771. // s4PLCData.Add("d5VehicleCode10", ""); // 载具10码(弹夹穴位10)
  9772. // s4PLCData.Add("d5Result", 0); // 产品结果
  9773. // s4PLCData.Add("d5OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  9774. // s4PLCData.Add("d5OEEMES_FLAG", 0); // MES_FLAG
  9775. // s4PLCData.Add("d5OEEProductSN", "");// 产品SN(载具SN)
  9776. // s4PLCData.Add("d5OEEType", 0); // 节拍类型(plc写入)
  9777. // #endregion 创建字典
  9778. // while (IsRun)
  9779. // {
  9780. // try
  9781. // {
  9782. // if (!GlobalContext._IsCon_Funs4)
  9783. // {
  9784. // UpdatePLCMonitor(1, plcNo, 0);
  9785. // continue;
  9786. // }
  9787. // if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  9788. // {
  9789. // Stopwatch stopwatch1 = new Stopwatch();
  9790. // Stopwatch stopwatch2 = new Stopwatch();
  9791. // stopwatch1.Start();
  9792. // stopwatch2.Start();
  9793. // #region 一次性读取所有数据
  9794. // // 载具下线装备(弹夹上线)
  9795. // int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100);
  9796. // int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 100);
  9797. // int[] data3 = Funs[plcNo].ReadHoldingRegisters(2200, 100);
  9798. // int[] data4 = Funs[plcNo].ReadHoldingRegisters(2300, 100);
  9799. // int[] data5 = Funs[plcNo].ReadHoldingRegisters(2400, 100);
  9800. // int[] data6 = Funs[plcNo].ReadHoldingRegisters(2500, 100);
  9801. // int[] data7 = Funs[plcNo].ReadHoldingRegisters(2600, 100);
  9802. // int[] data8 = Funs[plcNo].ReadHoldingRegisters(2700, 100);
  9803. // int[] data9 = Funs[plcNo].ReadHoldingRegisters(2800, 100);
  9804. // int[] data10 = Funs[plcNo].ReadHoldingRegisters(2900, 56);
  9805. // int[] datas = data1.Concat(data2).ToArray();
  9806. // datas = datas.Concat(data3).ToArray();
  9807. // datas = datas.Concat(data4).ToArray();
  9808. // datas = datas.Concat(data5).ToArray();
  9809. // datas = datas.Concat(data6).ToArray();
  9810. // datas = datas.Concat(data7).ToArray();
  9811. // datas = datas.Concat(data8).ToArray();
  9812. // datas = datas.Concat(data9).ToArray();
  9813. // datas = datas.Concat(data10).ToArray();
  9814. // // 载具下线装备(弹夹上线)
  9815. // s4PLCData["d1BulletclipScanCode"] = datas[2]; // 扫码信号 弹夹扫码
  9816. // int[] d1BulletclipCodeData = datas.Skip(3).Take(20).ToArray();
  9817. // s4PLCData["d1BulletclipCode"] = ModbusClient.ConvertRegistersToString(d1BulletclipCodeData, 0, 40);
  9818. // s4PLCData["d1VehicleScanCode"] = datas[33]; // 扫码信号 载具扫码
  9819. // int[] d1VehicleCodeData = datas.Skip(34).Take(20).ToArray();
  9820. // s4PLCData["d1VehicleCode"] = ModbusClient.ConvertRegistersToString(d1VehicleCodeData, 0, 40);
  9821. // s4PLCData["d1PLC_FLAG"] = datas[64]; // PLC_FLAG 出站接口
  9822. // s4PLCData["d1MES_FLAG"] = datas[65];
  9823. // int[] d1ProductSNData = datas.Skip(66).Take(20).ToArray();
  9824. // s4PLCData["d1ProductSN"] = ModbusClient.ConvertRegistersToString(d1ProductSNData, 0, 40); // 产品SN(物料码)
  9825. // int[] d1VehicleCode1Data = datas.Skip(86).Take(20).ToArray();
  9826. // s4PLCData["d1VehicleCode1"] = ModbusClient.ConvertRegistersToString(d1VehicleCode1Data, 0, 40);
  9827. // int[] d1VehicleCode2Data = datas.Skip(106).Take(20).ToArray();
  9828. // s4PLCData["d1VehicleCode2"] = ModbusClient.ConvertRegistersToString(d1VehicleCode2Data, 0, 40);
  9829. // int[] d1VehicleCode3Data = datas.Skip(126).Take(20).ToArray();
  9830. // s4PLCData["d1VehicleCode3"] = ModbusClient.ConvertRegistersToString(d1VehicleCode3Data, 0, 40);
  9831. // int[] d1VehicleCode4Data = datas.Skip(146).Take(20).ToArray();
  9832. // s4PLCData["d1VehicleCode4"] = ModbusClient.ConvertRegistersToString(d1VehicleCode4Data, 0, 40);
  9833. // int[] d1VehicleCode5Data = datas.Skip(166).Take(20).ToArray();
  9834. // s4PLCData["d1VehicleCode5"] = ModbusClient.ConvertRegistersToString(d1VehicleCode5Data, 0, 40);
  9835. // int[] d1VehicleCode6Data = datas.Skip(186).Take(20).ToArray();
  9836. // s4PLCData["d1VehicleCode6"] = ModbusClient.ConvertRegistersToString(d1VehicleCode6Data, 0, 40);
  9837. // int[] d1VehicleCode7Data = datas.Skip(206).Take(20).ToArray();
  9838. // s4PLCData["d1VehicleCode7"] = ModbusClient.ConvertRegistersToString(d1VehicleCode7Data, 0, 40);
  9839. // int[] d1VehicleCode8Data = datas.Skip(226).Take(20).ToArray();
  9840. // s4PLCData["d1VehicleCode8"] = ModbusClient.ConvertRegistersToString(d1VehicleCode8Data, 0, 40);
  9841. // int[] d1VehicleCode9Data = datas.Skip(246).Take(20).ToArray();
  9842. // s4PLCData["d1VehicleCode9"] = ModbusClient.ConvertRegistersToString(d1VehicleCode9Data, 0, 40);
  9843. // int[] d1VehicleCode10Data = datas.Skip(266).Take(20).ToArray();
  9844. // s4PLCData["d1VehicleCode10"] = ModbusClient.ConvertRegistersToString(d1VehicleCode10Data, 0, 40);
  9845. // int[] d1VehicleCode11Data = datas.Skip(286).Take(20).ToArray();
  9846. // s4PLCData["d1VehicleCode11"] = ModbusClient.ConvertRegistersToString(d1VehicleCode11Data, 0, 40);
  9847. // int[] d1VehicleCode12Data = datas.Skip(306).Take(20).ToArray();
  9848. // s4PLCData["d1VehicleCode12"] = ModbusClient.ConvertRegistersToString(d1VehicleCode12Data, 0, 40);
  9849. // int[] d1VehicleCode13Data = datas.Skip(326).Take(20).ToArray();
  9850. // s4PLCData["d1VehicleCode13"] = ModbusClient.ConvertRegistersToString(d1VehicleCode13Data, 0, 40);
  9851. // int[] d1VehicleCode14Data = datas.Skip(346).Take(20).ToArray();
  9852. // s4PLCData["d1VehicleCode14"] = ModbusClient.ConvertRegistersToString(d1VehicleCode14Data, 0, 40);
  9853. // int[] d1VehicleCode15Data = datas.Skip(366).Take(20).ToArray();
  9854. // s4PLCData["d1VehicleCode15"] = ModbusClient.ConvertRegistersToString(d1VehicleCode15Data, 0, 40);
  9855. // s4PLCData["d1Result"] = datas[386];
  9856. // s4PLCData["d1OEEPLC_FLAG"] = datas[397]; // PLC_FLAG 节拍接口
  9857. // s4PLCData["d1OEEMES_FLAG"] = datas[398];
  9858. // int[] d1OEEProductSNData = datas.Skip(399).Take(20).ToArray();
  9859. // s4PLCData["d1OEEProductSN"] = ModbusClient.ConvertRegistersToString(d1OEEProductSNData, 0, 40);
  9860. // s4PLCData["d1OEEType"] = datas[419];
  9861. // // 桁架(查询标机中弹夹的状态)
  9862. // s4PLCData["d2BulletclipScanCode"] = datas[430];
  9863. // s4PLCData["d2BulletclipStates"] = datas[431];
  9864. // int[] d2BulletclipCodeData = datas.Skip(432).Take(20).ToArray();
  9865. // s4PLCData["d2BulletclipCode"] = ModbusClient.ConvertRegistersToString(d2BulletclipCodeData, 0, 40);
  9866. // // 真空标机
  9867. // s4PLCData["d3PLC_FLAG"] = datas[462]; // 真空标机1 出站接口
  9868. // s4PLCData["d3MES_FLAG"] = datas[463];
  9869. // int[] d3ProductSNData = datas.Skip(464).Take(20).ToArray();
  9870. // s4PLCData["d3ProductSN"] = ModbusClient.ConvertRegistersToString(d3ProductSNData, 0, 40);
  9871. // s4PLCData["d3Result"] = datas[484];
  9872. // s4PLCData["d3Type"] = datas[485];
  9873. // s4PLCData["d4PLC_FLAG"] = datas[495]; // 真空标机2 出站接口
  9874. // s4PLCData["d4MES_FLAG"] = datas[496];
  9875. // int[] d4ProductSNData = datas.Skip(497).Take(20).ToArray();
  9876. // s4PLCData["d4ProductSN"] = ModbusClient.ConvertRegistersToString(d4ProductSNData, 0, 40);
  9877. // s4PLCData["d4Result"] = datas[517];
  9878. // s4PLCData["d4Type"] = datas[518];
  9879. // // 载具上线装备(弹夹下线)
  9880. // s4PLCData["d5BulletclipScanCode"] = datas[528]; // 扫码信号 弹夹扫码
  9881. // int[] d5BulletclipCodeData = datas.Skip(529).Take(20).ToArray();
  9882. // s4PLCData["d5BulletclipCode"] = ModbusClient.ConvertRegistersToString(d5BulletclipCodeData, 0, 40);
  9883. // s4PLCData["d5VehicleScanCode"] = datas[559]; // 扫码信号 载具扫码
  9884. // int[] d5VehicleCodeData = datas.Skip(560).Take(20).ToArray();
  9885. // s4PLCData["d5VehicleCode"] = ModbusClient.ConvertRegistersToString(d5VehicleCodeData, 0, 40);
  9886. // s4PLCData["d5PLC_FLAG"] = datas[590]; // PLC_FLAG 出站接口
  9887. // s4PLCData["d5MES_FLAG"] = datas[591];
  9888. // int[] d5ProductSNData = datas.Skip(592).Take(20).ToArray();
  9889. // s4PLCData["d5ProductSN"] = ModbusClient.ConvertRegistersToString(d5ProductSNData, 0, 40); // 产品SN(物料码)
  9890. // int[] d5VehicleCode1Data = datas.Skip(612).Take(20).ToArray();
  9891. // s4PLCData["d5VehicleCode1"] = ModbusClient.ConvertRegistersToString(d5VehicleCode1Data, 0, 40);
  9892. // int[] d5VehicleCode2Data = datas.Skip(632).Take(20).ToArray();
  9893. // s4PLCData["d5VehicleCode2"] = ModbusClient.ConvertRegistersToString(d5VehicleCode2Data, 0, 40);
  9894. // int[] d5VehicleCode3Data = datas.Skip(652).Take(20).ToArray();
  9895. // s4PLCData["d5VehicleCode3"] = ModbusClient.ConvertRegistersToString(d5VehicleCode3Data, 0, 40);
  9896. // int[] d5VehicleCode4Data = datas.Skip(672).Take(20).ToArray();
  9897. // s4PLCData["d5VehicleCode4"] = ModbusClient.ConvertRegistersToString(d5VehicleCode4Data, 0, 40);
  9898. // int[] d5VehicleCode5Data = datas.Skip(692).Take(20).ToArray();
  9899. // s4PLCData["d5VehicleCode5"] = ModbusClient.ConvertRegistersToString(d5VehicleCode5Data, 0, 40);
  9900. // int[] d5VehicleCode6Data = datas.Skip(712).Take(20).ToArray();
  9901. // s4PLCData["d5VehicleCode6"] = ModbusClient.ConvertRegistersToString(d5VehicleCode6Data, 0, 40);
  9902. // int[] d5VehicleCode7Data = datas.Skip(732).Take(20).ToArray();
  9903. // s4PLCData["d5VehicleCode7"] = ModbusClient.ConvertRegistersToString(d5VehicleCode7Data, 0, 40);
  9904. // int[] d5VehicleCode8Data = datas.Skip(752).Take(20).ToArray();
  9905. // s4PLCData["d5VehicleCode8"] = ModbusClient.ConvertRegistersToString(d5VehicleCode8Data, 0, 40);
  9906. // int[] d5VehicleCode9Data = datas.Skip(772).Take(20).ToArray();
  9907. // s4PLCData["d5VehicleCode9"] = ModbusClient.ConvertRegistersToString(d5VehicleCode9Data, 0, 40);
  9908. // int[] d5VehicleCode10Data = datas.Skip(792).Take(20).ToArray();
  9909. // s4PLCData["d5VehicleCode10"] = ModbusClient.ConvertRegistersToString(d5VehicleCode10Data, 0, 40);
  9910. // int[] d5VehicleCode11Data = datas.Skip(812).Take(20).ToArray();
  9911. // s4PLCData["d5VehicleCode11"] = ModbusClient.ConvertRegistersToString(d5VehicleCode11Data, 0, 40);
  9912. // int[] d5VehicleCode12Data = datas.Skip(832).Take(20).ToArray();
  9913. // s4PLCData["d5VehicleCode12"] = ModbusClient.ConvertRegistersToString(d5VehicleCode12Data, 0, 40);
  9914. // int[] d5VehicleCode13Data = datas.Skip(852).Take(20).ToArray();
  9915. // s4PLCData["d5VehicleCode13"] = ModbusClient.ConvertRegistersToString(d5VehicleCode13Data, 0, 40);
  9916. // int[] d5VehicleCode14Data = datas.Skip(872).Take(20).ToArray();
  9917. // s4PLCData["d5VehicleCode14"] = ModbusClient.ConvertRegistersToString(d5VehicleCode14Data, 0, 40);
  9918. // int[] d5VehicleCode15Data = datas.Skip(892).Take(20).ToArray();
  9919. // s4PLCData["d5VehicleCode15"] = ModbusClient.ConvertRegistersToString(d5VehicleCode15Data, 0, 40);
  9920. // s4PLCData["d5Result"] = datas[912];
  9921. // s4PLCData["d5OEEPLC_FLAG"] = datas[923]; // PLC_FLAG 节拍接口
  9922. // s4PLCData["d5OEEMES_FLAG"] = datas[924];
  9923. // int[] d5OEEProductSNData = datas.Skip(925).Take(20).ToArray();
  9924. // s4PLCData["d5OEEProductSN"] = ModbusClient.ConvertRegistersToString(d5OEEProductSNData, 0, 40);
  9925. // s4PLCData["d5OEEType"] = datas[945];
  9926. // #endregion 一次性读取所有数据
  9927. // stopwatch2.Stop();
  9928. // #region 回写操作,写后清空flag
  9929. // PLCWriteData(Funs[plcNo], ref s4PLCData, ref s4PLCWriteData);
  9930. // #endregion 回写操作,写后清空flag
  9931. // // N801A-S4_1 弹夹扫码
  9932. // #region N801A-S4_1 弹夹扫码
  9933. // try
  9934. // {
  9935. // int d1BulletclipScanCode = (int)s4PLCData["d1BulletclipScanCode"];
  9936. // int d1BulletclipScanCodeOld = (int)s4PLCSignal_Old["d1BulletclipScanCode"];
  9937. // if (d1BulletclipScanCode != d1BulletclipScanCodeOld)
  9938. // {
  9939. // if (d1BulletclipScanCode == 1) // 0->1
  9940. // Task.Run(() => S4_1弹夹扫码(plcNo, stationNameStr)); // MreTasks[1].Set();
  9941. // s4PLCSignal_Old["d1BulletclipScanCode"] = s4PLCData["d1BulletclipScanCode"];
  9942. // }
  9943. // }
  9944. // catch (Exception ex)
  9945. // {
  9946. // Funs[plcNo].WriteMultipleRegisters<short>(2002, (short)6); // 6代表上位机报警
  9947. // string str = ex.StackTrace;
  9948. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9949. // }
  9950. // #endregion N801A-S4_1 弹夹扫码
  9951. // // N801A-S4_1 载具扫码
  9952. // #region N801A-S4_1 载具扫码
  9953. // try
  9954. // {
  9955. // int d1VehicleScanCode = (int)s4PLCData["d1VehicleScanCode"];
  9956. // int d1VehicleScanCodeOld = (int)s4PLCSignal_Old["d1VehicleScanCode"];
  9957. // if (d1VehicleScanCode != d1VehicleScanCodeOld)
  9958. // {
  9959. // if (d1VehicleScanCode == 1) // 0->1
  9960. // Task.Run(() => S4_1载具扫码(plcNo, stationNameStr)); // MreTasks[1].Set();
  9961. // s4PLCSignal_Old["d1VehicleScanCode"] = s4PLCData["d1VehicleScanCode"];
  9962. // }
  9963. // }
  9964. // catch (Exception ex)
  9965. // {
  9966. // Funs[plcNo].WriteMultipleRegisters<short>(2033, (short)6); // 6代表上位机报警
  9967. // string str = ex.StackTrace;
  9968. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9969. // }
  9970. // #endregion N801A-S4_1 载具扫码
  9971. // // N801A-S4_1 出站接口
  9972. // #region N801A-S4_1 出站接口
  9973. // try
  9974. // {
  9975. // int d1PLC_FLAG = (int)s4PLCData["d1PLC_FLAG"];
  9976. // int d1MES_FLAG = (int)s4PLCData["d1MES_FLAG"];
  9977. // int d1PLC_FLAGOld = (int)s4PLCSignal_Old["d1PLC_FLAG"];
  9978. // if (d1PLC_FLAG != d1PLC_FLAGOld)
  9979. // {
  9980. // if (d1PLC_FLAG == 1 && d1MES_FLAG == 0) // 0->1
  9981. // Task.Run(() => S4_1出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  9982. // else if (d1PLC_FLAG == 0 && d1MES_FLAG != 0)
  9983. // Funs[plcNo].WriteMultipleRegisters<short>(2065, (short)0);
  9984. // s4PLCSignal_Old["d1PLC_FLAG"] = s4PLCData["d1PLC_FLAG"];
  9985. // }
  9986. // }
  9987. // catch (Exception ex)
  9988. // {
  9989. // Funs[plcNo].WriteMultipleRegisters<short>(2065, (short)6); // 6代表上位机报警
  9990. // string str = ex.StackTrace;
  9991. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  9992. // }
  9993. // #endregion N801A-S4_1 出站接口
  9994. // // N801A-S4_1 节拍接口
  9995. // #region N801A-S4_1 节拍接口
  9996. // try
  9997. // {
  9998. // int d1OEEPLC_FLAG = (int)s4PLCData["d1OEEPLC_FLAG"];
  9999. // int d1OEEMES_FLAG = (int)s4PLCData["d1OEEMES_FLAG"];
  10000. // int d1OEEPLC_FLAGOld = (int)s4PLCSignal_Old["d1OEEPLC_FLAG"];
  10001. // if (d1OEEPLC_FLAG != d1OEEPLC_FLAGOld)
  10002. // {
  10003. // if (d1OEEPLC_FLAG == 1 && d1OEEMES_FLAG == 0) // 0->1
  10004. // Task.Run(() => S4_1节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  10005. // else if (d1OEEPLC_FLAG == 0 && d1OEEMES_FLAG != 0)
  10006. // Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)0);
  10007. // s4PLCSignal_Old["d1OEEPLC_FLAG"] = s4PLCData["d1OEEPLC_FLAG"];
  10008. // }
  10009. // }
  10010. // catch (Exception ex)
  10011. // {
  10012. // Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)4); // 4代表上位机报警
  10013. // string str = ex.StackTrace;
  10014. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10015. // }
  10016. // #endregion N801A-S4_1 节拍接口
  10017. // // N801A-S4_2 桁架(查询标机中弹夹的状态) 数据
  10018. // #region N801A-S4_2 桁架(查询标机中弹夹的状态)
  10019. // try
  10020. // {
  10021. // int d2BulletclipScanCode = (int)s4PLCData["d2BulletclipScanCode"];
  10022. // int d2BulletclipScanCodeOld = (int)s4PLCSignal_Old["d2BulletclipScanCode"];
  10023. // if (d2BulletclipScanCode != d2BulletclipScanCodeOld)
  10024. // {
  10025. // if (d2BulletclipScanCode == 1) // 0->1
  10026. // Task.Run(() => S4_2桁架(plcNo, stationNameStr2)); // MreTasks[1].Set();
  10027. // s4PLCSignal_Old["d2BulletclipScanCode"] = s4PLCData["d2BulletclipScanCode"];
  10028. // }
  10029. // }
  10030. // catch (Exception ex)
  10031. // {
  10032. // Funs[plcNo].WriteMultipleRegisters<short>(2430, (short)6); // 6代表上位机报警
  10033. // string str = ex.StackTrace;
  10034. // AddMessage_Station(stationNameStr2, LogType.Error, $"PLC{plcNo}_{stationNameStr2} 桁架出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10035. // }
  10036. // #endregion N801A-S4_2 桁架(查询标机中弹夹的状态)
  10037. // // N801A-S4_3 真空标机1 数据
  10038. // #region N801A-S4_3 真空标机1
  10039. // try
  10040. // {
  10041. // int d3PLC_FLAG = (int)s4PLCData["d3PLC_FLAG"];
  10042. // int d3MES_FLAG = (int)s4PLCData["d3MES_FLAG"];
  10043. // int d3PLC_FLAGOld = (int)s4PLCSignal_Old["d3PLC_FLAG"];
  10044. // if (d3PLC_FLAG != d3PLC_FLAGOld)
  10045. // {
  10046. // if (d3PLC_FLAG == 1 && d3MES_FLAG == 0) // 0->1
  10047. // {
  10048. // int stationType = (int)s4PLCData["d3Type"];
  10049. // if (stationType == 1)
  10050. // {
  10051. // // S4_3进站接口
  10052. // Task.Run(() => S4_3进站接口(plcNo, stationNameStr3)); // MreTasks[3].Set();
  10053. // }
  10054. // else if (stationType == 2)
  10055. // {
  10056. // // S4_3出站接口
  10057. // Task.Run(() => S4_3出站接口(plcNo, stationCode3, stationName3)); // MreTasks[3].Set();
  10058. // }
  10059. // }
  10060. // else if (d3PLC_FLAG == 0 && d3MES_FLAG != 0)
  10061. // Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)0);
  10062. // s4PLCSignal_Old["d3PLC_FLAG"] = s4PLCData["d3PLC_FLAG"];
  10063. // }
  10064. // }
  10065. // catch (Exception ex)
  10066. // {
  10067. // Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)4); // 4代表上位机报警
  10068. // string str = ex.StackTrace;
  10069. // AddMessage_Station(stationNameStr3, LogType.Error, $"PLC{plcNo}_{stationNameStr3} 上传标机出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10070. // }
  10071. // #endregion N801A-S4_3 真空标机1
  10072. // // N801A-S4_4 真空标机2 数据
  10073. // #region N801A-S4_4 真空标机2
  10074. // try
  10075. // {
  10076. // int d4PLC_FLAG = (int)s4PLCData["d4PLC_FLAG"];
  10077. // int d4MES_FLAG = (int)s4PLCData["d4MES_FLAG"];
  10078. // int d4PLC_FLAGOld = (int)s4PLCSignal_Old["d4PLC_FLAG"];
  10079. // if (d4PLC_FLAG != d4PLC_FLAGOld)
  10080. // {
  10081. // if (d4PLC_FLAG == 1 && d4MES_FLAG == 0) // 0->1
  10082. // {
  10083. // int stationType = (int)s4PLCData["d4Type"];
  10084. // if (stationType == 1)
  10085. // {
  10086. // // S4_4进站接口
  10087. // Task.Run(() => S4_4进站接口(plcNo, stationNameStr4)); // MreTasks[3].Set();
  10088. // }
  10089. // else if (stationType == 2)
  10090. // {
  10091. // // S4_4出站接口
  10092. // Task.Run(() => S4_4出站接口(plcNo, stationCode4, stationName4)); // MreTasks[3].Set();
  10093. // }
  10094. // }
  10095. // else if (d4PLC_FLAG == 0 && d4MES_FLAG != 0)
  10096. // Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)0);
  10097. // s4PLCSignal_Old["d4PLC_FLAG"] = s4PLCData["d4PLC_FLAG"];
  10098. // }
  10099. // }
  10100. // catch (Exception ex)
  10101. // {
  10102. // Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)4); // 4代表上位机报警
  10103. // string str = ex.StackTrace;
  10104. // AddMessage_Station(stationNameStr4, LogType.Error, $"PLC{plcNo}_{stationNameStr4} 上传标机出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10105. // }
  10106. // #endregion N801A-S4_4 真空标机2
  10107. // // N801A-S4_5 弹夹扫码 数据
  10108. // #region N801A-S4_5 弹夹扫码
  10109. // try
  10110. // {
  10111. // int d5BulletclipScanCode = (int)s4PLCData["d5BulletclipScanCode"];
  10112. // int d5BulletclipScanCodeOld = (int)s4PLCSignal_Old["d5BulletclipScanCode"];
  10113. // if (d5BulletclipScanCode != d5BulletclipScanCodeOld)
  10114. // {
  10115. // if (d5BulletclipScanCode == 1) // 0->1
  10116. // Task.Run(() => S4_5弹夹扫码(plcNo, stationNameStr5)); // MreTasks[1].Set();
  10117. // s4PLCSignal_Old["d5BulletclipScanCode"] = s4PLCData["d5BulletclipScanCode"];
  10118. // }
  10119. // }
  10120. // catch (Exception ex)
  10121. // {
  10122. // Funs[plcNo].WriteMultipleRegisters<short>(2528, (short)6); // 6代表上位机报警
  10123. // string str = ex.StackTrace;
  10124. // AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10125. // }
  10126. // #endregion N801A-S4_5 弹夹扫码
  10127. // // N801A-S4_5 载具扫码 数据
  10128. // #region N801A-S4_5 载具扫码
  10129. // try
  10130. // {
  10131. // int d5VehicleScanCode = (int)s4PLCData["d5VehicleScanCode"];
  10132. // int d5VehicleScanCodeOld = (int)s4PLCSignal_Old["d5VehicleScanCode"];
  10133. // if (d5VehicleScanCode != d5VehicleScanCodeOld)
  10134. // {
  10135. // if (d5VehicleScanCode == 1) // 0->1
  10136. // Task.Run(() => S4_5载具扫码(plcNo, stationNameStr5)); // MreTasks[1].Set();
  10137. // s4PLCSignal_Old["d5VehicleScanCode"] = s4PLCData["d5VehicleScanCode"];
  10138. // }
  10139. // }
  10140. // catch (Exception ex)
  10141. // {
  10142. // Funs[plcNo].WriteMultipleRegisters<short>(2559, (short)6); // 6代表上位机报警
  10143. // string str = ex.StackTrace;
  10144. // AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10145. // }
  10146. // #endregion N801A-S4_5 载具扫码
  10147. // // N801A-S4_5 出站接口(扫完所有码后立即上传) 数据
  10148. // #region N801A-S4_5 出站接口
  10149. // try
  10150. // {
  10151. // int d5PLC_FLAG = (int)s4PLCData["d5PLC_FLAG"];
  10152. // int d5MES_FLAG = (int)s4PLCData["d5MES_FLAG"];
  10153. // int d5PLC_FLAGOld = (int)s4PLCSignal_Old["d5PLC_FLAG"];
  10154. // if (d5PLC_FLAG != d5PLC_FLAGOld)
  10155. // {
  10156. // if (d5PLC_FLAG == 1 && d5MES_FLAG == 0) // 0->1
  10157. // Task.Run(() => S4_5出站接口(plcNo, stationCode5, stationName5)); // MreTasks[3].Set();
  10158. // else if (d5PLC_FLAG == 0 && d5MES_FLAG != 0)
  10159. // Funs[plcNo].WriteMultipleRegisters<short>(2591, (short)0);
  10160. // s4PLCSignal_Old["d5PLC_FLAG"] = s4PLCData["d5PLC_FLAG"];
  10161. // }
  10162. // }
  10163. // catch (Exception ex)
  10164. // {
  10165. // Funs[plcNo].WriteMultipleRegisters<short>(2591, (short)6); // 6代表上位机报警
  10166. // string str = ex.StackTrace;
  10167. // AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10168. // }
  10169. // #endregion N801A-S4_5 出站接口
  10170. // // N801A-S4_5 节拍接口 数据
  10171. // #region N801A-S4_5 节拍接口
  10172. // try
  10173. // {
  10174. // int d5OEEPLC_FLAG = (int)s4PLCData["d5OEEPLC_FLAG"];
  10175. // int d5OEEMES_FLAG = (int)s4PLCData["d5OEEMES_FLAG"];
  10176. // int d5OEEPLC_FLAGOld = (int)s4PLCSignal_Old["d5OEEPLC_FLAG"];
  10177. // if (d5OEEPLC_FLAG != d5OEEPLC_FLAGOld)
  10178. // {
  10179. // if (d5OEEPLC_FLAG == 1 && d5OEEMES_FLAG == 0) // 0->1
  10180. // Task.Run(() => S4_5节拍接口(plcNo, stationNameStr5)); // MreTasks[4].Set();
  10181. // else if (d5OEEPLC_FLAG == 0 && d5OEEMES_FLAG != 0)
  10182. // Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)0);
  10183. // s4PLCSignal_Old["d5OEEPLC_FLAG"] = s4PLCData["d5OEEPLC_FLAG"];
  10184. // }
  10185. // }
  10186. // catch (Exception ex)
  10187. // {
  10188. // Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)4); // 4代表上位机报警
  10189. // string str = ex.StackTrace;
  10190. // AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10191. // }
  10192. // #endregion N801A-S4_5 节拍接口
  10193. // #region 心跳
  10194. // try
  10195. // {
  10196. // short states = 0;
  10197. // Funs[plcNo].WriteMultipleRegisters<short>(2000, states);
  10198. // }
  10199. // catch (Exception ex)
  10200. // {
  10201. // string str = ex.StackTrace;
  10202. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上位机心跳写入出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10203. // }
  10204. // #endregion 心跳
  10205. // UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  10206. // stopwatch1.Stop();
  10207. // //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  10208. // OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  10209. // }
  10210. // else
  10211. // {
  10212. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  10213. // AddMessage_Station(stationNameStr5, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr5 + "连接失败!");
  10214. // Funs[plcNo].Connect();
  10215. // }
  10216. // }
  10217. // catch (Exception ex)
  10218. // {
  10219. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  10220. // AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5}运行出错!错误信息:" + ex.Message.ToString());
  10221. // Funs[plcNo].ReConnect();
  10222. // }
  10223. // Thread.Sleep(IntervalReadPLC);
  10224. // }
  10225. //}
  10226. /// <summary>
  10227. /// [S4] 取放桁架 - S4_1弹夹扫码
  10228. /// </summary>
  10229. /// <param name="plcNo">PLC编号</param>
  10230. /// <param name="stationNameStr">工站全称</param>
  10231. private void S4_1弹夹扫码(int plcNo, string stationNameStr)
  10232. {
  10233. Stopwatch stopwatch1 = new Stopwatch();
  10234. Stopwatch stopwatch2 = new Stopwatch();
  10235. try
  10236. {
  10237. stopwatch1.Start();
  10238. // ZS 弹夹扫码
  10239. string d1BulletclipCode = " "; // 扫到的码
  10240. short d1BulletclipScanCode = 2;
  10241. stopwatch2.Start();
  10242. //Funs[plcNo].WriteMultipleRegisters<string>(2003, d1BulletclipCode, 20);
  10243. //// MES_Flag
  10244. //Funs[plcNo].WriteMultipleRegisters<short>(2002, d1BulletclipScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  10245. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10246. writeToPLC_Flag.Name = "d1BulletclipScanCode";
  10247. writeToPLC_Flag.Adress = 2002;
  10248. writeToPLC_Flag.Value = d1BulletclipScanCode;
  10249. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 穴位1物料SN(上位机写入)
  10250. {
  10251. Name = "d1BulletclipCode",
  10252. Adress = 2003,
  10253. ValueType = PLCValueType.String,
  10254. ValueTypeStrLength = 20,
  10255. Value = d1BulletclipCode
  10256. });
  10257. SxPLCWriteData_Add(ref s4PLCWriteData, "d1BulletclipScanCode", writeToPLC_Flag);
  10258. stopwatch2.Stop();
  10259. }
  10260. catch (Exception ex)
  10261. {
  10262. string str = ex.StackTrace;
  10263. AddMessage_Station(stationNameStr, LogType.Error,
  10264. $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" +
  10265. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10266. stopwatch2.Start();
  10267. //Funs[plcNo].WriteMultipleRegisters<string>(2003, " ", 20);
  10268. //// MES_Flag
  10269. //Funs[plcNo].WriteMultipleRegisters<short>(2002, (short)6); // 6代表上位机报警
  10270. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10271. writeToPLC_Flag.Name = "d1BulletclipScanCode";
  10272. writeToPLC_Flag.Adress = 2002;
  10273. writeToPLC_Flag.Value = (short)6;
  10274. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 穴位1物料SN(上位机写入)
  10275. {
  10276. Name = "d1BulletclipCode",
  10277. Adress = 2003,
  10278. ValueType = PLCValueType.String,
  10279. ValueTypeStrLength = 20,
  10280. Value = " "
  10281. });
  10282. SxPLCWriteData_Add(ref s4PLCWriteData, "d1BulletclipScanCode", writeToPLC_Flag);
  10283. stopwatch2.Stop();
  10284. }
  10285. stopwatch1.Stop();
  10286. AddMessage(LogType.Info,
  10287. stationNameStr + "_弹夹扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  10288. stopwatch2.ElapsedMilliseconds + "ms");
  10289. }
  10290. /// <summary>
  10291. /// [S4] 取放桁架 - S4_1载具扫码
  10292. /// </summary>
  10293. /// <param name="plcNo">PLC编号</param>
  10294. /// <param name="stationNameStr">工站全称</param>
  10295. private void S4_1载具扫码(int plcNo, string stationNameStr)
  10296. {
  10297. Stopwatch stopwatch1 = new Stopwatch();
  10298. Stopwatch stopwatch2 = new Stopwatch();
  10299. try
  10300. {
  10301. stopwatch1.Start();
  10302. // ZS 载具扫码
  10303. string d1VehicleCode = ""; // 扫到的码
  10304. short d1VehicleScanCode = 2;
  10305. #region 进站
  10306. if (d1VehicleScanCode == 2 && !string.IsNullOrEmpty(d1VehicleCode))
  10307. {
  10308. #region 查询载具上的产品信息
  10309. string cavityData = string.Empty;
  10310. int snResult = XiaomiMES_RouteCommunication.SNQueryData(d1VehicleCode, ref cavityData);
  10311. if (string.IsNullOrEmpty(cavityData))
  10312. cavityData = "";
  10313. if (snResult != 0)
  10314. {
  10315. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10316. writeToPLC_Flag1.Name = "d1VehicleScanCode";
  10317. writeToPLC_Flag1.Adress = 2033;
  10318. writeToPLC_Flag1.Value = (short)6; // 6代表上位机报警
  10319. writeToPLC_Flag1.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10320. {
  10321. Name = "d1VehicleCode",
  10322. Adress = 2034,
  10323. ValueType = PLCValueType.String,
  10324. ValueTypeStrLength = 20,
  10325. Value = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  10326. });
  10327. SxPLCWriteData_Add(ref s4PLCWriteData, "d1VehicleScanCode", writeToPLC_Flag1);
  10328. stopwatch1.Stop();
  10329. AddMessage(LogType.Info,
  10330. stationNameStr + $"_载具扫码失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  10331. "ms");
  10332. return;
  10333. }
  10334. string[] cavitySNs = cavityData.Split('.');
  10335. string partNo = "";
  10336. if (cavitySNs != null && cavitySNs.Length >= 1)
  10337. {
  10338. partNo = cavitySNs[0];
  10339. }
  10340. #endregion 查询载具上的产品信息
  10341. List<TestItem> item = new List<TestItem>();
  10342. item.Add(new TestItem()
  10343. {
  10344. Parameter_name = "载具码",
  10345. Parameter_value = d1VehicleCode,
  10346. });
  10347. item.Add(new TestItem()
  10348. {
  10349. Parameter_name = "载具穴号",
  10350. Parameter_value = "1",
  10351. });
  10352. stopwatch2.Start();
  10353. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  10354. partNo, item, out string errorMsg);
  10355. stopwatch2.Stop();
  10356. d1VehicleScanCode = (short)result == 1 ? d1VehicleScanCode : (short)result;
  10357. }
  10358. #endregion 进站
  10359. //Funs[plcNo].WriteMultipleRegisters<string>(2034, d1VehicleCode, 20);
  10360. //// MES_Flag
  10361. //Funs[plcNo].WriteMultipleRegisters<short>(2033, d1VehicleScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  10362. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10363. writeToPLC_Flag.Name = "d1VehicleScanCode";
  10364. writeToPLC_Flag.Adress = 2033;
  10365. writeToPLC_Flag.Value = d1VehicleScanCode;
  10366. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10367. {
  10368. Name = "d1VehicleCode",
  10369. Adress = 2034,
  10370. ValueType = PLCValueType.String,
  10371. ValueTypeStrLength = 20,
  10372. Value = d1VehicleCode
  10373. });
  10374. SxPLCWriteData_Add(ref s4PLCWriteData, "d1VehicleScanCode", writeToPLC_Flag);
  10375. }
  10376. catch (Exception ex)
  10377. {
  10378. string str = ex.StackTrace;
  10379. AddMessage_Station(stationNameStr, LogType.Error,
  10380. $"PLC{plcNo}_{stationNameStr} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" +
  10381. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10382. stopwatch2.Start();
  10383. //Funs[plcNo].WriteMultipleRegisters<string>(2034, " ", 20);
  10384. //// MES_Flag
  10385. //Funs[plcNo].WriteMultipleRegisters<short>(2033, (short)6); // 6代表上位机报警
  10386. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10387. writeToPLC_Flag.Name = "d1VehicleScanCode";
  10388. writeToPLC_Flag.Adress = 2033;
  10389. writeToPLC_Flag.Value = (short)6; // 6代表上位机报警
  10390. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10391. {
  10392. Name = "d1VehicleCode",
  10393. Adress = 2034,
  10394. ValueType = PLCValueType.String,
  10395. ValueTypeStrLength = 20,
  10396. Value = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  10397. });
  10398. SxPLCWriteData_Add(ref s4PLCWriteData, "d1VehicleScanCode", writeToPLC_Flag);
  10399. stopwatch2.Stop();
  10400. }
  10401. stopwatch1.Stop();
  10402. AddMessage(LogType.Info,
  10403. stationNameStr + "_载具扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  10404. stopwatch2.ElapsedMilliseconds + "ms");
  10405. }
  10406. // 上次采集到的SN
  10407. //private string sn_S4_1出站接口 = string.Empty;
  10408. /// <summary>
  10409. /// [S4] 取放桁架 - S4_1出站接口
  10410. /// </summary>
  10411. private void S4_1出站接口(int plcNo, string stationCode, string stationName)
  10412. {
  10413. Stopwatch stopwatch1 = new Stopwatch();
  10414. Stopwatch stopwatch2 = new Stopwatch();
  10415. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  10416. string stationNameStr = stationCode + stationName;
  10417. string processItem = stationName; // 测试项目
  10418. try
  10419. {
  10420. stopwatch1.Start();
  10421. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  10422. //string batch_num = GlobalContext.BatchNumber; // 批次号
  10423. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  10424. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  10425. string sn = (string)s4PLCData["d1ProductSN"]; // 产品SN(弹夹码)
  10426. sn = sn.Replace("\0", "");
  10427. string d1VehicleCode1 = (string)s4PLCData["d1VehicleCode1"]; // 载具1码(弹夹穴位1)
  10428. d1VehicleCode1 = d1VehicleCode1.Replace("\0", "");
  10429. string d1VehicleCode2 = (string)s4PLCData["d1VehicleCode2"]; // 载具2码(弹夹穴位2)
  10430. d1VehicleCode2 = d1VehicleCode2.Replace("\0", "");
  10431. string d1VehicleCode3 = (string)s4PLCData["d1VehicleCode3"]; // 载具3码(弹夹穴位3)
  10432. d1VehicleCode3 = d1VehicleCode3.Replace("\0", "");
  10433. string d1VehicleCode4 = (string)s4PLCData["d1VehicleCode4"]; // 载具4码(弹夹穴位4)
  10434. d1VehicleCode4 = d1VehicleCode4.Replace("\0", "");
  10435. string d1VehicleCode5 = (string)s4PLCData["d1VehicleCode5"]; // 载具5码(弹夹穴位5)
  10436. d1VehicleCode5 = d1VehicleCode5.Replace("\0", "");
  10437. string d1VehicleCode6 = (string)s4PLCData["d1VehicleCode6"]; // 载具6码(弹夹穴位6)
  10438. d1VehicleCode6 = d1VehicleCode6.Replace("\0", "");
  10439. string d1VehicleCode7 = (string)s4PLCData["d1VehicleCode7"]; // 载具7码(弹夹穴位7)
  10440. d1VehicleCode7 = d1VehicleCode7.Replace("\0", "");
  10441. string d1VehicleCode8 = (string)s4PLCData["d1VehicleCode8"]; // 载具8码(弹夹穴位8)
  10442. d1VehicleCode8 = d1VehicleCode8.Replace("\0", "");
  10443. string d1VehicleCode9 = (string)s4PLCData["d1VehicleCode9"]; // 载具9码(弹夹穴位9)
  10444. d1VehicleCode9 = d1VehicleCode9.Replace("\0", "");
  10445. string d1VehicleCode10 = (string)s4PLCData["d1VehicleCode10"]; // 载具10码(弹夹穴位10)
  10446. d1VehicleCode10 = d1VehicleCode10.Replace("\0", "");
  10447. string d1VehicleCode11 = (string)s4PLCData["d1VehicleCode11"]; // 载具11码(弹夹穴位11)
  10448. d1VehicleCode11 = d1VehicleCode11.Replace("\0", "");
  10449. string d1VehicleCode12 = (string)s4PLCData["d1VehicleCode12"]; // 载具12码(弹夹穴位12)
  10450. d1VehicleCode12 = d1VehicleCode12.Replace("\0", "");
  10451. string d1VehicleCode13 = (string)s4PLCData["d1VehicleCode13"]; // 载具13码(弹夹穴位13)
  10452. d1VehicleCode13 = d1VehicleCode13.Replace("\0", "");
  10453. string d1VehicleCode14 = (string)s4PLCData["d1VehicleCode14"]; // 载具14码(弹夹穴位14)
  10454. d1VehicleCode14 = d1VehicleCode14.Replace("\0", "");
  10455. string d1VehicleCode15 = (string)s4PLCData["d1VehicleCode15"]; // 载具15码(弹夹穴位15)
  10456. d1VehicleCode15 = d1VehicleCode15.Replace("\0", "");
  10457. int d1Result = (int)s4PLCData["d1Result"]; // 产品结果
  10458. bool pass = d1Result == 1;
  10459. // 存 载具SN列表
  10460. List<string> vehicleCodes = new List<string>()
  10461. {
  10462. d1VehicleCode1, d1VehicleCode2, d1VehicleCode3, d1VehicleCode4, d1VehicleCode5,
  10463. d1VehicleCode6, d1VehicleCode7, d1VehicleCode8, d1VehicleCode9, d1VehicleCode10,
  10464. d1VehicleCode11, d1VehicleCode12, d1VehicleCode13, d1VehicleCode14, d1VehicleCode15
  10465. };
  10466. // 统一查 产品SN列表
  10467. List<string> partNos = new List<string>();
  10468. foreach (string vehicleCode in vehicleCodes)
  10469. {
  10470. if (string.IsNullOrEmpty(vehicleCode))
  10471. partNos.Add("");
  10472. else
  10473. {
  10474. string partNo = "";
  10475. #region 查询载具上的产品信息
  10476. string cavityData = string.Empty;
  10477. int snResult = XiaomiMES_RouteCommunication.SNQueryData(vehicleCode, ref cavityData);
  10478. if (string.IsNullOrEmpty(cavityData))
  10479. cavityData = "";
  10480. if (snResult != 0)
  10481. {
  10482. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10483. writeToPLC_Flag1.Name = "d1MES_FLAG";
  10484. writeToPLC_Flag1.Adress = 2065;
  10485. writeToPLC_Flag1.Value = (short)4;
  10486. SxPLCWriteData_Add(ref s4PLCWriteData, "d1MES_FLAG", writeToPLC_Flag1);
  10487. stopwatch1.Stop();
  10488. AddMessage(LogType.Info,
  10489. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  10490. "ms");
  10491. return;
  10492. }
  10493. string[] cavitySNs = cavityData.Split('.');
  10494. if (cavitySNs != null && cavitySNs.Length >= 1)
  10495. partNo = cavitySNs[0];
  10496. #endregion 查询载具上的产品信息
  10497. partNos.Add(partNo);
  10498. }
  10499. }
  10500. // 统一上传
  10501. stopwatch2.Start();
  10502. List<int> results = new List<int>();
  10503. for (int i = 0; i < partNos.Count; i++)
  10504. {
  10505. string index = (i + 1).ToString(); // 弹夹穴号
  10506. if (string.IsNullOrEmpty(partNos[i]))
  10507. results.Add(1);
  10508. else
  10509. {
  10510. List<TestItem> items1 = new List<TestItem>();
  10511. items1.Add(new TestItem()
  10512. {
  10513. Parameter_name = "弹夹码",
  10514. Parameter_value = sn,
  10515. Parameter_unit = ""
  10516. });
  10517. items1.Add(new TestItem()
  10518. {
  10519. Parameter_name = "弹夹穴号",
  10520. Parameter_value = index,
  10521. Parameter_unit = ""
  10522. });
  10523. items1.Add(new TestItem()
  10524. {
  10525. Parameter_name = "载具码",
  10526. Parameter_value = vehicleCodes[i],
  10527. Parameter_unit = ""
  10528. });
  10529. items1.Add(new TestItem()
  10530. {
  10531. Parameter_name = "载具穴号",
  10532. Parameter_value = "1",
  10533. Parameter_unit = ""
  10534. });
  10535. items1.Add(new TestItem()
  10536. {
  10537. Parameter_name = "产品结果",
  10538. Parameter_value = d1Result == 1 ? "OK" : "NG",
  10539. Parameter_unit = ""
  10540. });
  10541. int result1 = SwitctProcessData_old(stationNameStr, items1, equipmentCode, processItem
  10542. , workorder_code, mtltmrk, partNos[i], pass, sn, index);
  10543. results.Add(result1);
  10544. }
  10545. }
  10546. short result = 0;
  10547. if (results.All(a => a == 1))
  10548. result = 1;
  10549. else if (results.Contains(3))
  10550. result = 3;
  10551. else if (results.Contains(2))
  10552. result = 2;
  10553. else if (results.Contains(4))
  10554. result = 4;
  10555. else
  10556. result = 4;
  10557. stopwatch2.Stop();
  10558. #region 存储绑定数据到 边线MES系统中
  10559. if (result == 1)
  10560. {
  10561. string data = string.Join(".", vehicleCodes);
  10562. int resultMesR = XiaomiMES_RouteCommunication.SNBindData(sn, data);
  10563. if (resultMesR != 0)
  10564. {
  10565. result = 4;
  10566. AddMessage_Station(stationNameStr, LogType.Error,
  10567. $"PLC{plcNo}_[{equipmentCode}]{processItem}_出站接口失败!MES边线程序返回:{resultMesR}");
  10568. }
  10569. }
  10570. #endregion 存储绑定数据到 边线MES系统中
  10571. // MES_Flag 为4MES报错
  10572. //Funs[plcNo].WriteMultipleRegisters<short>(2065, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  10573. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10574. writeToPLC_Flag.Name = "d1MES_FLAG";
  10575. writeToPLC_Flag.Adress = 2065;
  10576. writeToPLC_Flag.Value = result;
  10577. SxPLCWriteData_Add(ref s4PLCWriteData, "d1MES_FLAG", writeToPLC_Flag);
  10578. OnMessage(LogType.Debug,
  10579. $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  10580. }
  10581. catch (Exception ex)
  10582. {
  10583. stopwatch2.Restart();
  10584. // MES_Flag 为4上位机报错
  10585. //Funs[plcNo].WriteMultipleRegisters<short>(2065, (short)4); // 4代表上位机报警
  10586. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10587. writeToPLC_Flag.Name = "d1MES_FLAG";
  10588. writeToPLC_Flag.Adress = 2065;
  10589. writeToPLC_Flag.Value = (short)4;
  10590. SxPLCWriteData_Add(ref s4PLCWriteData, "d1MES_FLAG", writeToPLC_Flag);
  10591. stopwatch2.Stop();
  10592. string str = ex.StackTrace;
  10593. AddMessage_Station(stationNameStr, LogType.Error,
  10594. $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  10595. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10596. }
  10597. stopwatch1.Stop();
  10598. AddMessage(LogType.Info,
  10599. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  10600. stopwatch2.ElapsedMilliseconds + "ms");
  10601. }
  10602. /// <summary>
  10603. /// [S4] 取放桁架 - S4_1节拍接口
  10604. /// </summary>
  10605. /// <param name="plcNo">PLC编号</param>
  10606. /// <param name="stationNameStr">工站全称</param>
  10607. private void S4_1节拍接口(int plcNo, string stationNameStr)
  10608. {
  10609. Stopwatch stopwatch1 = new Stopwatch();
  10610. Stopwatch stopwatch2 = new Stopwatch();
  10611. string resultStr = string.Empty;
  10612. try
  10613. {
  10614. stopwatch1.Start();
  10615. string oEEType = ((int)s4PLCData["d1OEEType"]).ToString(); // 节拍类型(plc写入)
  10616. string d1OEEProductSN = (string)s4PLCData["d1OEEProductSN"]; // 载具SN
  10617. d1OEEProductSN = d1OEEProductSN.Replace("\0", "");
  10618. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  10619. if (!actionBool)
  10620. {
  10621. stopwatch2.Start();
  10622. // MES_Flag
  10623. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)4); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  10624. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10625. writeToPLC_Flag1.Name = "d1OEEMES_FLAG";
  10626. writeToPLC_Flag1.Adress = 2398;
  10627. writeToPLC_Flag1.Value = (short)4;
  10628. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag1);
  10629. stopwatch2.Stop();
  10630. AddMessage(LogType.Info,
  10631. stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds +
  10632. "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  10633. return;
  10634. }
  10635. string d1OEEPartNo = string.Empty; // 物料码
  10636. if (string.IsNullOrEmpty(d1OEEProductSN))
  10637. {
  10638. stopwatch2.Start();
  10639. // MES_Flag
  10640. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  10641. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10642. writeToPLC_Flag1.Name = "d1OEEMES_FLAG";
  10643. writeToPLC_Flag1.Adress = 2398;
  10644. writeToPLC_Flag1.Value = (short)1;
  10645. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag1);
  10646. stopwatch2.Stop();
  10647. AddMessage(LogType.Info,
  10648. stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  10649. stopwatch2.ElapsedMilliseconds + "ms");
  10650. return;
  10651. }
  10652. else
  10653. {
  10654. // 查产品SN ZS
  10655. d1OEEPartNo = "Test";
  10656. }
  10657. short d1OEEMES_FLAG = 0;
  10658. // 上传OEE
  10659. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, d1OEEPartNo, d1OEEProductSN);
  10660. d1OEEMES_FLAG = result.Item1;
  10661. resultStr = result.Item2;
  10662. stopwatch2.Start();
  10663. // MES_Flag
  10664. //Funs[plcNo].WriteMultipleRegisters<short>(2398, d1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  10665. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10666. writeToPLC_Flag.Name = "d1OEEMES_FLAG";
  10667. writeToPLC_Flag.Adress = 2398;
  10668. writeToPLC_Flag.Value = d1OEEMES_FLAG;
  10669. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag);
  10670. stopwatch2.Stop();
  10671. }
  10672. catch (Exception ex)
  10673. {
  10674. string str = ex.StackTrace;
  10675. AddMessage_Station(stationNameStr, LogType.Error,
  10676. $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" +
  10677. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10678. // MES_Flag
  10679. stopwatch2.Start();
  10680. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)4); // 4代表上位机报警
  10681. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10682. writeToPLC_Flag.Name = "d1OEEMES_FLAG";
  10683. writeToPLC_Flag.Adress = 2398;
  10684. writeToPLC_Flag.Value = (short)4;
  10685. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag);
  10686. stopwatch2.Stop();
  10687. }
  10688. stopwatch1.Stop();
  10689. AddMessage(LogType.Info,
  10690. stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  10691. stopwatch2.ElapsedMilliseconds + "ms");
  10692. }
  10693. /// <summary>
  10694. /// [S4] 取放桁架 - S4_2桁架
  10695. /// </summary>
  10696. /// <param name="plcNo">PLC编号</param>
  10697. /// <param name="stationNameStr">工站全称</param>
  10698. private void S4_2桁架(int plcNo, string stationNameStr)
  10699. {
  10700. Stopwatch stopwatch1 = new Stopwatch();
  10701. Stopwatch stopwatch2 = new Stopwatch();
  10702. try
  10703. {
  10704. stopwatch1.Start();
  10705. // ZS 弹夹扫码
  10706. string d2BulletclipCode = " "; // 扫到的码
  10707. short d2BulletclipStates = 1; // 弹夹状态(上位机写入)
  10708. short d2BulletclipScanCode = 2;
  10709. stopwatch2.Start();
  10710. //Funs[plcNo].WriteMultipleRegisters<string>(2432, d2BulletclipCode, 20); // 扫到的码
  10711. //Funs[plcNo].WriteMultipleRegisters<short>(2431, d2BulletclipStates); // 弹夹状态(上位机写入)
  10712. //// MES_Flag
  10713. //Funs[plcNo].WriteMultipleRegisters<short>(2430, d2BulletclipScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  10714. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10715. writeToPLC_Flag.Name = "d2BulletclipScanCode";
  10716. writeToPLC_Flag.Adress = 2430;
  10717. writeToPLC_Flag.Value = d2BulletclipScanCode;
  10718. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10719. {
  10720. Name = "d2BulletclipCode",
  10721. Adress = 2432,
  10722. ValueType = PLCValueType.String,
  10723. ValueTypeStrLength = 20,
  10724. Value = d2BulletclipCode
  10725. });
  10726. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10727. {
  10728. Name = "d2BulletclipStates",
  10729. Adress = 2431,
  10730. ValueType = PLCValueType.Short,
  10731. Value = d2BulletclipStates
  10732. });
  10733. SxPLCWriteData_Add(ref s4PLCWriteData, "d2BulletclipScanCode", writeToPLC_Flag);
  10734. stopwatch2.Stop();
  10735. }
  10736. catch (Exception ex)
  10737. {
  10738. string str = ex.StackTrace;
  10739. AddMessage_Station(stationNameStr, LogType.Error,
  10740. $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" +
  10741. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10742. stopwatch2.Start();
  10743. Funs[plcNo].WriteMultipleRegisters<string>(2432, " ", 20);
  10744. Funs[plcNo].WriteMultipleRegisters<short>(2431, (short)0);
  10745. // MES_Flag
  10746. Funs[plcNo].WriteMultipleRegisters<short>(2430, (short)6); // 6代表上位机报警
  10747. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10748. writeToPLC_Flag.Name = "d2BulletclipScanCode";
  10749. writeToPLC_Flag.Adress = 2430;
  10750. writeToPLC_Flag.Value = (short)6;
  10751. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10752. {
  10753. Name = "d2BulletclipCode",
  10754. Adress = 2432,
  10755. ValueType = PLCValueType.String,
  10756. ValueTypeStrLength = 20,
  10757. Value = " "
  10758. });
  10759. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  10760. {
  10761. Name = "d2BulletclipStates",
  10762. Adress = 2431,
  10763. ValueType = PLCValueType.Short,
  10764. Value = (short)0
  10765. });
  10766. SxPLCWriteData_Add(ref s4PLCWriteData, "d2BulletclipScanCode", writeToPLC_Flag);
  10767. stopwatch2.Stop();
  10768. }
  10769. stopwatch1.Stop();
  10770. AddMessage(LogType.Info,
  10771. stationNameStr + "_弹夹扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  10772. stopwatch2.ElapsedMilliseconds + "ms");
  10773. }
  10774. // 上次采集到的SN
  10775. //private string sn_S4_3进站接口 = string.Empty;
  10776. /// <summary>
  10777. /// [S4] 取放桁架 - S4_3进站接口(提升机1)
  10778. /// </summary>
  10779. private void S4_3进站接口(int plcNo, string stationNameStr)
  10780. {
  10781. Stopwatch stopwatch1 = new Stopwatch();
  10782. Stopwatch stopwatch2 = new Stopwatch();
  10783. try
  10784. {
  10785. stopwatch1.Start();
  10786. string sn = (string)s4PLCData["d3ProductSN"]; // 产品SN(弹夹码)
  10787. sn = sn.Replace("\0", "");
  10788. int d3Result = (int)s4PLCData["d3Result"]; // 产品结果
  10789. #region 查询15个载具码
  10790. List<string> vehicleCodes = new List<string>(); // 15个载具码
  10791. string vehicleData = string.Empty;
  10792. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref vehicleData);
  10793. if (string.IsNullOrEmpty(vehicleData))
  10794. vehicleData = "";
  10795. if (snResult != 0)
  10796. {
  10797. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10798. writeToPLC_Flag1.Name = "d3MES_FLAG";
  10799. writeToPLC_Flag1.Adress = 2463;
  10800. writeToPLC_Flag1.Value = (short)4;
  10801. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag1);
  10802. stopwatch1.Stop();
  10803. AddMessage(LogType.Info,
  10804. stationNameStr + $"_进站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  10805. return;
  10806. }
  10807. string[] cavitySNs = vehicleData.Split('.');
  10808. if (cavitySNs != null && cavitySNs.Length > 0)
  10809. {
  10810. for (int i = 0; i < cavitySNs.Length; i++)
  10811. {
  10812. if (string.IsNullOrEmpty(cavitySNs[i]))
  10813. vehicleCodes.Add("");
  10814. else
  10815. vehicleCodes.Add(cavitySNs[i]);
  10816. }
  10817. }
  10818. #endregion 查询15个载具码
  10819. #region 查询15个产品SN
  10820. List<string> portNos = new List<string>(); // 15个产品SN
  10821. foreach (string vehicleCode in vehicleCodes)
  10822. {
  10823. if (string.IsNullOrEmpty(vehicleCode))
  10824. portNos.Add("");
  10825. else
  10826. {
  10827. // 查询
  10828. string cavityData = string.Empty;
  10829. int snResult1 = XiaomiMES_RouteCommunication.SNQueryData(vehicleCode, ref cavityData);
  10830. if (string.IsNullOrEmpty(cavityData))
  10831. cavityData = "";
  10832. if (snResult1 != 0)
  10833. {
  10834. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10835. writeToPLC_Flag1.Name = "d3MES_FLAG";
  10836. writeToPLC_Flag1.Adress = 2463;
  10837. writeToPLC_Flag1.Value = (short)4;
  10838. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag1);
  10839. stopwatch1.Stop();
  10840. AddMessage(LogType.Info,
  10841. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult1};总用时" +
  10842. stopwatch1.ElapsedMilliseconds + "ms");
  10843. return;
  10844. }
  10845. string[] partSNs = cavityData.Split('.');
  10846. if (partSNs != null && partSNs.Length >= 1)
  10847. portNos.Add(partSNs[0]);
  10848. else
  10849. portNos.Add("");
  10850. }
  10851. }
  10852. #endregion 查询15个产品SN
  10853. // 调用MES进站(最多15个)
  10854. stopwatch2.Start();
  10855. List<int> results = new int[15].ToList(); // 结果集;0代表产品为空
  10856. for (int i = 0; i < vehicleCodes.Count; i++)
  10857. {
  10858. // 循环进站
  10859. if (!string.IsNullOrEmpty(vehicleCodes[i]))
  10860. {
  10861. // 产品SN(物料码)校验
  10862. string portNo = portNos[i];
  10863. List<TestItem> item = new List<TestItem>();
  10864. item.Add(new TestItem()
  10865. {
  10866. Parameter_name = "弹夹码",
  10867. Parameter_value = sn,
  10868. });
  10869. item.Add(new TestItem()
  10870. {
  10871. Parameter_name = "弹夹穴位",
  10872. Parameter_value = (i + 1).ToString(),
  10873. });
  10874. item.Add(new TestItem()
  10875. {
  10876. Parameter_name = "载具码",
  10877. Parameter_value = vehicleCodes[i],
  10878. });
  10879. item.Add(new TestItem()
  10880. {
  10881. Parameter_name = "载具穴号",
  10882. Parameter_value = "1",
  10883. });
  10884. results[i] = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode,
  10885. GlobalContext.Mtltmrk, portNo, item, out string errorMsg);
  10886. }
  10887. }
  10888. stopwatch2.Stop();
  10889. short result = 0;
  10890. bool haveMesWarn = results.Contains(5);
  10891. bool havePCWarn = results.Contains(6);
  10892. if (haveMesWarn)
  10893. result = 2; // 5->2
  10894. else if (havePCWarn)
  10895. result = 6; // 6->4
  10896. else
  10897. result = 1;
  10898. // MES_Flag 为4MES报错
  10899. //Funs[plcNo].WriteMultipleRegisters<short>(2463, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  10900. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10901. writeToPLC_Flag.Name = "d3MES_FLAG";
  10902. writeToPLC_Flag.Adress = 2463;
  10903. writeToPLC_Flag.Value = result;
  10904. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  10905. OnMessage(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  10906. }
  10907. catch (Exception ex)
  10908. {
  10909. stopwatch2.Stop();
  10910. // MES_Flag 为4上位机报错
  10911. //Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)4); // 4代表上位机报警
  10912. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  10913. writeToPLC_Flag.Name = "d3MES_FLAG";
  10914. writeToPLC_Flag.Adress = 2463;
  10915. writeToPLC_Flag.Value = (short)4;
  10916. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  10917. string str = ex.StackTrace;
  10918. AddMessage_Station(stationNameStr, LogType.Error,
  10919. $"PLC{plcNo}_{stationNameStr}S4_3进站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  10920. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  10921. }
  10922. stopwatch1.Stop();
  10923. AddMessage(LogType.Info,
  10924. stationNameStr + "_S4_3进站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  10925. stopwatch2.ElapsedMilliseconds + "ms");
  10926. }
  10927. // 上次采集到的SN
  10928. //private string sn_S4_3出站接口 = string.Empty;
  10929. /// <summary>
  10930. /// [S4] 取放桁架 - S4_3出站接口(提升机1)
  10931. /// </summary>
  10932. private void S4_3出站接口(int plcNo, string stationCode, string stationName)
  10933. {
  10934. Stopwatch stopwatch1 = new Stopwatch();
  10935. Stopwatch stopwatch2 = new Stopwatch();
  10936. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  10937. string stationNameStr = stationCode + stationName;
  10938. string processItem = stationName; // 测试项目
  10939. try
  10940. {
  10941. stopwatch1.Start();
  10942. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  10943. //string batch_num = GlobalContext.BatchNumber; // 批次号
  10944. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  10945. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  10946. string sn = (string)s4PLCData["d3ProductSN"]; // 产品SN(弹夹码)
  10947. sn = sn.Replace("\0", "");
  10948. int d3Result = (int)s4PLCData["d3Result"]; // 产品结果
  10949. bool isPass = d3Result == 1; // 产品结果 bool
  10950. #region 查询15个载具码
  10951. List<string> vehicleCodes = new List<string>(); // 15个载具码
  10952. string vehicleData = string.Empty;
  10953. int snResult1 = XiaomiMES_RouteCommunication.SNQueryData(sn, ref vehicleData);
  10954. if (string.IsNullOrEmpty(vehicleData))
  10955. vehicleData = "";
  10956. if (snResult1 != 0)
  10957. {
  10958. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10959. writeToPLC_Flag1.Name = "d3MES_FLAG";
  10960. writeToPLC_Flag1.Adress = 2463;
  10961. writeToPLC_Flag1.Value = (short)4;
  10962. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag1);
  10963. stopwatch1.Stop();
  10964. AddMessage(LogType.Info,
  10965. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult1};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  10966. return;
  10967. }
  10968. string[] cavitySNs = vehicleData.Split('.');
  10969. if (cavitySNs != null && cavitySNs.Length > 0)
  10970. {
  10971. for (int i = 0; i < cavitySNs.Length; i++)
  10972. {
  10973. if (string.IsNullOrEmpty(cavitySNs[i]))
  10974. vehicleCodes.Add("");
  10975. else
  10976. vehicleCodes.Add(cavitySNs[i]);
  10977. }
  10978. }
  10979. #endregion 查询15个载具码
  10980. // 统一查 产品SN列表
  10981. List<string> partNos = new List<string>();
  10982. foreach (string vehicleCode in vehicleCodes)
  10983. {
  10984. if (string.IsNullOrEmpty(vehicleCode))
  10985. partNos.Add("");
  10986. else
  10987. {
  10988. string partNo = "";
  10989. #region 查询载具上的产品信息
  10990. string cavityData = string.Empty;
  10991. int snResult = XiaomiMES_RouteCommunication.SNQueryData(vehicleCode, ref cavityData);
  10992. if (string.IsNullOrEmpty(cavityData))
  10993. cavityData = "";
  10994. if (snResult != 0)
  10995. {
  10996. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  10997. writeToPLC_Flag1.Name = "d3MES_FLAG";
  10998. writeToPLC_Flag1.Adress = 2463;
  10999. writeToPLC_Flag1.Value = (short)4;
  11000. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag1);
  11001. stopwatch1.Stop();
  11002. AddMessage(LogType.Info,
  11003. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  11004. "ms");
  11005. return;
  11006. }
  11007. string[] partSNs = cavityData.Split('.');
  11008. if (partSNs != null && partSNs.Length >= 1)
  11009. partNo = partSNs[0];
  11010. #endregion 查询载具上的产品信息
  11011. partNos.Add(partNo);
  11012. }
  11013. }
  11014. // 统一上传 - 调用MES出站
  11015. stopwatch2.Start();
  11016. List<int> results = new List<int>();
  11017. for (int i = 0; i < partNos.Count; i++)
  11018. {
  11019. string index = (i + 1).ToString(); // 弹夹穴号
  11020. if (string.IsNullOrEmpty(partNos[i]))
  11021. results.Add(1);
  11022. else
  11023. {
  11024. List<TestItem> items1 = new List<TestItem>();
  11025. items1.Add(new TestItem()
  11026. {
  11027. Parameter_name = "弹夹码",
  11028. Parameter_value = sn,
  11029. Parameter_unit = ""
  11030. });
  11031. items1.Add(new TestItem()
  11032. {
  11033. Parameter_name = "弹夹穴号",
  11034. Parameter_value = index,
  11035. Parameter_unit = ""
  11036. });
  11037. items1.Add(new TestItem()
  11038. {
  11039. Parameter_name = "载具码",
  11040. Parameter_value = vehicleCodes[i],
  11041. Parameter_unit = ""
  11042. });
  11043. items1.Add(new TestItem()
  11044. {
  11045. Parameter_name = "载具穴号",
  11046. Parameter_value = "1",
  11047. Parameter_unit = ""
  11048. });
  11049. items1.Add(new TestItem()
  11050. {
  11051. Parameter_name = "产品结果",
  11052. Parameter_value = d3Result == 1 ? "OK" : "NG",
  11053. Parameter_unit = ""
  11054. });
  11055. int result1 = SwitctProcessData_old(stationNameStr, items1, equipmentCode, processItem
  11056. , workorder_code, mtltmrk, partNos[i], isPass, sn, index);
  11057. results.Add(result1);
  11058. }
  11059. }
  11060. short result = 0;
  11061. if (results.All(a => a == 1))
  11062. result = 1;
  11063. else if (results.Contains(3))
  11064. result = 3;
  11065. else if (results.Contains(2))
  11066. result = 2;
  11067. else if (results.Contains(4))
  11068. result = 4;
  11069. else
  11070. result = 4;
  11071. stopwatch2.Stop();
  11072. // MES_Flag 为4MES报错
  11073. //Funs[plcNo].WriteMultipleRegisters<short>(2463, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  11074. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11075. writeToPLC_Flag.Name = "d3MES_FLAG";
  11076. writeToPLC_Flag.Adress = 2463;
  11077. writeToPLC_Flag.Value = result;
  11078. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  11079. OnMessage(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  11080. }
  11081. catch (Exception ex)
  11082. {
  11083. stopwatch2.Restart();
  11084. // MES_Flag 为4上位机报错
  11085. //Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)4); // 4代表上位机报警
  11086. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11087. writeToPLC_Flag.Name = "d3MES_FLAG";
  11088. writeToPLC_Flag.Adress = 2463;
  11089. writeToPLC_Flag.Value = (short)4;
  11090. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  11091. string str = ex.StackTrace;
  11092. AddMessage_Station(stationNameStr, LogType.Error,
  11093. $"PLC{plcNo}_{stationNameStr}S4_3出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  11094. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11095. stopwatch2.Stop();
  11096. }
  11097. stopwatch1.Stop();
  11098. AddMessage(LogType.Info,
  11099. stationNameStr + "_S4_3出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  11100. stopwatch2.ElapsedMilliseconds + "ms");
  11101. }
  11102. // 上次采集到的SN
  11103. //private string sn_S4_4进站接口 = string.Empty;
  11104. /// <summary>
  11105. /// [S4] 取放桁架 - S4_4进站接口(提升机2)
  11106. /// </summary>
  11107. private void S4_4进站接口(int plcNo, string stationNameStr)
  11108. {
  11109. Stopwatch stopwatch1 = new Stopwatch();
  11110. Stopwatch stopwatch2 = new Stopwatch();
  11111. try
  11112. {
  11113. stopwatch1.Start();
  11114. string sn = (string)s4PLCData["d4ProductSN"]; // 产品SN(弹夹码)
  11115. sn = sn.Replace("\0", "");
  11116. int d4Result = (int)s4PLCData["d4Result"]; // 产品结果
  11117. #region 查询15个载具码
  11118. List<string> vehicleCodes = new List<string>(); // 15个载具码
  11119. string vehicleData = string.Empty;
  11120. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref vehicleData);
  11121. if (string.IsNullOrEmpty(vehicleData))
  11122. vehicleData = "";
  11123. if (snResult != 0)
  11124. {
  11125. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11126. writeToPLC_Flag1.Name = "d3MES_FLAG";
  11127. writeToPLC_Flag1.Adress = 2463;
  11128. writeToPLC_Flag1.Value = (short)4;
  11129. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag1);
  11130. stopwatch1.Stop();
  11131. AddMessage(LogType.Info,
  11132. stationNameStr + $"_进站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  11133. return;
  11134. }
  11135. string[] cavitySNs = vehicleData.Split('.');
  11136. if (cavitySNs != null && cavitySNs.Length > 0)
  11137. {
  11138. for (int i = 0; i < cavitySNs.Length; i++)
  11139. {
  11140. if (string.IsNullOrEmpty(cavitySNs[i]))
  11141. vehicleCodes.Add("");
  11142. else
  11143. vehicleCodes.Add(cavitySNs[i]);
  11144. }
  11145. }
  11146. #endregion 查询15个载具码
  11147. #region 查询15个产品SN
  11148. List<string> portNos = new List<string>(); // 15个产品SN
  11149. foreach (string vehicleCode in vehicleCodes)
  11150. {
  11151. if (string.IsNullOrEmpty(vehicleCode))
  11152. portNos.Add("");
  11153. else
  11154. {
  11155. // 查询
  11156. string cavityData = string.Empty;
  11157. int snResult1 = XiaomiMES_RouteCommunication.SNQueryData(vehicleCode, ref cavityData);
  11158. if (string.IsNullOrEmpty(cavityData))
  11159. cavityData = "";
  11160. if (snResult1 != 0)
  11161. {
  11162. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11163. writeToPLC_Flag1.Name = "d3MES_FLAG";
  11164. writeToPLC_Flag1.Adress = 2463;
  11165. writeToPLC_Flag1.Value = (short)4;
  11166. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag1);
  11167. stopwatch1.Stop();
  11168. AddMessage(LogType.Info,
  11169. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult1};总用时" +
  11170. stopwatch1.ElapsedMilliseconds + "ms");
  11171. return;
  11172. }
  11173. string[] partSNs = cavityData.Split('.');
  11174. if (partSNs != null && partSNs.Length >= 1)
  11175. portNos.Add(partSNs[0]);
  11176. else
  11177. portNos.Add("");
  11178. }
  11179. }
  11180. #endregion 查询15个产品SN
  11181. // 调用MES进站(最多15个)
  11182. stopwatch2.Start();
  11183. List<int> results = new int[15].ToList(); // 结果集;0代表产品为空
  11184. for (int i = 0; i < vehicleCodes.Count; i++)
  11185. {
  11186. // 循环进站
  11187. if (!string.IsNullOrEmpty(vehicleCodes[i]))
  11188. {
  11189. // 产品SN(物料码)校验
  11190. string portNo = portNos[i];
  11191. List<TestItem> item = new List<TestItem>();
  11192. item.Add(new TestItem()
  11193. {
  11194. Parameter_name = "弹夹码",
  11195. Parameter_value = sn,
  11196. });
  11197. item.Add(new TestItem()
  11198. {
  11199. Parameter_name = "弹夹穴位",
  11200. Parameter_value = (i + 1).ToString(),
  11201. });
  11202. item.Add(new TestItem()
  11203. {
  11204. Parameter_name = "载具码",
  11205. Parameter_value = vehicleCodes[i],
  11206. });
  11207. item.Add(new TestItem()
  11208. {
  11209. Parameter_name = "载具穴号",
  11210. Parameter_value = "1",
  11211. });
  11212. results[i] = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode,
  11213. GlobalContext.Mtltmrk, portNo, item, out string errorMsg);
  11214. }
  11215. }
  11216. stopwatch2.Stop();
  11217. short result = 0;
  11218. bool haveMesWarn = results.Contains(5);
  11219. bool havePCWarn = results.Contains(6);
  11220. if (haveMesWarn)
  11221. result = 2; // 5->2
  11222. else if (havePCWarn)
  11223. result = 6; // 6->4
  11224. else
  11225. result = 1;
  11226. // MES_Flag 为4MES报错
  11227. //Funs[plcNo].WriteMultipleRegisters<short>(2496, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  11228. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11229. writeToPLC_Flag.Name = "d4MES_FLAG";
  11230. writeToPLC_Flag.Adress = 2496;
  11231. writeToPLC_Flag.Value = result;
  11232. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  11233. OnMessage(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  11234. }
  11235. catch (Exception ex)
  11236. {
  11237. stopwatch2.Stop();
  11238. // MES_Flag 为4上位机报错
  11239. //Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)4); // 4代表上位机报警
  11240. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11241. writeToPLC_Flag.Name = "d4MES_FLAG";
  11242. writeToPLC_Flag.Adress = 2496;
  11243. writeToPLC_Flag.Value = (short)4;
  11244. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  11245. string str = ex.StackTrace;
  11246. AddMessage_Station(stationNameStr, LogType.Error,
  11247. $"PLC{plcNo}_{stationNameStr}S4_4进站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  11248. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11249. }
  11250. stopwatch1.Stop();
  11251. AddMessage(LogType.Info,
  11252. stationNameStr + "_S4_4进站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  11253. stopwatch2.ElapsedMilliseconds + "ms");
  11254. }
  11255. // 上次采集到的SN
  11256. //private string sn_S4_4出站接口 = string.Empty;
  11257. /// <summary>
  11258. /// [S4] 取放桁架 - S4_4出站接口(提升机2)
  11259. /// </summary>
  11260. private void S4_4出站接口(int plcNo, string stationCode, string stationName)
  11261. {
  11262. Stopwatch stopwatch1 = new Stopwatch();
  11263. Stopwatch stopwatch2 = new Stopwatch();
  11264. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  11265. string stationNameStr = stationCode + stationName;
  11266. string processItem = stationName; // 测试项目
  11267. try
  11268. {
  11269. stopwatch1.Start();
  11270. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  11271. //string batch_num = GlobalContext.BatchNumber; // 批次号
  11272. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  11273. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  11274. string sn = (string)s4PLCData["d4ProductSN"]; // 产品SN(弹夹码)
  11275. sn = sn.Replace("\0", "");
  11276. int d4Result = (int)s4PLCData["d4Result"]; // 产品结果
  11277. bool isPass = d4Result == 1; // 产品结果 bool
  11278. #region 查询15个载具码
  11279. List<string> vehicleCodes = new List<string>(); // 15个载具码
  11280. string vehicleData = string.Empty;
  11281. int snResult1 = XiaomiMES_RouteCommunication.SNQueryData(sn, ref vehicleData);
  11282. if (string.IsNullOrEmpty(vehicleData))
  11283. vehicleData = "";
  11284. if (snResult1 != 0)
  11285. {
  11286. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11287. writeToPLC_Flag1.Name = "d4MES_FLAG";
  11288. writeToPLC_Flag1.Adress = 2496;
  11289. writeToPLC_Flag1.Value = (short)4;
  11290. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag1);
  11291. stopwatch1.Stop();
  11292. AddMessage(LogType.Info,
  11293. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult1};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  11294. return;
  11295. }
  11296. string[] cavitySNs = vehicleData.Split('.');
  11297. if (cavitySNs != null && cavitySNs.Length > 0)
  11298. {
  11299. for (int i = 0; i < cavitySNs.Length; i++)
  11300. {
  11301. if (string.IsNullOrEmpty(cavitySNs[i]))
  11302. vehicleCodes.Add("");
  11303. else
  11304. vehicleCodes.Add(cavitySNs[i]);
  11305. }
  11306. }
  11307. #endregion 查询15个载具码
  11308. // 统一查 产品SN列表
  11309. List<string> partNos = new List<string>();
  11310. foreach (string vehicleCode in vehicleCodes)
  11311. {
  11312. if (string.IsNullOrEmpty(vehicleCode))
  11313. partNos.Add("");
  11314. else
  11315. {
  11316. string partNo = "";
  11317. #region 查询载具上的产品信息
  11318. string cavityData = string.Empty;
  11319. int snResult = XiaomiMES_RouteCommunication.SNQueryData(vehicleCode, ref cavityData);
  11320. if (string.IsNullOrEmpty(cavityData))
  11321. cavityData = "";
  11322. if (snResult != 0)
  11323. {
  11324. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11325. writeToPLC_Flag1.Name = "d4MES_FLAG";
  11326. writeToPLC_Flag1.Adress = 2496;
  11327. writeToPLC_Flag1.Value = (short)4;
  11328. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag1);
  11329. stopwatch1.Stop();
  11330. AddMessage(LogType.Info,
  11331. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  11332. "ms");
  11333. return;
  11334. }
  11335. string[] partSNs = cavityData.Split('.');
  11336. if (partSNs != null && partSNs.Length >= 1)
  11337. partNo = partSNs[0];
  11338. #endregion 查询载具上的产品信息
  11339. partNos.Add(partNo);
  11340. }
  11341. }
  11342. // 调用MES出站
  11343. stopwatch2.Start();
  11344. // 统一上传
  11345. List<int> results = new List<int>();
  11346. for (int i = 0; i < partNos.Count; i++)
  11347. {
  11348. string index = (i + 1).ToString(); // 弹夹穴号
  11349. if (string.IsNullOrEmpty(partNos[i]))
  11350. results.Add(1);
  11351. else
  11352. {
  11353. List<TestItem> items1 = new List<TestItem>();
  11354. items1.Add(new TestItem()
  11355. {
  11356. Parameter_name = "弹夹码",
  11357. Parameter_value = sn,
  11358. Parameter_unit = ""
  11359. });
  11360. items1.Add(new TestItem()
  11361. {
  11362. Parameter_name = "弹夹穴号",
  11363. Parameter_value = index,
  11364. Parameter_unit = ""
  11365. });
  11366. items1.Add(new TestItem()
  11367. {
  11368. Parameter_name = "载具码",
  11369. Parameter_value = vehicleCodes[i],
  11370. Parameter_unit = ""
  11371. });
  11372. items1.Add(new TestItem()
  11373. {
  11374. Parameter_name = "载具穴号",
  11375. Parameter_value = "1",
  11376. Parameter_unit = ""
  11377. });
  11378. items1.Add(new TestItem()
  11379. {
  11380. Parameter_name = "产品结果",
  11381. Parameter_value = d4Result == 1 ? "OK" : "NG",
  11382. Parameter_unit = ""
  11383. });
  11384. int result1 = SwitctProcessData_old(stationNameStr, items1, equipmentCode, processItem
  11385. , workorder_code, mtltmrk, partNos[i], isPass, sn, index);
  11386. results.Add(result1);
  11387. }
  11388. }
  11389. short result = 0;
  11390. if (results.All(a => a == 1))
  11391. result = 1;
  11392. else if (results.Contains(3))
  11393. result = 3;
  11394. else if (results.Contains(2))
  11395. result = 2;
  11396. else if (results.Contains(4))
  11397. result = 4;
  11398. else
  11399. result = 4;
  11400. stopwatch2.Stop();
  11401. // MES_Flag 为4MES报错
  11402. //Funs[plcNo].WriteMultipleRegisters<short>(2496, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  11403. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11404. writeToPLC_Flag.Name = "d4MES_FLAG";
  11405. writeToPLC_Flag.Adress = 2496;
  11406. writeToPLC_Flag.Value = result;
  11407. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  11408. OnMessage(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  11409. }
  11410. catch (Exception ex)
  11411. {
  11412. stopwatch2.Restart();
  11413. // MES_Flag 为4上位机报错
  11414. //Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)4); // 4代表上位机报警
  11415. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11416. writeToPLC_Flag.Name = "d4MES_FLAG";
  11417. writeToPLC_Flag.Adress = 2496;
  11418. writeToPLC_Flag.Value = (short)4;
  11419. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  11420. string str = ex.StackTrace;
  11421. AddMessage_Station(stationNameStr, LogType.Error,
  11422. $"PLC{plcNo}_{stationNameStr}S4_4出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  11423. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11424. stopwatch2.Stop();
  11425. }
  11426. stopwatch1.Stop();
  11427. AddMessage(LogType.Info,
  11428. stationNameStr + "_S4_4出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  11429. stopwatch2.ElapsedMilliseconds + "ms");
  11430. }
  11431. /// <summary>
  11432. /// [S4] 取放桁架 - S4_5弹夹扫码
  11433. /// </summary>
  11434. /// <param name="plcNo">PLC编号</param>
  11435. /// <param name="stationNameStr">工站全称</param>
  11436. private void S4_5弹夹扫码(int plcNo, string stationNameStr)
  11437. {
  11438. Stopwatch stopwatch1 = new Stopwatch();
  11439. Stopwatch stopwatch2 = new Stopwatch();
  11440. try
  11441. {
  11442. stopwatch1.Start();
  11443. // ZS 弹夹扫码
  11444. string d5BulletclipCode = " "; // 扫到的码
  11445. short d5BulletclipScanCode = 2;
  11446. stopwatch2.Start();
  11447. //Funs[plcNo].WriteMultipleRegisters<string>(2529, d5BulletclipCode, 20);
  11448. //// MES_Flag
  11449. //Funs[plcNo].WriteMultipleRegisters<short>(2528, d5BulletclipScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  11450. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11451. writeToPLC_Flag.Name = "d5BulletclipScanCode";
  11452. writeToPLC_Flag.Adress = 2528;
  11453. writeToPLC_Flag.Value = d5BulletclipScanCode;
  11454. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  11455. {
  11456. Name = "d5BulletclipCode",
  11457. Adress = 2529,
  11458. ValueType = PLCValueType.String,
  11459. ValueTypeStrLength = 20,
  11460. Value = d5BulletclipCode
  11461. });
  11462. SxPLCWriteData_Add(ref s4PLCWriteData, "d5BulletclipScanCode", writeToPLC_Flag);
  11463. stopwatch2.Stop();
  11464. }
  11465. catch (Exception ex)
  11466. {
  11467. string str = ex.StackTrace;
  11468. AddMessage_Station(stationNameStr, LogType.Error,
  11469. $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" +
  11470. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11471. stopwatch2.Start();
  11472. //Funs[plcNo].WriteMultipleRegisters<string>(2529, " ", 20);
  11473. //// MES_Flag
  11474. //Funs[plcNo].WriteMultipleRegisters<short>(2528, (short)6); // 6代表上位机报警
  11475. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11476. writeToPLC_Flag.Name = "d5BulletclipScanCode";
  11477. writeToPLC_Flag.Adress = 2528;
  11478. writeToPLC_Flag.Value = (short)6;
  11479. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  11480. {
  11481. Name = "d5BulletclipCode",
  11482. Adress = 2529,
  11483. ValueType = PLCValueType.String,
  11484. ValueTypeStrLength = 20,
  11485. Value = " "
  11486. });
  11487. SxPLCWriteData_Add(ref s4PLCWriteData, "d5BulletclipScanCode", writeToPLC_Flag);
  11488. stopwatch2.Stop();
  11489. }
  11490. stopwatch1.Stop();
  11491. AddMessage(LogType.Info,
  11492. stationNameStr + "_弹夹扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  11493. stopwatch2.ElapsedMilliseconds + "ms");
  11494. }
  11495. /// <summary>
  11496. /// [S4] 取放桁架 - S4_5载具扫码
  11497. /// </summary>
  11498. /// <param name="plcNo">PLC编号</param>
  11499. /// <param name="stationNameStr">工站全称</param>
  11500. private void S4_5载具扫码(int plcNo, string stationNameStr)
  11501. {
  11502. Stopwatch stopwatch1 = new Stopwatch();
  11503. Stopwatch stopwatch2 = new Stopwatch();
  11504. try
  11505. {
  11506. stopwatch1.Start();
  11507. // ZS 载具扫码
  11508. string d5VehicleCode = " "; // 扫到的码
  11509. short d5VehicleScanCode = 2;
  11510. #region 进站
  11511. if (d5VehicleScanCode == 2 && !string.IsNullOrEmpty(d5VehicleCode))
  11512. {
  11513. // 查产品SN
  11514. #region 查询载具上的产品信息
  11515. string cavityData = string.Empty;
  11516. int snResult = XiaomiMES_RouteCommunication.SNQueryData(d5VehicleCode, ref cavityData);
  11517. if (string.IsNullOrEmpty(cavityData))
  11518. cavityData = "";
  11519. if (snResult != 0)
  11520. {
  11521. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11522. writeToPLC_Flag1.Name = "d5VehicleScanCode";
  11523. writeToPLC_Flag1.Adress = 2559;
  11524. writeToPLC_Flag1.Value = (short)6;
  11525. writeToPLC_Flag1.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  11526. {
  11527. Name = "d5VehicleCode",
  11528. Adress = 2560,
  11529. ValueType = PLCValueType.String,
  11530. ValueTypeStrLength = 20,
  11531. Value = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  11532. });
  11533. SxPLCWriteData_Add(ref s4PLCWriteData, "d5VehicleScanCode", writeToPLC_Flag1);
  11534. stopwatch1.Stop();
  11535. AddMessage(LogType.Info,
  11536. stationNameStr + $"_载具扫码失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  11537. "ms");
  11538. return;
  11539. }
  11540. string[] cavitySNs = cavityData.Split('.');
  11541. string partNo = "";
  11542. if (cavitySNs != null && cavitySNs.Length >= 1)
  11543. {
  11544. partNo = cavitySNs[0];
  11545. }
  11546. #endregion 查询载具上的产品信息
  11547. List<TestItem> item = new List<TestItem>();
  11548. item.Add(new TestItem()
  11549. {
  11550. Parameter_name = "载具码",
  11551. Parameter_value = d5VehicleCode,
  11552. });
  11553. item.Add(new TestItem()
  11554. {
  11555. Parameter_name = "载具穴号",
  11556. Parameter_value = "1",
  11557. });
  11558. stopwatch2.Start();
  11559. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  11560. partNo, item, out string errorMsg);
  11561. stopwatch2.Stop();
  11562. d5VehicleScanCode = (short)result == 1 ? d5VehicleScanCode : (short)result;
  11563. }
  11564. #endregion 进站
  11565. //Funs[plcNo].WriteMultipleRegisters<string>(2560, d5VehicleCode, 20);
  11566. //// MES_Flag
  11567. //Funs[plcNo].WriteMultipleRegisters<short>(2559, d5VehicleScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  11568. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11569. writeToPLC_Flag.Name = "d5VehicleScanCode";
  11570. writeToPLC_Flag.Adress = 2559;
  11571. writeToPLC_Flag.Value = d5VehicleScanCode;
  11572. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  11573. {
  11574. Name = "d5VehicleCode",
  11575. Adress = 2560,
  11576. ValueType = PLCValueType.String,
  11577. ValueTypeStrLength = 20,
  11578. Value = d5VehicleCode
  11579. });
  11580. SxPLCWriteData_Add(ref s4PLCWriteData, "d5VehicleScanCode", writeToPLC_Flag);
  11581. }
  11582. catch (Exception ex)
  11583. {
  11584. string str = ex.StackTrace;
  11585. AddMessage_Station(stationNameStr, LogType.Error,
  11586. $"PLC{plcNo}_{stationNameStr} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" +
  11587. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11588. stopwatch2.Start();
  11589. //Funs[plcNo].WriteMultipleRegisters<string>(2560, " ", 20);
  11590. //// MES_Flag
  11591. //Funs[plcNo].WriteMultipleRegisters<short>(2559, (short)6); // 6代表上位机报警
  11592. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11593. writeToPLC_Flag.Name = "d5VehicleScanCode";
  11594. writeToPLC_Flag.Adress = 2559;
  11595. writeToPLC_Flag.Value = (short)6;
  11596. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  11597. {
  11598. Name = "d5VehicleCode",
  11599. Adress = 2560,
  11600. ValueType = PLCValueType.String,
  11601. ValueTypeStrLength = 20,
  11602. Value = " "
  11603. });
  11604. SxPLCWriteData_Add(ref s4PLCWriteData, "d5VehicleScanCode", writeToPLC_Flag);
  11605. stopwatch2.Stop();
  11606. }
  11607. stopwatch1.Stop();
  11608. AddMessage(LogType.Info,
  11609. stationNameStr + "_载具扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  11610. stopwatch2.ElapsedMilliseconds + "ms");
  11611. }
  11612. // 上次采集到的SN
  11613. //private string sn_S4_5出站接口 = string.Empty;
  11614. /// <summary>
  11615. /// [S4] 取放桁架 - S4_5出站接口
  11616. /// </summary>
  11617. private void S4_5出站接口(int plcNo, string stationCode, string stationName)
  11618. {
  11619. Stopwatch stopwatch1 = new Stopwatch();
  11620. Stopwatch stopwatch2 = new Stopwatch();
  11621. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  11622. string stationNameStr = stationCode + stationName;
  11623. string processItem = stationName; // 测试项目
  11624. try
  11625. {
  11626. stopwatch1.Start();
  11627. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  11628. //string batch_num = GlobalContext.BatchNumber; // 批次号
  11629. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  11630. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  11631. string sn = (string)s4PLCData["d5ProductSN"]; // 产品SN(弹夹码)
  11632. sn = sn.Replace("\0", "");
  11633. string d5VehicleCode1 = (string)s4PLCData["d5VehicleCode1"]; // 载具1码(弹夹穴位1)
  11634. d5VehicleCode1 = d5VehicleCode1.Replace("\0", "");
  11635. string d5VehicleCode2 = (string)s4PLCData["d5VehicleCode2"]; // 载具2码(弹夹穴位2)
  11636. d5VehicleCode2 = d5VehicleCode2.Replace("\0", "");
  11637. string d5VehicleCode3 = (string)s4PLCData["d5VehicleCode3"]; // 载具3码(弹夹穴位3)
  11638. d5VehicleCode3 = d5VehicleCode3.Replace("\0", "");
  11639. string d5VehicleCode4 = (string)s4PLCData["d5VehicleCode4"]; // 载具4码(弹夹穴位4)
  11640. d5VehicleCode4 = d5VehicleCode4.Replace("\0", "");
  11641. string d5VehicleCode5 = (string)s4PLCData["d5VehicleCode5"]; // 载具5码(弹夹穴位5)
  11642. d5VehicleCode5 = d5VehicleCode5.Replace("\0", "");
  11643. string d5VehicleCode6 = (string)s4PLCData["d5VehicleCode6"]; // 载具6码(弹夹穴位6)
  11644. d5VehicleCode6 = d5VehicleCode6.Replace("\0", "");
  11645. string d5VehicleCode7 = (string)s4PLCData["d5VehicleCode7"]; // 载具7码(弹夹穴位7)
  11646. d5VehicleCode7 = d5VehicleCode7.Replace("\0", "");
  11647. string d5VehicleCode8 = (string)s4PLCData["d5VehicleCode8"]; // 载具8码(弹夹穴位8)
  11648. d5VehicleCode8 = d5VehicleCode8.Replace("\0", "");
  11649. string d5VehicleCode9 = (string)s4PLCData["d5VehicleCode9"]; // 载具9码(弹夹穴位9)
  11650. d5VehicleCode9 = d5VehicleCode9.Replace("\0", "");
  11651. string d5VehicleCode10 = (string)s4PLCData["d5VehicleCode10"]; // 载具10码(弹夹穴位10)
  11652. d5VehicleCode10 = d5VehicleCode10.Replace("\0", "");
  11653. string d5VehicleCode11 = (string)s4PLCData["d5VehicleCode11"]; // 载具11码(弹夹穴位11)
  11654. d5VehicleCode11 = d5VehicleCode11.Replace("\0", "");
  11655. string d5VehicleCode12 = (string)s4PLCData["d5VehicleCode12"]; // 载具12码(弹夹穴位12)
  11656. d5VehicleCode12 = d5VehicleCode12.Replace("\0", "");
  11657. string d5VehicleCode13 = (string)s4PLCData["d5VehicleCode13"]; // 载具13码(弹夹穴位13)
  11658. d5VehicleCode13 = d5VehicleCode13.Replace("\0", "");
  11659. string d5VehicleCode14 = (string)s4PLCData["d5VehicleCode14"]; // 载具14码(弹夹穴位14)
  11660. d5VehicleCode14 = d5VehicleCode14.Replace("\0", "");
  11661. string d5VehicleCode15 = (string)s4PLCData["d5VehicleCode15"]; // 载具15码(弹夹穴位15)
  11662. d5VehicleCode15 = d5VehicleCode15.Replace("\0", "");
  11663. int d5Result = (int)s4PLCData["d5Result"]; // 产品结果
  11664. bool pass = d5Result == 1;
  11665. // 存 载具SN列表
  11666. List<string> vehicleCodes = new List<string>()
  11667. {
  11668. d5VehicleCode1, d5VehicleCode2, d5VehicleCode3, d5VehicleCode4, d5VehicleCode5,
  11669. d5VehicleCode6, d5VehicleCode7, d5VehicleCode8, d5VehicleCode9, d5VehicleCode10,
  11670. d5VehicleCode11, d5VehicleCode12, d5VehicleCode13, d5VehicleCode14, d5VehicleCode15
  11671. };
  11672. // 统一查 产品SN列表
  11673. List<string> partNos = new List<string>();
  11674. foreach (string vehicleCode in vehicleCodes)
  11675. {
  11676. if (string.IsNullOrEmpty(vehicleCode))
  11677. partNos.Add("");
  11678. else
  11679. {
  11680. string partNo = "";
  11681. #region 查询载具上的产品信息
  11682. string cavityData = string.Empty;
  11683. int snResult = XiaomiMES_RouteCommunication.SNQueryData(vehicleCode, ref cavityData);
  11684. if (string.IsNullOrEmpty(cavityData))
  11685. cavityData = "";
  11686. if (snResult != 0)
  11687. {
  11688. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11689. writeToPLC_Flag1.Name = "d5MES_FLAG";
  11690. writeToPLC_Flag1.Adress = 2591;
  11691. writeToPLC_Flag1.Value = (short)4;
  11692. SxPLCWriteData_Add(ref s4PLCWriteData, "d5MES_FLAG", writeToPLC_Flag1);
  11693. stopwatch1.Stop();
  11694. AddMessage(LogType.Info,
  11695. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds +
  11696. "ms");
  11697. return;
  11698. }
  11699. string[] cavitySNs = cavityData.Split('.');
  11700. if (cavitySNs != null && cavitySNs.Length >= 1)
  11701. partNo = cavitySNs[0];
  11702. #endregion 查询载具上的产品信息
  11703. partNos.Add(partNo);
  11704. }
  11705. }
  11706. // 统一上传
  11707. stopwatch2.Start();
  11708. List<int> results = new List<int>();
  11709. for (int i = 0; i < partNos.Count; i++)
  11710. {
  11711. string index = (i + 1).ToString(); // 弹夹穴号
  11712. if (string.IsNullOrEmpty(partNos[i]))
  11713. results.Add(1);
  11714. else
  11715. {
  11716. List<TestItem> items1 = new List<TestItem>();
  11717. items1.Add(new TestItem()
  11718. {
  11719. Parameter_name = "弹夹码",
  11720. Parameter_value = sn,
  11721. Parameter_unit = ""
  11722. });
  11723. items1.Add(new TestItem()
  11724. {
  11725. Parameter_name = "弹夹穴号",
  11726. Parameter_value = index,
  11727. Parameter_unit = ""
  11728. });
  11729. items1.Add(new TestItem()
  11730. {
  11731. Parameter_name = "载具码",
  11732. Parameter_value = vehicleCodes[i],
  11733. Parameter_unit = ""
  11734. });
  11735. items1.Add(new TestItem()
  11736. {
  11737. Parameter_name = "载具穴号",
  11738. Parameter_value = "1",
  11739. Parameter_unit = ""
  11740. });
  11741. items1.Add(new TestItem()
  11742. {
  11743. Parameter_name = "产品结果",
  11744. Parameter_value = d5Result == 1 ? "OK" : "NG",
  11745. Parameter_unit = ""
  11746. });
  11747. int result1 = SwitctProcessData_old(stationNameStr, items1, equipmentCode, processItem
  11748. , workorder_code, mtltmrk, partNos[i], pass, sn, index);
  11749. results.Add(result1);
  11750. }
  11751. }
  11752. short result = 0;
  11753. if (results.All(a => a == 1))
  11754. result = 1;
  11755. else if (results.Contains(3))
  11756. result = 3;
  11757. else if (results.Contains(2))
  11758. result = 2;
  11759. else if (results.Contains(4))
  11760. result = 4;
  11761. else
  11762. result = 4;
  11763. stopwatch2.Stop();
  11764. #region 存储绑定数据到 边线MES系统中
  11765. if (result == 1)
  11766. {
  11767. // 删除绑定信息
  11768. int resultMesR = XiaomiMES_RouteCommunication.SNDeleteData(sn);
  11769. if (resultMesR != 0)
  11770. {
  11771. result = 4;
  11772. AddMessage_Station(stationNameStr, LogType.Error,
  11773. $"PLC{plcNo}_[{equipmentCode}]{processItem}_出站接口失败!MES边线程序返回:{resultMesR}");
  11774. }
  11775. }
  11776. #endregion 存储绑定数据到 边线MES系统中
  11777. // MES_Flag 为4MES报错
  11778. //Funs[plcNo].WriteMultipleRegisters<short>(2591, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  11779. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11780. writeToPLC_Flag.Name = "d5MES_FLAG";
  11781. writeToPLC_Flag.Adress = 2591;
  11782. writeToPLC_Flag.Value = result;
  11783. SxPLCWriteData_Add(ref s4PLCWriteData, "d5MES_FLAG", writeToPLC_Flag);
  11784. OnMessage(LogType.Debug,
  11785. $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  11786. }
  11787. catch (Exception ex)
  11788. {
  11789. stopwatch2.Restart();
  11790. // MES_Flag 为4上位机报错
  11791. //Funs[plcNo].WriteMultipleRegisters<short>(2591, (short)4); // 4代表上位机报警
  11792. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11793. writeToPLC_Flag.Name = "d5MES_FLAG";
  11794. writeToPLC_Flag.Adress = 2591;
  11795. writeToPLC_Flag.Value = (short)4;
  11796. SxPLCWriteData_Add(ref s4PLCWriteData, "d5MES_FLAG", writeToPLC_Flag);
  11797. stopwatch2.Stop();
  11798. string str = ex.StackTrace;
  11799. AddMessage_Station(stationNameStr, LogType.Error,
  11800. $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  11801. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11802. }
  11803. stopwatch1.Stop();
  11804. AddMessage(LogType.Info,
  11805. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  11806. stopwatch2.ElapsedMilliseconds + "ms");
  11807. }
  11808. /// <summary>
  11809. /// [S4] 取放桁架 - S4_5节拍接口
  11810. /// </summary>
  11811. /// <param name="plcNo">PLC编号</param>
  11812. /// <param name="stationNameStr">工站全称</param>
  11813. private void S4_5节拍接口(int plcNo, string stationNameStr)
  11814. {
  11815. Stopwatch stopwatch1 = new Stopwatch();
  11816. Stopwatch stopwatch2 = new Stopwatch();
  11817. string resultStr = string.Empty;
  11818. try
  11819. {
  11820. stopwatch1.Start();
  11821. string oEEType = ((int)s4PLCData["d5OEEType"]).ToString(); // 节拍类型(plc写入)
  11822. string d5OEEProductSN = (string)s4PLCData["d5OEEProductSN"]; // 载具SN
  11823. d5OEEProductSN = d5OEEProductSN.Replace("\0", "");
  11824. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  11825. if (!actionBool)
  11826. {
  11827. stopwatch2.Start();
  11828. // MES_Flag
  11829. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)4); // 上位机;发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警
  11830. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11831. writeToPLC_Flag1.Name = "d5OEEMES_FLAG";
  11832. writeToPLC_Flag1.Adress = 2924;
  11833. writeToPLC_Flag1.Value = (short)4;
  11834. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag1);
  11835. stopwatch2.Stop();
  11836. AddMessage(LogType.Info,
  11837. stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds +
  11838. "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  11839. return;
  11840. }
  11841. string d5OEEPartNo = string.Empty; // 物料码
  11842. if (string.IsNullOrEmpty(d5OEEProductSN))
  11843. {
  11844. stopwatch2.Start();
  11845. // MES_Flag
  11846. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  11847. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  11848. writeToPLC_Flag1.Name = "d5OEEMES_FLAG";
  11849. writeToPLC_Flag1.Adress = 2924;
  11850. writeToPLC_Flag1.Value = (short)1;
  11851. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag1);
  11852. stopwatch2.Stop();
  11853. AddMessage(LogType.Info,
  11854. stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  11855. stopwatch2.ElapsedMilliseconds + "ms");
  11856. return;
  11857. }
  11858. else
  11859. {
  11860. // 查产品SN
  11861. d5OEEPartNo = "Test"; // ZS
  11862. }
  11863. short d5OEEMES_FLAG = 0;
  11864. // 上传OEE
  11865. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, d5OEEPartNo, d5OEEProductSN);
  11866. d5OEEMES_FLAG = result.Item1;
  11867. resultStr = result.Item2;
  11868. stopwatch2.Start();
  11869. // MES_Flag
  11870. //Funs[plcNo].WriteMultipleRegisters<short>(2924, d5OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  11871. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11872. writeToPLC_Flag.Name = "d5OEEMES_FLAG";
  11873. writeToPLC_Flag.Adress = 2924;
  11874. writeToPLC_Flag.Value = d5OEEMES_FLAG;
  11875. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag);
  11876. stopwatch2.Stop();
  11877. }
  11878. catch (Exception ex)
  11879. {
  11880. string str = ex.StackTrace;
  11881. AddMessage_Station(stationNameStr, LogType.Error,
  11882. $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" +
  11883. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  11884. // MES_Flag
  11885. stopwatch2.Start();
  11886. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)4); // 4代表上位机报警
  11887. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  11888. writeToPLC_Flag.Name = "d5OEEMES_FLAG";
  11889. writeToPLC_Flag.Adress = 2924;
  11890. writeToPLC_Flag.Value = (short)4;
  11891. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag);
  11892. stopwatch2.Stop();
  11893. }
  11894. stopwatch1.Stop();
  11895. AddMessage(LogType.Info,
  11896. stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  11897. stopwatch2.ElapsedMilliseconds + "ms");
  11898. }
  11899. #endregion [S4] 取放桁架
  11900. #endregion PLC4 刘果段
  11901. #region PLC5 张超凡
  11902. #region [S5] Tray盘下料装备
  11903. /// <summary>
  11904. /// S5工位的数据- 触发信号上次的值
  11905. /// </summary>
  11906. private Dictionary<string, object> s5PLCSignal_Old = new Dictionary<string, object>();
  11907. /// <summary>
  11908. /// S5工位的数据(含触发信号)
  11909. /// </summary>
  11910. private Dictionary<string, object> s5PLCData = new Dictionary<string, object>();
  11911. /// <summary>
  11912. /// S5工位的数据- 回写点位
  11913. /// </summary>
  11914. private Dictionary<string, WriteToPLC_Flag> s5PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  11915. /// <summary>
  11916. /// [S5] Tray盘下料装备
  11917. /// </summary>
  11918. /// <param name="plcNo">PLC编号</param>
  11919. //private void ReadStation_S5(int plcNo)
  11920. //{
  11921. // // [S1] Tray盘上料装备
  11922. // // [S2] FCT
  11923. // // [S3] 值板机
  11924. // // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  11925. // // [S5] Tray盘下料装备
  11926. // /// 上位机心跳
  11927. // /// 获取设备报警数据与状态信息
  11928. // string stationCode = "[S5]";
  11929. // string stationName = "Tray盘下料装备";
  11930. // string stationNameStr = stationCode + stationName;
  11931. // #region 创建字典
  11932. // // 触发信号字典 赋值
  11933. // s5PLCSignal_Old.Add("e1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  11934. // s5PLCSignal_Old.Add("e1PLC_FLAG", 0); // PLC_FLAG 出站接口
  11935. // s5PLCSignal_Old.Add("e1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  11936. // s5PLCSignal_Old.Add("e1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  11937. // s5PLCSignal_Old.Add("e1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  11938. // s5PLCSignal_Old.Add("e1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  11939. // s5PLCSignal_Old.Add("e1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  11940. // // PLC数据字典 赋值
  11941. // s5PLCData.Add("e1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  11942. // s5PLCData.Add("e1MES_FLAG_Check", 0); // MES_FLAG
  11943. // s5PLCData.Add("e1ProductSN_Check", ""); //
  11944. // s5PLCData.Add("e1PLC_FLAG", 0); // PLC_FLAG 出站接口
  11945. // s5PLCData.Add("e1MES_FLAG", 0); // MES_FLAG
  11946. // s5PLCData.Add("e1ProductSN", ""); // 产品SN
  11947. // s5PLCData.Add("e1PartNo", ""); // 物料码
  11948. // s5PLCData.Add("e1Result", 0); // 产品结果
  11949. // s5PLCData.Add("e1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  11950. // s5PLCData.Add("e1OEEMES_FLAG", 0); // MES_FLAG
  11951. // s5PLCData.Add("e1OEEProductSN", "");// 产品SN(载具SN)
  11952. // s5PLCData.Add("e1OEEType", 0); // 节拍类型(plc写入)
  11953. // s5PLCData.Add("e1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  11954. // s5PLCData.Add("e1AGVUpStart", 0); // AGV上料开始信号
  11955. // s5PLCData.Add("e1AGVUpEnd", 0); // AGV上料完成信号
  11956. // s5PLCData.Add("e1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  11957. // s5PLCData.Add("e1AGVDownStart", 0); // AGV下料开始信号
  11958. // s5PLCData.Add("e1AGVDownEnd", 0); // AGV下料完成信号
  11959. // #endregion 创建字典
  11960. // while (IsRun)
  11961. // {
  11962. // try
  11963. // {
  11964. // if (!GlobalContext._IsCon_Funs5)
  11965. // {
  11966. // UpdatePLCMonitor(1, plcNo, 0);
  11967. // continue;
  11968. // }
  11969. // if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  11970. // {
  11971. // Stopwatch stopwatch1 = new Stopwatch();
  11972. // Stopwatch stopwatch2 = new Stopwatch();
  11973. // stopwatch1.Start();
  11974. // stopwatch2.Start();
  11975. // #region 一次性读取所有数据
  11976. // int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100);
  11977. // int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 46);
  11978. // int[] datas = data1.Concat(data2).ToArray();
  11979. // s5PLCData["e1PLC_FLAG_Check"] = datas[2]; // 进站校验
  11980. // s5PLCData["e1MES_FLAG_Check"] = datas[3];
  11981. // int[] e1ProductSN_CheckData = datas.Skip(4).Take(20).ToArray();
  11982. // s5PLCData["e1ProductSN_Check"] = ModbusClient.ConvertRegistersToString(e1ProductSN_CheckData, 0, 40);
  11983. // s5PLCData["e1PLC_FLAG"] = datas[34]; // 出站接口
  11984. // s5PLCData["e1MES_FLAG"] = datas[35];
  11985. // int[] e1ProductSNData = datas.Skip(36).Take(20).ToArray();
  11986. // s5PLCData["e1ProductSN"] = ModbusClient.ConvertRegistersToString(e1ProductSNData, 0, 40);
  11987. // int[] e1PartNoData = datas.Skip(56).Take(20).ToArray();
  11988. // s5PLCData["e1PartNo"] = ModbusClient.ConvertRegistersToString(e1PartNoData, 0, 40);
  11989. // s5PLCData["e1Result"] = datas[76];
  11990. // s5PLCData["e1OEEPLC_FLAG"] = datas[87]; // 节拍接口
  11991. // s5PLCData["e1OEEMES_FLAG"] = datas[88];
  11992. // int[] e1OEEProductSNData = datas.Skip(89).Take(20).ToArray();
  11993. // s5PLCData["e1OEEProductSN"] = ModbusClient.ConvertRegistersToString(e1OEEProductSNData, 0, 40);
  11994. // s5PLCData["e1OEEType"] = datas[109];
  11995. // s5PLCData["e1AGVUpCall"] = datas[120]; // AGV上料
  11996. // s5PLCData["e1AGVUpStart"] = datas[121];
  11997. // s5PLCData["e1AGVUpEnd"] = datas[122];
  11998. // s5PLCData["e1AGVDownCall"] = datas[133]; // AGV下料
  11999. // s5PLCData["e1AGVDownStart"] = datas[134];
  12000. // s5PLCData["e1AGVDownEnd"] = datas[135];
  12001. // #endregion 一次性读取所有数据
  12002. // stopwatch2.Stop();
  12003. // #region 回写操作,写后清空flag
  12004. // PLCWriteData(Funs[plcNo], ref s5PLCData, ref s5PLCWriteData);
  12005. // #endregion 回写操作,写后清空flag
  12006. // #region 进站校验
  12007. // try
  12008. // {
  12009. // int e1PLC_FLAG_Check = (int)s5PLCData["e1PLC_FLAG_Check"];
  12010. // int e1MES_FLAG_Check = (int)s5PLCData["e1MES_FLAG_Check"];
  12011. // int e1PLC_FLAG_CheckOld = (int)s5PLCSignal_Old["e1PLC_FLAG_Check"];
  12012. // if (e1PLC_FLAG_Check != e1PLC_FLAG_CheckOld)
  12013. // {
  12014. // if (e1PLC_FLAG_Check == 1 && e1MES_FLAG_Check == 0) // 0->1
  12015. // Task.Run(() => S5进站校验(plcNo, stationNameStr)); // MreTasks[2].Set();
  12016. // else if (e1PLC_FLAG_Check == 0 && e1MES_FLAG_Check != 0)
  12017. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)0);
  12018. // s5PLCSignal_Old["e1PLC_FLAG_Check"] = s5PLCData["e1PLC_FLAG_Check"];
  12019. // }
  12020. // }
  12021. // catch (Exception ex)
  12022. // {
  12023. // Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  12024. // string str = ex.StackTrace;
  12025. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12026. // }
  12027. // #endregion 进站校验
  12028. // #region 出站接口
  12029. // try
  12030. // {
  12031. // int e1PLC_FLAG = (int)s5PLCData["e1PLC_FLAG"];
  12032. // int e1MES_FLAG = (int)s5PLCData["e1MES_FLAG"];
  12033. // int e1PLC_FLAGOld = (int)s5PLCSignal_Old["e1PLC_FLAG"];
  12034. // if (e1PLC_FLAG != e1PLC_FLAGOld)
  12035. // {
  12036. // if (e1PLC_FLAG == 1 && e1MES_FLAG == 0) // 0->1
  12037. // Task.Run(() => S5出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  12038. // else if (e1PLC_FLAG == 0 && e1MES_FLAG != 0)
  12039. // Funs[plcNo].WriteMultipleRegisters<short>(2035, (short)0);
  12040. // s5PLCSignal_Old["e1PLC_FLAG"] = s5PLCData["e1PLC_FLAG"];
  12041. // }
  12042. // }
  12043. // catch (Exception ex)
  12044. // {
  12045. // Funs[plcNo].WriteMultipleRegisters<short>(2035, (short)6); // 6代表上位机报警
  12046. // string str = ex.StackTrace;
  12047. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12048. // }
  12049. // #endregion 出站接口
  12050. // #region 节拍接口
  12051. // try
  12052. // {
  12053. // int e1OEEPLC_FLAG = (int)s5PLCData["e1OEEPLC_FLAG"];
  12054. // int e1OEEMES_FLAG = (int)s5PLCData["e1OEEMES_FLAG"];
  12055. // int e1OEEPLC_FLAGOld = (int)s5PLCSignal_Old["e1OEEPLC_FLAG"];
  12056. // if (e1OEEPLC_FLAG != e1OEEPLC_FLAGOld)
  12057. // {
  12058. // if (e1OEEPLC_FLAG == 1 && e1OEEMES_FLAG == 0) // 0->1
  12059. // Task.Run(() => S5节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  12060. // else if (e1OEEPLC_FLAG == 0 && e1OEEMES_FLAG != 0)
  12061. // Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)0);
  12062. // s5PLCSignal_Old["e1OEEPLC_FLAG"] = s5PLCData["e1OEEPLC_FLAG"];
  12063. // }
  12064. // }
  12065. // catch (Exception ex)
  12066. // {
  12067. // Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)4); // 4代表上位机报警
  12068. // string str = ex.StackTrace;
  12069. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12070. // }
  12071. // #endregion 节拍接口
  12072. // #region AGV上料
  12073. // // AGV上料叫AGV信号
  12074. // try
  12075. // {
  12076. // int e1AGVUpCall = (int)s5PLCData["e1AGVUpCall"];
  12077. // int e1AGVUpCallOld = (int)s5PLCSignal_Old["e1AGVUpCall"];
  12078. // if (e1AGVUpCall != e1AGVUpCallOld)
  12079. // {
  12080. // if (e1AGVUpCall == 1) // 0->1
  12081. // Task.Run(() => S5AGV上料叫agv(plcNo, stationNameStr)); // MreTasks[5].Set();
  12082. // s5PLCSignal_Old["e1AGVUpCall"] = s5PLCData["e1AGVUpCall"];
  12083. // }
  12084. // }
  12085. // catch (Exception ex)
  12086. // {
  12087. // Funs[plcNo].WriteMultipleRegisters<short>(2120, (short)4); // 4代表上位机报警
  12088. // string str = ex.StackTrace;
  12089. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12090. // }
  12091. // // AGV上料完成信号
  12092. // try
  12093. // {
  12094. // int e1AGVUpEnd = (int)s5PLCData["e1AGVUpEnd"];
  12095. // int e1AGVUpEndOld = (int)s5PLCSignal_Old["e1AGVUpEnd"];
  12096. // if (e1AGVUpEnd != e1AGVUpEndOld)
  12097. // {
  12098. // if (e1AGVUpEnd == 1) // 0->1
  12099. // Task.Run(() => S5AGV上料完成(plcNo, stationNameStr)); // MreTasks[6].Set();
  12100. // s5PLCSignal_Old["e1AGVUpEnd"] = s5PLCData["e1AGVUpEnd"];
  12101. // }
  12102. // }
  12103. // catch (Exception ex)
  12104. // {
  12105. // Funs[plcNo].WriteMultipleRegisters<short>(2122, (short)4); // 4代表上位机报警
  12106. // string str = ex.StackTrace;
  12107. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料完成信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12108. // }
  12109. // #endregion AGV上料
  12110. // #region AGV下料
  12111. // // AGV下料叫agv信号
  12112. // try
  12113. // {
  12114. // int e1AGVDownCall = (int)s5PLCData["e1AGVDownCall"];
  12115. // int e1AGVDownCallOld = (int)s5PLCSignal_Old["e1AGVDownCall"];
  12116. // if (e1AGVDownCall != e1AGVDownCallOld)
  12117. // {
  12118. // if (e1AGVDownCall == 1) // 0->1
  12119. // Task.Run(() => S5AGV下料叫agv(plcNo, stationNameStr)); // MreTasks[7].Set();
  12120. // s5PLCSignal_Old["e1AGVDownCall"] = s5PLCData["e1AGVDownCall"];
  12121. // }
  12122. // }
  12123. // catch (Exception ex)
  12124. // {
  12125. // Funs[plcNo].WriteMultipleRegisters<short>(2133, (short)4); // 4代表上位机报警
  12126. // string str = ex.StackTrace;
  12127. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料叫agv信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12128. // }
  12129. // // AGV下料完成信号
  12130. // try
  12131. // {
  12132. // int e1AGVDownEnd = (int)s5PLCData["e1AGVDownEnd"];
  12133. // int e1AGVDownEndOld = (int)s5PLCSignal_Old["e1AGVDownEnd"];
  12134. // if (e1AGVDownEnd != e1AGVDownEndOld)
  12135. // {
  12136. // if (e1AGVDownEnd == 1) // 0->1
  12137. // Task.Run(() => S5AGV下料完成(plcNo, stationNameStr)); // MreTasks[8].Set();
  12138. // s5PLCSignal_Old["e1AGVDownEnd"] = s5PLCData["e1AGVDownEnd"];
  12139. // }
  12140. // }
  12141. // catch (Exception ex)
  12142. // {
  12143. // Funs[plcNo].WriteMultipleRegisters<short>(2135, (short)4); // 4代表上位机报警
  12144. // string str = ex.StackTrace;
  12145. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料完成信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12146. // }
  12147. // #endregion AGV下料
  12148. // #region 心跳
  12149. // try
  12150. // {
  12151. // short states = 0;
  12152. // Funs[plcNo].WriteMultipleRegisters<short>(2000, states);
  12153. // }
  12154. // catch (Exception ex)
  12155. // {
  12156. // string str = ex.StackTrace;
  12157. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上位机心跳写入出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12158. // }
  12159. // #endregion 心跳
  12160. // UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  12161. // stopwatch1.Stop();
  12162. // //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  12163. // OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  12164. // }
  12165. // else
  12166. // {
  12167. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  12168. // AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  12169. // Funs[plcNo].Connect();
  12170. // }
  12171. // }
  12172. // catch (Exception ex)
  12173. // {
  12174. // UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  12175. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  12176. // Funs[plcNo].ReConnect();
  12177. // }
  12178. // Thread.Sleep(IntervalReadPLC);
  12179. // }
  12180. //}
  12181. /// <summary>
  12182. /// [S5] Tray盘下料装备 - 进站校验
  12183. /// </summary>
  12184. /// <param name="plcNo">PLC编号</param>
  12185. /// <param name="stationNameStr">工站全称</param>
  12186. private void S5进站校验(int plcNo, string stationNameStr)
  12187. {
  12188. Stopwatch stopwatch1 = new Stopwatch();
  12189. Stopwatch stopwatch2 = new Stopwatch();
  12190. try
  12191. {
  12192. stopwatch1.Start();
  12193. string sn = (string)s5PLCData["e1ProductSN_Check"]; // 产品SN(载具码)
  12194. sn = sn.Replace("\0", "");
  12195. // 获取产品SN By 载具码
  12196. #region 查询载具上的产品信息
  12197. string cavityData = string.Empty;
  12198. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref cavityData);
  12199. if (string.IsNullOrEmpty(cavityData))
  12200. cavityData = "";
  12201. if (snResult != 0)
  12202. {
  12203. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  12204. writeToPLC_Flag1.Name = "e1MES_FLAG_Check";
  12205. writeToPLC_Flag1.Adress = 2003;
  12206. writeToPLC_Flag1.Value = (short)6;
  12207. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG_Check", writeToPLC_Flag1);
  12208. stopwatch1.Stop();
  12209. AddMessage(LogType.Info,
  12210. stationNameStr + $"_进站校验失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  12211. return;
  12212. }
  12213. string[] cavitySNs = cavityData.Split('.');
  12214. string partNo = string.Empty;
  12215. if (cavitySNs != null && cavitySNs.Length >= 1)
  12216. partNo = cavitySNs[0];
  12217. #endregion 查询载具上的产品信息
  12218. // 产品SN(物料码)校验
  12219. List<TestItem> item = new List<TestItem>();
  12220. item.Add(new TestItem()
  12221. {
  12222. Parameter_name = "载具码",
  12223. Parameter_value = sn,
  12224. });
  12225. item.Add(new TestItem()
  12226. {
  12227. Parameter_name = "载具穴号",
  12228. Parameter_value = "1",
  12229. });
  12230. stopwatch2.Start();
  12231. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk,
  12232. partNo, item, out string errorMsg);
  12233. stopwatch2.Stop();
  12234. short e1MES_FLAG_Check = (short)result;
  12235. // MES_Flag
  12236. //Funs[plcNo].WriteMultipleRegisters<short>(2003, e1MES_FLAG_Check); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  12237. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12238. writeToPLC_Flag.Name = "e1MES_FLAG_Check";
  12239. writeToPLC_Flag.Adress = 2003;
  12240. writeToPLC_Flag.Value = e1MES_FLAG_Check;
  12241. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG_Check", writeToPLC_Flag);
  12242. }
  12243. catch (Exception ex)
  12244. {
  12245. string str = ex.StackTrace;
  12246. AddMessage_Station(stationNameStr, LogType.Error,
  12247. $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" +
  12248. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12249. // MES_Flag
  12250. //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  12251. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12252. writeToPLC_Flag.Name = "e1MES_FLAG_Check";
  12253. writeToPLC_Flag.Adress = 2003;
  12254. writeToPLC_Flag.Value = (short)6;
  12255. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG_Check", writeToPLC_Flag);
  12256. }
  12257. stopwatch1.Stop();
  12258. AddMessage(LogType.Info,
  12259. stationNameStr + "_进站校验;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" +
  12260. stopwatch2.ElapsedMilliseconds + "ms");
  12261. }
  12262. /// <summary>
  12263. /// [S5] Tray盘下料装备 - 出站接口
  12264. /// </summary>
  12265. /// <param name="plcNo"></param>
  12266. /// <param name="stationCode"></param>
  12267. /// <param name="stationName"></param>
  12268. private void S5出站接口(int plcNo, string stationCode, string stationName)
  12269. {
  12270. Stopwatch stopwatch1 = new Stopwatch();
  12271. Stopwatch stopwatch2 = new Stopwatch();
  12272. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  12273. string stationNameStr = stationCode + stationName;
  12274. string processItem = stationName; // 测试项目
  12275. try
  12276. {
  12277. stopwatch1.Start();
  12278. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  12279. //string batch_num = GlobalContext.BatchNumber; // 批次号
  12280. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  12281. //string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  12282. string sn = (string)s5PLCData["e1ProductSN"]; // 产品SN(载具SN码)
  12283. sn = sn.Replace("\0", "");
  12284. //string partNo = (string)s5PLCData["e1PartNo"]; // 物料码
  12285. //partNo = partNo.Replace("\0", "");
  12286. #region 查询载具上的产品信息
  12287. string cavityData = string.Empty;
  12288. int snResult = XiaomiMES_RouteCommunication.SNQueryData(sn, ref cavityData);
  12289. if (string.IsNullOrEmpty(cavityData))
  12290. cavityData = "";
  12291. if (snResult != 0)
  12292. {
  12293. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  12294. writeToPLC_Flag1.Name = "e1MES_FLAG";
  12295. writeToPLC_Flag1.Adress = 2035;
  12296. writeToPLC_Flag1.Value = (short)4;
  12297. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG", writeToPLC_Flag1);
  12298. stopwatch1.Stop();
  12299. AddMessage(LogType.Info,
  12300. stationNameStr + $"_出站接口失败!MES边线软件返回结果{snResult};总用时" + stopwatch1.ElapsedMilliseconds + "ms");
  12301. return;
  12302. }
  12303. string[] cavitySNs = cavityData.Split('.');
  12304. string partNo = string.Empty;
  12305. if (cavitySNs != null && cavitySNs.Length >= 1)
  12306. partNo = cavitySNs[0];
  12307. #endregion 查询载具上的产品信息
  12308. int e1Result = (int)s5PLCData["e1Result"]; // 产品结果
  12309. bool pass = e1Result == 1;
  12310. stopwatch2.Start();
  12311. // 上传MES
  12312. List<TestItem> items = new List<TestItem>();
  12313. items.Add(new TestItem()
  12314. {
  12315. Parameter_name = "载具码",
  12316. Parameter_value = sn,
  12317. Parameter_unit = ""
  12318. });
  12319. items.Add(new TestItem()
  12320. {
  12321. Parameter_name = "载具穴号",
  12322. Parameter_value = "1",
  12323. Parameter_unit = ""
  12324. });
  12325. items.Add(new TestItem()
  12326. {
  12327. Parameter_name = "产品结果",
  12328. Parameter_value = e1Result == 1 ? "OK" : "NG",
  12329. Parameter_unit = ""
  12330. });
  12331. int result1 = SwitctProcessData_old(stationNameStr, items, equipmentCode, processItem
  12332. , workorder_code, mtltmrk, partNo, pass, sn, "1");
  12333. //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
  12334. short result = result1 == 1 ? (short)1 : (short)3;
  12335. stopwatch2.Stop();
  12336. #region 存储绑定数据到 边线MES系统中
  12337. if (result == 1)
  12338. {
  12339. // 删除绑定信息
  12340. int resultMesR = XiaomiMES_RouteCommunication.SNDeleteData(sn);
  12341. if (resultMesR != 0)
  12342. {
  12343. result = 4;
  12344. AddMessage_Station(stationNameStr, LogType.Error,
  12345. $"PLC{plcNo}_[{equipmentCode}]{processItem}_出站接口失败!MES边线程序返回:{resultMesR}");
  12346. }
  12347. }
  12348. #endregion 存储绑定数据到 边线MES系统中
  12349. // MES_Flag 为MES报错
  12350. // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  12351. //Funs[plcNo].WriteMultipleRegisters<short>(2035, result); // 4代表上位机报警
  12352. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12353. writeToPLC_Flag.Name = "e1MES_FLAG";
  12354. writeToPLC_Flag.Adress = 2035;
  12355. writeToPLC_Flag.Value = result;
  12356. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG", writeToPLC_Flag);
  12357. OnMessage(LogType.Debug,
  12358. $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  12359. }
  12360. catch (Exception ex)
  12361. {
  12362. stopwatch2.Restart();
  12363. // MES_Flag 为4上位机报错
  12364. //Funs[plcNo].WriteMultipleRegisters<short>(2035, (short)4); // 4代表上位机报警
  12365. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12366. writeToPLC_Flag.Name = "e1MES_FLAG";
  12367. writeToPLC_Flag.Adress = 2035;
  12368. writeToPLC_Flag.Value = (short)4;
  12369. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG", writeToPLC_Flag);
  12370. stopwatch2.Stop();
  12371. string str = ex.StackTrace;
  12372. AddMessage_Station(stationNameStr, LogType.Error,
  12373. $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口报错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  12374. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12375. }
  12376. stopwatch1.Stop();
  12377. AddMessage(LogType.Info,
  12378. stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;上传接口用时" +
  12379. stopwatch2.ElapsedMilliseconds + "ms");
  12380. }
  12381. /// <summary>
  12382. /// [S5] Tray盘下料装备 - 节拍接口
  12383. /// </summary>
  12384. /// <param name="plcNo">PLC编号</param>
  12385. /// <param name="stationNameStr">工站全称</param>
  12386. //private void S5节拍接口(int plcNo, string stationNameStr)
  12387. //{
  12388. // Stopwatch stopwatch1 = new Stopwatch();
  12389. // Stopwatch stopwatch2 = new Stopwatch();
  12390. // string resultStr = string.Empty;
  12391. // try
  12392. // {
  12393. // stopwatch1.Start();
  12394. // string oEEType = ((int)s5PLCData["e1OEEType"]).ToString(); // 节拍类型(plc写入)
  12395. // string e1OEEProductSN = (string)s5PLCData["e1OEEProductSN"]; // 载具SN
  12396. // e1OEEProductSN = e1OEEProductSN.Replace("\0", "");
  12397. // bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  12398. // if (!actionBool)
  12399. // {
  12400. // stopwatch2.Start();
  12401. // // MES_Flag
  12402. // //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)4); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  12403. // WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  12404. // writeToPLC_Flag1.Name = "e1OEEMES_FLAG";
  12405. // writeToPLC_Flag1.Adress = 2088;
  12406. // writeToPLC_Flag1.Value = (short)4;
  12407. // SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag1);
  12408. // stopwatch2.Stop();
  12409. // AddMessage(LogType.Info,
  12410. // stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds +
  12411. // "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  12412. // return;
  12413. // }
  12414. // string e1OEEPartNo = string.Empty; // 物料码
  12415. // if (string.IsNullOrEmpty(e1OEEProductSN))
  12416. // {
  12417. // stopwatch2.Start();
  12418. // // MES_Flag
  12419. // //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  12420. // WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  12421. // writeToPLC_Flag1.Name = "e1OEEMES_FLAG";
  12422. // writeToPLC_Flag1.Adress = 2088;
  12423. // writeToPLC_Flag1.Value = (short)1;
  12424. // SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag1);
  12425. // stopwatch2.Stop();
  12426. // AddMessage(LogType.Info,
  12427. // stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  12428. // stopwatch2.ElapsedMilliseconds + "ms");
  12429. // return;
  12430. // }
  12431. // else
  12432. // {
  12433. // // 查产品SN
  12434. // e1OEEPartNo = "Test"; // ZS
  12435. // }
  12436. // short e1OEEMES_FLAG = 0;
  12437. // // 上传OEE
  12438. // (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, e1OEEPartNo, e1OEEProductSN);
  12439. // e1OEEMES_FLAG = result.Item1;
  12440. // resultStr = result.Item2;
  12441. // stopwatch2.Start();
  12442. // // MES_Flag
  12443. // //Funs[plcNo].WriteMultipleRegisters<short>(2088, e1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  12444. // WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12445. // writeToPLC_Flag.Name = "e1OEEMES_FLAG";
  12446. // writeToPLC_Flag.Adress = 2088;
  12447. // writeToPLC_Flag.Value = e1OEEMES_FLAG;
  12448. // SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag);
  12449. // stopwatch2.Stop();
  12450. // }
  12451. // catch (Exception ex)
  12452. // {
  12453. // string str = ex.StackTrace;
  12454. // AddMessage_Station(stationNameStr, LogType.Error,
  12455. // $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" +
  12456. // str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12457. // // MES_Flag
  12458. // stopwatch2.Start();
  12459. // //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)4); // 4代表上位机报警
  12460. // WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12461. // writeToPLC_Flag.Name = "e1OEEMES_FLAG";
  12462. // writeToPLC_Flag.Adress = 2088;
  12463. // writeToPLC_Flag.Value = (short)4;
  12464. // SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag);
  12465. // stopwatch2.Stop();
  12466. // }
  12467. // stopwatch1.Stop();
  12468. // AddMessage(LogType.Info,
  12469. // stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  12470. // stopwatch2.ElapsedMilliseconds + "ms");
  12471. //}
  12472. /// <summary>
  12473. /// [S5] Tray盘下料装备 - AGV上料叫agv
  12474. /// </summary>
  12475. /// <param name="plcNo">PLC编号</param>
  12476. /// <param name="stationNameStr">工站全称</param>
  12477. private void S5AGV上料叫agv(int plcNo, string stationNameStr)
  12478. {
  12479. Stopwatch stopwatch1 = new Stopwatch();
  12480. Stopwatch stopwatch2 = new Stopwatch();
  12481. try
  12482. {
  12483. stopwatch1.Start();
  12484. // ZS 呼叫AGV
  12485. short e1AGVUpCall = 2;
  12486. stopwatch2.Start();
  12487. // e1AGVUpCall
  12488. //Funs[plcNo].WriteMultipleRegisters<short>(2120, e1AGVUpCall); // 1:plc请求上料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  12489. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12490. writeToPLC_Flag.Name = "e1AGVUpCall";
  12491. writeToPLC_Flag.Adress = 2120;
  12492. writeToPLC_Flag.Value = e1AGVUpCall;
  12493. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpCall", writeToPLC_Flag);
  12494. stopwatch2.Stop();
  12495. }
  12496. catch (Exception ex)
  12497. {
  12498. string str = ex.StackTrace;
  12499. AddMessage_Station(stationNameStr, LogType.Error,
  12500. $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" +
  12501. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12502. // e1AGVUpCall
  12503. stopwatch2.Start();
  12504. //Funs[plcNo].WriteMultipleRegisters<short>(2120, (short)4); // 4代表上位机报警
  12505. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12506. writeToPLC_Flag.Name = "e1AGVUpCall";
  12507. writeToPLC_Flag.Adress = 2120;
  12508. writeToPLC_Flag.Value = (short)4;
  12509. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpCall", writeToPLC_Flag);
  12510. stopwatch2.Stop();
  12511. }
  12512. stopwatch1.Stop();
  12513. AddMessage(LogType.Info,
  12514. stationNameStr + "_AGV上料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  12515. stopwatch2.ElapsedMilliseconds + "ms");
  12516. }
  12517. /// <summary>
  12518. /// [S5] Tray盘下料装备 - AGV上料完成
  12519. /// </summary>
  12520. /// <param name="plcNo">PLC编号</param>
  12521. /// <param name="stationNameStr">工站全称</param>
  12522. private void S5AGV上料完成(int plcNo, string stationNameStr)
  12523. {
  12524. Stopwatch stopwatch1 = new Stopwatch();
  12525. Stopwatch stopwatch2 = new Stopwatch();
  12526. try
  12527. {
  12528. stopwatch1.Start();
  12529. // ZS AGV上料完成,让小车离开
  12530. short e1AGVUpEnd = 2;
  12531. stopwatch2.Start();
  12532. // e1AGVUpEnd
  12533. //Funs[plcNo].WriteMultipleRegisters<short>(2122, e1AGVUpEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  12534. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12535. writeToPLC_Flag.Name = "e1AGVUpEnd";
  12536. writeToPLC_Flag.Adress = 2122;
  12537. writeToPLC_Flag.Value = e1AGVUpEnd;
  12538. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpEnd", writeToPLC_Flag);
  12539. stopwatch2.Stop();
  12540. }
  12541. catch (Exception ex)
  12542. {
  12543. string str = ex.StackTrace;
  12544. AddMessage_Station(stationNameStr, LogType.Error,
  12545. $"PLC{plcNo}_{stationNameStr} AGV上料完成出错!错误信息:" + ex.Message + "异常位置:" +
  12546. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12547. // e1AGVUpEnd
  12548. stopwatch2.Start();
  12549. //Funs[plcNo].WriteMultipleRegisters<short>(2122, (short)4); // 4代表上位机报警
  12550. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12551. writeToPLC_Flag.Name = "e1AGVUpEnd";
  12552. writeToPLC_Flag.Adress = 2122;
  12553. writeToPLC_Flag.Value = (short)4;
  12554. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpEnd", writeToPLC_Flag);
  12555. stopwatch2.Stop();
  12556. }
  12557. stopwatch1.Stop();
  12558. AddMessage(LogType.Info,
  12559. stationNameStr + "_AGV上料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  12560. stopwatch2.ElapsedMilliseconds + "ms");
  12561. }
  12562. /// <summary>
  12563. /// [S5] Tray盘下料装备 - AGV下料叫agv
  12564. /// </summary>
  12565. /// <param name="plcNo">PLC编号</param>
  12566. /// <param name="stationNameStr">工站全称</param>
  12567. private void S5AGV下料叫agv(int plcNo, string stationNameStr)
  12568. {
  12569. Stopwatch stopwatch1 = new Stopwatch();
  12570. Stopwatch stopwatch2 = new Stopwatch();
  12571. try
  12572. {
  12573. stopwatch1.Start();
  12574. // ZS 呼叫AGV
  12575. short e1AGVDownCall = 2;
  12576. stopwatch2.Start();
  12577. // e1AGVDownCall
  12578. //Funs[plcNo].WriteMultipleRegisters<short>(2133, e1AGVDownCall); // 1:plc请求下料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  12579. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12580. writeToPLC_Flag.Name = "e1AGVDownCall";
  12581. writeToPLC_Flag.Adress = 2133;
  12582. writeToPLC_Flag.Value = e1AGVDownCall;
  12583. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownCall", writeToPLC_Flag);
  12584. stopwatch2.Stop();
  12585. }
  12586. catch (Exception ex)
  12587. {
  12588. string str = ex.StackTrace;
  12589. AddMessage_Station(stationNameStr, LogType.Error,
  12590. $"PLC{plcNo}_{stationNameStr} AGV下料叫agv出错!错误信息:" + ex.Message + "异常位置:" +
  12591. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12592. // e1AGVDownCall
  12593. stopwatch2.Start();
  12594. //Funs[plcNo].WriteMultipleRegisters<short>(2133, (short)4); // 4代表上位机报警
  12595. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12596. writeToPLC_Flag.Name = "e1AGVDownCall";
  12597. writeToPLC_Flag.Adress = 2133;
  12598. writeToPLC_Flag.Value = (short)4;
  12599. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownCall", writeToPLC_Flag);
  12600. stopwatch2.Stop();
  12601. }
  12602. stopwatch1.Stop();
  12603. AddMessage(LogType.Info,
  12604. stationNameStr + "_AGV下料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  12605. stopwatch2.ElapsedMilliseconds + "ms");
  12606. }
  12607. /// <summary>
  12608. /// [S5] Tray盘下料装备 - AGV下料完成
  12609. /// </summary>
  12610. /// <param name="plcNo">PLC编号</param>
  12611. /// <param name="stationNameStr">工站全称</param>
  12612. private void S5AGV下料完成(int plcNo, string stationNameStr)
  12613. {
  12614. Stopwatch stopwatch1 = new Stopwatch();
  12615. Stopwatch stopwatch2 = new Stopwatch();
  12616. try
  12617. {
  12618. stopwatch1.Start();
  12619. // ZS AGV上料完成,让小车离开
  12620. short e1AGVDownEnd = 2;
  12621. stopwatch2.Start();
  12622. // e1AGVDownEnd
  12623. //Funs[plcNo].WriteMultipleRegisters<short>(2135, e1AGVDownEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  12624. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12625. writeToPLC_Flag.Name = "e1AGVDownEnd";
  12626. writeToPLC_Flag.Adress = 2135;
  12627. writeToPLC_Flag.Value = e1AGVDownEnd;
  12628. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownEnd", writeToPLC_Flag);
  12629. stopwatch2.Stop();
  12630. }
  12631. catch (Exception ex)
  12632. {
  12633. string str = ex.StackTrace;
  12634. AddMessage_Station(stationNameStr, LogType.Error,
  12635. $"PLC{plcNo}_{stationNameStr} AGV下料完成出错!错误信息:" + ex.Message + "异常位置:" +
  12636. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12637. // e1AGVDownEnd
  12638. stopwatch2.Start();
  12639. //Funs[plcNo].WriteMultipleRegisters<short>(2135, (short)4); // 4代表上位机报警
  12640. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  12641. writeToPLC_Flag.Name = "e1AGVDownEnd";
  12642. writeToPLC_Flag.Adress = 2135;
  12643. writeToPLC_Flag.Value = (short)4;
  12644. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownEnd", writeToPLC_Flag);
  12645. stopwatch2.Stop();
  12646. }
  12647. stopwatch1.Stop();
  12648. AddMessage(LogType.Info,
  12649. stationNameStr + "_AGV下料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" +
  12650. stopwatch2.ElapsedMilliseconds + "ms");
  12651. }
  12652. #endregion [S5] Tray盘下料装备
  12653. #endregion PLC5 张超凡
  12654. #region 缓存读取到的PLC数据 与 需要写入的PLC数据
  12655. /// <summary>
  12656. /// PLC读取到的数据 -添加数据
  12657. /// </summary>
  12658. public static void SxPLCData_Add(ref Dictionary<string, object> sxPlcData, string newKey, object newValue)
  12659. {
  12660. if (sxPlcData.ContainsKey(newKey))
  12661. sxPlcData[newKey] = newValue;
  12662. else
  12663. sxPlcData.Add(newKey, newValue);
  12664. }
  12665. /// <summary>
  12666. /// PLC需要写入的数据 -添加数据
  12667. /// </summary>
  12668. public static void SxPLCWriteData_Add(ref Dictionary<string, WriteToPLC_Flag> sxPLCWriteData, string newKey,
  12669. WriteToPLC_Flag newValue)
  12670. {
  12671. if (sxPLCWriteData.ContainsKey(newKey))
  12672. sxPLCWriteData[newKey] = newValue;
  12673. else
  12674. sxPLCWriteData.Add(newKey, newValue);
  12675. }
  12676. /// <summary>
  12677. /// PLC回写操作,写后清空flag
  12678. /// </summary>
  12679. /// <param name="modbusClient">modbus对象</param>
  12680. /// <param name="pLCReadDatas">读取到的数据字典</param>
  12681. /// <param name="pLCWriteDatas">需要写入的数据</param>
  12682. public static void PLCWriteData(ModbusClientHelper modbusClient, ref Dictionary<string, object> pLCReadDatas,
  12683. ref Dictionary<string, WriteToPLC_Flag> pLCWriteDataDic)
  12684. {
  12685. if (pLCWriteDataDic != null && pLCWriteDataDic.Count > 0)
  12686. {
  12687. List<WriteToPLC_Flag> pLCWriteDatas = pLCWriteDataDic.Values.ToList();
  12688. for (int i = 0; i < pLCWriteDatas.Count; i++)
  12689. {
  12690. string mesFlagName = pLCWriteDatas[i].Name;
  12691. int mesFlagAdress = pLCWriteDatas[i].Adress;
  12692. short mesFlagValue = (short)pLCWriteDatas[i].Value; // short
  12693. if (mesFlagValue != 0) // 不为0则证明需要写入结果信息
  12694. {
  12695. // 先回写数据
  12696. List<WriteToPLC_Data> writeToPLCDatas = pLCWriteDatas[i].WriteToPLCDatas;
  12697. for (int j = 0; j < writeToPLCDatas.Count; j++)
  12698. {
  12699. int mesDataAdress = writeToPLCDatas[j].Adress;
  12700. PLCValueType mesDataType = writeToPLCDatas[j].ValueType;
  12701. switch (mesDataType)
  12702. {
  12703. case PLCValueType.Short:
  12704. short mesDataValueShort = (short)writeToPLCDatas[j].Value;
  12705. modbusClient.WriteMultipleRegisters<short>(mesDataAdress, mesDataValueShort);
  12706. break;
  12707. case PLCValueType.String:
  12708. string mesDataValueStr = (string)writeToPLCDatas[j].Value;
  12709. int mesDataValueStrLength = writeToPLCDatas[j].ValueTypeStrLength;
  12710. modbusClient.WriteMultipleRegisters<string>(mesDataAdress, mesDataValueStr,
  12711. mesDataValueStrLength);
  12712. break;
  12713. }
  12714. }
  12715. // 再回写信号
  12716. modbusClient.WriteMultipleRegisters<short>(mesFlagAdress, mesFlagValue);
  12717. // 存储读取数据的字典
  12718. pLCReadDatas[mesFlagName] = (int)mesFlagValue;
  12719. // 存储写入数据的字典 - 清空写入值
  12720. pLCWriteDatas[i].Value = (short)0;
  12721. pLCWriteDataDic[mesFlagName] = pLCWriteDatas[i];
  12722. }
  12723. }
  12724. }
  12725. }
  12726. /// <summary>
  12727. /// 提交点检数据到MES - 取数据库中缓存的 点检数据
  12728. /// </summary>
  12729. /// <param name="no">3</param>
  12730. /// <param name="stationCode">设备编号</param>
  12731. /// <param name="stationNameStr">设备名称</param>
  12732. /// <param name="plcOrder">车间订单号</param>
  12733. private void SubmitOneCheckDataToMESByDB(int plcNo, int stationCode, string stationNameStr, string plcOrder)
  12734. {
  12735. try
  12736. {
  12737. /// [S2]FCT (2-上传点检数据;102-清空该工单该工单的所有点检项缓存)
  12738. /// [S3]值板机 (3-上传点检数据;103-清空该工单该工单的所有点检项缓存)
  12739. /// [S4]取放桁架 (4-上传点检数据;104-清空该工单该工单的所有点检项缓存)
  12740. /// [S6]CCD检测 (6-上传点检数据;106-清空该工单该工单的所有点检项缓存)
  12741. int result1 = 0;
  12742. switch (stationCode)
  12743. {
  12744. case 2:
  12745. case 3:
  12746. case 4:
  12747. case 6:
  12748. result1 = SubmitToMESByDB(stationCode.ToString(), stationNameStr, plcOrder);
  12749. break;
  12750. case 102:
  12751. result1 = ClearOneCheckDataByDB("2", stationNameStr, plcOrder);
  12752. break;
  12753. case 103:
  12754. result1 = ClearOneCheckDataByDB("3", stationNameStr, plcOrder);
  12755. break;
  12756. case 104:
  12757. result1 = ClearOneCheckDataByDB("4", stationNameStr, plcOrder);
  12758. break;
  12759. case 106:
  12760. result1 = ClearOneCheckDataByDB("6", stationNameStr, plcOrder);
  12761. break;
  12762. default:
  12763. // MES_Flag 为“6未找到正确设备编号”
  12764. Funs[plcNo].WriteMultipleRegisters<int>(2406, 6);
  12765. AddMessage_Station(stationNameStr, LogType.Error, $"PLC通知上传点检数据到MES运行出错!未找到需要点检的正确设备编号");
  12766. return;
  12767. }
  12768. short result = result1 == 1 ? (short)1 : (short)2;
  12769. Funs[plcNo].WriteMultipleRegisters<int>(2406, result); // MES_Flag 为4MES报错
  12770. OnMessage(LogType.Debug, $"PLC{plcNo}_PLC通知MES上传点检数据运行完毕!-Write" + (result == 1 ? "成功!" : "失败!"));
  12771. }
  12772. catch (Exception ex)
  12773. {
  12774. // MES_Flag 为2上位机报错
  12775. Funs[plcNo].WriteMultipleRegisters<int>(2406, 2);
  12776. string str = ex.StackTrace;
  12777. AddMessage_Station(stationNameStr, LogType.Error,
  12778. $"PLC通知上传点检数据到MES运行出错!错误信息:" + ex.Message.ToString() + ";异常位置:" +
  12779. str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  12780. }
  12781. }
  12782. #endregion 缓存读取到的PLC数据 与 需要写入的PLC数据
  12783. #region UI刷新
  12784. /// <summary>
  12785. /// 更新商品信息的UI + 下发产品信息(SN)
  12786. /// </summary>
  12787. private void UpdateProductInfo()
  12788. {
  12789. currentWC.Text = GlobalContext.WorkOrderCode; // 订单号
  12790. currentMtltmrk.Text = GlobalContext.Mtltmrk; // 产品型号
  12791. //currentBN.Text = GlobalContext.BatchNumber; // 批次号
  12792. //txt_CurSupplierCode.Text = ""; // 供应商代号
  12793. }
  12794. /// <summary>
  12795. /// 更新PLC连接状态的UI
  12796. /// </summary>
  12797. /// <param name="no">PLC编号</param>
  12798. /// <param name="status">状态</param>
  12799. private void UpdatePLCMonitor(int imgNo, int plcNo, int status)
  12800. {
  12801. if (this != null && !this.IsDisposed)
  12802. {
  12803. switch (imgNo)
  12804. {
  12805. case 1:
  12806. this.BeginInvoke(new Action(() => { picPLC.Image = imageListState.Images[status]; }));
  12807. break;
  12808. case 2:
  12809. this.BeginInvoke(new Action(() => { pictureBox2.Image = imageListState.Images[status]; }));
  12810. break;
  12811. case 3:
  12812. this.BeginInvoke(new Action(() => { pictureBox3.Image = imageListState.Images[status]; }));
  12813. break;
  12814. case 4:
  12815. this.BeginInvoke(new Action(() => { pictureBox4.Image = imageListState.Images[status]; }));
  12816. break;
  12817. case 5:
  12818. this.BeginInvoke(new Action(() => { pictureBox5.Image = imageListState.Images[status]; }));
  12819. break;
  12820. case 6:
  12821. this.BeginInvoke(new Action(() => { pictureBox6.Image = imageListState.Images[status]; }));
  12822. break;
  12823. case 7:
  12824. this.BeginInvoke(new Action(() => { pictureBox7.Image = imageListState.Images[status]; }));
  12825. break;
  12826. case 8:
  12827. this.BeginInvoke(new Action(() => { pictureBox8.Image = imageListState.Images[status]; }));
  12828. break;
  12829. default:
  12830. break;
  12831. }
  12832. }
  12833. Task.Run(() => // 更新PLC交互页的指示灯
  12834. {
  12835. try
  12836. {
  12837. if (Form_Main.formPLCDB != null && !Form_Main.formPLCDB.IsDisposed)
  12838. {
  12839. Form_Main.formPLCDB.UpdatePLCFunMonitor(plcNo, status);
  12840. }
  12841. }
  12842. catch
  12843. {
  12844. }
  12845. });
  12846. }
  12847. #endregion UI刷新
  12848. #region 日志
  12849. /// <summary>
  12850. /// 添加各工位运行日志(同步至PLC交互页面)
  12851. /// </summary>
  12852. /// <param name="stationNameStr">工站名称</param>
  12853. /// <param name="logType">日志类型</param>
  12854. /// <param name="message">日志内容</param>
  12855. /// <param name="snNumber">产品数字SN</param>
  12856. public void AddMessage_Station(string stationNameStr, LogType logType, string message, string snNumber = "")
  12857. {
  12858. if (!(stationNameStr.Equals("获取设备报警数据与状态信息")))
  12859. {
  12860. AddMessage(logType, message); // 首页展示+日志记录
  12861. }
  12862. PLCDBFormMessage plcMessage = new PLCDBFormMessage()
  12863. {
  12864. StationName = stationNameStr,
  12865. SnNumber = snNumber,
  12866. Message = message,
  12867. CreateTime = DateTime.Now
  12868. };
  12869. // PLC交互页展示
  12870. Task.Run(() =>
  12871. {
  12872. try
  12873. {
  12874. if (Form_Main.formPLCDB != null && !Form_Main.formPLCDB.IsDisposed)
  12875. {
  12876. Form_Main.formPLCDB.UpdateMessage(plcMessage);
  12877. }
  12878. }
  12879. catch
  12880. {
  12881. }
  12882. });
  12883. }
  12884. /// <summary>
  12885. /// 添加运行日志
  12886. /// </summary>
  12887. /// <param name="logType">日志类型</param>
  12888. /// <param name="message">日志内容</param>
  12889. public void AddMessage(LogType logType, string message)
  12890. {
  12891. OnMessage(logType, message);
  12892. string date = DateTime.Now.ToString("yyyy/MM/dd");
  12893. string time = DateTime.Now.ToString("HH:mm:ss:fff");
  12894. string msgShow = time + "--> " + message + "\r\n";
  12895. try
  12896. {
  12897. this.BeginInvoke(new Action(() =>
  12898. {
  12899. systemLog.Rows.Insert(0, date, time, message);
  12900. if (systemLog.Rows.Count >= 100)
  12901. systemLog.Rows.RemoveAt(systemLog.Rows.Count - 1);
  12902. }));
  12903. }
  12904. catch (Exception ex) { }
  12905. }
  12906. /// <summary>
  12907. /// 添加运行日志-保存
  12908. /// </summary>
  12909. /// <param name="logType">日志类型</param>
  12910. /// <param name="message">日志内容</param>
  12911. public void OnMessage(LogType logType, string msg)
  12912. {
  12913. MessageEvent?.Invoke(logType, msg);
  12914. }
  12915. /// <summary>
  12916. /// 保存PLC写入日志
  12917. /// </summary>
  12918. /// <param name="logType"></param>
  12919. /// <param name="logValue"></param>
  12920. private void WritePLCLog(LogType logType, string logValue)
  12921. {
  12922. switch ((int)logType)
  12923. {
  12924. case 0:
  12925. _PLCLogNet.WriteDebug(logValue);
  12926. break;
  12927. case 1:
  12928. _PLCLogNet.WriteInfo(logValue);
  12929. break;
  12930. case 2:
  12931. _PLCLogNet.WriteWarn(logValue);
  12932. break;
  12933. case 3:
  12934. _PLCLogNet.WriteError(logValue);
  12935. break;
  12936. default:
  12937. _PLCLogNet.WriteFatal(logValue);
  12938. break;
  12939. }
  12940. }
  12941. /// <summary>
  12942. /// IOT Mqtt回调方法- With DataId
  12943. /// </summary>
  12944. /// <param name="id"></param>
  12945. /// <param name="v"></param>
  12946. /// <param name="dataId"></param>
  12947. public void CallbackWithDataId(string id, string msg, string dataId)
  12948. {
  12949. //_MqttLogNet.WriteInfo("-------CallbackWithDataId-------");
  12950. //byte[] buffer1 = Encoding.Default.GetBytes(v);
  12951. //byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length);
  12952. //string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length);
  12953. //Console.WriteLine("{0} -> {1} {2}", id, strBuffer, dataId);
  12954. string datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
  12955. _IOTMqttLogNet.WriteInfo($"{datetime}-> [消息ID:{id}][事件ID:{dataId}]{msg}");
  12956. }
  12957. /// <summary>
  12958. /// AGV Mqtt回调方法- 记录Log并处理数据
  12959. /// </summary>
  12960. /// <param name="obj"></param>
  12961. private void AGVMqttShowLog(ResultData_MQTT resultData_MQTT)
  12962. {
  12963. string datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
  12964. _AGVMqttLogNet.WriteInfo($"{datetime}->返回结果:{resultData_MQTT.ResultCode},返回信息:{resultData_MQTT.ResultMsg}");
  12965. // 接收到的信息
  12966. string topic = (string)resultData_MQTT.ResultObject1; // 订阅的标识
  12967. string jsonData = (string)resultData_MQTT.ResultObject2; // 订阅的数据
  12968. if (resultData_MQTT.ResultCode == 1 && !string.IsNullOrEmpty(topic)) // 是接收到的数据
  12969. {
  12970. }
  12971. }
  12972. #endregion 日志
  12973. //private void button1_Click(object sender, EventArgs e)
  12974. //{
  12975. // OpenDailogFalg=true;
  12976. // if (OpenDailogFalg)
  12977. // {
  12978. // using (var dialog = new BandBarodeDialog())
  12979. // {
  12980. // string strCarrierBarcode = "N801A-003";
  12981. // dialog._CarrierBarcode = strCarrierBarcode;
  12982. // string sn = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  12983. // dialog._ProductBarcode = sn;
  12984. // var rs = dialog.ShowDialog();
  12985. // if (rs == DialogResult.OK)
  12986. // {
  12987. // AddMessage(LogType.Info, $"扫码校验通过,载具码:{strCarrierBarcode};产品码:{sn};产品码:{sn}");
  12988. // OpenDailogFalg = false;//关闭扫码
  12989. // }
  12990. // }
  12991. // }
  12992. //}
  12993. }
  12994. }