Form_Home.cs 364 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821
  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 NPOI.Util;
  15. using Sunny.UI;
  16. using MainForm.ClassFile.XiaomiAPI;
  17. using System.Diagnostics;
  18. using MainForm.Models;
  19. using SqlSugar;
  20. using EasyModbus;
  21. using ModBusClientSimple.Util;
  22. using MainForm.ClassFile.XiaomiAPI_MES;
  23. using static MainForm.ClassFile.XiaomiAPI.XiaomiMqttClient_Extend;
  24. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationOutbound;
  25. using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationInbound;
  26. using EIP_Protocol;
  27. using DevComponents.DotNetBar.Controls;
  28. using ICSharpCode.SharpZipLib.Zip;
  29. using static MainForm.SQLHelper;
  30. using NPOI.SS.Formula.Functions;
  31. using MainForm.ClassFile.ProjectClass;
  32. using HslCommunication.Controls;
  33. /*
  34. * 注:本源码对外提供,所以有些地方使用中文命名方法及变量
  35. */
  36. namespace MainForm
  37. {
  38. /// <summary>
  39. /// 记录日志的委托
  40. /// </summary>
  41. /// <param name="logType">日志类型</param>
  42. /// <param name="message">日志信息</param>
  43. public delegate void HomeMessageHandler(LogType logType, string message);
  44. /// <summary>
  45. /// 主页窗体
  46. /// </summary>
  47. public partial class Form_Home : Form
  48. {
  49. #region 常量
  50. //文本常量
  51. private const string Head = "开始采集";
  52. private const string Tail = "采集完成";
  53. private const string Body = "工位出站数据";
  54. private const string BodyCheck = "工位点检数据";
  55. private const string BodyRun = "整线运行数据";
  56. private const string BodyAlarm = "整线报警数据";
  57. #endregion 常量
  58. #region 变量
  59. /// <summary>
  60. /// 委托-记录日志的方法
  61. /// </summary>
  62. public event HomeMessageHandler MessageEvent;
  63. /// <summary>
  64. /// 日志接口
  65. /// </summary>
  66. ILogNet _PLCLogNet;
  67. /// <summary>
  68. /// 用于记录MQTT日志
  69. /// </summary>
  70. ILogNet _MqttLogNet;
  71. //private int DataSwitch = 1; // 1-SQLServer;2-Excel
  72. // 定义信号量,index0给MES(true有信号,false无信号;set()让被控线程运行,Reset()让被控线程停止;WaitOne(等待时间)等待线程运行)
  73. //间隔时间
  74. private int IntervalReadPLC = 300; //ms 读PLC
  75. private int IntervalMonitorMES = 1000; //ms MES心跳
  76. private int IntervalUpHead = 1000; //ms 上位机心跳(给PLC用)
  77. private int IntervalAlarm = 1000; //ms 数据(报警)查询与设备运行信息
  78. //定义一个字典,存plc对象(通讯)
  79. //ModbusClientHelper plc1Alarm; // PLC‘运行数据’与‘报警数据’线程用ModbusTCP
  80. //Dictionary<int, ModbusClientHelper> Funs = new Dictionary<int, ModbusClientHelper>();
  81. Inovance_EIP plc1Alarm; // PLC‘运行数据’与‘报警数据’线程用ModbusTCP
  82. Dictionary<int, Inovance_EIP> Funs = new Dictionary<int, Inovance_EIP>();
  83. /// <summary>
  84. /// 上次的设备运行信息
  85. /// </summary>
  86. private string lineWorkingData1_OldStr = string.Empty;
  87. /// <summary>
  88. /// 设备报警字典-当前结果
  89. /// Dictionary<工位代码,List<报警信息>>
  90. /// </summary>
  91. private Dictionary<string, List<Alarm>> DicAlarms_Cur = new Dictionary<string, List<Alarm>>();
  92. #endregion 变量
  93. #region 窗体基础事件
  94. /// <summary>
  95. /// 初始化
  96. /// </summary>
  97. public Form_Home()
  98. {
  99. InitializeComponent();
  100. CheckForIllegalCrossThreadCalls = false; // 不检查跨线程访问
  101. _PLCLogNet = new LogNetDateTime(GlobalContext.PlcLogDir, GenerateMode.ByEveryDay); // 按天记录日志
  102. _MqttLogNet = new LogNetDateTime(GlobalContext.MqttLogDir, GenerateMode.ByEveryHour); // 按小时记录日志
  103. GlobalContext.Set += new Action(UpdateProductInfo); // 产品信息变化时更新UI
  104. }
  105. /// <summary>
  106. /// 窗体加载事件
  107. /// </summary>
  108. private void Form_Home_Load(object sender, EventArgs e)
  109. {
  110. try
  111. {
  112. AddMessage(LogType.Info, "开始初始化程序");
  113. InitalDicAlarm(); // 实例化报警字典
  114. //组建plc对象字典
  115. //plc1Alarm = new ModbusClientHelper(GlobalContext.Machine1Address, GlobalContext.MachinePort);
  116. //plc1Alarm = new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine1Address);
  117. if (GlobalContext.IsUsePLC1)
  118. Funs.Add(1, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine1Address)); //OP10 壳体清洁上料装备
  119. //Funs.Add(1, new ModbusClientHelper(GlobalContext.Machine1Address, GlobalContext.MachinePort, 2001)); // Tray盘上料装备(板测)
  120. if (GlobalContext.IsUsePLC2)
  121. //Funs.Add(2, new ModbusClientHelper(GlobalContext.Machine2Address, GlobalContext.MachinePort, 2001)); // FCT(板测),
  122. Funs.Add(2, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine2Address)); //OP20 顶盖上料设备
  123. if (GlobalContext.IsUsePLC3)
  124. Funs.Add(3, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine3Address)); //OP30 点胶设备
  125. //Funs.Add(3, new ModbusClientHelper(GlobalContext.Machine3Address, GlobalContext.MachinePort, 2001)); // 值板机,
  126. if (GlobalContext.IsUsePLC4)
  127. Funs.Add(4, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine4Address)); //OP40 3D胶线检测
  128. //Funs.Add(4, new ModbusClientHelper(GlobalContext.Machine4Address, GlobalContext.MachinePort, 2001)); // 取放桁
  129. if (GlobalContext.IsUsePLC5)
  130. Funs.Add(5, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine5Address)); //OP50 ADD PCB板上料
  131. //Funs.Add(5, new ModbusClientHelper(GlobalContext.Machine5Address, GlobalContext.MachinePort, 2001)); //Tray盘下料装备
  132. if (GlobalContext.IsUsePLC6)
  133. Funs.Add(6, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine6Address)); //OP60 顶盖装配
  134. if (GlobalContext.IsUsePLC7)
  135. Funs.Add(7, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine7Address)); //OP70 锁螺丝
  136. if (GlobalContext.IsUsePLC8)
  137. Funs.Add(8, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine8Address)); //OP80 3D螺丝高度检测,NG出料站
  138. if (GlobalContext.IsUsePLC9)
  139. Funs.Add(9, new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine9Address)); //OP90 下料站
  140. foreach (Inovance_EIP plcEIP in Funs.Values)
  141. {
  142. if (plcEIP != null)
  143. {
  144. try
  145. {
  146. plcEIP.Connect();
  147. }
  148. catch (Exception ex)
  149. {
  150. MessageBox.Show($"PLC[{GlobalContext.Machine1Address}]连接失败!失败信息:" + ex.Message,
  151. "PLC连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
  152. }
  153. }
  154. }
  155. /*
  156. //plc1Alarm.Connect();
  157. foreach (ModbusClientHelper modbusClient in Funs.Values)
  158. {
  159. if (modbusClient != null)
  160. {
  161. try
  162. {
  163. modbusClient.Connect();
  164. }
  165. catch (Exception ex)
  166. {
  167. MessageBox.Show($"PLC[{modbusClient.IPAddress}:{modbusClient.Port}]连接失败!失败信息:" + ex.Message,
  168. "PLC连接提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
  169. }
  170. }
  171. }
  172. */
  173. // 采集任务
  174. Task TaskReadAlarm = new Task(ReadAlarmAllPLC); // 线程-获取线体报警数据
  175. List<Task> TaskReadProcess = new List<Task>(); // 线程-触发点位(PLC)的线程
  176. //TaskReadProcess.Add(new Task(() => { ReadStation_DownOrderInfo(1); })); // 下发机种
  177. if (GlobalContext.IsUsePLC1)
  178. //ReadStation_S1(1);
  179. TaskReadProcess.Add(new Task(() => { ReadStation_S1(1); })); //OP10 壳体清洁上料装备
  180. if (GlobalContext.IsUsePLC2)
  181. TaskReadProcess.Add(new Task(() => { ReadStation_S2(2); })); //OP20 顶盖上料设备
  182. if (GlobalContext.IsUsePLC3)
  183. //TaskReadProcess.Add(new Task(() => { ReadStation_S3(3); })); //OP30 点胶设备
  184. if (GlobalContext.IsUsePLC4)
  185. TaskReadProcess.Add(new Task(() => { ReadStation_S4(4); })); //OP40 点胶检测设备
  186. if (GlobalContext.IsUsePLC5)
  187. TaskReadProcess.Add(new Task(() => { ReadStation_S5(5); })); //OP50 ADD PCB板上料设备
  188. if (GlobalContext.IsUsePLC6)
  189. TaskReadProcess.Add(new Task(() => { ReadStation_S6(6); })); //OP60 顶盖装配设备
  190. if (GlobalContext.IsUsePLC8)
  191. TaskReadProcess.Add(new Task(() => { ReadStation_S8(8); })); //OP80 3D螺丝高度检测设备
  192. if (GlobalContext.IsUsePLC9)
  193. TaskReadProcess.Add(new Task(() => { ReadStation_S9(9); })); //OP90 下料设备
  194. /*
  195. if (GlobalContext.IsUsePLC7)
  196. TaskReadProcess.Add(new Task(() => { ReadStation_S7(7); })); //OP70 锁螺丝设备
  197. */
  198. #region 初始化
  199. try
  200. {
  201. // 开启MES(Http)
  202. //bool mesret = HttpUitls.PingIP(GlobalContext.ServerHost1);
  203. //if (mesret)
  204. //{
  205. // OnMessage(LogType.Info, "MES初始连接正常");
  206. // pictureBoxMESStatus.Image = imageListState.Images[1];
  207. // GlobalContext.MESIsConnect = true;
  208. //}
  209. //else
  210. //{
  211. // OnMessage(LogType.Info, "MES初始连接失败");
  212. // pictureBoxMESStatus.Image = imageListState.Images[0];
  213. // GlobalContext.MESIsConnect = false;
  214. //}
  215. // 开启IOT(MQTT)
  216. string addr = GlobalContext.MQTTServerHost;
  217. int port = GlobalContext.MQTTServerPort;
  218. int qmttResult = XiaomiMqttClient_Extend.OpenWithMqttServer(addr, port, GlobalContext.MqttServerPath, GlobalContext.MqttServerName);
  219. XiaomiMqttResponse_ErrCode response_ErrCode = (XiaomiMqttResponse_ErrCode)qmttResult;
  220. if (response_ErrCode == XiaomiMqttResponse_ErrCode.OK)
  221. {
  222. AddMessage(LogType.Info, "小米MQTT连接成功!--- OK");
  223. pictureBoxMESStatus.Image = imageListState.Images[1];
  224. GlobalContext.IOTIsConnect1 = true;
  225. XiaomiMqttClient_Extend.SetCallbackWithDataId(CallbackWithDataId);
  226. }
  227. else
  228. {
  229. AddMessage(LogType.Info, $"小米MQTT连接失败!--- {response_ErrCode.ToString()}");
  230. pictureBoxMESStatus.Image = imageListState.Images[0];
  231. GlobalContext.IOTIsConnect1 = false;
  232. }
  233. // 开启AGV HTTP
  234. //bool mesret = HttpUitls.PingIP(GlobalContext.ServerHost1);
  235. //if (mesret)
  236. //{
  237. // OnMessage(LogType.Info, "MES初始连接正常");
  238. // pictureBoxMESStatus.Image = imageListState.Images[1];
  239. // GlobalContext.MESIsConnect = true;
  240. //}
  241. //else
  242. //{
  243. // OnMessage(LogType.Info, "MES初始连接失败");
  244. // pictureBoxMESStatus.Image = imageListState.Images[0];
  245. // GlobalContext.MESIsConnect = false;
  246. //}
  247. // 开启AGV MQTT
  248. // 持续监视MES、IOT、AGV HTTP、AGV MQTT连接状态
  249. Task.Run(MonitorMESConnect);
  250. // 查询PLC连接状态
  251. foreach (int plcNo in Funs.Keys)
  252. {
  253. bool connected = Funs[plcNo].IsConnected;
  254. if (connected)
  255. {
  256. string msg = plcNo.ToString() + "工位初始连接成功---" + Funs[plcNo]._plcIPStr;
  257. AddMessage(LogType.Info, msg);
  258. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI
  259. }
  260. else
  261. {
  262. string msg = plcNo.ToString() + "工位初始连接失败---" + Funs[plcNo]._plcIPStr;
  263. AddMessage(LogType.Info, msg);
  264. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  265. }
  266. }
  267. // 开启PLC的业务处理线程-监听PLC点位+状态
  268. foreach (Task task in TaskReadProcess)
  269. {
  270. if (task != null)
  271. task.Start();
  272. }
  273. //// 开启“获取线体报警数据”的线程
  274. //TaskReadAlarm.Start();
  275. ////下传MES信息给1工位(先判断下plc对象数量)
  276. //if (Funs.Count > 1)
  277. // DownLoadProductInfo(1);
  278. AddMessage(LogType.Info, "程序初始化完成");
  279. }
  280. catch (Exception ex)
  281. {
  282. string str = ex.StackTrace;
  283. this.BeginInvoke(new Action(() =>
  284. {
  285. AddMessage(LogType.Error, "初始化PLC连接失败!异常信息:" + ex.Message + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  286. }));
  287. }
  288. #endregion
  289. }
  290. catch (Exception ex)
  291. {
  292. string str = ex.StackTrace;
  293. OnMessage(LogType.Info, "主窗体的首页初始化出错!异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1) + ";异常信息:" + ex.Message.ToString());
  294. if (ex.Message != null && ex.Message.Contains("timed out"))
  295. MessageBox.Show("主窗体的首页初始化出错!异常信息:PLC连接超时!" + ex.Message);
  296. else
  297. MessageBox.Show("主窗体的首页初始化出错!异常信息:" + ex.Message);
  298. }
  299. }
  300. /// <summary>
  301. /// 窗体关闭事件
  302. /// </summary>
  303. private void Form_Home_FormClosed(object sender, FormClosedEventArgs e)
  304. {
  305. Closed2();
  306. }
  307. public void Closed2()
  308. {
  309. try
  310. {
  311. XiaomiMqttClient_Extend.CloseWithMqttServer(GlobalContext.MqttServerPath, GlobalContext.MqttServerName);
  312. }
  313. catch { }
  314. }
  315. #endregion 窗体基础事件
  316. #region 监控MES状态
  317. /// <summary>
  318. /// 监控MES连接状态
  319. /// </summary>
  320. private void MonitorMESConnect()
  321. {
  322. while (true) // 运行被控线程
  323. {
  324. bool mesret = XiaomiMqttClient.IsOpen;
  325. if (mesret)
  326. {
  327. pictureBoxMESStatus.Image = imageListState.Images[1];
  328. GlobalContext.IOTIsConnect1 = true;
  329. }
  330. else
  331. {
  332. OnMessage(LogType.Info, "MES1连接失败");
  333. pictureBoxMESStatus.Image = imageListState.Images[0];
  334. GlobalContext.IOTIsConnect1 = false;
  335. }
  336. Thread.Sleep(IntervalMonitorMES);
  337. }
  338. }
  339. #endregion 监控MES连接状态
  340. #region 采集设备状态、运行数据、报警数据
  341. /// <summary>
  342. /// 请求设备状态 5000
  343. /// </summary>
  344. /// <param name="no">1</param>
  345. /// <param name="stationNameStr"></param>
  346. /// <returns>0:证明未连接到PLC;1,代表设备控制状态处于运行状态;2,代表设备控制状态处于故障状态;3,代表设备控制状态处于缺料状态;4,代表设备控制状态处于待机状态;5,代表设备控制状态处于维修状态;</returns>
  347. public int GetDeviceStatus(int plcNo, string stationNameStr = "[S0]壳体上料")
  348. {
  349. try
  350. {
  351. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  352. {
  353. short result = 0; //Funs[plcNo].ReadHoldingRegisters<short>(5000); // 5000
  354. return result;
  355. }
  356. else
  357. {
  358. return 0;
  359. }
  360. }
  361. catch (Exception ex)
  362. {
  363. string str = ex.StackTrace;
  364. AddMessage_Station(stationNameStr, LogType.Error, "请求设备状态失败!" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  365. return 0;
  366. }
  367. }
  368. /// <summary>
  369. /// 检查是否可采集点检数据 - 不取新值
  370. /// 5000不为1时可点检
  371. /// </summary>
  372. /// <returns></returns>
  373. public bool CheckCanSpotcheck1(int deviceState)
  374. {
  375. //return true;
  376. //D5000 = 1,代表设备控制状态处于运行状态
  377. //D5000 = 2, 代表设备控制状态处于故障状态
  378. //D5000 = 3,代表设备控制状态处于缺料状态
  379. //D5000 = 4, 代表设备控制状态处于待机状态
  380. //D5000 = 5,代表设备控制状态处于维修状态
  381. return deviceState != 1;
  382. }
  383. /// <summary>
  384. /// 检查是否可采集产品数据 - 不取新值
  385. /// </summary>
  386. /// <returns></returns>
  387. public bool CheckCanCollData(int deviceState)
  388. {
  389. return deviceState == 0; // 点检时该值不为0
  390. }
  391. /// <summary>
  392. /// 获取设备报警数据与获取设备运行信息
  393. /// </summary>
  394. private async void ReadAlarmAllPLC()
  395. {
  396. // [S1] Tray盘上料装备(板测)
  397. // [S2] FCT(板测)
  398. // [S3] 值板机
  399. // [S4] 取放桁架
  400. // [S5] Tray盘下料装备
  401. /// 上位机心跳
  402. /// 获取设备报警数据与状态信息
  403. string stationNameStr = "获取设备报警数据与状态信息";
  404. while (true)
  405. {
  406. try
  407. {
  408. if (!GlobalContext._IsCon_plc1Alarm)
  409. {
  410. UpdatePLCMonitor(1, -2, 0);
  411. continue;
  412. }
  413. if (plc1Alarm.IsConnected) // 检查PLC是否已连接上
  414. {
  415. DateTime dtNow = DateTime.Now;
  416. #region 获取设备运行信息
  417. try
  418. {
  419. LineWorkingData_ThisTime lineWorkingData1 = new LineWorkingData_ThisTime();
  420. lineWorkingData1.GUID = Guid.NewGuid().ToString();
  421. lineWorkingData1.LineName = GlobalContext.LineCode;
  422. //
  423. /*
  424. lineWorkingData1.BootTimeLong = plc1Alarm.ReadHoldingRegisters<float>(5500); // 本次开机时间(整线)D5500 h
  425. lineWorkingData1.NormalTimeLong = plc1Alarm.ReadHoldingRegisters<float>(5502); // 本次开机运行时间(整线)D5502 h
  426. lineWorkingData1.StandbyTimeLong = plc1Alarm.ReadHoldingRegisters<float>(5504); // 本次开机待机时间(整线)D5504 h
  427. lineWorkingData1.FaultTimeLong = plc1Alarm.ReadHoldingRegisters<float>(5506); // 本次开机故障时间(整线)D5506 h
  428. lineWorkingData1.MaterialShortageTimeLong = plc1Alarm.ReadHoldingRegisters<float>(5508); // 本次开机缺料时间(整线)D5508 h
  429. lineWorkingData1.MaintenanceTimeLong = plc1Alarm.ReadHoldingRegisters<float>(5510); // 本次开机维修时间(整线)D5510 h
  430. lineWorkingData1.FaultNumber = plc1Alarm.ReadHoldingRegisters<short>(5514); // 本次开机故障停机次数(整线)D5514
  431. lineWorkingData1.OutputNumber = plc1Alarm.ReadHoldingRegisters<short>(5700); // 本次开机产量(整线) D5700
  432. lineWorkingData1.QualifiedNumber = plc1Alarm.ReadHoldingRegisters<short>(5704); // 本次开机合格数量(整线) D5704
  433. lineWorkingData1.QualifiedRate = plc1Alarm.ReadHoldingRegisters<float>(5710); // 本次开机合格率(整线) D5710
  434. lineWorkingData1.DesignRhythm = plc1Alarm.ReadHoldingRegisters<float>(5714); // 设计节拍(整线) D5714
  435. lineWorkingData1.RealityRhythm = plc1Alarm.ReadHoldingRegisters<float>(5716); // 本次开机实际节拍(整线) D5716
  436. */
  437. lineWorkingData1.CreateTime = DateTime.Now;
  438. string lineWorkingData1_Str = JsonConvert.SerializeObject(lineWorkingData1);
  439. // UI展示-展示到设备状态页
  440. if (string.IsNullOrEmpty(lineWorkingData1_OldStr)) // 软件启动后第一次运行
  441. {
  442. // 查询数据库最新一条数据,确定是不是更新
  443. string qSql = @"SELECT top(1) [GUID]
  444. ,[LineName]
  445. ,[BootTimeLong]
  446. ,[NormalTimeLong]
  447. ,[StandbyTimeLong]
  448. ,[FaultTimeLong]
  449. ,[MaterialShortageTimeLong]
  450. ,[MaintenanceTimeLong]
  451. ,[FaultNumber]
  452. ,[OutputNumber]
  453. ,[QualifiedNumber]
  454. ,[QualifiedRate]
  455. ,[DesignRhythm]
  456. ,[RealityRhythm]
  457. ,[CreateTime]
  458. FROM [LineWorkingData]
  459. where [CreateTime] > '{0}'
  460. and [LineName]='{1}'
  461. order by [CreateTime] desc
  462. ";
  463. qSql = string.Format(qSql, DateTime.Now.ToString("yyyy-MM-dd") + " 00:00:00", lineWorkingData1.LineName);
  464. var ds = SQLHelper_New.Query(qSql, null);
  465. if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
  466. {
  467. var dataDBlast = new LineWorkingData_ThisTime();
  468. dataDBlast.GUID = ds.Tables[0].Rows[0][0].ToString(); // 主键
  469. dataDBlast.LineName = ds.Tables[0].Rows[0][1].ToString(); // 线体名称
  470. dataDBlast.BootTimeLong = Convert.ToSingle(ds.Tables[0].Rows[0][2].ToString()); // 本次开机时间(整线)
  471. dataDBlast.CreateTime = Convert.ToDateTime(ds.Tables[0].Rows[0][14].ToString()); // 创建时间
  472. if (lineWorkingData1.BootTimeLong > dataDBlast.BootTimeLong) // 需要更新的情况;不需要更新的走后面的插入
  473. {
  474. dataDBlast.BootTimeLong = lineWorkingData1.BootTimeLong; // 本次开机时间(整线)
  475. dataDBlast.NormalTimeLong = lineWorkingData1.NormalTimeLong; // 本次开机运行时间(整线)
  476. dataDBlast.StandbyTimeLong = lineWorkingData1.StandbyTimeLong; // 本次开机待机时间(整线)
  477. dataDBlast.FaultTimeLong = lineWorkingData1.FaultTimeLong; // 本次开机故障时间(整线)
  478. dataDBlast.MaterialShortageTimeLong = lineWorkingData1.MaterialShortageTimeLong; // 本次开机缺料时间(整线)
  479. dataDBlast.MaintenanceTimeLong = lineWorkingData1.MaintenanceTimeLong; // 本次开机维修时间(整线)
  480. dataDBlast.FaultNumber = lineWorkingData1.FaultNumber; // 本次开机故障停机次数(整线)
  481. dataDBlast.OutputNumber = lineWorkingData1.OutputNumber; // 本次开机产量(整线)
  482. dataDBlast.QualifiedNumber = lineWorkingData1.QualifiedNumber; // 本次开机合格数量(整线)
  483. dataDBlast.QualifiedRate = lineWorkingData1.QualifiedRate; // 本次开机合格率(整线)
  484. dataDBlast.DesignRhythm = lineWorkingData1.DesignRhythm; // 设计节拍(整线)
  485. dataDBlast.RealityRhythm = lineWorkingData1.RealityRhythm; // 本次开机实际节拍(整线)
  486. string usql = dataDBlast.ToStringUpdate();
  487. SQLHelper_New.ExecuteSQL(usql, null);
  488. lineWorkingData1_OldStr = JsonConvert.SerializeObject(dataDBlast);
  489. AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyRun}完毕![{lineWorkingData1_OldStr}]");
  490. //AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyRun}完毕!");
  491. }
  492. }
  493. else
  494. {
  495. // 插入
  496. SQLHelper_New.ExecuteSQL(lineWorkingData1.ToStringInsert(), null);
  497. lineWorkingData1_OldStr = String.Copy(lineWorkingData1_Str);
  498. AddMessage_Station(stationNameStr, LogType.Info, $"保存{BodyRun}完毕![{lineWorkingData1_OldStr}]");
  499. //AddMessage_Station(stationNameStr, LogType.Info, $"保存{BodyRun}完毕!");
  500. }
  501. }
  502. else if (!lineWorkingData1_Str.Equals(lineWorkingData1_OldStr)) // 非“软件启动后第一次运行”
  503. {
  504. LineWorkingData_ThisTime lineWorkingData1_Old = string.IsNullOrEmpty(lineWorkingData1_OldStr) ? lineWorkingData1 : JsonConvert.DeserializeObject<LineWorkingData_ThisTime>(lineWorkingData1_OldStr); // 上次的状态信息
  505. //// 本次开机设备运行情况
  506. //LineWorkingData1_ThisTime lineWorkingData_UI = JsonConvert.DeserializeObject<LineWorkingData1_ThisTime>(lineWorkingData1_OldStr);
  507. //Task.Run(() =>
  508. //{
  509. // if (Form_Main.formDevAlarm != null && !Form_Main.formDevAlarm.IsDisposed && Form_Main.formDevAlarm.Visible)
  510. // {
  511. // Form_Main.formDevAlarm.UpdDeviceStatus_ThisTime(lineWorkingData_UI); // UI更新
  512. // }
  513. //});
  514. // 本日设备运行情况
  515. // 存数据库(开机时间>上次的开机时间,则更新上次记录;<则作为新数据插入)
  516. if (lineWorkingData1.BootTimeLong > lineWorkingData1_Old.BootTimeLong)
  517. {
  518. // 更新
  519. lineWorkingData1_Old.BootTimeLong = lineWorkingData1.BootTimeLong; // 本次开机时间(整线)
  520. lineWorkingData1_Old.NormalTimeLong = lineWorkingData1.NormalTimeLong; // 本次开机运行时间(整线)
  521. lineWorkingData1_Old.StandbyTimeLong = lineWorkingData1.StandbyTimeLong; // 本次开机待机时间(整线)
  522. lineWorkingData1_Old.FaultTimeLong = lineWorkingData1.FaultTimeLong; // 本次开机故障时间(整线)
  523. lineWorkingData1_Old.MaterialShortageTimeLong = lineWorkingData1.MaterialShortageTimeLong; // 本次开机缺料时间(整线)
  524. lineWorkingData1_Old.MaintenanceTimeLong = lineWorkingData1.MaintenanceTimeLong; // 本次开机维修时间(整线)
  525. lineWorkingData1_Old.FaultNumber = lineWorkingData1.FaultNumber; // 本次开机故障停机次数(整线)
  526. lineWorkingData1_Old.OutputNumber = lineWorkingData1.OutputNumber; // 本次开机产量(整线)
  527. lineWorkingData1_Old.QualifiedNumber = lineWorkingData1.QualifiedNumber; // 本次开机合格数量(整线)
  528. lineWorkingData1_Old.QualifiedRate = lineWorkingData1.QualifiedRate; // 本次开机合格率(整线)
  529. lineWorkingData1_Old.DesignRhythm = lineWorkingData1.DesignRhythm; // 设计节拍(整线)
  530. lineWorkingData1_Old.RealityRhythm = lineWorkingData1.RealityRhythm; // 本次开机实际节拍(整线)
  531. SQLHelper_New.ExecuteSQL(lineWorkingData1_Old.ToStringUpdate(), null);
  532. lineWorkingData1_OldStr = JsonConvert.SerializeObject(lineWorkingData1_Old);
  533. AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyRun}完毕![{lineWorkingData1_OldStr}]");
  534. //AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyRun}完毕!");
  535. }
  536. else if (lineWorkingData1.BootTimeLong < lineWorkingData1_Old.BootTimeLong)
  537. {
  538. // 插入
  539. SQLHelper_New.ExecuteSQL(lineWorkingData1.ToStringInsert(), null);
  540. lineWorkingData1_OldStr = String.Copy(lineWorkingData1_Str);
  541. AddMessage_Station(stationNameStr, LogType.Info, $"保存{BodyRun}完毕![{lineWorkingData1_OldStr}]");
  542. //AddMessage_Station(stationNameStr, LogType.Info, $"保存{BodyRun}完毕!");
  543. }
  544. await Task.Run(() =>
  545. {
  546. try
  547. {
  548. if (Form_Main.formDevAlarm != null && !Form_Main.formDevAlarm.IsDisposed && Form_Main.formDevAlarm.Visible)
  549. {
  550. Form_Main.formDevAlarm.UpdDeviceStatus_Today(); // UI更新
  551. }
  552. }
  553. catch { }
  554. });
  555. }
  556. }
  557. catch (Exception ex)
  558. {
  559. string str = ex.StackTrace;
  560. AddMessage_Station(stationNameStr, LogType.Error, $"PLC1_{stationNameStr}_获取设备运行信息出错!错误信息:" + ex.Message.ToString() + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  561. }
  562. #endregion 获取设备运行信息
  563. #region 报警数据
  564. try
  565. {
  566. List<DeviceAlarm_Cur> deviceAlarm_Curs = new List<DeviceAlarm_Cur>(); // 同步到报警页面用传输载体
  567. bool isNeedUpdUI = false; // 是否需要更新历史报警UI
  568. // 同步“设备报警信息”到“设备报警临时字典DicAlarms_Cur”
  569. var dicAlarms_Cur_PLC1 = DicAlarms_Cur[GlobalContext.LineCode];
  570. for (int i = 0; i < dicAlarms_Cur_PLC1.Count; i++) // 读取
  571. {
  572. short shortBuf = 0;// plc1Alarm.ReadHoldingRegisters<short>(dicAlarms_Cur_PLC1[i].关联的PLC地址);
  573. dicAlarms_Cur_PLC1[i].是否报警 = shortBuf != 0;
  574. if (dicAlarms_Cur_PLC1[i].上次的运行状态 != dicAlarms_Cur_PLC1[i].是否报警)
  575. {
  576. isNeedUpdUI = true; // 需要更新历史报警UI信息
  577. // 记录
  578. dicAlarms_Cur_PLC1[i].上次的运行状态 = dicAlarms_Cur_PLC1[i].是否报警;
  579. switch (dicAlarms_Cur_PLC1[i].是否报警)
  580. {
  581. case true: // 报警
  582. dicAlarms_Cur_PLC1[i].报警数据 = new AlarmData()
  583. {
  584. GUID = Guid.NewGuid().ToString(),
  585. LineName = GlobalContext.LineCode, // 线体
  586. AlarmType = dicAlarms_Cur_PLC1[i].报警类型, // 报警类型
  587. AlarmDesc = dicAlarms_Cur_PLC1[i].报警详情, // 报警内容
  588. StartTime = dtNow // 开始时间
  589. };
  590. // 传输到页面
  591. deviceAlarm_Curs.Add(new DeviceAlarm_Cur()
  592. {
  593. 线体名称 = dicAlarms_Cur_PLC1[i].报警数据.LineName,
  594. 报警类型 = dicAlarms_Cur_PLC1[i].报警数据.AlarmType,
  595. 报警内容 = dicAlarms_Cur_PLC1[i].报警数据.AlarmDesc,
  596. 开始时间 = dtNow
  597. });
  598. // 新增到数据库
  599. var data1 = dicAlarms_Cur_PLC1[i].报警数据;
  600. SaveAlarmDataByDB(stationNameStr, data1, false);
  601. AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyAlarm}完毕!");
  602. break;
  603. case false: // 消除报警
  604. if (dicAlarms_Cur_PLC1[i].报警数据 == null || string.IsNullOrEmpty(dicAlarms_Cur_PLC1[i].报警数据.GUID))
  605. {
  606. dicAlarms_Cur_PLC1[i].报警数据 = new AlarmData()
  607. {
  608. GUID = Guid.NewGuid().ToString(),
  609. LineName = GlobalContext.LineCode, // 线体
  610. AlarmType = dicAlarms_Cur_PLC1[i].报警类型, // 报警类型
  611. AlarmDesc = dicAlarms_Cur_PLC1[i].报警详情, // 报警内容
  612. StartTime = dtNow, // 开始时间
  613. EndTime = dtNow, // 开始时间
  614. PersistTime = 1, // 耗时1s
  615. };
  616. // 新增
  617. var data2 = dicAlarms_Cur_PLC1[i].报警数据;
  618. SaveAlarmDataByDB(stationNameStr, data2, false);
  619. AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyAlarm}完毕!");
  620. }
  621. else
  622. {
  623. dicAlarms_Cur_PLC1[i].报警数据.EndTime = dtNow; // 开始时间
  624. dicAlarms_Cur_PLC1[i].报警数据.PersistTime = Convert.ToInt32((dicAlarms_Cur_PLC1[i].报警数据.EndTime
  625. - dicAlarms_Cur_PLC1[i].报警数据.StartTime).TotalSeconds); // 耗时s
  626. // 修改
  627. var data3 = dicAlarms_Cur_PLC1[i].报警数据;
  628. SaveAlarmDataByDB(stationNameStr, data3, true);
  629. AddMessage_Station(stationNameStr, LogType.Info, $"更新{BodyAlarm}完毕!");
  630. }
  631. break;
  632. default:
  633. break;
  634. }
  635. }
  636. }
  637. DicAlarms_Cur[GlobalContext.LineCode] = dicAlarms_Cur_PLC1;
  638. // 有新报警则更新
  639. if (isNeedUpdUI)
  640. {
  641. // UI展示 - 展示到设备状态页
  642. await Task.Run(() =>
  643. {
  644. try
  645. {
  646. if (Form_Main.formDevAlarm != null && !Form_Main.formDevAlarm.IsDisposed)
  647. {
  648. Form_Main.formDevAlarm.UpdDeviceAlarm_Cur(deviceAlarm_Curs); // 报警UI 更新
  649. if (Form_Main.formDevAlarm.Visible)
  650. {
  651. Form_Main.formDevAlarm.UpdDeviceAlarm_History_48H(); // 历史报警UI 更新
  652. }
  653. }
  654. }
  655. catch { }
  656. });
  657. }
  658. }
  659. catch (Exception ex)
  660. {
  661. string str = ex.StackTrace;
  662. AddMessage_Station(stationNameStr, LogType.Error, $"PLC1_{stationNameStr}_获取报警数据出错!错误信息:" + ex.Message.ToString() + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  663. }
  664. #endregion 报警数据
  665. UpdatePLCMonitor(1, -2, 1);
  666. }
  667. else
  668. {
  669. UpdatePLCMonitor(1, -2, 0);
  670. }
  671. }
  672. catch (Exception ex)
  673. {
  674. AddMessage_Station(stationNameStr, LogType.Error, $"PLC1_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  675. }
  676. Thread.Sleep(IntervalAlarm);
  677. }
  678. }
  679. #endregion 轮询PLC
  680. #region 下发订单信息
  681. ///// <summary>
  682. ///// 壳体上料(下发工单)的交互逻辑
  683. ///// </summary>
  684. ///// <param name="no"></param>
  685. ///// <exception cref="NotImplementedException"></exception>
  686. //private void ReadStation_DownOrderInfo(int plcNo)
  687. //{
  688. // // [S1] Tray盘上料装备(板测)
  689. // // [S2] FCT(板测)
  690. // // [S3] 值板机
  691. // // [S4] 取放桁架
  692. // // [S5] Tray盘下料装备
  693. // /// 上位机心跳
  694. // /// 获取设备报警数据与状态信息
  695. // string stationNameStr = "[S0]壳体上料";
  696. // while (true)
  697. // {
  698. // try
  699. // {
  700. // if (!GlobalContext._IsCon_Funs1)
  701. // {
  702. // UpdatePLCMonitor(plcNo, 0);
  703. // continue;
  704. // }
  705. // if (Funs[plcNo].isConnected) // 检查PLC是否已连接上
  706. // {
  707. // #region 壳体上料(下发工单)
  708. // try
  709. // {
  710. // Funs[plcNo].Read_Int_Tag("500", 1, out short[] iiMes0);
  711. // Funs[plcNo].Read_Int_Tag("501", 1, out short[] iiPlc0);
  712. // bool mES_FLAG_1 = iiMes0[0] == 1 ? true : false; // MES_FLAG_1
  713. // bool pLC_Flag_1 = iiPlc0[0] == 1 ? true : false; // PLC_FLAG_1
  714. // // 重置数据和信号
  715. // if (mES_FLAG_1 && pLC_Flag_1) // 1 1
  716. // {
  717. // // 清空写给PLC的数据
  718. // int[] i497 = new int[1] { 0 };
  719. // Funs[plcNo].Write_DInt_Tag("497", 1, i497); // SN号(数字部分)重置信号
  720. // // MES_Flag重置为0
  721. // int[] i500 = new int[1] { 0 };
  722. // Funs[plcNo].Write_DInt_Tag("500", 1, i500); // MES_FLAG_1
  723. // }
  724. // }
  725. // catch (Exception ex)
  726. // {
  727. // string str = ex.StackTrace;
  728. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}下发订单信息运行出错!错误信息:" + ex.Message.ToString() + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  729. // }
  730. // #endregion 壳体上料(下发工单)
  731. // UpdatePLCMonitor(plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  732. // }
  733. // else
  734. // {
  735. // UpdatePLCMonitor(plcNo, 0); // 更新PLC状态的UI
  736. // AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  737. //
  738. // Funs[plcNo].Connect();
  739. // }
  740. // }
  741. // catch (Exception ex)
  742. // {
  743. // UpdatePLCMonitor(plcNo, 0); // 更新PLC状态的UI
  744. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  745. //
  746. // Funs[plcNo].ReConnect();
  747. // }
  748. // Thread.Sleep(IntervalReadPLC);
  749. // }
  750. //}
  751. ///// <summary>
  752. ///// 下发订单信息到PLC
  753. ///// </summary>
  754. ///// <param name="no">PLC编号</param>
  755. //private void DownLoadProductInfo(int plcNo, string stationNameStr = "[S0]壳体上料")
  756. //{
  757. // try
  758. // {
  759. // if (!string.IsNullOrEmpty(GlobalContext.Mtltmrk))
  760. // {
  761. // Funs[plcNo].Write_String_Tag("568", 1, GlobalContext.Mtltmrk); // 产品型号(mtltmrk)
  762. // WritePLCLog(LogType.Debug, GlobalContext.Mtltmrk);
  763. // }
  764. // Funs[plcNo].Write_DInt_Tag("500", 1, new Int32[1] { 1 }); // MES_FLAG_1
  765. // }
  766. // catch (Exception ex)
  767. // {
  768. // string str = ex.StackTrace;
  769. // AddMessage_Station(stationNameStr, LogType.Error, "下发订单信息到PLC失败!" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  770. // }
  771. //}
  772. /// <summary>
  773. /// 下发清料信号
  774. /// </summary>
  775. /// <param name="no">PLC编号</param>
  776. public bool ClearProducts(int plcNo, string stationNameStr = "[S0]壳体上料")
  777. {
  778. try
  779. {
  780. //Funs[plcNo].ReadHoldingRegisters<int>(496); //
  781. AddMessage_Station(stationNameStr, LogType.Info, "下发了清料信号!");
  782. return true;
  783. }
  784. catch (Exception ex)
  785. {
  786. string str = ex.StackTrace;
  787. AddMessage_Station(stationNameStr, LogType.Error, "下发清料信号失败!" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  788. return false;
  789. }
  790. }
  791. #endregion 下发订单信息
  792. #region PLC1 贲流
  793. #region [S1] 壳体清洁上料装备
  794. /// <summary>
  795. /// S1工位的数据- 触发信号上次的值
  796. /// </summary>
  797. private Dictionary<string, object> s1PLCSignal_Old = new Dictionary<string, object>();
  798. /// <summary>
  799. /// S1工位的数据(含触发信号)
  800. /// </summary>
  801. private Dictionary<string, object> s1PLCData = new Dictionary<string, object>();
  802. /// <summary>
  803. /// S1工位的数据- 回写点位
  804. /// </summary>
  805. private Dictionary<string, WriteToPLC_Flag> s1PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  806. ///// <summary>
  807. ///// 触发信号
  808. ///// </summary>
  809. //private ManualResetEvent[] MreTasks;
  810. /// <summary>
  811. /// [S1] 壳体清洁上料装备
  812. /// </summary>
  813. /// <param name="plcNo">PLC编号</param>
  814. private void ReadStation_S1(int plcNo)
  815. {
  816. string stationCode = "[S1]";
  817. string stationName = "壳体清洁上料";
  818. string stationNameStr = stationCode + stationName;
  819. string tagBaseName = "g_OP10_MES"; //标签变量名称
  820. string tagMesCommName = "mesCommToPC"; //标签变量名称
  821. string tagAgvCommName = "agvCommFrmPC";
  822. string tagBarsetName = "BarcodeSet";
  823. OP10_MesData_t stPLC_MesData; //PLC的MES数据
  824. (int, string) result;
  825. bool ProgressState = true;
  826. #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  827. // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  828. s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  829. s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  830. s1PLCSignal_Old.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  831. s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  832. s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  833. s1PLCSignal_Old.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  834. s1PLCSignal_Old.Add("a1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  835. s1PLCSignal_Old.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  836. s1PLCSignal_Old.Add("a1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  837. // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  838. s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  839. s1PLCData.Add("a1MES_FLAG_VehicleStates", 0); // MES_FLAG
  840. s1PLCData.Add("a1ProductSN_VehicleStates", ""); // 产品SN(载具码)
  841. s1PLCData.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  842. s1PLCData.Add("a1MES_FLAG_Check", 0); // MES_FLAG
  843. s1PLCData.Add("a1ProductSN_Check", ""); // 产品SN(物料码)
  844. s1PLCData.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  845. s1PLCData.Add("a1MES_FLAG", 0); // MES_FLAG
  846. s1PLCData.Add("a1ProductSN", ""); // 产品SN(载具SN)
  847. s1PLCData.Add("a1PartNo1", ""); // 物料码1(穴位1)
  848. s1PLCData.Add("a1PartNo2", ""); // 物料码2(穴位2)
  849. s1PLCData.Add("a1Result", 0); // 产品结果
  850. s1PLCData.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  851. s1PLCData.Add("a1MES_FLAG_ICT", 0); // MES_FLAG
  852. s1PLCData.Add("a1ProductSN_ICT", ""); // 产品SN(载具SN)
  853. s1PLCData.Add("a1PartNo1_ICT", ""); // 物料码1(穴位1)
  854. s1PLCData.Add("a1PartNo2_ICT", ""); // 物料码2(穴位2)
  855. s1PLCData.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  856. s1PLCData.Add("a1OEEMES_FLAG", 0); // MES_FLAG
  857. s1PLCData.Add("a1OEEPartNo", ""); // 物料码(物料码还未绑定载具SN时必填)
  858. s1PLCData.Add("a1OEEVehicleCode", ""); // 载具SN
  859. s1PLCData.Add("a1OEEPartNum", 0); // 穴位号
  860. s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  861. s1PLCData.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  862. s1PLCData.Add("a1AGVUpStart", 0); // AGV上料开始信号
  863. s1PLCData.Add("a1AGVUpEnd", 0); // AGV上料完成信号
  864. s1PLCData.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  865. s1PLCData.Add("a1AGVDownStart", 0); // AGV下料开始信号
  866. s1PLCData.Add("a1AGVDownEnd", 0); // AGV下料完成信号
  867. #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  868. while (true)
  869. {
  870. try
  871. {
  872. if (!GlobalContext._IsCon_Funs1)
  873. {
  874. UpdatePLCMonitor(1, plcNo, 0);
  875. continue;
  876. }
  877. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  878. {
  879. Stopwatch stopwatch1 = new Stopwatch();
  880. Stopwatch stopwatch2 = new Stopwatch();
  881. stopwatch1.Start();
  882. stopwatch2.Start();
  883. #region 一次性读取所有数据
  884. // 一次性读取所有数据
  885. result = Funs[plcNo].Read_SingleTag<OP10_MesData_t>(tagBaseName, 1, out stPLC_MesData); //读取单个结构体数据
  886. if (result.Item1 != 0)
  887. {
  888. //richTextBox1.AppendText("\n" + strRet);
  889. }
  890. else
  891. {
  892. //richTextBox1.AppendText("\n" + "读取成功");
  893. }
  894. #endregion 一次性读取所有数据
  895. stopwatch2.Stop();
  896. #region 进站
  897. try
  898. {
  899. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
  900. {
  901. ProgressState = false;
  902. Task.Run(() => S1进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName,out ProgressState));
  903. }
  904. }
  905. catch (Exception ex)
  906. {
  907. ProgressState = false;
  908. string str = ex.StackTrace;
  909. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  910. }
  911. #endregion 进站
  912. #region 出站
  913. try
  914. {
  915. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
  916. {
  917. ProgressState = false;
  918. Task.Run(() => S1出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName,out ProgressState));
  919. }
  920. }
  921. catch (Exception ex)
  922. {
  923. string str = ex.StackTrace;
  924. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  925. }
  926. #endregion 进站
  927. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  928. stopwatch1.Stop();
  929. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  930. }
  931. else
  932. {
  933. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  934. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  935. Funs[plcNo].Connect(); // 重连
  936. }
  937. }
  938. catch (Exception ex)
  939. {
  940. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  941. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  942. }
  943. Thread.Sleep(IntervalReadPLC);
  944. }
  945. }
  946. /// <summary>
  947. /// [S1] 壳体清洁上料 - 进站
  948. /// </summary>
  949. /// <param name="plcNo">PLC编号</param>
  950. /// <param name="stationNameStr">工站全称</param>
  951. /// <param name="stPLC_MesData"></param>
  952. /// <param name="tagMesCommName"></param>
  953. private void S1进站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName,out bool ProgressState)
  954. {
  955. int nRet=0;
  956. string strRet = "";
  957. Stopwatch stopwatch1 = new Stopwatch();
  958. Stopwatch stopwatch2 = new Stopwatch();
  959. ProgressState = true;
  960. try
  961. {
  962. stopwatch1.Start();
  963. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  964. string MachineId = GlobalContext.S1_MachineId; // 装备ID(可配置)
  965. string StationId = GlobalContext.S1_StationId; // 工位ID(可配置)
  966. // 产品SN(物料码)校验
  967. List<TestItem> item = new List<TestItem>();
  968. stopwatch2.Start();
  969. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
  970. stopwatch2.Stop();
  971. //指令执行结果 1:OK 110:失败
  972. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  973. //进站结果写入PLC
  974. CommandFromPLC resultToPlC = new CommandFromPLC();
  975. resultToPlC.cmd = 0;
  976. resultToPlC.cmdParam = 0; //指令参数
  977. resultToPlC.cmdResult = mesResultFrmWeb;
  978. WriteResultToPlc(plcNo,stationNameStr, tagMesCommName,1, resultToPlC);
  979. }
  980. catch (Exception ex)
  981. {
  982. string str = ex.StackTrace;
  983. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  984. CommandFromPLC resultToPlC = new CommandFromPLC();
  985. resultToPlC.cmd = 0;
  986. resultToPlC.cmdParam = 0; //指令参数
  987. resultToPlC.cmdResult = 110;
  988. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  989. }
  990. stopwatch1.Stop();
  991. AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  992. }
  993. /// <summary>
  994. /// 进出站结果写入PLC
  995. /// </summary>
  996. public void WriteResultToPlc(int plcNo,string stationNameStr,string strTagName, int nCount, CommandFromPLC resultToPlC)
  997. {
  998. int i = 0;
  999. int nRet = 0;
  1000. string strRet = "";
  1001. while (i < 3) // 最多上传三次
  1002. {
  1003. (nRet, strRet) = Funs[plcNo].Write_SingleTag<CommandFromPLC>(strTagName, nCount, resultToPlC);
  1004. if (nRet == 0) //成功
  1005. {
  1006. break;
  1007. }
  1008. else
  1009. {
  1010. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站结果写入PLC出错!错误信息:" + strRet);
  1011. i++;
  1012. }
  1013. }
  1014. }
  1015. /// <summary>
  1016. /// [S1] 壳体清洁上料 - 出站接口
  1017. /// </summary>
  1018. private void S1出站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName,string stationCode,string stationName, out bool ProgressState)
  1019. {
  1020. ProgressState = true;
  1021. Stopwatch stopwatch1 = new Stopwatch();
  1022. Stopwatch stopwatch2 = new Stopwatch();
  1023. try
  1024. {
  1025. stopwatch1.Start();
  1026. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  1027. string processItem = stationName; // 测试项目
  1028. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  1029. string supplierCode = ""; // 供应商代码
  1030. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  1031. string batch_num = GlobalContext.BatchNumber; // 批次号
  1032. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  1033. string sn=(string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  1034. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  1035. string MachineId = GlobalContext.S1_MachineId; // 装备id(可配置) // ZS
  1036. string StationId = GlobalContext.S1_StationId; // ⼯位ID(可配置) // ZS
  1037. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  1038. bool pass = a1Result == 1;
  1039. List<TestItem> items = new List<TestItem>();
  1040. items.Add(new TestItem()
  1041. {
  1042. Parameter_name = "载具码",
  1043. Parameter_value = CarrierBarcode,
  1044. Parameter_unit = ""
  1045. });
  1046. items.Add(new TestItem()
  1047. {
  1048. Parameter_name = "产品码",
  1049. Parameter_value = mtltmrk,
  1050. Parameter_unit = ""
  1051. });
  1052. //绑定载具和产品
  1053. ResponseMessage message = new ResponseMessage();
  1054. message= SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
  1055. if (message.result==false)
  1056. {
  1057. AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
  1058. }
  1059. //绑定PLC返回MES数据到本地
  1060. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  1061. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
  1062. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  1063. stopwatch2.Start();
  1064. //进站结果写入PLC
  1065. CommandFromPLC resultToPlC = new CommandFromPLC();
  1066. resultToPlC.cmd = 0;
  1067. resultToPlC.cmdParam = 0; //指令参数
  1068. resultToPlC.cmdResult = mesResultFrmWeb;
  1069. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  1070. stopwatch2.Stop();
  1071. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
  1072. }
  1073. catch (Exception ex)
  1074. {
  1075. stopwatch2.Start();
  1076. CommandFromPLC resultToPlC = new CommandFromPLC();
  1077. resultToPlC.cmd = 0;
  1078. resultToPlC.cmdParam = 0; //指令参数
  1079. resultToPlC.cmdResult = 110;
  1080. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  1081. stopwatch2.Stop();
  1082. string str = ex.StackTrace;
  1083. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1084. }
  1085. stopwatch1.Stop();
  1086. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1087. }
  1088. //// 上传点检数据_ [S1] Tray盘上料装备(板测)
  1089. //private void DoOneCheckData_Tray盘上料装备(int plcNo, string stationCode, string stationName)
  1090. //{
  1091. // string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  1092. // string stationNameStr = stationCode + stationName;
  1093. // string processItem = stationName; // 测试项目
  1094. // try
  1095. // {
  1096. // string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  1097. // string accno = "1"; // 工序编号
  1098. // Funs[plcNo].Read_Real_Tag("896", 1, out float[] float0);
  1099. // float travelLimitUp = float0[0]; // 胶圈装配行程设定上限
  1100. // List<OneCheckItem> items = new List<OneCheckItem>()
  1101. // {
  1102. // new OneCheckItem()
  1103. // {
  1104. // Onecheck_name="胶圈装配行程设定上限",
  1105. // Onecheck_content="上限值",
  1106. // Onecheck_result=$"正常|胶圈装配行程设定上限{travelLimitUp} mm"
  1107. // },
  1108. // };
  1109. // OneCheckData oneCheckData = new OneCheckData()
  1110. // {
  1111. // Line_code = GlobalContext.LineCode,
  1112. // Line_name = GlobalContext.LineName,
  1113. // Equipment_code = equipmentCode,
  1114. // Equipment_name = equipmentCode,
  1115. // Workorder_code = workorder_code,
  1116. // Procedure_code = accno,
  1117. // Procedure_name = processItem,
  1118. // Oneckeck_values = items,
  1119. // Onecheck_empcode = "",
  1120. // Onecheck_empname = "",
  1121. // Onecheck_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
  1122. // };
  1123. // int result1 = SaveOneCheckDataByDBAndSubmit(oneCheckData, equipmentCode, processItem);
  1124. // //int result = result1 == 1 ? 1 : (GlobalContext.IsSendCheckOneData ? 4 : 1);
  1125. // short result = result1 == 1 ? (short)1 : (short)2;
  1126. // // MES_Flag 为4MES报错
  1127. // Funs[plcNo].Write_DInt_Tag("829", 1, new Int32[1] { result });
  1128. // WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  1129. // }
  1130. // catch (Exception ex)
  1131. // {
  1132. // // MES_Flag 为2上位机报错
  1133. // Funs[plcNo].Write_DInt_Tag("829", 1, new Int32[1] { 2 });
  1134. // string str = ex.StackTrace;
  1135. // AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}点检报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1136. // }
  1137. //}
  1138. // ReadStation_S1_2 节拍接口+AGV
  1139. /// <summary>
  1140. /// [S1] Tray盘上料装备(板测)- 将SN发给ICT标机(串口)
  1141. /// </summary>
  1142. /// <param name="plcNo">PLC编号</param>
  1143. /// <param name="stationNameStr">工站全称</param>
  1144. private void S1将SN发给ICT标机(int plcNo, string stationNameStr)
  1145. {
  1146. Stopwatch stopwatch1 = new Stopwatch();
  1147. Stopwatch stopwatch2 = new Stopwatch();
  1148. try
  1149. {
  1150. stopwatch1.Start();
  1151. string a1ProductSN_ICT = (string)s1PLCData["a1ProductSN_ICT"]; // 产品SN(载具SN)
  1152. a1ProductSN_ICT = a1ProductSN_ICT.Replace("\0", "");
  1153. string a1PartNo1_ICT = (string)s1PLCData["a1PartNo1_ICT"]; // 物料码1(穴位1)
  1154. a1PartNo1_ICT = a1PartNo1_ICT.Replace("\0", "");
  1155. string a1PartNo2_ICT = (string)s1PLCData["a1PartNo2_ICT"]; // 物料码2(穴位2)
  1156. a1PartNo2_ICT = a1PartNo2_ICT.Replace("\0", "");
  1157. // ZS 将SN发给ICT标机(串口)
  1158. short a1MES_FLAG_ICT = 1;
  1159. stopwatch2.Start();
  1160. // MES_Flag
  1161. //Funs[plcNo].WriteMultipleRegisters<short>(2182, a1MES_FLAG_ICT); // 上位机发送1代表OK;2代表失败;4代表上位机报警;
  1162. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1163. writeToPLC_Flag.Name = "a1MES_FLAG_ICT";
  1164. writeToPLC_Flag.Adress = 2182;
  1165. writeToPLC_Flag.Value = a1MES_FLAG_ICT;
  1166. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_ICT", writeToPLC_Flag);
  1167. stopwatch2.Stop();
  1168. }
  1169. catch (Exception ex)
  1170. {
  1171. string str = ex.StackTrace;
  1172. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 将SN发给ICT标机出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1173. stopwatch2.Start();
  1174. // MES_Flag
  1175. //Funs[plcNo].WriteMultipleRegisters<short>(2182, (short)4); // 4代表上位机报警
  1176. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1177. writeToPLC_Flag.Name = "a1MES_FLAG_ICT";
  1178. writeToPLC_Flag.Adress = 2182;
  1179. writeToPLC_Flag.Value = (short)4;
  1180. SxPLCWriteData_Add(ref s1PLCWriteData, "a1MES_FLAG_ICT", writeToPLC_Flag);
  1181. stopwatch2.Stop();
  1182. }
  1183. stopwatch1.Stop();
  1184. AddMessage(LogType.Info, stationNameStr + "_将SN发给ICT标机;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1185. }
  1186. /// <summary>
  1187. /// [S1] Tray盘上料装备(板测)- 节拍接口
  1188. /// </summary>
  1189. /// <param name="plcNo">PLC编号</param>
  1190. /// <param name="stationNameStr">工站全称</param>
  1191. private void S1节拍接口(int plcNo, string stationNameStr)
  1192. {
  1193. Stopwatch stopwatch1 = new Stopwatch();
  1194. Stopwatch stopwatch2 = new Stopwatch();
  1195. string resultStr = string.Empty;
  1196. try
  1197. {
  1198. stopwatch1.Start();
  1199. string oEEType = ((int)s1PLCData["a1OEEType"]).ToString(); // 节拍类型(plc写入)
  1200. string a1OEEPartNo = (string)s1PLCData["a1OEEPartNo"]; // 物料码
  1201. a1OEEPartNo = a1OEEPartNo.Replace("\0", "");
  1202. string a1OEEVehicleCode = (string)s1PLCData["a1OEEVehicleCode"]; // 载具SN
  1203. a1OEEVehicleCode = a1OEEVehicleCode.Replace("\0", "");
  1204. string a1OEEPartNum = ((int)s1PLCData["a1OEEPartNum"]).ToString(); // 穴位号
  1205. a1OEEPartNum = a1OEEPartNum.Replace("\0", "");
  1206. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  1207. if (!actionBool)
  1208. {
  1209. stopwatch2.Start();
  1210. // MES_Flag
  1211. //Funs[plcNo].WriteMultipleRegisters<short>(2254, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  1212. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  1213. writeToPLC_Flag1.Name = "a1OEEMES_FLAG";
  1214. writeToPLC_Flag1.Adress = 2254;
  1215. writeToPLC_Flag1.Value = (short)1;
  1216. SxPLCWriteData_Add(ref s1PLCWriteData, "a1OEEMES_FLAG", writeToPLC_Flag1);
  1217. stopwatch2.Stop();
  1218. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1219. return;
  1220. }
  1221. if (string.IsNullOrEmpty(a1OEEPartNo) && string.IsNullOrEmpty(a1OEEVehicleCode))
  1222. {
  1223. stopwatch2.Start();
  1224. // MES_Flag
  1225. //Funs[plcNo].WriteMultipleRegisters<short>(2254, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  1226. WriteToPLC_Flag writeToPLC_Flag2 = new WriteToPLC_Flag(); // MES_Flag
  1227. writeToPLC_Flag2.Name = "a1OEEMES_FLAG";
  1228. writeToPLC_Flag2.Adress = 2254;
  1229. writeToPLC_Flag2.Value = (short)1;
  1230. SxPLCWriteData_Add(ref s1PLCWriteData, "a1OEEMES_FLAG", writeToPLC_Flag2);
  1231. stopwatch2.Stop();
  1232. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1233. return;
  1234. }
  1235. else if (string.IsNullOrEmpty(a1OEEPartNo) && !string.IsNullOrEmpty(a1OEEVehicleCode))
  1236. { // 查产品SN
  1237. a1OEEPartNo = "Test"; // ZS
  1238. }
  1239. short a1OEEMES_FLAG = 0;
  1240. // 上传OEE
  1241. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, a1OEEPartNo, a1OEEVehicleCode);
  1242. a1OEEMES_FLAG = result.Item1;
  1243. resultStr = result.Item2;
  1244. stopwatch2.Start();
  1245. // MES_Flag
  1246. //Funs[plcNo].WriteMultipleRegisters<short>(2254, a1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  1247. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1248. writeToPLC_Flag.Name = "a1OEEMES_FLAG";
  1249. writeToPLC_Flag.Adress = 2254;
  1250. writeToPLC_Flag.Value = a1OEEMES_FLAG;
  1251. SxPLCWriteData_Add(ref s1PLCWriteData, "a1OEEMES_FLAG", writeToPLC_Flag);
  1252. stopwatch2.Stop();
  1253. }
  1254. catch (Exception ex)
  1255. {
  1256. string str = ex.StackTrace;
  1257. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1258. // MES_Flag
  1259. stopwatch2.Start();
  1260. //Funs[plcNo].WriteMultipleRegisters<short>(2254, (short)4); // 4代表上位机报警
  1261. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1262. writeToPLC_Flag.Name = "a1OEEMES_FLAG";
  1263. writeToPLC_Flag.Adress = 2254;
  1264. writeToPLC_Flag.Value = (short)4;
  1265. SxPLCWriteData_Add(ref s1PLCWriteData, "a1OEEMES_FLAG", writeToPLC_Flag);
  1266. stopwatch2.Stop();
  1267. }
  1268. stopwatch1.Stop();
  1269. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1270. }
  1271. /// <summary>
  1272. /// [S1] Tray盘上料装备(板测)- AGV上料叫agv
  1273. /// </summary>
  1274. /// <param name="plcNo">PLC编号</param>
  1275. /// <param name="stationNameStr">工站全称</param>
  1276. private void S1AGV上料叫agv(int plcNo, string stationNameStr)
  1277. {
  1278. Stopwatch stopwatch1 = new Stopwatch();
  1279. Stopwatch stopwatch2 = new Stopwatch();
  1280. try
  1281. {
  1282. stopwatch1.Start();
  1283. // ZS 呼叫AGV
  1284. short a1AGVUpCall = 2;
  1285. stopwatch2.Start();
  1286. // a1AGVUpCall
  1287. //Funs[plcNo].WriteMultipleRegisters<short>(2307, a1AGVUpCall); // 1:plc请求上料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  1288. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1289. writeToPLC_Flag.Name = "a1AGVUpCall";
  1290. writeToPLC_Flag.Adress = 2307;
  1291. writeToPLC_Flag.Value = a1AGVUpCall;
  1292. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpCall", writeToPLC_Flag);
  1293. stopwatch2.Stop();
  1294. }
  1295. catch (Exception ex)
  1296. {
  1297. string str = ex.StackTrace;
  1298. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1299. // a1AGVUpCall
  1300. stopwatch2.Start();
  1301. //Funs[plcNo].WriteMultipleRegisters<short>(2307, (short)4); // 4代表上位机报警
  1302. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1303. writeToPLC_Flag.Name = "a1AGVUpCall";
  1304. writeToPLC_Flag.Adress = 2307;
  1305. writeToPLC_Flag.Value = (short)4;
  1306. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpCall", writeToPLC_Flag);
  1307. stopwatch2.Stop();
  1308. }
  1309. stopwatch1.Stop();
  1310. AddMessage(LogType.Info, stationNameStr + "_AGV上料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1311. }
  1312. /// <summary>
  1313. /// [S1] Tray盘上料装备(板测)- AGV上料完成
  1314. /// </summary>
  1315. /// <param name="plcNo">PLC编号</param>
  1316. /// <param name="stationNameStr">工站全称</param>
  1317. private void S1AGV上料完成(int plcNo, string stationNameStr)
  1318. {
  1319. Stopwatch stopwatch1 = new Stopwatch();
  1320. Stopwatch stopwatch2 = new Stopwatch();
  1321. try
  1322. {
  1323. stopwatch1.Start();
  1324. // ZS AGV上料完成,让小车离开
  1325. short a1AGVUpEnd = 2;
  1326. stopwatch2.Start();
  1327. // a1AGVUpEnd
  1328. //Funs[plcNo].WriteMultipleRegisters<short>(2309, a1AGVUpEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  1329. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1330. writeToPLC_Flag.Name = "a1AGVUpEnd";
  1331. writeToPLC_Flag.Adress = 2309;
  1332. writeToPLC_Flag.Value = a1AGVUpEnd;
  1333. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpEnd", writeToPLC_Flag);
  1334. stopwatch2.Stop();
  1335. }
  1336. catch (Exception ex)
  1337. {
  1338. string str = ex.StackTrace;
  1339. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料完成出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1340. // a1AGVUpEnd
  1341. stopwatch2.Start();
  1342. //Funs[plcNo].WriteMultipleRegisters<short>(2309, (short)4); // 4代表上位机报警
  1343. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1344. writeToPLC_Flag.Name = "a1AGVUpEnd";
  1345. writeToPLC_Flag.Adress = 2309;
  1346. writeToPLC_Flag.Value = (short)4;
  1347. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVUpEnd", writeToPLC_Flag);
  1348. stopwatch2.Stop();
  1349. }
  1350. stopwatch1.Stop();
  1351. AddMessage(LogType.Info, stationNameStr + "_AGV上料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1352. }
  1353. /// <summary>
  1354. /// [S1] Tray盘上料装备(板测)- AGV下料叫agv
  1355. /// </summary>
  1356. /// <param name="plcNo">PLC编号</param>
  1357. /// <param name="stationNameStr">工站全称</param>
  1358. private void S1AGV下料叫agv(int plcNo, string stationNameStr)
  1359. {
  1360. Stopwatch stopwatch1 = new Stopwatch();
  1361. Stopwatch stopwatch2 = new Stopwatch();
  1362. try
  1363. {
  1364. stopwatch1.Start();
  1365. // ZS 呼叫AGV
  1366. short a1AGVDownCall = 2;
  1367. stopwatch2.Start();
  1368. // a1AGVDownCall
  1369. //Funs[plcNo].WriteMultipleRegisters<short>(2320, a1AGVDownCall); // 1:plc请求下料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  1370. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1371. writeToPLC_Flag.Name = "a1AGVDownCall";
  1372. writeToPLC_Flag.Adress = 2320;
  1373. writeToPLC_Flag.Value = a1AGVDownCall;
  1374. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownCall", writeToPLC_Flag);
  1375. stopwatch2.Stop();
  1376. }
  1377. catch (Exception ex)
  1378. {
  1379. string str = ex.StackTrace;
  1380. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1381. // a1AGVDownCall
  1382. stopwatch2.Start();
  1383. //Funs[plcNo].WriteMultipleRegisters<short>(2320, (short)4); // 4代表上位机报警
  1384. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1385. writeToPLC_Flag.Name = "a1AGVDownCall";
  1386. writeToPLC_Flag.Adress = 2320;
  1387. writeToPLC_Flag.Value = (short)4;
  1388. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownCall", writeToPLC_Flag);
  1389. stopwatch2.Stop();
  1390. }
  1391. stopwatch1.Stop();
  1392. AddMessage(LogType.Info, stationNameStr + "_AGV下料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1393. }
  1394. /// <summary>
  1395. /// [S1] Tray盘上料装备(板测)- AGV下料完成
  1396. /// </summary>
  1397. /// <param name="plcNo">PLC编号</param>
  1398. /// <param name="stationNameStr">工站全称</param>
  1399. private void S1AGV下料完成(int plcNo, string stationNameStr)
  1400. {
  1401. Stopwatch stopwatch1 = new Stopwatch();
  1402. Stopwatch stopwatch2 = new Stopwatch();
  1403. try
  1404. {
  1405. stopwatch1.Start();
  1406. // ZS AGV上料完成,让小车离开
  1407. short a1AGVDownEnd = 2;
  1408. stopwatch2.Start();
  1409. // a1AGVDownEnd
  1410. //Funs[plcNo].WriteMultipleRegisters<short>(2322, a1AGVDownEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  1411. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1412. writeToPLC_Flag.Name = "a1AGVDownEnd";
  1413. writeToPLC_Flag.Adress = 2322;
  1414. writeToPLC_Flag.Value = a1AGVDownEnd;
  1415. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownEnd", writeToPLC_Flag);
  1416. stopwatch2.Stop();
  1417. }
  1418. catch (Exception ex)
  1419. {
  1420. string str = ex.StackTrace;
  1421. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料完成出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1422. // a1AGVDownEnd
  1423. stopwatch2.Start();
  1424. //Funs[plcNo].WriteMultipleRegisters<short>(2322, (short)4); // 4代表上位机报警
  1425. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1426. writeToPLC_Flag.Name = "a1AGVDownEnd";
  1427. writeToPLC_Flag.Adress = 2322;
  1428. writeToPLC_Flag.Value = (short)4;
  1429. SxPLCWriteData_Add(ref s1PLCWriteData, "a1AGVDownEnd", writeToPLC_Flag);
  1430. stopwatch2.Stop();
  1431. }
  1432. stopwatch1.Stop();
  1433. AddMessage(LogType.Info, stationNameStr + "_AGV下料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1434. }
  1435. #endregion [S1] Tray盘上料装备(板测)
  1436. #endregion PLC1 张超凡
  1437. #region PLC2 贲流
  1438. #region [S2] 上盖板上料装备
  1439. /// <summary>
  1440. /// S2工位的数据- 触发信号上次的值
  1441. /// </summary>
  1442. private Dictionary<string, object> s2PLCSignal_Old = new Dictionary<string, object>();
  1443. /// <summary>
  1444. /// S2工位的数据(含触发信号)
  1445. /// </summary>
  1446. private Dictionary<string, object> s2PLCData = new Dictionary<string, object>();
  1447. /// <summary>
  1448. /// S2工位的数据- 回写点位
  1449. /// </summary>
  1450. private Dictionary<string, WriteToPLC_Flag> s2PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  1451. /// <summary>
  1452. /// [S2] FCT(板测)
  1453. /// </summary>
  1454. /// <param name="plcNo">PLC编号</param>
  1455. private void ReadStation_S2(int plcNo)
  1456. {
  1457. string stationCode = "[S2]";
  1458. string stationName = "上盖板上料装备";
  1459. string stationNameStr = stationCode + stationName;
  1460. string tagBaseName = "g_OP20_MES"; //标签变量名称
  1461. string tagMesCommName = "mesCommToPC"; //标签变量名称
  1462. string tagAgvCommName = "agvCommFrmPC";
  1463. string tagBarsetName = "BarcodeSet";
  1464. OP20_MesData_t stPLC_MesData; //PLC的MES数据
  1465. (int, string) result;
  1466. bool ProgressState = true;
  1467. while (true)
  1468. {
  1469. try
  1470. {
  1471. if (!GlobalContext._IsCon_Funs2)
  1472. {
  1473. UpdatePLCMonitor(1, plcNo, 0);
  1474. continue;
  1475. }
  1476. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  1477. {
  1478. Stopwatch stopwatch1 = new Stopwatch();
  1479. Stopwatch stopwatch2 = new Stopwatch();
  1480. stopwatch1.Start();
  1481. stopwatch2.Start();
  1482. #region 一次性读取所有数据
  1483. // 一次性读取所有数据
  1484. result = Funs[plcNo].Read_SingleTag<OP20_MesData_t>(tagBaseName, 1, out stPLC_MesData); //读取单个结构体数据
  1485. if (result.Item1 != 0)
  1486. {
  1487. //richTextBox1.AppendText("\n" + strRet);
  1488. }
  1489. else
  1490. {
  1491. //richTextBox1.AppendText("\n" + "读取成功");
  1492. }
  1493. #endregion 一次性读取所有数据
  1494. stopwatch2.Stop();
  1495. #region 进站
  1496. try
  1497. {
  1498. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
  1499. {
  1500. ProgressState = false;
  1501. Task.Run(() => S2进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName, out ProgressState));
  1502. }
  1503. }
  1504. catch (Exception ex)
  1505. {
  1506. ProgressState = false;
  1507. string str = ex.StackTrace;
  1508. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1509. }
  1510. #endregion 进站
  1511. #region 出站
  1512. try
  1513. {
  1514. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
  1515. {
  1516. ProgressState = false;
  1517. Task.Run(() => S2出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
  1518. }
  1519. }
  1520. catch (Exception ex)
  1521. {
  1522. string str = ex.StackTrace;
  1523. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1524. }
  1525. #endregion 进站
  1526. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  1527. stopwatch1.Stop();
  1528. //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  1529. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  1530. }
  1531. else
  1532. {
  1533. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  1534. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  1535. Funs[plcNo].Connect();
  1536. }
  1537. }
  1538. catch (Exception ex)
  1539. {
  1540. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  1541. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  1542. //Funs[plcNo].ReConnect();
  1543. }
  1544. Thread.Sleep(IntervalReadPLC);
  1545. }
  1546. }
  1547. /// <summary>
  1548. /// [S2] 上盖板上料装备
  1549. /// </summary>
  1550. /// <param name="plcNo">PLC编号</param>
  1551. /// <param name="stationNameStr">工站全称</param>
  1552. private void S2进站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,string tagBarsetName, out bool ProgressState)
  1553. {
  1554. Stopwatch stopwatch1 = new Stopwatch();
  1555. Stopwatch stopwatch2 = new Stopwatch();
  1556. ProgressState = true;
  1557. try
  1558. {
  1559. stopwatch1.Start();
  1560. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  1561. string MachineId = GlobalContext.S1_MachineId; // 装备ID(可配置)
  1562. string StationId = GlobalContext.S1_StationId; // 工位ID(可配置)
  1563. string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  1564. strCarrierBarcode = strCarrierBarcode.Replace("\0", "");
  1565. //载具码验证产品码 错误码111
  1566. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  1567. if (string.IsNullOrEmpty(strProductBarcode))
  1568. {
  1569. AddMessage_Station(stationNameStr, LogType.Error, $"PLC S2 上盖板上料装备未能成功绑定载具信息");
  1570. }
  1571. if (!string.IsNullOrEmpty(strProductBarcode) && !string.IsNullOrEmpty(sn) && strProductBarcode!=sn)
  1572. {
  1573. AddMessage_Station(stationNameStr, LogType.Error, $"PLC S2 上盖板上料装备PLC返回产品码与载具绑定物料码不同");
  1574. }
  1575. // 产品SN(物料码)校验
  1576. List <TestItem> item = new List<TestItem>();
  1577. stopwatch2.Start();
  1578. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
  1579. stopwatch2.Stop();
  1580. //指令执行结果 1:OK 110:失败
  1581. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  1582. if (!string.IsNullOrEmpty(strProductBarcode) && !string.IsNullOrEmpty(sn) && strProductBarcode != sn)
  1583. {
  1584. mesResultFrmWeb = 111;
  1585. }
  1586. //进站结果写入PLC
  1587. CommandFromPLC resultToPlC = new CommandFromPLC();
  1588. resultToPlC.cmd = 0;
  1589. resultToPlC.cmdParam = 0; //指令参数
  1590. resultToPlC.cmdResult = mesResultFrmWeb;
  1591. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  1592. if (string.IsNullOrEmpty(sn) && !string.IsNullOrEmpty(strProductBarcode))
  1593. {
  1594. BarcodeSet_t BarcodeToPlc= new BarcodeSet_t();
  1595. BarcodeToPlc.strCarrierBarcode = strCarrierBarcode;
  1596. BarcodeToPlc.strProductBarcode = sn;
  1597. Funs[plcNo].Write_SingleTag<BarcodeSet_t>(tagBarsetName, 1, BarcodeToPlc);
  1598. }
  1599. }
  1600. catch (Exception ex)
  1601. {
  1602. string str = ex.StackTrace;
  1603. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1604. CommandFromPLC resultToPlC = new CommandFromPLC();
  1605. resultToPlC.cmd = 0;
  1606. resultToPlC.cmdParam = 0; //指令参数
  1607. resultToPlC.cmdResult = 110;
  1608. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  1609. }
  1610. stopwatch1.Stop();
  1611. AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1612. }
  1613. /// <summary>
  1614. /// [S2] 上盖板上料装备 - 出站接口
  1615. /// </summary>
  1616. private void S2出站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,string stationCode,string stationName, out bool ProgressState)
  1617. {
  1618. ProgressState = true;
  1619. Stopwatch stopwatch1 = new Stopwatch();
  1620. Stopwatch stopwatch2 = new Stopwatch();
  1621. try
  1622. {
  1623. stopwatch1.Start();
  1624. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  1625. string processItem = stationName; // 测试项目
  1626. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  1627. string supplierCode = ""; // 供应商代码
  1628. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  1629. string batch_num = GlobalContext.BatchNumber; // 批次号
  1630. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  1631. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  1632. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  1633. string MachineId = GlobalContext.S1_MachineId; // 装备id(可配置) // ZS
  1634. string StationId = GlobalContext.S1_StationId; // ⼯位ID(可配置) // ZS
  1635. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  1636. bool pass = a1Result == 1;
  1637. List<TestItem> items = new List<TestItem>();
  1638. items.Add(new TestItem()
  1639. {
  1640. Parameter_name = "载具码",
  1641. Parameter_value = CarrierBarcode,
  1642. Parameter_unit = ""
  1643. });
  1644. items.Add(new TestItem()
  1645. {
  1646. Parameter_name = "产品码",
  1647. Parameter_value = mtltmrk,
  1648. Parameter_unit = ""
  1649. });
  1650. //保存PLC返回MES数据到本地
  1651. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  1652. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
  1653. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  1654. stopwatch2.Start();
  1655. //进站结果写入PLC
  1656. CommandFromPLC resultToPlC = new CommandFromPLC();
  1657. resultToPlC.cmd = 0;
  1658. resultToPlC.cmdParam = 0; //指令参数
  1659. resultToPlC.cmdResult = mesResultFrmWeb;
  1660. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  1661. stopwatch2.Stop();
  1662. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
  1663. }
  1664. catch (Exception ex)
  1665. {
  1666. stopwatch2.Start();
  1667. CommandFromPLC resultToPlC = new CommandFromPLC();
  1668. resultToPlC.cmd = 0;
  1669. resultToPlC.cmdParam = 0; //指令参数
  1670. resultToPlC.cmdResult = 110;
  1671. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  1672. stopwatch2.Stop();
  1673. string str = ex.StackTrace;
  1674. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1675. }
  1676. stopwatch1.Stop();
  1677. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1678. }
  1679. /// <summary>
  1680. /// [S2] FCT(板测)- 节拍接口
  1681. /// </summary>
  1682. /// <param name="plcNo">PLC编号</param>
  1683. /// <param name="stationNameStr">工站全称</param>
  1684. private void S2节拍接口(int plcNo, string stationNameStr)
  1685. {
  1686. Stopwatch stopwatch1 = new Stopwatch();
  1687. Stopwatch stopwatch2 = new Stopwatch();
  1688. string resultStr = string.Empty;
  1689. try
  1690. {
  1691. stopwatch1.Start();
  1692. string oEEType = ((int)s2PLCData["b1OEEType"]).ToString(); // 节拍类型(plc写入)
  1693. string b1OEEProductSN = (string)s2PLCData["b1OEEProductSN"]; // 载具SN
  1694. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  1695. if (!actionBool)
  1696. {
  1697. stopwatch2.Start();
  1698. // MES_Flag
  1699. //Funs[plcNo].WriteMultipleRegisters<short>(2203, (short)4); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  1700. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  1701. writeToPLC_Flag1.Name = "b1OEEMES_FLAG";
  1702. writeToPLC_Flag1.Adress = 2203;
  1703. writeToPLC_Flag1.Value = (short)4;
  1704. SxPLCWriteData_Add(ref s2PLCWriteData, "b1OEEMES_FLAG", writeToPLC_Flag1);
  1705. stopwatch2.Stop();
  1706. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1707. return;
  1708. }
  1709. string b1OEEPartNo = string.Empty; // 物料码
  1710. if (string.IsNullOrEmpty(b1OEEProductSN))
  1711. {
  1712. stopwatch2.Start();
  1713. // MES_Flag
  1714. //Funs[plcNo].WriteMultipleRegisters<short>(2203, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  1715. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  1716. writeToPLC_Flag1.Name = "b1OEEMES_FLAG";
  1717. writeToPLC_Flag1.Adress = 2203;
  1718. writeToPLC_Flag1.Value = (short)1;
  1719. SxPLCWriteData_Add(ref s2PLCWriteData, "b1OEEMES_FLAG", writeToPLC_Flag1);
  1720. stopwatch2.Stop();
  1721. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1722. return;
  1723. }
  1724. else
  1725. { // 查产品SN
  1726. b1OEEPartNo = "Test"; // ZS
  1727. }
  1728. short b1OEEMES_FLAG = 0;
  1729. // 上传OEE
  1730. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, b1OEEPartNo, b1OEEProductSN);
  1731. b1OEEMES_FLAG = result.Item1;
  1732. resultStr = result.Item2;
  1733. stopwatch2.Start();
  1734. // MES_Flag
  1735. //Funs[plcNo].WriteMultipleRegisters<short>(2203, b1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  1736. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1737. writeToPLC_Flag.Name = "b1OEEMES_FLAG";
  1738. writeToPLC_Flag.Adress = 2203;
  1739. writeToPLC_Flag.Value = b1OEEMES_FLAG;
  1740. SxPLCWriteData_Add(ref s2PLCWriteData, "b1OEEMES_FLAG", writeToPLC_Flag);
  1741. stopwatch2.Stop();
  1742. }
  1743. catch (Exception ex)
  1744. {
  1745. string str = ex.StackTrace;
  1746. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1747. // MES_Flag
  1748. stopwatch2.Start();
  1749. //Funs[plcNo].WriteMultipleRegisters<short>(2203, (short)4); // 4代表上位机报警
  1750. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  1751. writeToPLC_Flag.Name = "b1OEEMES_FLAG";
  1752. writeToPLC_Flag.Adress = 2203;
  1753. writeToPLC_Flag.Value = (short)4;
  1754. SxPLCWriteData_Add(ref s2PLCWriteData, "b1OEEMES_FLAG", writeToPLC_Flag);
  1755. stopwatch2.Stop();
  1756. }
  1757. stopwatch1.Stop();
  1758. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1759. }
  1760. #endregion [S2] FCT(板测)
  1761. #endregion PLC2 李晓奇
  1762. #region PLC3 刘永村
  1763. #region [S3] 值板机
  1764. /// <summary>
  1765. /// S3工位的数据- 触发信号上次的值
  1766. /// </summary>
  1767. private Dictionary<string, object> s3PLCSignal_Old = new Dictionary<string, object>();
  1768. /// <summary>
  1769. /// S3工位的数据(含触发信号)
  1770. /// </summary>
  1771. private Dictionary<string, object> s3PLCData = new Dictionary<string, object>();
  1772. /// <summary>
  1773. /// S3工位的数据- 回写点位
  1774. /// </summary>
  1775. private Dictionary<string, WriteToPLC_Flag> s3PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  1776. /// <summary>
  1777. /// [S3] 值板机
  1778. /// </summary>
  1779. /// <param name="plcNo">PLC编号</param>
  1780. private void ReadStation_S3(int plcNo)
  1781. {
  1782. string stationCode = "[S3]";
  1783. string stationName = "点散热胶装备";
  1784. string stationNameStr = stationCode + stationName;
  1785. string tagBaseName = "g_OP30_MES"; //标签变量名称
  1786. string tagMesCommName = "mesCommToPC"; //标签变量名称
  1787. string tagAgvCommName = "agvCommFrmPC";
  1788. string tagBarsetName = "BarcodeSet";
  1789. OP30_MesData_t stPLC_MesData; //PLC的MES数据
  1790. (int, string) result;
  1791. #region 创建字典
  1792. // 触发信号字典 赋值
  1793. s3PLCSignal_Old.Add("c1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  1794. s3PLCSignal_Old.Add("c1PLC_FLAG_Unbind", 0); // PLC_FLAG 二穴载具解绑
  1795. s3PLCSignal_Old.Add("c1PLC_FLAG_Bind", 0); // PLC_FLAG 二穴载具绑定
  1796. s3PLCSignal_Old.Add("c1PLC_FLAG", 0); // PLC_FLAG 出站接口
  1797. s3PLCSignal_Old.Add("c1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  1798. // PLC数据字典 赋值
  1799. s3PLCData.Add("c1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  1800. s3PLCData.Add("c1MES_FLAG_Check", 0); // MES_FLAG
  1801. s3PLCData.Add("c1ProductSN_Check", ""); // 产品SN(二穴载具SN)
  1802. s3PLCData.Add("c1PLC_FLAG_Unbind", 0); // PLC_FLAG 二穴载具解绑
  1803. s3PLCData.Add("c1MES_FLAG_Unbind", 0); // MES_FLAG
  1804. //s3PLCData.Add("c1ProductSN_Check", ""); // 产品SN(二穴载具SN)
  1805. s3PLCData.Add("c1VehicleCavity_Unbind", 0); // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  1806. s3PLCData.Add("c1PLC_FLAG_Bind", 0); // PLC_FLAG 二穴载具绑定
  1807. s3PLCData.Add("c1MES_FLAG_Bind", 0); // MES_FLAG
  1808. //s3PLCData.Add("c1ProductSN_Check", ""); // 产品SN(二穴载具SN)
  1809. s3PLCData.Add("c1CavityReverse_Bind", 0); // 是否是两个穴位交换
  1810. s3PLCData.Add("c1VehicleCavityFr_Bind", 0); // 来源穴位号(产品取自二穴载具哪个穴位)
  1811. s3PLCData.Add("c1VehicleCavityTo_Bind", 0); // 目标载具穴位号(产品放到二穴载具哪个穴位)
  1812. s3PLCData.Add("c1PLC_FLAG", 0); // PLC_FLAG 出站接口
  1813. s3PLCData.Add("c1MES_FLAG", 0); // MES_FLAG
  1814. s3PLCData.Add("c1ProductSN", ""); // 产品SN(一穴载具SN)
  1815. //s3PLCData.Add("c1ProductSN_Check", ""); // 二穴载具SN(产品取自哪个二穴载具)
  1816. s3PLCData.Add("c1VehicleCavity", 0); // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  1817. s3PLCData.Add("c1Result", 0); // 产品结果
  1818. s3PLCData.Add("c1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  1819. s3PLCData.Add("c1OEEMES_FLAG", 0); // MES_FLAG
  1820. s3PLCData.Add("c1OEEProductSN", "");// 产品SN(载具SN)
  1821. s3PLCData.Add("c1OEEType", 0); // 节拍类型(plc写入)
  1822. #endregion 创建字典
  1823. while (true)
  1824. {
  1825. try
  1826. {
  1827. if (!GlobalContext._IsCon_Funs2)
  1828. {
  1829. UpdatePLCMonitor(1, plcNo, 0);
  1830. continue;
  1831. }
  1832. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  1833. {
  1834. Stopwatch stopwatch1 = new Stopwatch();
  1835. Stopwatch stopwatch2 = new Stopwatch();
  1836. stopwatch1.Start();
  1837. stopwatch2.Start();
  1838. #region 一次性读取所有数据
  1839. // 一次性读取所有数据
  1840. result = Funs[plcNo].Read_SingleTag<OP30_MesData_t>(tagBaseName, 1, out stPLC_MesData); //读取单个结构体数据
  1841. if (result.Item1 != 0)
  1842. {
  1843. //richTextBox1.AppendText("\n" + strRet);
  1844. }
  1845. else
  1846. {
  1847. //richTextBox1.AppendText("\n" + "读取成功");
  1848. }
  1849. #endregion 一次性读取所有数据
  1850. stopwatch2.Stop();
  1851. #region 左边进站
  1852. try
  1853. {
  1854. //if (stPLC_MesData.Left.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && !string.IsNullOrEmpty(stPLC_MesData.iotData.Left.work_type.ToString()))
  1855. //{
  1856. // Task.Run(() => S3进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName));
  1857. // //进站
  1858. //}
  1859. }
  1860. catch (Exception ex)
  1861. {
  1862. //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  1863. string str = ex.StackTrace;
  1864. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1865. }
  1866. #endregion 进站
  1867. #region 左边出站
  1868. try
  1869. {
  1870. //if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
  1871. //{
  1872. // Task.Run(() => S3出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, "Left"));
  1873. //}
  1874. }
  1875. catch (Exception ex)
  1876. {
  1877. string str = ex.StackTrace;
  1878. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1879. }
  1880. #endregion 出站
  1881. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  1882. stopwatch1.Stop();
  1883. //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  1884. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  1885. }
  1886. else
  1887. {
  1888. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  1889. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  1890. Funs[plcNo].Connect();
  1891. }
  1892. }
  1893. catch (Exception ex)
  1894. {
  1895. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  1896. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  1897. //Funs[plcNo].ReConnect();
  1898. }
  1899. Thread.Sleep(IntervalReadPLC);
  1900. }
  1901. }
  1902. /// <summary>
  1903. /// [S3] 点散热胶装备
  1904. /// </summary>
  1905. /// <param name="plcNo">PLC编号</param>
  1906. /// <param name="stationNameStr">工站全称</param>
  1907. private void S3进站(int plcNo, string stationNameStr, OP30_MesData_t stPLC_MesData, string tagMesCommName, string tagBarsetName)
  1908. {
  1909. Stopwatch stopwatch1 = new Stopwatch();
  1910. Stopwatch stopwatch2 = new Stopwatch();
  1911. try
  1912. {
  1913. stopwatch1.Start();
  1914. string sn = "";//(string)stPLC_MesDataBarcodeSet.strProductBarcode; // 产品SN(物料码)
  1915. sn = sn.Replace("\0", "");
  1916. string strCarrierBarcode = "";//(string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 产品SN(物料码)
  1917. strCarrierBarcode = strCarrierBarcode.Replace("\0", "");
  1918. //载具码验证产品码
  1919. string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
  1920. if (string.IsNullOrEmpty(strProductBarcode))
  1921. {
  1922. AddMessage_Station(stationNameStr, LogType.Error, $"PLC S3 点散热胶装备未能成功绑定载具信息");
  1923. }
  1924. if (!string.IsNullOrEmpty(strProductBarcode) && !string.IsNullOrEmpty(sn) && strProductBarcode != sn)
  1925. {
  1926. AddMessage_Station(stationNameStr, LogType.Error, $"PLC S3 点散热胶装备未能成功绑定载具信息");
  1927. }
  1928. // 产品SN(物料码)校验
  1929. List<TestItem> item = new List<TestItem>();
  1930. stopwatch2.Start();
  1931. int result = 0;
  1932. //int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item);
  1933. stopwatch2.Stop();
  1934. //指令执行结果 1:OK 110:失败
  1935. byte cmdToPC = (byte)(result == 1 ? 1 : 110);
  1936. //进站结果写入PLC
  1937. if (string.IsNullOrEmpty(sn))
  1938. {
  1939. BarcodeSet_t BarcodeToPlc = new BarcodeSet_t();
  1940. BarcodeToPlc.strCarrierBarcode = strCarrierBarcode;
  1941. BarcodeToPlc.strProductBarcode = sn;
  1942. Funs[plcNo].Write_SingleTag<BarcodeSet_t>(tagBarsetName, 1, BarcodeToPlc);
  1943. }
  1944. }
  1945. catch (Exception ex)
  1946. {
  1947. string str = ex.StackTrace;
  1948. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  1949. }
  1950. stopwatch1.Stop();
  1951. AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  1952. }
  1953. /// <summary>
  1954. /// [S3] 点散热胶装备 - 出站接口
  1955. /// </summary>
  1956. private void S3出站(int plcNo, string stationNameStr, OP30_MesData_t stPLC_MesData, string tagMesCommName,string direction)
  1957. {
  1958. Stopwatch stopwatch1 = new Stopwatch();
  1959. Stopwatch stopwatch2 = new Stopwatch();
  1960. try
  1961. {
  1962. stopwatch1.Start();
  1963. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  1964. string batch_num = GlobalContext.BatchNumber; // 批次号
  1965. string mtltmrk = GlobalContext.Mtltmrk; // 产品条码; // 产品型号
  1966. mtltmrk = mtltmrk.Replace("\0", "");
  1967. string CarrierBarcode = "";//(string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  1968. // 产品结果
  1969. int a1Result = 0;
  1970. //if (direction=="Left")
  1971. //{
  1972. // a1Result=(int)stPLC_MesData.iotData.Left.testStatus;
  1973. //}
  1974. //if (direction == "Right")
  1975. //{
  1976. // a1Result = (int)stPLC_MesData.iotData.Left.testStatus;
  1977. //}
  1978. bool pass = a1Result == 1;
  1979. List<TestItem> items = new List<TestItem>();
  1980. items.Add(new TestItem()
  1981. {
  1982. Parameter_name = "载具码",
  1983. Parameter_value = CarrierBarcode,
  1984. Parameter_unit = ""
  1985. });
  1986. items.Add(new TestItem()
  1987. {
  1988. Parameter_name = "产品码",
  1989. Parameter_value = mtltmrk,
  1990. Parameter_unit = ""
  1991. });
  1992. //保存PLC返回MES数据到本地
  1993. int result1 = 0;
  1994. //int result1 = SwitctProcessData(stationNameStr, items, "", ""
  1995. // , workorder_code, batch_num, mtltmrk, "", "", "", pass, CarrierBarcode, "1");
  1996. byte cmdToPC = (byte)(result1 == 1 ? 1 : 110);
  1997. stopwatch2.Start();
  1998. //进站结果写入PLC
  1999. stopwatch2.Stop();
  2000. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
  2001. }
  2002. catch (Exception ex)
  2003. {
  2004. stopwatch2.Start();
  2005. stopwatch2.Stop();
  2006. string str = ex.StackTrace;
  2007. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2008. }
  2009. stopwatch1.Stop();
  2010. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2011. }
  2012. //// 上次采集到的SN
  2013. //private string sn_值板机 = string.Empty;
  2014. /// <summary>
  2015. /// [S3] 值板机 - 出站接口
  2016. /// </summary>
  2017. /// <param name="plcNo">PLC编号</param>
  2018. private void S3出站接口(int plcNo, string stationCode, string stationName)
  2019. {
  2020. Stopwatch stopwatch1 = new Stopwatch();
  2021. Stopwatch stopwatch2 = new Stopwatch();
  2022. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  2023. string stationNameStr = stationCode + stationName;
  2024. string processItem = stationName; // 测试项目
  2025. try
  2026. {
  2027. stopwatch1.Start();
  2028. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  2029. string batch_num = GlobalContext.BatchNumber; // 批次号
  2030. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  2031. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  2032. string supplierCode = ""; // 供应商代码
  2033. string sn = (string)s3PLCData["c1ProductSN"]; // 产品SN(一穴载具SN)
  2034. sn = sn.Replace("\0", "");
  2035. string c1ProductSN_Check = (string)s3PLCData["c1ProductSN_Check"]; // 二穴载具SN(产品取自哪个二穴载具)
  2036. c1ProductSN_Check = c1ProductSN_Check.Replace("\0", "");
  2037. int c1VehicleCavity = (int)s3PLCData["c1VehicleCavity"]; // 二穴载具穴位号(产品取自二穴载具哪个穴位)
  2038. int c1Result = (int)s3PLCData["c1Result"]; // 产品结果
  2039. bool pass = c1Result == 1;
  2040. //
  2041. string productSN = string.Empty;
  2042. // 是否是两个穴位交换
  2043. List<TestItem> items = new List<TestItem>();
  2044. items.Add(new TestItem()
  2045. {
  2046. Parameter_name = "产品结果",
  2047. Parameter_value = c1Result == 1 ? "OK" : "NG",
  2048. Parameter_unit = ""
  2049. });
  2050. int result1 = 0;
  2051. //int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  2052. // , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, productSN, pass, sn, "1");
  2053. short result = result1 == 1 ? (short)1 : (short)2;
  2054. stopwatch2.Start();
  2055. // MES_Flag 为MES报错
  2056. // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2057. //Funs[plcNo].WriteMultipleRegisters<short>(2150, result); // 4代表上位机报警
  2058. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2059. writeToPLC_Flag.Name = "c1MES_FLAG";
  2060. writeToPLC_Flag.Adress = 2150;
  2061. writeToPLC_Flag.Value = result;
  2062. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG", writeToPLC_Flag);
  2063. stopwatch2.Stop();
  2064. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  2065. }
  2066. catch (Exception ex)
  2067. {
  2068. stopwatch2.Start();
  2069. // MES_Flag 为4上位机报错
  2070. //Funs[plcNo].WriteMultipleRegisters<short>(2150, (short)4); // 4代表上位机报警
  2071. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2072. writeToPLC_Flag.Name = "c1MES_FLAG";
  2073. writeToPLC_Flag.Adress = 2150;
  2074. writeToPLC_Flag.Value = (short)4;
  2075. SxPLCWriteData_Add(ref s3PLCWriteData, "c1MES_FLAG", writeToPLC_Flag);
  2076. stopwatch2.Stop();
  2077. string str = ex.StackTrace;
  2078. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2079. }
  2080. stopwatch1.Stop();
  2081. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2082. }
  2083. /// <summary>
  2084. /// [S3] 值板机- 节拍接口
  2085. /// </summary>
  2086. /// <param name="plcNo">PLC编号</param>
  2087. /// <param name="stationNameStr">工站全称</param>
  2088. private void S3节拍接口(int plcNo, string stationNameStr)
  2089. {
  2090. Stopwatch stopwatch1 = new Stopwatch();
  2091. Stopwatch stopwatch2 = new Stopwatch();
  2092. string resultStr = string.Empty;
  2093. try
  2094. {
  2095. stopwatch1.Start();
  2096. string oEEType = ((int)s3PLCData["c1OEEType"]).ToString(); // 节拍类型(plc写入)
  2097. string c1OEEProductSN = (string)s3PLCData["c1OEEProductSN"]; // 载具SN
  2098. c1OEEProductSN = c1OEEProductSN.Replace("\0", "");
  2099. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  2100. if (!actionBool)
  2101. {
  2102. stopwatch2.Start();
  2103. // MES_Flag
  2104. //Funs[plcNo].WriteMultipleRegisters<short>(2204, (short)4); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2105. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  2106. writeToPLC_Flag1.Name = "c1OEEMES_FLAG";
  2107. writeToPLC_Flag1.Adress = 2204;
  2108. writeToPLC_Flag1.Value = (short)4;
  2109. SxPLCWriteData_Add(ref s3PLCWriteData, "c1OEEMES_FLAG", writeToPLC_Flag1);
  2110. stopwatch2.Stop();
  2111. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2112. return;
  2113. }
  2114. string c1OEEPartNo = string.Empty; // 物料码
  2115. if (string.IsNullOrEmpty(c1OEEProductSN))
  2116. {
  2117. stopwatch2.Start();
  2118. // MES_Flag
  2119. //Funs[plcNo].WriteMultipleRegisters<short>(2204, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2120. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  2121. writeToPLC_Flag1.Name = "c1OEEMES_FLAG";
  2122. writeToPLC_Flag1.Adress = 2204;
  2123. writeToPLC_Flag1.Value = (short)1;
  2124. SxPLCWriteData_Add(ref s3PLCWriteData, "c1OEEMES_FLAG", writeToPLC_Flag1);
  2125. stopwatch2.Stop();
  2126. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2127. return;
  2128. }
  2129. else
  2130. { // 查产品SN
  2131. c1OEEPartNo = "Test"; // ZS
  2132. }
  2133. short c1OEEMES_FLAG = 0;
  2134. // 上传OEE
  2135. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, c1OEEPartNo, c1OEEProductSN);
  2136. c1OEEMES_FLAG = result.Item1;
  2137. resultStr = result.Item2;
  2138. stopwatch2.Start();
  2139. // MES_Flag
  2140. //Funs[plcNo].WriteMultipleRegisters<short>(2204, c1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2141. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2142. writeToPLC_Flag.Name = "c1OEEMES_FLAG";
  2143. writeToPLC_Flag.Adress = 2204;
  2144. writeToPLC_Flag.Value = c1OEEMES_FLAG;
  2145. SxPLCWriteData_Add(ref s3PLCWriteData, "c1OEEMES_FLAG", writeToPLC_Flag);
  2146. stopwatch2.Stop();
  2147. }
  2148. catch (Exception ex)
  2149. {
  2150. string str = ex.StackTrace;
  2151. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2152. // MES_Flag
  2153. stopwatch2.Start();
  2154. //Funs[plcNo].WriteMultipleRegisters<short>(2204, (short)4); // 4代表上位机报警
  2155. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2156. writeToPLC_Flag.Name = "c1OEEMES_FLAG";
  2157. writeToPLC_Flag.Adress = 2204;
  2158. writeToPLC_Flag.Value = (short)4;
  2159. SxPLCWriteData_Add(ref s3PLCWriteData, "c1OEEMES_FLAG", writeToPLC_Flag);
  2160. stopwatch2.Stop();
  2161. }
  2162. stopwatch1.Stop();
  2163. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2164. }
  2165. #endregion [S3] 值板机
  2166. #endregion PLC3 刘永村
  2167. #region PLC4 刘果段
  2168. #region [S4] 取放桁架
  2169. /// <summary>
  2170. /// S4工位的数据- 触发信号上次的值
  2171. /// </summary>
  2172. private Dictionary<string, object> s4PLCSignal_Old = new Dictionary<string, object>();
  2173. /// <summary>
  2174. /// S4工位的数据(含触发信号)
  2175. /// </summary>
  2176. private Dictionary<string, object> s4PLCData = new Dictionary<string, object>();
  2177. /// <summary>
  2178. /// S4工位的数据- 回写点位
  2179. /// </summary>
  2180. private Dictionary<string, WriteToPLC_Flag> s4PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  2181. /// <summary>
  2182. /// [S4] 取放桁架
  2183. /// </summary>
  2184. /// <param name="plcNo">PLC编号</param>
  2185. private void ReadStation_S4(int plcNo)
  2186. {
  2187. // [S1] Tray盘上料装备
  2188. // [S2] FCT
  2189. // [S3] 值板机
  2190. // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  2191. // [S5] Tray盘下料装备
  2192. /// 上位机心跳
  2193. /// 获取设备报警数据与状态信息
  2194. string stationCode = "[S4_1]";
  2195. string stationName = "载具下线装备";
  2196. string stationNameStr = stationCode + stationName;
  2197. string stationCode5 = "[S4_5]";
  2198. string stationName5 = "载具上线装备";
  2199. string stationNameStr5 = stationCode5 + stationName5;
  2200. #region 创建字典
  2201. // 触发信号字典 赋值
  2202. s4PLCSignal_Old.Add("d1BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  2203. s4PLCSignal_Old.Add("d1VehicleScanCode", 0); // 扫码信号 载具扫码
  2204. s4PLCSignal_Old.Add("d1PLC_FLAG", 0); // PLC_FLAG 出站接口
  2205. s4PLCSignal_Old.Add("d1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  2206. s4PLCSignal_Old.Add("d2BulletclipScanCode", 0); // 扫码信号 查询标机中弹夹的状态
  2207. s4PLCSignal_Old.Add("d3PLC_FLAG", 0); // PLC_FLAG 真空标机1出站接口
  2208. s4PLCSignal_Old.Add("d4PLC_FLAG", 0); // PLC_FLAG 真空标机2出站接口
  2209. s4PLCSignal_Old.Add("d5BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  2210. s4PLCSignal_Old.Add("d5VehicleScanCode", 0); // 扫码信号 载具扫码
  2211. s4PLCSignal_Old.Add("d5PLC_FLAG", 0); // PLC_FLAG 出站接口
  2212. s4PLCSignal_Old.Add("d5OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  2213. // PLC数据字典 赋值
  2214. // 载具下线装备(弹夹上线)
  2215. s4PLCData.Add("d1BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  2216. s4PLCData.Add("d1BulletclipCode", ""); // 扫到的码
  2217. s4PLCData.Add("d1VehicleScanCode", 0); // 扫码信号 载具扫码
  2218. s4PLCData.Add("d1VehicleCode", ""); // 扫到的码
  2219. s4PLCData.Add("d1PLC_FLAG", 0); // PLC_FLAG 出站接口
  2220. s4PLCData.Add("d1MES_FLAG", 0); // MES_FLAG
  2221. s4PLCData.Add("d1ProductSN", ""); // 产品SN(弹夹码)
  2222. s4PLCData.Add("d1VehicleCode1", ""); // 载具1码(弹夹穴位1)
  2223. s4PLCData.Add("d1VehicleCode2", ""); // 载具2码(弹夹穴位2)
  2224. s4PLCData.Add("d1VehicleCode3", ""); // 载具3码(弹夹穴位3)
  2225. s4PLCData.Add("d1VehicleCode4", ""); // 载具4码(弹夹穴位4)
  2226. s4PLCData.Add("d1VehicleCode5", ""); // 载具5码(弹夹穴位5)
  2227. s4PLCData.Add("d1VehicleCode6", ""); // 载具6码(弹夹穴位6)
  2228. s4PLCData.Add("d1VehicleCode7", ""); // 载具7码(弹夹穴位7)
  2229. s4PLCData.Add("d1VehicleCode8", ""); // 载具8码(弹夹穴位8)
  2230. s4PLCData.Add("d1VehicleCode9", ""); // 载具9码(弹夹穴位9)
  2231. s4PLCData.Add("d1VehicleCode10", ""); // 载具10码(弹夹穴位10)
  2232. s4PLCData.Add("d1Result", 0); // 产品结果
  2233. s4PLCData.Add("d1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  2234. s4PLCData.Add("d1OEEMES_FLAG", 0); // MES_FLAG
  2235. s4PLCData.Add("d1OEEProductSN", "");// 产品SN(载具SN)
  2236. s4PLCData.Add("d1OEEType", 0); // 节拍类型(plc写入)
  2237. s4PLCData.Add("d2BulletclipScanCode", 0); // 扫码信号 查询标机中弹夹的状态
  2238. s4PLCData.Add("d2BulletclipStates", 0); // 弹夹状态
  2239. s4PLCData.Add("d2BulletclipCode", ""); // 扫到的码
  2240. // 真空标机(提升机)
  2241. s4PLCData.Add("d3PLC_FLAG", 0); // PLC_FLAG 真空标机1出站接口
  2242. s4PLCData.Add("d3MES_FLAG", 0); // MES_FLAG
  2243. s4PLCData.Add("d3Type", 0); // 进站还是出站
  2244. s4PLCData.Add("d3ProductSN", ""); // 产品SN(弹夹码)
  2245. s4PLCData.Add("d3Result", 0); // 产品结果
  2246. s4PLCData.Add("d4PLC_FLAG", 0); // PLC_FLAG 真空标机2出站接口
  2247. s4PLCData.Add("d4MES_FLAG", 0); // MES_FLAG
  2248. s4PLCData.Add("d4Type", 0); // 进站还是出站
  2249. s4PLCData.Add("d4ProductSN", ""); // 产品SN(弹夹码)
  2250. s4PLCData.Add("d4Result", 0); // 产品结果
  2251. // 载具上线装备(弹夹下线)
  2252. s4PLCData.Add("d5BulletclipScanCode", 0); // 扫码信号 弹夹扫码
  2253. s4PLCData.Add("d5BulletclipCode", ""); // 扫到的码
  2254. s4PLCData.Add("d5VehicleScanCode", 0); // 扫码信号 载具扫码
  2255. s4PLCData.Add("d5VehicleCode", ""); // 扫到的码
  2256. s4PLCData.Add("d5PLC_FLAG", 0); // PLC_FLAG 出站接口
  2257. s4PLCData.Add("d5MES_FLAG", 0); // MES_FLAG
  2258. s4PLCData.Add("d5ProductSN", ""); // 产品SN(弹夹码)
  2259. s4PLCData.Add("d5VehicleCode1", ""); // 载具1码(弹夹穴位1)
  2260. s4PLCData.Add("d5VehicleCode2", ""); // 载具2码(弹夹穴位2)
  2261. s4PLCData.Add("d5VehicleCode3", ""); // 载具3码(弹夹穴位3)
  2262. s4PLCData.Add("d5VehicleCode4", ""); // 载具4码(弹夹穴位4)
  2263. s4PLCData.Add("d5VehicleCode5", ""); // 载具5码(弹夹穴位5)
  2264. s4PLCData.Add("d5VehicleCode6", ""); // 载具6码(弹夹穴位6)
  2265. s4PLCData.Add("d5VehicleCode7", ""); // 载具7码(弹夹穴位7)
  2266. s4PLCData.Add("d5VehicleCode8", ""); // 载具8码(弹夹穴位8)
  2267. s4PLCData.Add("d5VehicleCode9", ""); // 载具9码(弹夹穴位9)
  2268. s4PLCData.Add("d5VehicleCode10", ""); // 载具10码(弹夹穴位10)
  2269. s4PLCData.Add("d5Result", 0); // 产品结果
  2270. s4PLCData.Add("d5OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  2271. s4PLCData.Add("d5OEEMES_FLAG", 0); // MES_FLAG
  2272. s4PLCData.Add("d5OEEProductSN", "");// 产品SN(载具SN)
  2273. s4PLCData.Add("d5OEEType", 0); // 节拍类型(plc写入)
  2274. #endregion 创建字典
  2275. while (true)
  2276. {
  2277. try
  2278. {
  2279. if (!GlobalContext._IsCon_Funs4)
  2280. {
  2281. UpdatePLCMonitor(1, plcNo, 0);
  2282. continue;
  2283. }
  2284. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  2285. {
  2286. Stopwatch stopwatch1 = new Stopwatch();
  2287. Stopwatch stopwatch2 = new Stopwatch();
  2288. stopwatch1.Start();
  2289. stopwatch2.Start();
  2290. /*
  2291. #region 一次性读取所有数据
  2292. // 载具下线装备(弹夹上线)
  2293. int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100);
  2294. int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 100);
  2295. int[] data3 = Funs[plcNo].ReadHoldingRegisters(2200, 100);
  2296. int[] data4 = Funs[plcNo].ReadHoldingRegisters(2300, 100);
  2297. int[] data5 = Funs[plcNo].ReadHoldingRegisters(2400, 100);
  2298. int[] data6 = Funs[plcNo].ReadHoldingRegisters(2500, 100);
  2299. int[] data7 = Funs[plcNo].ReadHoldingRegisters(2600, 100);
  2300. int[] data8 = Funs[plcNo].ReadHoldingRegisters(2700, 100);
  2301. int[] data9 = Funs[plcNo].ReadHoldingRegisters(2800, 100);
  2302. int[] data10 = Funs[plcNo].ReadHoldingRegisters(2900, 56);
  2303. int[] datas = data1.Concat(data2).ToArray();
  2304. datas = datas.Concat(data3).ToArray();
  2305. datas = datas.Concat(data4).ToArray();
  2306. datas = datas.Concat(data5).ToArray();
  2307. datas = datas.Concat(data6).ToArray();
  2308. datas = datas.Concat(data7).ToArray();
  2309. datas = datas.Concat(data8).ToArray();
  2310. datas = datas.Concat(data9).ToArray();
  2311. datas = datas.Concat(data10).ToArray();
  2312. // 载具下线装备(弹夹上线)
  2313. s4PLCData["d1BulletclipScanCode"] = datas[2]; // 扫码信号 弹夹扫码
  2314. int[] d1BulletclipCodeData = datas.Skip(3).Take(20).ToArray();
  2315. s4PLCData["d1BulletclipCode"] = ModbusClient.ConvertRegistersToString(d1BulletclipCodeData, 0, 40);
  2316. s4PLCData["d1VehicleScanCode"] = datas[33]; // 扫码信号 载具扫码
  2317. int[] d1VehicleCodeData = datas.Skip(34).Take(20).ToArray();
  2318. s4PLCData["d1VehicleCode"] = ModbusClient.ConvertRegistersToString(d1VehicleCodeData, 0, 40);
  2319. s4PLCData["d1PLC_FLAG"] = datas[64]; // PLC_FLAG 出站接口
  2320. s4PLCData["d1MES_FLAG"] = datas[65];
  2321. int[] d1ProductSNData = datas.Skip(66).Take(20).ToArray();
  2322. s4PLCData["d1ProductSN"] = ModbusClient.ConvertRegistersToString(d1ProductSNData, 0, 40); // 产品SN(物料码)
  2323. int[] d1VehicleCode1Data = datas.Skip(86).Take(20).ToArray();
  2324. s4PLCData["d1VehicleCode1"] = ModbusClient.ConvertRegistersToString(d1VehicleCode1Data, 0, 40);
  2325. int[] d1VehicleCode2Data = datas.Skip(106).Take(20).ToArray();
  2326. s4PLCData["d1VehicleCode2"] = ModbusClient.ConvertRegistersToString(d1VehicleCode2Data, 0, 40);
  2327. int[] d1VehicleCode3Data = datas.Skip(126).Take(20).ToArray();
  2328. s4PLCData["d1VehicleCode3"] = ModbusClient.ConvertRegistersToString(d1VehicleCode3Data, 0, 40);
  2329. int[] d1VehicleCode4Data = datas.Skip(146).Take(20).ToArray();
  2330. s4PLCData["d1VehicleCode4"] = ModbusClient.ConvertRegistersToString(d1VehicleCode4Data, 0, 40);
  2331. int[] d1VehicleCode5Data = datas.Skip(166).Take(20).ToArray();
  2332. s4PLCData["d1VehicleCode5"] = ModbusClient.ConvertRegistersToString(d1VehicleCode5Data, 0, 40);
  2333. int[] d1VehicleCode6Data = datas.Skip(186).Take(20).ToArray();
  2334. s4PLCData["d1VehicleCode6"] = ModbusClient.ConvertRegistersToString(d1VehicleCode6Data, 0, 40);
  2335. int[] d1VehicleCode7Data = datas.Skip(206).Take(20).ToArray();
  2336. s4PLCData["d1VehicleCode7"] = ModbusClient.ConvertRegistersToString(d1VehicleCode7Data, 0, 40);
  2337. int[] d1VehicleCode8Data = datas.Skip(226).Take(20).ToArray();
  2338. s4PLCData["d1VehicleCode8"] = ModbusClient.ConvertRegistersToString(d1VehicleCode8Data, 0, 40);
  2339. int[] d1VehicleCode9Data = datas.Skip(246).Take(20).ToArray();
  2340. s4PLCData["d1VehicleCode9"] = ModbusClient.ConvertRegistersToString(d1VehicleCode9Data, 0, 40);
  2341. int[] d1VehicleCode10Data = datas.Skip(266).Take(20).ToArray();
  2342. s4PLCData["d1VehicleCode10"] = ModbusClient.ConvertRegistersToString(d1VehicleCode10Data, 0, 40);
  2343. int[] d1VehicleCode11Data = datas.Skip(286).Take(20).ToArray();
  2344. s4PLCData["d1VehicleCode11"] = ModbusClient.ConvertRegistersToString(d1VehicleCode11Data, 0, 40);
  2345. int[] d1VehicleCode12Data = datas.Skip(306).Take(20).ToArray();
  2346. s4PLCData["d1VehicleCode12"] = ModbusClient.ConvertRegistersToString(d1VehicleCode12Data, 0, 40);
  2347. int[] d1VehicleCode13Data = datas.Skip(326).Take(20).ToArray();
  2348. s4PLCData["d1VehicleCode13"] = ModbusClient.ConvertRegistersToString(d1VehicleCode13Data, 0, 40);
  2349. int[] d1VehicleCode14Data = datas.Skip(346).Take(20).ToArray();
  2350. s4PLCData["d1VehicleCode14"] = ModbusClient.ConvertRegistersToString(d1VehicleCode14Data, 0, 40);
  2351. int[] d1VehicleCode15Data = datas.Skip(366).Take(20).ToArray();
  2352. s4PLCData["d1VehicleCode15"] = ModbusClient.ConvertRegistersToString(d1VehicleCode15Data, 0, 40);
  2353. s4PLCData["d1Result"] = datas[386];
  2354. s4PLCData["d1OEEPLC_FLAG"] = datas[397]; // PLC_FLAG 节拍接口
  2355. s4PLCData["d1OEEMES_FLAG"] = datas[398];
  2356. int[] d1OEEProductSNData = datas.Skip(399).Take(20).ToArray();
  2357. s4PLCData["d1OEEProductSN"] = ModbusClient.ConvertRegistersToString(d1OEEProductSNData, 0, 40);
  2358. s4PLCData["d1OEEType"] = datas[419];
  2359. // 桁架(查询标机中弹夹的状态)
  2360. s4PLCData["d2BulletclipScanCode"] = datas[430];
  2361. s4PLCData["d2BulletclipStates"] = datas[431];
  2362. int[] d2BulletclipCodeData = datas.Skip(432).Take(20).ToArray();
  2363. s4PLCData["d2BulletclipCode"] = ModbusClient.ConvertRegistersToString(d2BulletclipCodeData, 0, 40);
  2364. // 真空标机
  2365. s4PLCData["d3PLC_FLAG"] = datas[462]; // 真空标机1 出站接口
  2366. s4PLCData["d3MES_FLAG"] = datas[463];
  2367. int[] d3ProductSNData = datas.Skip(464).Take(20).ToArray();
  2368. s4PLCData["d3ProductSN"] = ModbusClient.ConvertRegistersToString(d3ProductSNData, 0, 40);
  2369. s4PLCData["d3Result"] = datas[484];
  2370. s4PLCData["d3Type"] = datas[485];
  2371. s4PLCData["d4PLC_FLAG"] = datas[495]; // 真空标机2 出站接口
  2372. s4PLCData["d4MES_FLAG"] = datas[496];
  2373. int[] d4ProductSNData = datas.Skip(497).Take(20).ToArray();
  2374. s4PLCData["d4ProductSN"] = ModbusClient.ConvertRegistersToString(d4ProductSNData, 0, 40);
  2375. s4PLCData["d4Result"] = datas[517];
  2376. s4PLCData["d4Type"] = datas[518];
  2377. // 载具上线装备(弹夹下线)
  2378. s4PLCData["d5BulletclipScanCode"] = datas[528]; // 扫码信号 弹夹扫码
  2379. int[] d5BulletclipCodeData = datas.Skip(529).Take(20).ToArray();
  2380. s4PLCData["d5BulletclipCode"] = ModbusClient.ConvertRegistersToString(d5BulletclipCodeData, 0, 40);
  2381. s4PLCData["d5VehicleScanCode"] = datas[559]; // 扫码信号 载具扫码
  2382. int[] d5VehicleCodeData = datas.Skip(560).Take(20).ToArray();
  2383. s4PLCData["d5VehicleCode"] = ModbusClient.ConvertRegistersToString(d5VehicleCodeData, 0, 40);
  2384. s4PLCData["d5PLC_FLAG"] = datas[590]; // PLC_FLAG 出站接口
  2385. s4PLCData["d5MES_FLAG"] = datas[591];
  2386. int[] d5ProductSNData = datas.Skip(592).Take(20).ToArray();
  2387. s4PLCData["d5ProductSN"] = ModbusClient.ConvertRegistersToString(d5ProductSNData, 0, 40); // 产品SN(物料码)
  2388. int[] d5VehicleCode1Data = datas.Skip(612).Take(20).ToArray();
  2389. s4PLCData["d5VehicleCode1"] = ModbusClient.ConvertRegistersToString(d5VehicleCode1Data, 0, 40);
  2390. int[] d5VehicleCode2Data = datas.Skip(632).Take(20).ToArray();
  2391. s4PLCData["d5VehicleCode2"] = ModbusClient.ConvertRegistersToString(d5VehicleCode2Data, 0, 40);
  2392. int[] d5VehicleCode3Data = datas.Skip(652).Take(20).ToArray();
  2393. s4PLCData["d5VehicleCode3"] = ModbusClient.ConvertRegistersToString(d5VehicleCode3Data, 0, 40);
  2394. int[] d5VehicleCode4Data = datas.Skip(672).Take(20).ToArray();
  2395. s4PLCData["d5VehicleCode4"] = ModbusClient.ConvertRegistersToString(d5VehicleCode4Data, 0, 40);
  2396. int[] d5VehicleCode5Data = datas.Skip(692).Take(20).ToArray();
  2397. s4PLCData["d5VehicleCode5"] = ModbusClient.ConvertRegistersToString(d5VehicleCode5Data, 0, 40);
  2398. int[] d5VehicleCode6Data = datas.Skip(712).Take(20).ToArray();
  2399. s4PLCData["d5VehicleCode6"] = ModbusClient.ConvertRegistersToString(d5VehicleCode6Data, 0, 40);
  2400. int[] d5VehicleCode7Data = datas.Skip(732).Take(20).ToArray();
  2401. s4PLCData["d5VehicleCode7"] = ModbusClient.ConvertRegistersToString(d5VehicleCode7Data, 0, 40);
  2402. int[] d5VehicleCode8Data = datas.Skip(752).Take(20).ToArray();
  2403. s4PLCData["d5VehicleCode8"] = ModbusClient.ConvertRegistersToString(d5VehicleCode8Data, 0, 40);
  2404. int[] d5VehicleCode9Data = datas.Skip(772).Take(20).ToArray();
  2405. s4PLCData["d5VehicleCode9"] = ModbusClient.ConvertRegistersToString(d5VehicleCode9Data, 0, 40);
  2406. int[] d5VehicleCode10Data = datas.Skip(792).Take(20).ToArray();
  2407. s4PLCData["d5VehicleCode10"] = ModbusClient.ConvertRegistersToString(d5VehicleCode10Data, 0, 40);
  2408. int[] d5VehicleCode11Data = datas.Skip(812).Take(20).ToArray();
  2409. s4PLCData["d5VehicleCode11"] = ModbusClient.ConvertRegistersToString(d5VehicleCode11Data, 0, 40);
  2410. int[] d5VehicleCode12Data = datas.Skip(832).Take(20).ToArray();
  2411. s4PLCData["d5VehicleCode12"] = ModbusClient.ConvertRegistersToString(d5VehicleCode12Data, 0, 40);
  2412. int[] d5VehicleCode13Data = datas.Skip(852).Take(20).ToArray();
  2413. s4PLCData["d5VehicleCode13"] = ModbusClient.ConvertRegistersToString(d5VehicleCode13Data, 0, 40);
  2414. int[] d5VehicleCode14Data = datas.Skip(872).Take(20).ToArray();
  2415. s4PLCData["d5VehicleCode14"] = ModbusClient.ConvertRegistersToString(d5VehicleCode14Data, 0, 40);
  2416. int[] d5VehicleCode15Data = datas.Skip(892).Take(20).ToArray();
  2417. s4PLCData["d5VehicleCode15"] = ModbusClient.ConvertRegistersToString(d5VehicleCode15Data, 0, 40);
  2418. s4PLCData["d5Result"] = datas[912];
  2419. s4PLCData["d5OEEPLC_FLAG"] = datas[923]; // PLC_FLAG 节拍接口
  2420. s4PLCData["d5OEEMES_FLAG"] = datas[924];
  2421. int[] d5OEEProductSNData = datas.Skip(925).Take(20).ToArray();
  2422. s4PLCData["d5OEEProductSN"] = ModbusClient.ConvertRegistersToString(d5OEEProductSNData, 0, 40);
  2423. s4PLCData["d5OEEType"] = datas[945];
  2424. #endregion 一次性读取所有数据
  2425. stopwatch2.Stop();
  2426. #region 回写操作,写后清空flag
  2427. PLCWriteData(Funs[plcNo], ref s4PLCData, ref s4PLCWriteData);
  2428. #endregion 回写操作,写后清空flag
  2429. */
  2430. // N801A-S4_1 弹夹扫码
  2431. #region N801A-S4_1 弹夹扫码
  2432. try
  2433. {
  2434. int d1BulletclipScanCode = (int)s4PLCData["d1BulletclipScanCode"];
  2435. int d1BulletclipScanCodeOld = (int)s4PLCSignal_Old["d1BulletclipScanCode"];
  2436. if (d1BulletclipScanCode != d1BulletclipScanCodeOld)
  2437. {
  2438. if (d1BulletclipScanCode == 1) // 0->1
  2439. Task.Run(() => S4_1弹夹扫码(plcNo, stationNameStr)); // MreTasks[1].Set();
  2440. s4PLCSignal_Old["d1BulletclipScanCode"] = s4PLCData["d1BulletclipScanCode"];
  2441. }
  2442. }
  2443. catch (Exception ex)
  2444. {
  2445. //Funs[plcNo].WriteMultipleRegisters<short>(2002, (short)6); // 6代表上位机报警
  2446. string str = ex.StackTrace;
  2447. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2448. }
  2449. #endregion N801A-S4_1 弹夹扫码
  2450. // N801A-S4_1 载具扫码
  2451. #region N801A-S4_1 载具扫码
  2452. try
  2453. {
  2454. int d1VehicleScanCode = (int)s4PLCData["d1VehicleScanCode"];
  2455. int d1VehicleScanCodeOld = (int)s4PLCSignal_Old["d1VehicleScanCode"];
  2456. if (d1VehicleScanCode != d1VehicleScanCodeOld)
  2457. {
  2458. if (d1VehicleScanCode == 1) // 0->1
  2459. Task.Run(() => S4_1载具扫码(plcNo, stationNameStr)); // MreTasks[1].Set();
  2460. s4PLCSignal_Old["d1VehicleScanCode"] = s4PLCData["d1VehicleScanCode"];
  2461. }
  2462. }
  2463. catch (Exception ex)
  2464. {
  2465. //Funs[plcNo].WriteMultipleRegisters<short>(2033, (short)6); // 6代表上位机报警
  2466. string str = ex.StackTrace;
  2467. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2468. }
  2469. #endregion N801A-S4_1 载具扫码
  2470. // N801A-S4_1 出站接口
  2471. #region N801A-S4_1 出站接口
  2472. try
  2473. {
  2474. int d1PLC_FLAG = (int)s4PLCData["d1PLC_FLAG"];
  2475. int d1MES_FLAG = (int)s4PLCData["d1MES_FLAG"];
  2476. int d1PLC_FLAGOld = (int)s4PLCSignal_Old["d1PLC_FLAG"];
  2477. if (d1PLC_FLAG != d1PLC_FLAGOld)
  2478. {
  2479. if (d1PLC_FLAG == 1 && d1MES_FLAG == 0) // 0->1
  2480. Task.Run(() => S4_1出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  2481. //else if (d1PLC_FLAG == 0 && d1MES_FLAG != 0)
  2482. //Funs[plcNo].WriteMultipleRegisters<short>(2065, (short)0);
  2483. s4PLCSignal_Old["d1PLC_FLAG"] = s4PLCData["d1PLC_FLAG"];
  2484. }
  2485. }
  2486. catch (Exception ex)
  2487. {
  2488. //Funs[plcNo].WriteMultipleRegisters<short>(2065, (short)6); // 6代表上位机报警
  2489. string str = ex.StackTrace;
  2490. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2491. }
  2492. #endregion N801A-S4_1 出站接口
  2493. // N801A-S4_1 节拍接口
  2494. #region N801A-S4_1 节拍接口
  2495. try
  2496. {
  2497. int d1OEEPLC_FLAG = (int)s4PLCData["d1OEEPLC_FLAG"];
  2498. int d1OEEMES_FLAG = (int)s4PLCData["d1OEEMES_FLAG"];
  2499. int d1OEEPLC_FLAGOld = (int)s4PLCSignal_Old["d1OEEPLC_FLAG"];
  2500. if (d1OEEPLC_FLAG != d1OEEPLC_FLAGOld)
  2501. {
  2502. if (d1OEEPLC_FLAG == 1 && d1OEEMES_FLAG == 0) // 0->1
  2503. Task.Run(() => S4_1节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  2504. //else if (d1OEEPLC_FLAG == 0 && d1OEEMES_FLAG != 0)
  2505. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)0);
  2506. s4PLCSignal_Old["d1OEEPLC_FLAG"] = s4PLCData["d1OEEPLC_FLAG"];
  2507. }
  2508. }
  2509. catch (Exception ex)
  2510. {
  2511. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)4); // 4代表上位机报警
  2512. string str = ex.StackTrace;
  2513. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2514. }
  2515. #endregion N801A-S4_1 节拍接口
  2516. // N801A-S4_2 桁架(查询标机中弹夹的状态) 数据
  2517. #region N801A-S4_2 桁架(查询标机中弹夹的状态)
  2518. try
  2519. {
  2520. int d2BulletclipScanCode = (int)s4PLCData["d2BulletclipScanCode"];
  2521. int d2BulletclipScanCodeOld = (int)s4PLCSignal_Old["d2BulletclipScanCode"];
  2522. if (d2BulletclipScanCode != d2BulletclipScanCodeOld)
  2523. {
  2524. if (d2BulletclipScanCode == 1) // 0->1
  2525. Task.Run(() => S4_2桁架(plcNo, stationNameStr)); // MreTasks[1].Set();
  2526. s4PLCSignal_Old["d2BulletclipScanCode"] = s4PLCData["d2BulletclipScanCode"];
  2527. }
  2528. }
  2529. catch (Exception ex)
  2530. {
  2531. //Funs[plcNo].WriteMultipleRegisters<short>(2430, (short)6); // 6代表上位机报警
  2532. string str = ex.StackTrace;
  2533. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 桁架出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2534. }
  2535. #endregion N801A-S4_2 桁架(查询标机中弹夹的状态)
  2536. // N801A-S4_3 真空标机1 数据
  2537. #region N801A-S4_3 真空标机1
  2538. try
  2539. {
  2540. int d3PLC_FLAG = (int)s4PLCData["d3PLC_FLAG"];
  2541. int d3MES_FLAG = (int)s4PLCData["d3MES_FLAG"];
  2542. int d3PLC_FLAGOld = (int)s4PLCSignal_Old["d3PLC_FLAG"];
  2543. if (d3PLC_FLAG != d3PLC_FLAGOld)
  2544. {
  2545. if (d3PLC_FLAG == 1 && d3MES_FLAG == 0) // 0->1
  2546. {
  2547. int stationType = (int)s4PLCData["d3Type"];
  2548. if (stationType == 1)
  2549. {
  2550. // S4_3进站接口
  2551. Task.Run(() => S4_3进站接口(plcNo, stationNameStr)); // MreTasks[3].Set();
  2552. }
  2553. else if (stationType == 2)
  2554. {
  2555. // S4_3出站接口
  2556. Task.Run(() => S4_3出站接口(plcNo, stationNameStr)); // MreTasks[3].Set();
  2557. }
  2558. }
  2559. //else if (d3PLC_FLAG == 0 && d3MES_FLAG != 0)
  2560. //Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)0);
  2561. s4PLCSignal_Old["d3PLC_FLAG"] = s4PLCData["d3PLC_FLAG"];
  2562. }
  2563. }
  2564. catch (Exception ex)
  2565. {
  2566. //Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)4); // 4代表上位机报警
  2567. string str = ex.StackTrace;
  2568. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传标机出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2569. }
  2570. #endregion N801A-S4_3 真空标机1
  2571. // N801A-S4_4 真空标机2 数据
  2572. #region N801A-S4_4 真空标机2
  2573. try
  2574. {
  2575. int d4PLC_FLAG = (int)s4PLCData["d4PLC_FLAG"];
  2576. int d4MES_FLAG = (int)s4PLCData["d4MES_FLAG"];
  2577. int d4PLC_FLAGOld = (int)s4PLCSignal_Old["d4PLC_FLAG"];
  2578. if (d4PLC_FLAG != d4PLC_FLAGOld)
  2579. {
  2580. if (d4PLC_FLAG == 1 && d4MES_FLAG == 0) // 0->1
  2581. {
  2582. int stationType = (int)s4PLCData["d4Type"];
  2583. if (stationType == 1)
  2584. {
  2585. // S4_4进站接口
  2586. Task.Run(() => S4_4进站接口(plcNo, stationNameStr)); // MreTasks[3].Set();
  2587. }
  2588. else if (stationType == 2)
  2589. {
  2590. // S4_4出站接口
  2591. Task.Run(() => S4_4出站接口(plcNo, stationNameStr)); // MreTasks[3].Set();
  2592. }
  2593. }
  2594. //else if (d4PLC_FLAG == 0 && d4MES_FLAG != 0)
  2595. //Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)0);
  2596. s4PLCSignal_Old["d4PLC_FLAG"] = s4PLCData["d4PLC_FLAG"];
  2597. }
  2598. }
  2599. catch (Exception ex)
  2600. {
  2601. //Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)4); // 4代表上位机报警
  2602. string str = ex.StackTrace;
  2603. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传标机出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2604. }
  2605. #endregion N801A-S4_4 真空标机2
  2606. // N801A-S4_5 弹夹扫码 数据
  2607. #region N801A-S4_5 弹夹扫码
  2608. try
  2609. {
  2610. int d5BulletclipScanCode = (int)s4PLCData["d5BulletclipScanCode"];
  2611. int d5BulletclipScanCodeOld = (int)s4PLCSignal_Old["d5BulletclipScanCode"];
  2612. if (d5BulletclipScanCode != d5BulletclipScanCodeOld)
  2613. {
  2614. if (d5BulletclipScanCode == 1) // 0->1
  2615. Task.Run(() => S4_5弹夹扫码(plcNo, stationNameStr5)); // MreTasks[1].Set();
  2616. s4PLCSignal_Old["d5BulletclipScanCode"] = s4PLCData["d5BulletclipScanCode"];
  2617. }
  2618. }
  2619. catch (Exception ex)
  2620. {
  2621. //Funs[plcNo].WriteMultipleRegisters<short>(2528, (short)6); // 6代表上位机报警
  2622. string str = ex.StackTrace;
  2623. AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2624. }
  2625. #endregion N801A-S4_5 弹夹扫码
  2626. // N801A-S4_5 载具扫码 数据
  2627. #region N801A-S4_5 载具扫码
  2628. try
  2629. {
  2630. int d5VehicleScanCode = (int)s4PLCData["d5VehicleScanCode"];
  2631. int d5VehicleScanCodeOld = (int)s4PLCSignal_Old["d5VehicleScanCode"];
  2632. if (d5VehicleScanCode != d5VehicleScanCodeOld)
  2633. {
  2634. if (d5VehicleScanCode == 1) // 0->1
  2635. Task.Run(() => S4_5载具扫码(plcNo, stationNameStr5)); // MreTasks[1].Set();
  2636. s4PLCSignal_Old["d5VehicleScanCode"] = s4PLCData["d5VehicleScanCode"];
  2637. }
  2638. }
  2639. catch (Exception ex)
  2640. {
  2641. //Funs[plcNo].WriteMultipleRegisters<short>(2559, (short)6); // 6代表上位机报警
  2642. string str = ex.StackTrace;
  2643. AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2644. }
  2645. #endregion N801A-S4_5 载具扫码
  2646. // N801A-S4_5 出站接口(扫完所有码后立即上传) 数据
  2647. #region N801A-S4_5 出站接口
  2648. try
  2649. {
  2650. int d5PLC_FLAG = (int)s4PLCData["d5PLC_FLAG"];
  2651. int d5MES_FLAG = (int)s4PLCData["d5MES_FLAG"];
  2652. int d5PLC_FLAGOld = (int)s4PLCSignal_Old["d5PLC_FLAG"];
  2653. if (d5PLC_FLAG != d5PLC_FLAGOld)
  2654. {
  2655. if (d5PLC_FLAG == 1 && d5MES_FLAG == 0) // 0->1
  2656. Task.Run(() => S4_5出站接口(plcNo, stationCode5, stationName5)); // MreTasks[3].Set();
  2657. //else if (d5PLC_FLAG == 0 && d5MES_FLAG != 0)
  2658. //Funs[plcNo].WriteMultipleRegisters<short>(2591, (short)0);
  2659. s4PLCSignal_Old["d5PLC_FLAG"] = s4PLCData["d5PLC_FLAG"];
  2660. }
  2661. }
  2662. catch (Exception ex)
  2663. {
  2664. //Funs[plcNo].WriteMultipleRegisters<short>(2591, (short)6); // 6代表上位机报警
  2665. string str = ex.StackTrace;
  2666. AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2667. }
  2668. #endregion N801A-S4_5 出站接口
  2669. // N801A-S4_5 节拍接口 数据
  2670. #region N801A-S4_5 节拍接口
  2671. try
  2672. {
  2673. int d5OEEPLC_FLAG = (int)s4PLCData["d5OEEPLC_FLAG"];
  2674. int d5OEEMES_FLAG = (int)s4PLCData["d5OEEMES_FLAG"];
  2675. int d5OEEPLC_FLAGOld = (int)s4PLCSignal_Old["d5OEEPLC_FLAG"];
  2676. if (d5OEEPLC_FLAG != d5OEEPLC_FLAGOld)
  2677. {
  2678. if (d5OEEPLC_FLAG == 1 && d5OEEMES_FLAG == 0) // 0->1
  2679. Task.Run(() => S4_5节拍接口(plcNo, stationNameStr5)); // MreTasks[4].Set();
  2680. //else if (d5OEEPLC_FLAG == 0 && d5OEEMES_FLAG != 0)
  2681. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)0);
  2682. s4PLCSignal_Old["d5OEEPLC_FLAG"] = s4PLCData["d5OEEPLC_FLAG"];
  2683. }
  2684. }
  2685. catch (Exception ex)
  2686. {
  2687. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)4); // 4代表上位机报警
  2688. string str = ex.StackTrace;
  2689. AddMessage_Station(stationNameStr5, LogType.Error, $"PLC{plcNo}_{stationNameStr5} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2690. }
  2691. #endregion N801A-S4_5 节拍接口
  2692. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  2693. stopwatch1.Stop();
  2694. //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  2695. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  2696. }
  2697. else
  2698. {
  2699. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  2700. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  2701. Funs[plcNo].Connect();
  2702. }
  2703. }
  2704. catch (Exception ex)
  2705. {
  2706. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  2707. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  2708. //Funs[plcNo].ReConnect();
  2709. }
  2710. Thread.Sleep(IntervalReadPLC);
  2711. }
  2712. }
  2713. /// <summary>
  2714. /// [S4] 取放桁架 - S4_1弹夹扫码
  2715. /// </summary>
  2716. /// <param name="plcNo">PLC编号</param>
  2717. /// <param name="stationNameStr">工站全称</param>
  2718. private void S4_1弹夹扫码(int plcNo, string stationNameStr)
  2719. {
  2720. Stopwatch stopwatch1 = new Stopwatch();
  2721. Stopwatch stopwatch2 = new Stopwatch();
  2722. try
  2723. {
  2724. stopwatch1.Start();
  2725. // ZS 弹夹扫码
  2726. string d1BulletclipCode = " "; // 扫到的码
  2727. short d1BulletclipScanCode = 2;
  2728. stopwatch2.Start();
  2729. //Funs[plcNo].WriteMultipleRegisters<string>(2003, d1BulletclipCode, 20);
  2730. //// MES_Flag
  2731. //Funs[plcNo].WriteMultipleRegisters<short>(2002, d1BulletclipScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  2732. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2733. writeToPLC_Flag.Name = "d1BulletclipScanCode";
  2734. writeToPLC_Flag.Adress = 2002;
  2735. writeToPLC_Flag.Value = d1BulletclipScanCode;
  2736. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 穴位1物料SN(上位机写入)
  2737. {
  2738. Name = "d1BulletclipCode",
  2739. Adress = 2003,
  2740. ValueType = PLCValueType.String,
  2741. ValueTypeStrLength = 20,
  2742. Value = d1BulletclipCode
  2743. });
  2744. SxPLCWriteData_Add(ref s4PLCWriteData, "d1BulletclipScanCode", writeToPLC_Flag);
  2745. stopwatch2.Stop();
  2746. }
  2747. catch (Exception ex)
  2748. {
  2749. string str = ex.StackTrace;
  2750. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2751. stopwatch2.Start();
  2752. //Funs[plcNo].WriteMultipleRegisters<string>(2003, " ", 20);
  2753. //// MES_Flag
  2754. //Funs[plcNo].WriteMultipleRegisters<short>(2002, (short)6); // 6代表上位机报警
  2755. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2756. writeToPLC_Flag.Name = "d1BulletclipScanCode";
  2757. writeToPLC_Flag.Adress = 2002;
  2758. writeToPLC_Flag.Value = (short)6;
  2759. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 穴位1物料SN(上位机写入)
  2760. {
  2761. Name = "d1BulletclipCode",
  2762. Adress = 2003,
  2763. ValueType = PLCValueType.String,
  2764. ValueTypeStrLength = 20,
  2765. Value = " "
  2766. });
  2767. SxPLCWriteData_Add(ref s4PLCWriteData, "d1BulletclipScanCode", writeToPLC_Flag);
  2768. stopwatch2.Stop();
  2769. }
  2770. stopwatch1.Stop();
  2771. AddMessage(LogType.Info, stationNameStr + "_弹夹扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2772. }
  2773. /// <summary>
  2774. /// [S4] 取放桁架 - S4_1载具扫码
  2775. /// </summary>
  2776. /// <param name="plcNo">PLC编号</param>
  2777. /// <param name="stationNameStr">工站全称</param>
  2778. private void S4_1载具扫码(int plcNo, string stationNameStr)
  2779. {
  2780. Stopwatch stopwatch1 = new Stopwatch();
  2781. Stopwatch stopwatch2 = new Stopwatch();
  2782. try
  2783. {
  2784. stopwatch1.Start();
  2785. // ZS 载具扫码
  2786. string d1VehicleCode = " "; // 扫到的码
  2787. // 查产品SN
  2788. string partNo = " ";
  2789. short d1VehicleScanCode = 2;
  2790. #region 进站
  2791. if (!string.IsNullOrEmpty(d1VehicleCode))
  2792. {
  2793. List<TestItem> item = new List<TestItem>();
  2794. item.Add(new TestItem()
  2795. {
  2796. Parameter_name = "载具码",
  2797. Parameter_value = d1VehicleCode,
  2798. });
  2799. item.Add(new TestItem()
  2800. {
  2801. Parameter_name = "载具穴号",
  2802. Parameter_value = "1",
  2803. });
  2804. stopwatch2.Start();
  2805. int result = 0;
  2806. //int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
  2807. stopwatch2.Stop();
  2808. d1VehicleScanCode = (short)result == 1 ? d1VehicleScanCode : (short)result;
  2809. }
  2810. #endregion 进站
  2811. //Funs[plcNo].WriteMultipleRegisters<string>(2034, d1VehicleCode, 20);
  2812. //// MES_Flag
  2813. //Funs[plcNo].WriteMultipleRegisters<short>(2033, d1VehicleScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  2814. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2815. writeToPLC_Flag.Name = "d1VehicleScanCode";
  2816. writeToPLC_Flag.Adress = 2033;
  2817. writeToPLC_Flag.Value = d1VehicleScanCode;
  2818. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  2819. {
  2820. Name = "d1VehicleCode",
  2821. Adress = 2034,
  2822. ValueType = PLCValueType.String,
  2823. ValueTypeStrLength = 20,
  2824. Value = d1VehicleCode
  2825. });
  2826. SxPLCWriteData_Add(ref s4PLCWriteData, "d1VehicleScanCode", writeToPLC_Flag);
  2827. }
  2828. catch (Exception ex)
  2829. {
  2830. string str = ex.StackTrace;
  2831. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2832. stopwatch2.Start();
  2833. //Funs[plcNo].WriteMultipleRegisters<string>(2034, " ", 20);
  2834. //// MES_Flag
  2835. //Funs[plcNo].WriteMultipleRegisters<short>(2033, (short)6); // 6代表上位机报警
  2836. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2837. writeToPLC_Flag.Name = "d1VehicleScanCode";
  2838. writeToPLC_Flag.Adress = 2033;
  2839. writeToPLC_Flag.Value = (short)6; // 6代表上位机报警
  2840. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  2841. {
  2842. Name = "d1VehicleCode",
  2843. Adress = 2034,
  2844. ValueType = PLCValueType.String,
  2845. ValueTypeStrLength = 20,
  2846. Value = " "
  2847. });
  2848. SxPLCWriteData_Add(ref s4PLCWriteData, "d1VehicleScanCode", writeToPLC_Flag);
  2849. stopwatch2.Stop();
  2850. }
  2851. stopwatch1.Stop();
  2852. AddMessage(LogType.Info, stationNameStr + "_载具扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2853. }
  2854. // 上次采集到的SN
  2855. //private string sn_S4_1出站接口 = string.Empty;
  2856. /// <summary>
  2857. /// [S4] 取放桁架 - S4_1出站接口
  2858. /// </summary>
  2859. private void S4_1出站接口(int plcNo, string stationCode, string stationName)
  2860. {
  2861. Stopwatch stopwatch1 = new Stopwatch();
  2862. Stopwatch stopwatch2 = new Stopwatch();
  2863. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  2864. string stationNameStr = stationCode + stationName;
  2865. string processItem = stationName; // 测试项目
  2866. try
  2867. {
  2868. stopwatch1.Start();
  2869. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  2870. string batch_num = GlobalContext.BatchNumber; // 批次号
  2871. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  2872. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  2873. string supplierCode = ""; // 供应商代码
  2874. string sn = (string)s4PLCData["d1ProductSN"]; // 产品SN(弹夹码)
  2875. sn = sn.Replace("\0", "");
  2876. string d1VehicleCode1 = (string)s4PLCData["d1VehicleCode1"]; // 载具1码(弹夹穴位1)
  2877. string d1VehicleCode2 = (string)s4PLCData["d1VehicleCode2"]; // 载具2码(弹夹穴位2)
  2878. string d1VehicleCode3 = (string)s4PLCData["d1VehicleCode3"]; // 载具3码(弹夹穴位3)
  2879. string d1VehicleCode4 = (string)s4PLCData["d1VehicleCode4"]; // 载具4码(弹夹穴位4)
  2880. string d1VehicleCode5 = (string)s4PLCData["d1VehicleCode5"]; // 载具5码(弹夹穴位5)
  2881. string d1VehicleCode6 = (string)s4PLCData["d1VehicleCode6"]; // 载具6码(弹夹穴位6)
  2882. string d1VehicleCode7 = (string)s4PLCData["d1VehicleCode7"]; // 载具7码(弹夹穴位7)
  2883. string d1VehicleCode8 = (string)s4PLCData["d1VehicleCode8"]; // 载具8码(弹夹穴位8)
  2884. string d1VehicleCode9 = (string)s4PLCData["d1VehicleCode9"]; // 载具9码(弹夹穴位9)
  2885. string d1VehicleCode10 = (string)s4PLCData["d1VehicleCode10"]; // 载具10码(弹夹穴位10)
  2886. string d1VehicleCode11 = (string)s4PLCData["d1VehicleCode11"]; // 载具11码(弹夹穴位11)
  2887. string d1VehicleCode12 = (string)s4PLCData["d1VehicleCode12"]; // 载具12码(弹夹穴位12)
  2888. string d1VehicleCode13 = (string)s4PLCData["d1VehicleCode13"]; // 载具13码(弹夹穴位13)
  2889. string d1VehicleCode14 = (string)s4PLCData["d1VehicleCode14"]; // 载具14码(弹夹穴位14)
  2890. string d1VehicleCode15 = (string)s4PLCData["d1VehicleCode15"]; // 载具15码(弹夹穴位15)
  2891. int d1Result = (int)s4PLCData["d1Result"]; // 产品结果
  2892. bool pass = d1Result == 1;
  2893. List<TestItem> items1 = new List<TestItem>();
  2894. items1.Add(new TestItem()
  2895. {
  2896. Parameter_name = "产品结果",
  2897. Parameter_value = d1Result == 1 ? "OK" : "NG",
  2898. Parameter_unit = ""
  2899. });
  2900. int result1 = 0;
  2901. //int result1 = SwitctProcessData(stationNameStr, items1, equipmentCode, processItem
  2902. //, workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, d1VehicleCode1, "1");
  2903. //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
  2904. short result = result1 == 1 ? (short)1 : (short)3;
  2905. stopwatch2.Start();
  2906. // MES_Flag 为4MES报错
  2907. //Funs[plcNo].WriteMultipleRegisters<short>(2065, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2908. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2909. writeToPLC_Flag.Name = "d1MES_FLAG";
  2910. writeToPLC_Flag.Adress = 2065;
  2911. writeToPLC_Flag.Value = result;
  2912. SxPLCWriteData_Add(ref s4PLCWriteData, "d1MES_FLAG", writeToPLC_Flag);
  2913. stopwatch2.Stop();
  2914. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  2915. }
  2916. catch (Exception ex)
  2917. {
  2918. stopwatch2.Start();
  2919. // MES_Flag 为4上位机报错
  2920. //Funs[plcNo].WriteMultipleRegisters<short>(2065, (short)4); // 4代表上位机报警
  2921. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2922. writeToPLC_Flag.Name = "d1MES_FLAG";
  2923. writeToPLC_Flag.Adress = 2065;
  2924. writeToPLC_Flag.Value = (short)4;
  2925. SxPLCWriteData_Add(ref s4PLCWriteData, "d1MES_FLAG", writeToPLC_Flag);
  2926. stopwatch2.Stop();
  2927. string str = ex.StackTrace;
  2928. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  2929. }
  2930. stopwatch1.Stop();
  2931. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2932. }
  2933. /// <summary>
  2934. /// [S4] 取放桁架 - S4_1节拍接口
  2935. /// </summary>
  2936. /// <param name="plcNo">PLC编号</param>
  2937. /// <param name="stationNameStr">工站全称</param>
  2938. private void S4_1节拍接口(int plcNo, string stationNameStr)
  2939. {
  2940. Stopwatch stopwatch1 = new Stopwatch();
  2941. Stopwatch stopwatch2 = new Stopwatch();
  2942. string resultStr = string.Empty;
  2943. try
  2944. {
  2945. stopwatch1.Start();
  2946. string oEEType = ((int)s4PLCData["d1OEEType"]).ToString(); // 节拍类型(plc写入)
  2947. string d1OEEProductSN = (string)s4PLCData["d1OEEProductSN"]; // 载具SN
  2948. d1OEEProductSN = d1OEEProductSN.Replace("\0", "");
  2949. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  2950. if (!actionBool)
  2951. {
  2952. stopwatch2.Start();
  2953. // MES_Flag
  2954. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)4); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2955. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  2956. writeToPLC_Flag1.Name = "d1OEEMES_FLAG";
  2957. writeToPLC_Flag1.Adress = 2398;
  2958. writeToPLC_Flag1.Value = (short)4;
  2959. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag1);
  2960. stopwatch2.Stop();
  2961. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2962. return;
  2963. }
  2964. string d1OEEPartNo = string.Empty; // 物料码
  2965. if (string.IsNullOrEmpty(d1OEEProductSN))
  2966. {
  2967. stopwatch2.Start();
  2968. // MES_Flag
  2969. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2970. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  2971. writeToPLC_Flag1.Name = "d1OEEMES_FLAG";
  2972. writeToPLC_Flag1.Adress = 2398;
  2973. writeToPLC_Flag1.Value = (short)1;
  2974. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag1);
  2975. stopwatch2.Stop();
  2976. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  2977. return;
  2978. }
  2979. else
  2980. { // 查产品SN
  2981. d1OEEPartNo = "Test"; // ZS
  2982. }
  2983. short d1OEEMES_FLAG = 0;
  2984. // 上传OEE
  2985. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, d1OEEPartNo, d1OEEProductSN);
  2986. d1OEEMES_FLAG = result.Item1;
  2987. resultStr = result.Item2;
  2988. stopwatch2.Start();
  2989. // MES_Flag
  2990. //Funs[plcNo].WriteMultipleRegisters<short>(2398, d1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  2991. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  2992. writeToPLC_Flag.Name = "d1OEEMES_FLAG";
  2993. writeToPLC_Flag.Adress = 2398;
  2994. writeToPLC_Flag.Value = d1OEEMES_FLAG;
  2995. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag);
  2996. stopwatch2.Stop();
  2997. }
  2998. catch (Exception ex)
  2999. {
  3000. string str = ex.StackTrace;
  3001. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3002. // MES_Flag
  3003. stopwatch2.Start();
  3004. //Funs[plcNo].WriteMultipleRegisters<short>(2398, (short)4); // 4代表上位机报警
  3005. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3006. writeToPLC_Flag.Name = "d1OEEMES_FLAG";
  3007. writeToPLC_Flag.Adress = 2398;
  3008. writeToPLC_Flag.Value = (short)4;
  3009. SxPLCWriteData_Add(ref s4PLCWriteData, "d1OEEMES_FLAG", writeToPLC_Flag);
  3010. stopwatch2.Stop();
  3011. }
  3012. stopwatch1.Stop();
  3013. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3014. }
  3015. /// <summary>
  3016. /// [S4] 取放桁架 - S4_2桁架
  3017. /// </summary>
  3018. /// <param name="plcNo">PLC编号</param>
  3019. /// <param name="stationNameStr">工站全称</param>
  3020. private void S4_2桁架(int plcNo, string stationNameStr)
  3021. {
  3022. Stopwatch stopwatch1 = new Stopwatch();
  3023. Stopwatch stopwatch2 = new Stopwatch();
  3024. try
  3025. {
  3026. stopwatch1.Start();
  3027. // ZS 弹夹扫码
  3028. string d2BulletclipCode = " "; // 扫到的码
  3029. short d2BulletclipStates = 1; // 弹夹状态(上位机写入)
  3030. short d2BulletclipScanCode = 2;
  3031. stopwatch2.Start();
  3032. //Funs[plcNo].WriteMultipleRegisters<string>(2432, d2BulletclipCode, 20); // 扫到的码
  3033. //Funs[plcNo].WriteMultipleRegisters<short>(2431, d2BulletclipStates); // 弹夹状态(上位机写入)
  3034. //// MES_Flag
  3035. //Funs[plcNo].WriteMultipleRegisters<short>(2430, d2BulletclipScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  3036. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3037. writeToPLC_Flag.Name = "d2BulletclipScanCode";
  3038. writeToPLC_Flag.Adress = 2430;
  3039. writeToPLC_Flag.Value = d2BulletclipScanCode;
  3040. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  3041. {
  3042. Name = "d2BulletclipCode",
  3043. Adress = 2432,
  3044. ValueType = PLCValueType.String,
  3045. ValueTypeStrLength = 20,
  3046. Value = d2BulletclipCode
  3047. });
  3048. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  3049. {
  3050. Name = "d2BulletclipStates",
  3051. Adress = 2431,
  3052. ValueType = PLCValueType.Short,
  3053. Value = d2BulletclipStates
  3054. });
  3055. SxPLCWriteData_Add(ref s4PLCWriteData, "d2BulletclipScanCode", writeToPLC_Flag);
  3056. stopwatch2.Stop();
  3057. }
  3058. catch (Exception ex)
  3059. {
  3060. string str = ex.StackTrace;
  3061. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3062. stopwatch2.Start();
  3063. //Funs[plcNo].WriteMultipleRegisters<string>(2432, " ", 20);
  3064. //Funs[plcNo].WriteMultipleRegisters<short>(2431, (short)0);
  3065. // MES_Flag
  3066. //Funs[plcNo].WriteMultipleRegisters<short>(2430, (short)6); // 6代表上位机报警
  3067. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3068. writeToPLC_Flag.Name = "d2BulletclipScanCode";
  3069. writeToPLC_Flag.Adress = 2430;
  3070. writeToPLC_Flag.Value = (short)6;
  3071. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  3072. {
  3073. Name = "d2BulletclipCode",
  3074. Adress = 2432,
  3075. ValueType = PLCValueType.String,
  3076. ValueTypeStrLength = 20,
  3077. Value = " "
  3078. });
  3079. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data()
  3080. {
  3081. Name = "d2BulletclipStates",
  3082. Adress = 2431,
  3083. ValueType = PLCValueType.Short,
  3084. Value = (short)0
  3085. });
  3086. SxPLCWriteData_Add(ref s4PLCWriteData, "d2BulletclipScanCode", writeToPLC_Flag);
  3087. stopwatch2.Stop();
  3088. }
  3089. stopwatch1.Stop();
  3090. AddMessage(LogType.Info, stationNameStr + "_弹夹扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3091. }
  3092. // 上次采集到的SN
  3093. //private string sn_S4_3进站接口 = string.Empty;
  3094. /// <summary>
  3095. /// [S4] 取放桁架 - S4_3进站接口(提升机1)
  3096. /// </summary>
  3097. private void S4_3进站接口(int plcNo, string stationNameStr)
  3098. {
  3099. Stopwatch stopwatch1 = new Stopwatch();
  3100. Stopwatch stopwatch2 = new Stopwatch();
  3101. try
  3102. {
  3103. stopwatch1.Start();
  3104. string sn = (string)s4PLCData["d3ProductSN"]; // 产品SN(弹夹码)
  3105. sn = sn.Replace("\0", "");
  3106. int d3Result = (int)s4PLCData["d3Result"]; // 产品结果
  3107. // ZS 查询15个载具码与15个产品SN
  3108. List<string> vehicleCodes = new string[15].ToList();
  3109. List<string> portNos = new string[15].ToList();
  3110. // 调用MES进站(最多15个)
  3111. stopwatch2.Start();
  3112. List<int> results = new int[15].ToList(); // 结果集;0代表产品为空
  3113. for (int i = 0; i < vehicleCodes.Count; i++)
  3114. {
  3115. // 循环进站
  3116. if (!string.IsNullOrEmpty(vehicleCodes[i]))
  3117. {
  3118. // 产品SN(物料码)校验
  3119. string portNo = portNos[i];
  3120. List<TestItem> item = new List<TestItem>();
  3121. item.Add(new TestItem()
  3122. {
  3123. Parameter_name = "弹夹码",
  3124. Parameter_value = sn,
  3125. });
  3126. item.Add(new TestItem()
  3127. {
  3128. Parameter_name = "弹夹穴位",
  3129. Parameter_value = (i + 1).ToString(),
  3130. });
  3131. item.Add(new TestItem()
  3132. {
  3133. Parameter_name = "载具码",
  3134. Parameter_value = vehicleCodes[i],
  3135. });
  3136. item.Add(new TestItem()
  3137. {
  3138. Parameter_name = "载具穴号",
  3139. Parameter_value = "1",
  3140. });
  3141. results[i] = 0;//SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, portNo, item);
  3142. }
  3143. }
  3144. stopwatch2.Stop();
  3145. short result = 0;
  3146. bool haveMesWarn = results.Contains(5);
  3147. bool havePCWarn = results.Contains(6);
  3148. if (haveMesWarn)
  3149. result = 2; // 5->2
  3150. else if (havePCWarn)
  3151. result = 6; // 6->4
  3152. else
  3153. result = 1;
  3154. // MES_Flag 为4MES报错
  3155. //Funs[plcNo].WriteMultipleRegisters<short>(2463, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3156. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3157. writeToPLC_Flag.Name = "d3MES_FLAG";
  3158. writeToPLC_Flag.Adress = 2463;
  3159. writeToPLC_Flag.Value = result;
  3160. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  3161. WritePLCLog(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  3162. }
  3163. catch (Exception ex)
  3164. {
  3165. stopwatch2.Stop();
  3166. // MES_Flag 为4上位机报错
  3167. //Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)4); // 4代表上位机报警
  3168. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3169. writeToPLC_Flag.Name = "d3MES_FLAG";
  3170. writeToPLC_Flag.Adress = 2463;
  3171. writeToPLC_Flag.Value = (short)4;
  3172. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  3173. string str = ex.StackTrace;
  3174. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}S4_3进站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3175. }
  3176. stopwatch1.Stop();
  3177. AddMessage(LogType.Info, stationNameStr + "_S4_3进站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3178. }
  3179. // 上次采集到的SN
  3180. //private string sn_S4_3出站接口 = string.Empty;
  3181. /// <summary>
  3182. /// [S4] 取放桁架 - S4_3出站接口(提升机1)
  3183. /// </summary>
  3184. private void S4_3出站接口(int plcNo, string stationNameStr)
  3185. {
  3186. Stopwatch stopwatch1 = new Stopwatch();
  3187. Stopwatch stopwatch2 = new Stopwatch();
  3188. try
  3189. {
  3190. stopwatch1.Start();
  3191. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  3192. string batch_num = GlobalContext.BatchNumber; // 批次号
  3193. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  3194. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  3195. string supplierCode = ""; // 供应商代码
  3196. string sn = (string)s4PLCData["d3ProductSN"]; // 产品SN(弹夹码)
  3197. sn = sn.Replace("\0", "");
  3198. int d3Result = (int)s4PLCData["d3Result"]; // 产品结果
  3199. bool isPass = d3Result == 1; // 产品结果 bool
  3200. // ZS 查询15个载具码与15个产品SN
  3201. List<string> vehicleCodes = new string[15].ToList();
  3202. List<string> portNos = new string[15].ToList();
  3203. // 调用MES出站
  3204. stopwatch2.Start();
  3205. List<int> results = new int[15].ToList(); // 结果集;0代表产品为空
  3206. for (int i = 0; i < vehicleCodes.Count; i++)
  3207. {
  3208. // 循环出站
  3209. if (!string.IsNullOrEmpty(vehicleCodes[i]))
  3210. {
  3211. string portNo = portNos[i];
  3212. List<TestItem> items1 = new List<TestItem>();
  3213. items1.Add(new TestItem()
  3214. {
  3215. Parameter_name = "弹夹码",
  3216. Parameter_value = sn,
  3217. });
  3218. items1.Add(new TestItem()
  3219. {
  3220. Parameter_name = "弹夹穴位",
  3221. Parameter_value = (i + 1).ToString(),
  3222. });
  3223. items1.Add(new TestItem()
  3224. {
  3225. Parameter_name = "载具码",
  3226. Parameter_value = vehicleCodes[i],
  3227. });
  3228. items1.Add(new TestItem()
  3229. {
  3230. Parameter_name = "载具穴号",
  3231. Parameter_value = "1",
  3232. });
  3233. items1.Add(new TestItem()
  3234. {
  3235. Parameter_name = "产品结果",
  3236. Parameter_value = isPass ? "OK" : "NG",
  3237. });
  3238. int mesResult = 0;
  3239. //int mesResult = SwitctProcessData(stationNameStr, items1, "", ""
  3240. // , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, portNo, isPass, vehicleCodes[i], "1");
  3241. results[i] = mesResult == 1 ? 1 : 2;
  3242. }
  3243. }
  3244. stopwatch2.Stop();
  3245. short result = 0;
  3246. bool haveMesWarn = results.Contains(2);
  3247. bool havePCWarn = results.Contains(3);
  3248. if (haveMesWarn)
  3249. result = 2; // 2->2
  3250. else if (havePCWarn)
  3251. result = 4; // 3->4
  3252. else
  3253. result = 1;
  3254. // MES_Flag 为4MES报错
  3255. //Funs[plcNo].WriteMultipleRegisters<short>(2463, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3256. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3257. writeToPLC_Flag.Name = "d3MES_FLAG";
  3258. writeToPLC_Flag.Adress = 2463;
  3259. writeToPLC_Flag.Value = result;
  3260. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  3261. WritePLCLog(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  3262. }
  3263. catch (Exception ex)
  3264. {
  3265. stopwatch2.Stop();
  3266. // MES_Flag 为4上位机报错
  3267. //Funs[plcNo].WriteMultipleRegisters<short>(2463, (short)4); // 4代表上位机报警
  3268. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3269. writeToPLC_Flag.Name = "d3MES_FLAG";
  3270. writeToPLC_Flag.Adress = 2463;
  3271. writeToPLC_Flag.Value = (short)4;
  3272. SxPLCWriteData_Add(ref s4PLCWriteData, "d3MES_FLAG", writeToPLC_Flag);
  3273. string str = ex.StackTrace;
  3274. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}S4_3出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3275. }
  3276. stopwatch1.Stop();
  3277. AddMessage(LogType.Info, stationNameStr + "_S4_3出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3278. }
  3279. // 上次采集到的SN
  3280. //private string sn_S4_4进站接口 = string.Empty;
  3281. /// <summary>
  3282. /// [S4] 取放桁架 - S4_4进站接口(提升机2)
  3283. /// </summary>
  3284. private void S4_4进站接口(int plcNo, string stationNameStr)
  3285. {
  3286. Stopwatch stopwatch1 = new Stopwatch();
  3287. Stopwatch stopwatch2 = new Stopwatch();
  3288. try
  3289. {
  3290. stopwatch1.Start();
  3291. string sn = (string)s4PLCData["d4ProductSN"]; // 产品SN(弹夹码)
  3292. sn = sn.Replace("\0", "");
  3293. int d4Result = (int)s4PLCData["d4Result"]; // 产品结果
  3294. // ZS 查询15个载具码与15个产品SN
  3295. List<string> vehicleCodes = new string[15].ToList();
  3296. List<string> portNos = new string[15].ToList();
  3297. // 调用MES进站(最多15个)
  3298. stopwatch2.Start();
  3299. List<int> results = new int[15].ToList(); // 结果集;0代表产品为空
  3300. for (int i = 0; i < vehicleCodes.Count; i++)
  3301. {
  3302. // 循环进站
  3303. if (!string.IsNullOrEmpty(vehicleCodes[i]))
  3304. {
  3305. // 产品SN(物料码)校验
  3306. string portNo = portNos[i];
  3307. List<TestItem> item = new List<TestItem>();
  3308. item.Add(new TestItem()
  3309. {
  3310. Parameter_name = "弹夹码",
  3311. Parameter_value = sn,
  3312. });
  3313. item.Add(new TestItem()
  3314. {
  3315. Parameter_name = "弹夹穴位",
  3316. Parameter_value = (i + 1).ToString(),
  3317. });
  3318. item.Add(new TestItem()
  3319. {
  3320. Parameter_name = "载具码",
  3321. Parameter_value = vehicleCodes[i],
  3322. });
  3323. item.Add(new TestItem()
  3324. {
  3325. Parameter_name = "载具穴号",
  3326. Parameter_value = "1",
  3327. });
  3328. results[i] = 0;// SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, portNo, item);
  3329. }
  3330. }
  3331. stopwatch2.Stop();
  3332. short result = 0;
  3333. bool haveMesWarn = results.Contains(5);
  3334. bool havePCWarn = results.Contains(6);
  3335. if (haveMesWarn)
  3336. result = 2; // 5->2
  3337. else if (havePCWarn)
  3338. result = 6; // 6->4
  3339. else
  3340. result = 1;
  3341. // MES_Flag 为4MES报错
  3342. //Funs[plcNo].WriteMultipleRegisters<short>(2496, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3343. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3344. writeToPLC_Flag.Name = "d4MES_FLAG";
  3345. writeToPLC_Flag.Adress = 2496;
  3346. writeToPLC_Flag.Value = result;
  3347. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  3348. WritePLCLog(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  3349. }
  3350. catch (Exception ex)
  3351. {
  3352. stopwatch2.Stop();
  3353. // MES_Flag 为4上位机报错
  3354. //Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)4); // 4代表上位机报警
  3355. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3356. writeToPLC_Flag.Name = "d4MES_FLAG";
  3357. writeToPLC_Flag.Adress = 2496;
  3358. writeToPLC_Flag.Value = (short)4;
  3359. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  3360. string str = ex.StackTrace;
  3361. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}S4_4进站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3362. }
  3363. stopwatch1.Stop();
  3364. AddMessage(LogType.Info, stationNameStr + "_S4_4进站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3365. }
  3366. // 上次采集到的SN
  3367. //private string sn_S4_4出站接口 = string.Empty;
  3368. /// <summary>
  3369. /// [S4] 取放桁架 - S4_4出站接口(提升机2)
  3370. /// </summary>
  3371. private void S4_4出站接口(int plcNo, string stationNameStr)
  3372. {
  3373. Stopwatch stopwatch1 = new Stopwatch();
  3374. Stopwatch stopwatch2 = new Stopwatch();
  3375. try
  3376. {
  3377. stopwatch1.Start();
  3378. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  3379. string batch_num = GlobalContext.BatchNumber; // 批次号
  3380. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  3381. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  3382. string supplierCode = ""; // 供应商代码
  3383. string sn = (string)s4PLCData["d4ProductSN"]; // 产品SN(弹夹码)
  3384. sn = sn.Replace("\0", "");
  3385. int d4Result = (int)s4PLCData["d4Result"]; // 产品结果
  3386. bool isPass = d4Result == 1; // 产品结果 bool
  3387. // ZS 查询15个载具码与15个产品SN
  3388. List<string> vehicleCodes = new string[15].ToList();
  3389. List<string> portNos = new string[15].ToList();
  3390. // 调用MES出站
  3391. stopwatch2.Start();
  3392. List<int> results = new int[15].ToList(); // 结果集;0代表产品为空
  3393. for (int i = 0; i < vehicleCodes.Count; i++)
  3394. {
  3395. // 循环出站
  3396. if (!string.IsNullOrEmpty(vehicleCodes[i]))
  3397. {
  3398. string portNo = portNos[i];
  3399. List<TestItem> items1 = new List<TestItem>();
  3400. items1.Add(new TestItem()
  3401. {
  3402. Parameter_name = "弹夹码",
  3403. Parameter_value = sn,
  3404. });
  3405. items1.Add(new TestItem()
  3406. {
  3407. Parameter_name = "弹夹穴位",
  3408. Parameter_value = (i + 1).ToString(),
  3409. });
  3410. items1.Add(new TestItem()
  3411. {
  3412. Parameter_name = "载具码",
  3413. Parameter_value = vehicleCodes[i],
  3414. });
  3415. items1.Add(new TestItem()
  3416. {
  3417. Parameter_name = "载具穴号",
  3418. Parameter_value = "1",
  3419. });
  3420. items1.Add(new TestItem()
  3421. {
  3422. Parameter_name = "产品结果",
  3423. Parameter_value = isPass ? "OK" : "NG",
  3424. });
  3425. int mesResult = 0;
  3426. //int mesResult = SwitctProcessData(stationNameStr, items1, "", ""
  3427. // , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, portNo, isPass, vehicleCodes[i], "1");
  3428. results[i] = mesResult == 1 ? 1 : 2;
  3429. }
  3430. }
  3431. stopwatch2.Stop();
  3432. short result = 0;
  3433. bool haveMesWarn = results.Contains(2);
  3434. bool havePCWarn = results.Contains(3);
  3435. if (haveMesWarn)
  3436. result = 2; // 2->2
  3437. else if (havePCWarn)
  3438. result = 4; // 3->4
  3439. else
  3440. result = 1;
  3441. // MES_Flag 为4MES报错
  3442. //Funs[plcNo].WriteMultipleRegisters<short>(2496, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3443. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3444. writeToPLC_Flag.Name = "d4MES_FLAG";
  3445. writeToPLC_Flag.Adress = 2496;
  3446. writeToPLC_Flag.Value = result;
  3447. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  3448. WritePLCLog(LogType.Debug, $"PLC{plcNo}_{stationNameStr}-Write" + (result == 1 ? "成功!" : "失败!"));
  3449. }
  3450. catch (Exception ex)
  3451. {
  3452. stopwatch2.Stop();
  3453. // MES_Flag 为4上位机报错
  3454. //Funs[plcNo].WriteMultipleRegisters<short>(2496, (short)4); // 4代表上位机报警
  3455. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3456. writeToPLC_Flag.Name = "d4MES_FLAG";
  3457. writeToPLC_Flag.Adress = 2496;
  3458. writeToPLC_Flag.Value = (short)4;
  3459. SxPLCWriteData_Add(ref s4PLCWriteData, "d4MES_FLAG", writeToPLC_Flag);
  3460. string str = ex.StackTrace;
  3461. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}S4_4出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3462. }
  3463. stopwatch1.Stop();
  3464. AddMessage(LogType.Info, stationNameStr + "_S4_4出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3465. }
  3466. /// <summary>
  3467. /// [S4] 取放桁架 - S4_5弹夹扫码
  3468. /// </summary>
  3469. /// <param name="plcNo">PLC编号</param>
  3470. /// <param name="stationNameStr">工站全称</param>
  3471. private void S4_5弹夹扫码(int plcNo, string stationNameStr)
  3472. {
  3473. Stopwatch stopwatch1 = new Stopwatch();
  3474. Stopwatch stopwatch2 = new Stopwatch();
  3475. try
  3476. {
  3477. stopwatch1.Start();
  3478. // ZS 弹夹扫码
  3479. string d5BulletclipCode = " "; // 扫到的码
  3480. short d5BulletclipScanCode = 2;
  3481. stopwatch2.Start();
  3482. //Funs[plcNo].WriteMultipleRegisters<string>(2529, d5BulletclipCode, 20);
  3483. //// MES_Flag
  3484. //Funs[plcNo].WriteMultipleRegisters<short>(2528, d5BulletclipScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  3485. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3486. writeToPLC_Flag.Name = "d5BulletclipScanCode";
  3487. writeToPLC_Flag.Adress = 2528;
  3488. writeToPLC_Flag.Value = d5BulletclipScanCode;
  3489. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  3490. {
  3491. Name = "d5BulletclipCode",
  3492. Adress = 2529,
  3493. ValueType = PLCValueType.String,
  3494. ValueTypeStrLength = 20,
  3495. Value = d5BulletclipCode
  3496. });
  3497. SxPLCWriteData_Add(ref s4PLCWriteData, "d5BulletclipScanCode", writeToPLC_Flag);
  3498. stopwatch2.Stop();
  3499. }
  3500. catch (Exception ex)
  3501. {
  3502. string str = ex.StackTrace;
  3503. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 弹夹扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3504. stopwatch2.Start();
  3505. //Funs[plcNo].WriteMultipleRegisters<string>(2529, " ", 20);
  3506. //// MES_Flag
  3507. //Funs[plcNo].WriteMultipleRegisters<short>(2528, (short)6); // 6代表上位机报警
  3508. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3509. writeToPLC_Flag.Name = "d5BulletclipScanCode";
  3510. writeToPLC_Flag.Adress = 2528;
  3511. writeToPLC_Flag.Value = (short)6;
  3512. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  3513. {
  3514. Name = "d5BulletclipCode",
  3515. Adress = 2529,
  3516. ValueType = PLCValueType.String,
  3517. ValueTypeStrLength = 20,
  3518. Value = " "
  3519. });
  3520. SxPLCWriteData_Add(ref s4PLCWriteData, "d5BulletclipScanCode", writeToPLC_Flag);
  3521. stopwatch2.Stop();
  3522. }
  3523. stopwatch1.Stop();
  3524. AddMessage(LogType.Info, stationNameStr + "_弹夹扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3525. }
  3526. /// <summary>
  3527. /// [S4] 取放桁架 - S4_5载具扫码
  3528. /// </summary>
  3529. /// <param name="plcNo">PLC编号</param>
  3530. /// <param name="stationNameStr">工站全称</param>
  3531. private void S4_5载具扫码(int plcNo, string stationNameStr)
  3532. {
  3533. Stopwatch stopwatch1 = new Stopwatch();
  3534. Stopwatch stopwatch2 = new Stopwatch();
  3535. try
  3536. {
  3537. stopwatch1.Start();
  3538. // ZS 载具扫码
  3539. string d5VehicleCode = " "; // 扫到的码
  3540. // 查产品SN
  3541. string partNo = " ";
  3542. short d5VehicleScanCode = 2;
  3543. #region 进站
  3544. if (!string.IsNullOrEmpty(d5VehicleCode))
  3545. {
  3546. List<TestItem> item = new List<TestItem>();
  3547. item.Add(new TestItem()
  3548. {
  3549. Parameter_name = "载具码",
  3550. Parameter_value = d5VehicleCode,
  3551. });
  3552. item.Add(new TestItem()
  3553. {
  3554. Parameter_name = "载具穴号",
  3555. Parameter_value = "1",
  3556. });
  3557. stopwatch2.Start();
  3558. int result = 0;//SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
  3559. stopwatch2.Stop();
  3560. d5VehicleScanCode = (short)result == 1 ? d5VehicleScanCode : (short)result;
  3561. }
  3562. #endregion 进站
  3563. //Funs[plcNo].WriteMultipleRegisters<string>(2560, d5VehicleCode, 20);
  3564. //// MES_Flag
  3565. //Funs[plcNo].WriteMultipleRegisters<short>(2559, d5VehicleScanCode); // plc发送1代表请求扫码,上位机发送2代表扫码OK,3代表扫码NG,6代表上位机报警;7s未给结果代表扫码超时(扫不到码);请求前200ms确保 扫码信号 为0;
  3566. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3567. writeToPLC_Flag.Name = "d5VehicleScanCode";
  3568. writeToPLC_Flag.Adress = 2559;
  3569. writeToPLC_Flag.Value = d5VehicleScanCode;
  3570. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  3571. {
  3572. Name = "d5VehicleCode",
  3573. Adress = 2560,
  3574. ValueType = PLCValueType.String,
  3575. ValueTypeStrLength = 20,
  3576. Value = d5VehicleCode
  3577. });
  3578. SxPLCWriteData_Add(ref s4PLCWriteData, "d5VehicleScanCode", writeToPLC_Flag);
  3579. }
  3580. catch (Exception ex)
  3581. {
  3582. string str = ex.StackTrace;
  3583. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 载具扫码出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3584. stopwatch2.Start();
  3585. //Funs[plcNo].WriteMultipleRegisters<string>(2560, " ", 20);
  3586. //// MES_Flag
  3587. //Funs[plcNo].WriteMultipleRegisters<short>(2559, (short)6); // 6代表上位机报警
  3588. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3589. writeToPLC_Flag.Name = "d5VehicleScanCode";
  3590. writeToPLC_Flag.Adress = 2559;
  3591. writeToPLC_Flag.Value = (short)6;
  3592. writeToPLC_Flag.WriteToPLCDatas.Add(new WriteToPLC_Data() // 1空;2ng;3假产品;
  3593. {
  3594. Name = "d5VehicleCode",
  3595. Adress = 2560,
  3596. ValueType = PLCValueType.String,
  3597. ValueTypeStrLength = 20,
  3598. Value = " "
  3599. });
  3600. SxPLCWriteData_Add(ref s4PLCWriteData, "d5VehicleScanCode", writeToPLC_Flag);
  3601. stopwatch2.Stop();
  3602. }
  3603. stopwatch1.Stop();
  3604. AddMessage(LogType.Info, stationNameStr + "_载具扫码;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3605. }
  3606. // 上次采集到的SN
  3607. //private string sn_S4_5出站接口 = string.Empty;
  3608. /// <summary>
  3609. /// [S4] 取放桁架 - S4_5出站接口
  3610. /// </summary>
  3611. private void S4_5出站接口(int plcNo, string stationCode, string stationName)
  3612. {
  3613. Stopwatch stopwatch1 = new Stopwatch();
  3614. Stopwatch stopwatch2 = new Stopwatch();
  3615. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  3616. string stationNameStr = stationCode + stationName;
  3617. string processItem = stationName; // 测试项目
  3618. try
  3619. {
  3620. stopwatch1.Start();
  3621. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  3622. string batch_num = GlobalContext.BatchNumber; // 批次号
  3623. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  3624. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  3625. string supplierCode = ""; // 供应商代码
  3626. string sn = (string)s4PLCData["d5ProductSN"]; // 产品SN(弹夹码)
  3627. sn = sn.Replace("\0", "");
  3628. string d5VehicleCode1 = (string)s4PLCData["d5VehicleCode1"]; // 载具1码(弹夹穴位1)
  3629. string d5VehicleCode2 = (string)s4PLCData["d5VehicleCode2"]; // 载具2码(弹夹穴位2)
  3630. string d5VehicleCode3 = (string)s4PLCData["d5VehicleCode3"]; // 载具3码(弹夹穴位3)
  3631. string d5VehicleCode4 = (string)s4PLCData["d5VehicleCode4"]; // 载具4码(弹夹穴位4)
  3632. string d5VehicleCode5 = (string)s4PLCData["d5VehicleCode5"]; // 载具5码(弹夹穴位5)
  3633. string d5VehicleCode6 = (string)s4PLCData["d5VehicleCode6"]; // 载具6码(弹夹穴位6)
  3634. string d5VehicleCode7 = (string)s4PLCData["d5VehicleCode7"]; // 载具7码(弹夹穴位7)
  3635. string d5VehicleCode8 = (string)s4PLCData["d5VehicleCode8"]; // 载具8码(弹夹穴位8)
  3636. string d5VehicleCode9 = (string)s4PLCData["d5VehicleCode9"]; // 载具9码(弹夹穴位9)
  3637. string d5VehicleCode10 = (string)s4PLCData["d5VehicleCode10"]; // 载具10码(弹夹穴位10)
  3638. string d5VehicleCode11 = (string)s4PLCData["d5VehicleCode11"]; // 载具11码(弹夹穴位11)
  3639. string d5VehicleCode12 = (string)s4PLCData["d5VehicleCode12"]; // 载具12码(弹夹穴位12)
  3640. string d5VehicleCode13 = (string)s4PLCData["d5VehicleCode13"]; // 载具13码(弹夹穴位13)
  3641. string d5VehicleCode14 = (string)s4PLCData["d5VehicleCode14"]; // 载具14码(弹夹穴位14)
  3642. string d5VehicleCode15 = (string)s4PLCData["d5VehicleCode15"]; // 载具15码(弹夹穴位15)
  3643. int d5Result = (int)s4PLCData["d5Result"]; // 产品结果
  3644. bool pass = d5Result == 1;
  3645. List<TestItem> items1 = new List<TestItem>();
  3646. items1.Add(new TestItem()
  3647. {
  3648. Parameter_name = "产品结果",
  3649. Parameter_value = d5Result == 1 ? "OK" : "NG",
  3650. Parameter_unit = ""
  3651. });
  3652. int result1 = 0;
  3653. //int result1 = SwitctProcessData(stationNameStr, items1, equipmentCode, processItem
  3654. // , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, d5VehicleCode1, "1");
  3655. //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
  3656. short result = result1 == 1 ? (short)1 : (short)3;
  3657. stopwatch2.Start();
  3658. // MES_Flag 为4MES报错
  3659. //Funs[plcNo].WriteMultipleRegisters<short>(2591, result); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3660. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3661. writeToPLC_Flag.Name = "d5MES_FLAG";
  3662. writeToPLC_Flag.Adress = 2591;
  3663. writeToPLC_Flag.Value = result;
  3664. SxPLCWriteData_Add(ref s4PLCWriteData, "d5MES_FLAG", writeToPLC_Flag);
  3665. stopwatch2.Stop();
  3666. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  3667. }
  3668. catch (Exception ex)
  3669. {
  3670. stopwatch2.Start();
  3671. // MES_Flag 为4上位机报错
  3672. //Funs[plcNo].WriteMultipleRegisters<short>(2591, (short)4); // 4代表上位机报警
  3673. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3674. writeToPLC_Flag.Name = "d5MES_FLAG";
  3675. writeToPLC_Flag.Adress = 2591;
  3676. writeToPLC_Flag.Value = (short)4;
  3677. SxPLCWriteData_Add(ref s4PLCWriteData, "d5MES_FLAG", writeToPLC_Flag);
  3678. stopwatch2.Stop();
  3679. string str = ex.StackTrace;
  3680. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3681. }
  3682. stopwatch1.Stop();
  3683. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3684. }
  3685. /// <summary>
  3686. /// [S4] 取放桁架 - S4_5节拍接口
  3687. /// </summary>
  3688. /// <param name="plcNo">PLC编号</param>
  3689. /// <param name="stationNameStr">工站全称</param>
  3690. private void S4_5节拍接口(int plcNo, string stationNameStr)
  3691. {
  3692. Stopwatch stopwatch1 = new Stopwatch();
  3693. Stopwatch stopwatch2 = new Stopwatch();
  3694. string resultStr = string.Empty;
  3695. try
  3696. {
  3697. stopwatch1.Start();
  3698. string oEEType = ((int)s4PLCData["d5OEEType"]).ToString(); // 节拍类型(plc写入)
  3699. string d5OEEProductSN = (string)s4PLCData["d5OEEProductSN"]; // 载具SN
  3700. d5OEEProductSN = d5OEEProductSN.Replace("\0", "");
  3701. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  3702. if (!actionBool)
  3703. {
  3704. stopwatch2.Start();
  3705. // MES_Flag
  3706. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)4); // 上位机;发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警
  3707. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  3708. writeToPLC_Flag1.Name = "d5OEEMES_FLAG";
  3709. writeToPLC_Flag1.Adress = 2924;
  3710. writeToPLC_Flag1.Value = (short)4;
  3711. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag1);
  3712. stopwatch2.Stop();
  3713. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3714. return;
  3715. }
  3716. string d5OEEPartNo = string.Empty; // 物料码
  3717. if (string.IsNullOrEmpty(d5OEEProductSN))
  3718. {
  3719. stopwatch2.Start();
  3720. // MES_Flag
  3721. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3722. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  3723. writeToPLC_Flag1.Name = "d5OEEMES_FLAG";
  3724. writeToPLC_Flag1.Adress = 2924;
  3725. writeToPLC_Flag1.Value = (short)1;
  3726. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag1);
  3727. stopwatch2.Stop();
  3728. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3729. return;
  3730. }
  3731. else
  3732. { // 查产品SN
  3733. d5OEEPartNo = "Test"; // ZS
  3734. }
  3735. short d5OEEMES_FLAG = 0;
  3736. // 上传OEE
  3737. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, d5OEEPartNo, d5OEEProductSN);
  3738. d5OEEMES_FLAG = result.Item1;
  3739. resultStr = result.Item2;
  3740. stopwatch2.Start();
  3741. // MES_Flag
  3742. //Funs[plcNo].WriteMultipleRegisters<short>(2924, d5OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  3743. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3744. writeToPLC_Flag.Name = "d5OEEMES_FLAG";
  3745. writeToPLC_Flag.Adress = 2924;
  3746. writeToPLC_Flag.Value = d5OEEMES_FLAG;
  3747. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag);
  3748. stopwatch2.Stop();
  3749. }
  3750. catch (Exception ex)
  3751. {
  3752. string str = ex.StackTrace;
  3753. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3754. // MES_Flag
  3755. stopwatch2.Start();
  3756. //Funs[plcNo].WriteMultipleRegisters<short>(2924, (short)4); // 4代表上位机报警
  3757. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  3758. writeToPLC_Flag.Name = "d5OEEMES_FLAG";
  3759. writeToPLC_Flag.Adress = 2924;
  3760. writeToPLC_Flag.Value = (short)4;
  3761. SxPLCWriteData_Add(ref s4PLCWriteData, "d5OEEMES_FLAG", writeToPLC_Flag);
  3762. stopwatch2.Stop();
  3763. }
  3764. stopwatch1.Stop();
  3765. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  3766. }
  3767. #endregion [S4] 取放桁架
  3768. #endregion PLC4 刘果段
  3769. #region PLC5 张超凡
  3770. #region [S5] Tray盘下料装备
  3771. /// <summary>
  3772. /// S5工位的数据- 触发信号上次的值
  3773. /// </summary>
  3774. private Dictionary<string, object> s5PLCSignal_Old = new Dictionary<string, object>();
  3775. /// <summary>
  3776. /// S5工位的数据(含触发信号)
  3777. /// </summary>
  3778. private Dictionary<string, object> s5PLCData = new Dictionary<string, object>();
  3779. /// <summary>
  3780. /// S5工位的数据- 回写点位
  3781. /// </summary>
  3782. private Dictionary<string, WriteToPLC_Flag> s5PLCWriteData = new Dictionary<string, WriteToPLC_Flag>();
  3783. /// <summary>
  3784. /// [S5] Tray盘下料装备
  3785. /// </summary>
  3786. /// <param name="plcNo">PLC编号</param>
  3787. private void ReadStation_S5(int plcNo)
  3788. {
  3789. // [S1] Tray盘上料装备
  3790. // [S2] FCT
  3791. // [S3] 值板机
  3792. // [S4_1] 载具下线装备 [S4_5] 载具上线装备
  3793. // [S5] Tray盘下料装备
  3794. /// 上位机心跳
  3795. /// 获取设备报警数据与状态信息
  3796. string stationCode = "[S5]";
  3797. string stationName = "Tray盘下料装备";
  3798. string stationNameStr = stationCode + stationName;
  3799. #region 创建字典
  3800. // 触发信号字典 赋值
  3801. s5PLCSignal_Old.Add("e1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  3802. s5PLCSignal_Old.Add("e1PLC_FLAG", 0); // PLC_FLAG 出站接口
  3803. s5PLCSignal_Old.Add("e1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  3804. s5PLCSignal_Old.Add("e1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  3805. s5PLCSignal_Old.Add("e1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  3806. s5PLCSignal_Old.Add("e1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  3807. s5PLCSignal_Old.Add("e1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  3808. // PLC数据字典 赋值
  3809. s5PLCData.Add("e1PLC_FLAG_Check", 0); // PLC_FLAG 进站校验
  3810. s5PLCData.Add("e1MES_FLAG_Check", 0); // MES_FLAG
  3811. s5PLCData.Add("e1ProductSN_Check", ""); //
  3812. s5PLCData.Add("e1PLC_FLAG", 0); // PLC_FLAG 出站接口
  3813. s5PLCData.Add("e1MES_FLAG", 0); // MES_FLAG
  3814. s5PLCData.Add("e1ProductSN", ""); // 产品SN
  3815. s5PLCData.Add("e1PartNo", ""); // 物料码
  3816. s5PLCData.Add("e1Result", 0); // 产品结果
  3817. s5PLCData.Add("e1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  3818. s5PLCData.Add("e1OEEMES_FLAG", 0); // MES_FLAG
  3819. s5PLCData.Add("e1OEEProductSN", "");// 产品SN(载具SN)
  3820. s5PLCData.Add("e1OEEType", 0); // 节拍类型(plc写入)
  3821. s5PLCData.Add("e1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  3822. s5PLCData.Add("e1AGVUpStart", 0); // AGV上料开始信号
  3823. s5PLCData.Add("e1AGVUpEnd", 0); // AGV上料完成信号
  3824. s5PLCData.Add("e1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  3825. s5PLCData.Add("e1AGVDownStart", 0); // AGV下料开始信号
  3826. s5PLCData.Add("e1AGVDownEnd", 0); // AGV下料完成信号
  3827. #endregion 创建字典
  3828. while (true)
  3829. {
  3830. try
  3831. {
  3832. if (!GlobalContext._IsCon_Funs5)
  3833. {
  3834. UpdatePLCMonitor(1, plcNo, 0);
  3835. continue;
  3836. }
  3837. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  3838. {
  3839. Stopwatch stopwatch1 = new Stopwatch();
  3840. Stopwatch stopwatch2 = new Stopwatch();
  3841. stopwatch1.Start();
  3842. /*
  3843. stopwatch2.Start();
  3844. #region 一次性读取所有数据
  3845. int[] data1 = Funs[plcNo].ReadHoldingRegisters(2000, 100);
  3846. int[] data2 = Funs[plcNo].ReadHoldingRegisters(2100, 46);
  3847. int[] datas = data1.Concat(data2).ToArray();
  3848. s5PLCData["e1PLC_FLAG_Check"] = datas[2]; // 进站校验
  3849. s5PLCData["e1MES_FLAG_Check"] = datas[3];
  3850. int[] e1ProductSN_CheckData = datas.Skip(4).Take(20).ToArray();
  3851. s5PLCData["e1ProductSN_Check"] = ModbusClient.ConvertRegistersToString(e1ProductSN_CheckData, 0, 40);
  3852. s5PLCData["e1PLC_FLAG"] = datas[34]; // 出站接口
  3853. s5PLCData["e1MES_FLAG"] = datas[35];
  3854. int[] e1ProductSNData = datas.Skip(36).Take(20).ToArray();
  3855. s5PLCData["e1ProductSN"] = ModbusClient.ConvertRegistersToString(e1ProductSNData, 0, 40);
  3856. int[] e1PartNoData = datas.Skip(56).Take(20).ToArray();
  3857. s5PLCData["e1PartNo"] = ModbusClient.ConvertRegistersToString(e1PartNoData, 0, 40);
  3858. s5PLCData["e1Result"] = datas[76];
  3859. s5PLCData["e1OEEPLC_FLAG"] = datas[87]; // 节拍接口
  3860. s5PLCData["e1OEEMES_FLAG"] = datas[88];
  3861. int[] e1OEEProductSNData = datas.Skip(89).Take(20).ToArray();
  3862. s5PLCData["e1OEEProductSN"] = ModbusClient.ConvertRegistersToString(e1OEEProductSNData, 0, 40);
  3863. s5PLCData["e1OEEType"] = datas[109];
  3864. s5PLCData["e1AGVUpCall"] = datas[120]; // AGV上料
  3865. s5PLCData["e1AGVUpStart"] = datas[121];
  3866. s5PLCData["e1AGVUpEnd"] = datas[122];
  3867. s5PLCData["e1AGVDownCall"] = datas[133]; // AGV下料
  3868. s5PLCData["e1AGVDownStart"] = datas[134];
  3869. s5PLCData["e1AGVDownEnd"] = datas[135];
  3870. #endregion 一次性读取所有数据
  3871. stopwatch2.Stop();
  3872. #region 回写操作,写后清空flag
  3873. PLCWriteData(Funs[plcNo], ref s5PLCData, ref s5PLCWriteData);
  3874. #endregion 回写操作,写后清空flag
  3875. #region 进站校验
  3876. try
  3877. {
  3878. int e1PLC_FLAG_Check = (int)s5PLCData["e1PLC_FLAG_Check"];
  3879. int e1MES_FLAG_Check = (int)s5PLCData["e1MES_FLAG_Check"];
  3880. int e1PLC_FLAG_CheckOld = (int)s5PLCSignal_Old["e1PLC_FLAG_Check"];
  3881. if (e1PLC_FLAG_Check != e1PLC_FLAG_CheckOld)
  3882. {
  3883. if (e1PLC_FLAG_Check == 1 && e1MES_FLAG_Check == 0) // 0->1
  3884. Task.Run(() => S5进站校验(plcNo, stationNameStr)); // MreTasks[2].Set();
  3885. else if (e1PLC_FLAG_Check == 0 && e1MES_FLAG_Check != 0)
  3886. Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)0);
  3887. s5PLCSignal_Old["e1PLC_FLAG_Check"] = s5PLCData["e1PLC_FLAG_Check"];
  3888. }
  3889. }
  3890. catch (Exception ex)
  3891. {
  3892. Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  3893. string str = ex.StackTrace;
  3894. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3895. }
  3896. #endregion 进站校验
  3897. */
  3898. #region 出站接口
  3899. try
  3900. {
  3901. int e1PLC_FLAG = (int)s5PLCData["e1PLC_FLAG"];
  3902. int e1MES_FLAG = (int)s5PLCData["e1MES_FLAG"];
  3903. int e1PLC_FLAGOld = (int)s5PLCSignal_Old["e1PLC_FLAG"];
  3904. if (e1PLC_FLAG != e1PLC_FLAGOld)
  3905. {
  3906. if (e1PLC_FLAG == 1 && e1MES_FLAG == 0) // 0->1
  3907. Task.Run(() => S5出站接口(plcNo, stationCode, stationName)); // MreTasks[3].Set();
  3908. //else if (e1PLC_FLAG == 0 && e1MES_FLAG != 0)
  3909. //Funs[plcNo].WriteMultipleRegisters<short>(2035, (short)0);
  3910. s5PLCSignal_Old["e1PLC_FLAG"] = s5PLCData["e1PLC_FLAG"];
  3911. }
  3912. }
  3913. catch (Exception ex)
  3914. {
  3915. //Funs[plcNo].WriteMultipleRegisters<short>(2035, (short)6); // 6代表上位机报警
  3916. string str = ex.StackTrace;
  3917. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传出站接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3918. }
  3919. #endregion 出站接口
  3920. #region 节拍接口
  3921. try
  3922. {
  3923. int e1OEEPLC_FLAG = (int)s5PLCData["e1OEEPLC_FLAG"];
  3924. int e1OEEMES_FLAG = (int)s5PLCData["e1OEEMES_FLAG"];
  3925. int e1OEEPLC_FLAGOld = (int)s5PLCSignal_Old["e1OEEPLC_FLAG"];
  3926. if (e1OEEPLC_FLAG != e1OEEPLC_FLAGOld)
  3927. {
  3928. if (e1OEEPLC_FLAG == 1 && e1OEEMES_FLAG == 0) // 0->1
  3929. Task.Run(() => S5节拍接口(plcNo, stationNameStr)); // MreTasks[4].Set();
  3930. //else if (e1OEEPLC_FLAG == 0 && e1OEEMES_FLAG != 0)
  3931. //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)0);
  3932. s5PLCSignal_Old["e1OEEPLC_FLAG"] = s5PLCData["e1OEEPLC_FLAG"];
  3933. }
  3934. }
  3935. catch (Exception ex)
  3936. {
  3937. //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)4); // 4代表上位机报警
  3938. string str = ex.StackTrace;
  3939. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3940. }
  3941. #endregion 节拍接口
  3942. #region AGV上料
  3943. // AGV上料叫AGV信号
  3944. try
  3945. {
  3946. int e1AGVUpCall = (int)s5PLCData["e1AGVUpCall"];
  3947. int e1AGVUpCallOld = (int)s5PLCSignal_Old["e1AGVUpCall"];
  3948. if (e1AGVUpCall != e1AGVUpCallOld)
  3949. {
  3950. if (e1AGVUpCall == 1) // 0->1
  3951. Task.Run(() => S5AGV上料叫agv(plcNo, stationNameStr)); // MreTasks[5].Set();
  3952. s5PLCSignal_Old["e1AGVUpCall"] = s5PLCData["e1AGVUpCall"];
  3953. }
  3954. }
  3955. catch (Exception ex)
  3956. {
  3957. //Funs[plcNo].WriteMultipleRegisters<short>(2120, (short)4); // 4代表上位机报警
  3958. string str = ex.StackTrace;
  3959. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3960. }
  3961. // AGV上料完成信号
  3962. try
  3963. {
  3964. int e1AGVUpEnd = (int)s5PLCData["e1AGVUpEnd"];
  3965. int e1AGVUpEndOld = (int)s5PLCSignal_Old["e1AGVUpEnd"];
  3966. if (e1AGVUpEnd != e1AGVUpEndOld)
  3967. {
  3968. if (e1AGVUpEnd == 1) // 0->1
  3969. Task.Run(() => S5AGV上料完成(plcNo, stationNameStr)); // MreTasks[6].Set();
  3970. s5PLCSignal_Old["e1AGVUpEnd"] = s5PLCData["e1AGVUpEnd"];
  3971. }
  3972. }
  3973. catch (Exception ex)
  3974. {
  3975. //Funs[plcNo].WriteMultipleRegisters<short>(2122, (short)4); // 4代表上位机报警
  3976. string str = ex.StackTrace;
  3977. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料完成信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3978. }
  3979. #endregion AGV上料
  3980. #region AGV下料
  3981. // AGV下料叫agv信号
  3982. try
  3983. {
  3984. int e1AGVDownCall = (int)s5PLCData["e1AGVDownCall"];
  3985. int e1AGVDownCallOld = (int)s5PLCSignal_Old["e1AGVDownCall"];
  3986. if (e1AGVDownCall != e1AGVDownCallOld)
  3987. {
  3988. if (e1AGVDownCall == 1) // 0->1
  3989. Task.Run(() => S5AGV下料叫agv(plcNo, stationNameStr)); // MreTasks[7].Set();
  3990. s5PLCSignal_Old["e1AGVDownCall"] = s5PLCData["e1AGVDownCall"];
  3991. }
  3992. }
  3993. catch (Exception ex)
  3994. {
  3995. //Funs[plcNo].WriteMultipleRegisters<short>(2133, (short)4); // 4代表上位机报警
  3996. string str = ex.StackTrace;
  3997. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料叫agv信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  3998. }
  3999. // AGV下料完成信号
  4000. try
  4001. {
  4002. int e1AGVDownEnd = (int)s5PLCData["e1AGVDownEnd"];
  4003. int e1AGVDownEndOld = (int)s5PLCSignal_Old["e1AGVDownEnd"];
  4004. if (e1AGVDownEnd != e1AGVDownEndOld)
  4005. {
  4006. if (e1AGVDownEnd == 1) // 0->1
  4007. Task.Run(() => S5AGV下料完成(plcNo, stationNameStr)); // MreTasks[8].Set();
  4008. s5PLCSignal_Old["e1AGVDownEnd"] = s5PLCData["e1AGVDownEnd"];
  4009. }
  4010. }
  4011. catch (Exception ex)
  4012. {
  4013. // Funs[plcNo].WriteMultipleRegisters<short>(2135, (short)4); // 4代表上位机报警
  4014. string str = ex.StackTrace;
  4015. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料完成信号出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4016. }
  4017. #endregion AGV下料
  4018. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  4019. stopwatch1.Stop();
  4020. //if (stopwatch1.ElapsedMilliseconds > 60) // ZS 稳定后取消注释该项
  4021. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  4022. }
  4023. else
  4024. {
  4025. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4026. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  4027. Funs[plcNo].Connect();
  4028. }
  4029. }
  4030. catch (Exception ex)
  4031. {
  4032. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4033. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  4034. //Funs[plcNo].ReConnect();
  4035. }
  4036. Thread.Sleep(IntervalReadPLC);
  4037. }
  4038. }
  4039. /// <summary>
  4040. /// [S5] Tray盘下料装备 - 进站校验
  4041. /// </summary>
  4042. /// <param name="plcNo">PLC编号</param>
  4043. /// <param name="stationNameStr">工站全称</param>
  4044. private void S5进站校验(int plcNo, string stationNameStr)
  4045. {
  4046. Stopwatch stopwatch1 = new Stopwatch();
  4047. Stopwatch stopwatch2 = new Stopwatch();
  4048. try
  4049. {
  4050. stopwatch1.Start();
  4051. string sn = (string)s5PLCData["e1ProductSN_Check"]; // 产品SN(载具码)
  4052. sn = sn.Replace("\0", "");
  4053. // 获取产品SN By 载具码
  4054. string partNo = string.Empty;
  4055. // 产品SN(物料码)校验
  4056. List<TestItem> item = new List<TestItem>();
  4057. item.Add(new TestItem()
  4058. {
  4059. Parameter_name = "载具码",
  4060. Parameter_value = sn,
  4061. });
  4062. item.Add(new TestItem()
  4063. {
  4064. Parameter_name = "载具穴号",
  4065. Parameter_value = "1",
  4066. });
  4067. stopwatch2.Start();
  4068. int result = 0;
  4069. //int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
  4070. stopwatch2.Stop();
  4071. short e1MES_FLAG_Check = (short)result;
  4072. // MES_Flag
  4073. //Funs[plcNo].WriteMultipleRegisters<short>(2003, e1MES_FLAG_Check); // 上位机发送1代表OK可以进站;2代表不需要进站;3代表本站返修料;5客户MES报警;6代表上位机报警
  4074. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4075. writeToPLC_Flag.Name = "e1MES_FLAG_Check";
  4076. writeToPLC_Flag.Adress = 2003;
  4077. writeToPLC_Flag.Value = e1MES_FLAG_Check;
  4078. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG_Check", writeToPLC_Flag);
  4079. }
  4080. catch (Exception ex)
  4081. {
  4082. string str = ex.StackTrace;
  4083. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4084. // MES_Flag
  4085. //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6); // 6代表上位机报警
  4086. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4087. writeToPLC_Flag.Name = "e1MES_FLAG_Check";
  4088. writeToPLC_Flag.Adress = 2003;
  4089. writeToPLC_Flag.Value = (short)6;
  4090. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG_Check", writeToPLC_Flag);
  4091. }
  4092. stopwatch1.Stop();
  4093. AddMessage(LogType.Info, stationNameStr + "_进站校验;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4094. }
  4095. /// <summary>
  4096. /// [S5] Tray盘下料装备 - 出站接口
  4097. /// </summary>
  4098. /// <param name="plcNo"></param>
  4099. /// <param name="stationCode"></param>
  4100. /// <param name="stationName"></param>
  4101. private void S5出站接口(int plcNo, string stationCode, string stationName)
  4102. {
  4103. Stopwatch stopwatch1 = new Stopwatch();
  4104. Stopwatch stopwatch2 = new Stopwatch();
  4105. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  4106. string stationNameStr = stationCode + stationName;
  4107. string processItem = stationName; // 测试项目
  4108. try
  4109. {
  4110. stopwatch1.Start();
  4111. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  4112. string batch_num = GlobalContext.BatchNumber; // 批次号
  4113. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  4114. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  4115. string supplierCode = ""; // 供应商代码
  4116. string sn = (string)s5PLCData["e1ProductSN"]; // 产品SN(载具SN码)
  4117. sn = sn.Replace("\0", "");
  4118. //string partNo = (string)s5PLCData["e1PartNo"]; // 物料码
  4119. //partNo = partNo.Replace("\0", "");
  4120. string partNo = string.Empty;
  4121. int e1Result = (int)s5PLCData["e1Result"]; // 产品结果
  4122. bool pass = e1Result == 1;
  4123. List<TestItem> items = new List<TestItem>();
  4124. items.Add(new TestItem()
  4125. {
  4126. Parameter_name = "载具码",
  4127. Parameter_value = sn,
  4128. Parameter_unit = ""
  4129. });
  4130. items.Add(new TestItem()
  4131. {
  4132. Parameter_name = "产品码",
  4133. Parameter_value = partNo,
  4134. Parameter_unit = ""
  4135. });
  4136. int result1 = 0;
  4137. //int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  4138. //, workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, partNo, pass, sn, "1");
  4139. //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
  4140. short result = result1 == 1 ? (short)1 : (short)3;
  4141. stopwatch2.Start();
  4142. // MES_Flag 为MES报错
  4143. // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  4144. //Funs[plcNo].WriteMultipleRegisters<short>(2035, result); // 4代表上位机报警
  4145. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4146. writeToPLC_Flag.Name = "e1MES_FLAG";
  4147. writeToPLC_Flag.Adress = 2035;
  4148. writeToPLC_Flag.Value = result;
  4149. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG", writeToPLC_Flag);
  4150. stopwatch2.Stop();
  4151. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  4152. }
  4153. catch (Exception ex)
  4154. {
  4155. stopwatch2.Start();
  4156. // MES_Flag 为4上位机报错
  4157. //Funs[plcNo].WriteMultipleRegisters<short>(2035, (short)4); // 4代表上位机报警
  4158. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4159. writeToPLC_Flag.Name = "e1MES_FLAG";
  4160. writeToPLC_Flag.Adress = 2035;
  4161. writeToPLC_Flag.Value = (short)4;
  4162. SxPLCWriteData_Add(ref s5PLCWriteData, "e1MES_FLAG", writeToPLC_Flag);
  4163. stopwatch2.Stop();
  4164. string str = ex.StackTrace;
  4165. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{equipmentCode}]{processItem}上传出站接口报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4166. }
  4167. stopwatch1.Stop();
  4168. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4169. }
  4170. /// <summary>
  4171. /// [S5] Tray盘下料装备 - 节拍接口
  4172. /// </summary>
  4173. /// <param name="plcNo">PLC编号</param>
  4174. /// <param name="stationNameStr">工站全称</param>
  4175. private void S5节拍接口(int plcNo, string stationNameStr)
  4176. {
  4177. Stopwatch stopwatch1 = new Stopwatch();
  4178. Stopwatch stopwatch2 = new Stopwatch();
  4179. string resultStr = string.Empty;
  4180. try
  4181. {
  4182. stopwatch1.Start();
  4183. string oEEType = ((int)s5PLCData["e1OEEType"]).ToString(); // 节拍类型(plc写入)
  4184. string e1OEEProductSN = (string)s5PLCData["e1OEEProductSN"]; // 载具SN
  4185. e1OEEProductSN = e1OEEProductSN.Replace("\0", "");
  4186. bool actionBool = Enum.TryParse(oEEType, out XiaomiDeviceOEE deviceOEE);
  4187. if (!actionBool)
  4188. {
  4189. stopwatch2.Start();
  4190. // MES_Flag
  4191. //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)4); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  4192. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  4193. writeToPLC_Flag1.Name = "e1OEEMES_FLAG";
  4194. writeToPLC_Flag1.Adress = 2088;
  4195. writeToPLC_Flag1.Value = (short)4;
  4196. SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag1);
  4197. stopwatch2.Stop();
  4198. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 设备上传了未识别的节拍类型【{oEEType}】请检查;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4199. return;
  4200. }
  4201. string e1OEEPartNo = string.Empty; // 物料码
  4202. if (string.IsNullOrEmpty(e1OEEProductSN))
  4203. {
  4204. stopwatch2.Start();
  4205. // MES_Flag
  4206. //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)1); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  4207. WriteToPLC_Flag writeToPLC_Flag1 = new WriteToPLC_Flag(); // MES_Flag
  4208. writeToPLC_Flag1.Name = "e1OEEMES_FLAG";
  4209. writeToPLC_Flag1.Adress = 2088;
  4210. writeToPLC_Flag1.Value = (short)1;
  4211. SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag1);
  4212. stopwatch2.Stop();
  4213. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- 上传内容无效已自动省略;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4214. return;
  4215. }
  4216. else
  4217. { // 查产品SN
  4218. e1OEEPartNo = "Test"; // ZS
  4219. }
  4220. short e1OEEMES_FLAG = 0;
  4221. // 上传OEE
  4222. (short, string) result = SaveOEEData(plcNo, stationNameStr, deviceOEE, e1OEEPartNo, e1OEEProductSN);
  4223. e1OEEMES_FLAG = result.Item1;
  4224. resultStr = result.Item2;
  4225. stopwatch2.Start();
  4226. // MES_Flag
  4227. //Funs[plcNo].WriteMultipleRegisters<short>(2088, e1OEEMES_FLAG); // 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警;
  4228. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4229. writeToPLC_Flag.Name = "e1OEEMES_FLAG";
  4230. writeToPLC_Flag.Adress = 2088;
  4231. writeToPLC_Flag.Value = e1OEEMES_FLAG;
  4232. SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag);
  4233. stopwatch2.Stop();
  4234. }
  4235. catch (Exception ex)
  4236. {
  4237. string str = ex.StackTrace;
  4238. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4239. // MES_Flag
  4240. stopwatch2.Start();
  4241. //Funs[plcNo].WriteMultipleRegisters<short>(2088, (short)4); // 4代表上位机报警
  4242. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4243. writeToPLC_Flag.Name = "e1OEEMES_FLAG";
  4244. writeToPLC_Flag.Adress = 2088;
  4245. writeToPLC_Flag.Value = (short)4;
  4246. SxPLCWriteData_Add(ref s5PLCWriteData, "e1OEEMES_FLAG", writeToPLC_Flag);
  4247. stopwatch2.Stop();
  4248. }
  4249. stopwatch1.Stop();
  4250. AddMessage(LogType.Info, stationNameStr + $"_节拍接口-- {resultStr};总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4251. }
  4252. /// <summary>
  4253. /// [S5] Tray盘下料装备 - AGV上料叫agv
  4254. /// </summary>
  4255. /// <param name="plcNo">PLC编号</param>
  4256. /// <param name="stationNameStr">工站全称</param>
  4257. private void S5AGV上料叫agv(int plcNo, string stationNameStr)
  4258. {
  4259. Stopwatch stopwatch1 = new Stopwatch();
  4260. Stopwatch stopwatch2 = new Stopwatch();
  4261. try
  4262. {
  4263. stopwatch1.Start();
  4264. // ZS 呼叫AGV
  4265. short e1AGVUpCall = 2;
  4266. stopwatch2.Start();
  4267. // e1AGVUpCall
  4268. //Funs[plcNo].WriteMultipleRegisters<short>(2120, e1AGVUpCall); // 1:plc请求上料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  4269. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4270. writeToPLC_Flag.Name = "e1AGVUpCall";
  4271. writeToPLC_Flag.Adress = 2120;
  4272. writeToPLC_Flag.Value = e1AGVUpCall;
  4273. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpCall", writeToPLC_Flag);
  4274. stopwatch2.Stop();
  4275. }
  4276. catch (Exception ex)
  4277. {
  4278. string str = ex.StackTrace;
  4279. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4280. // e1AGVUpCall
  4281. stopwatch2.Start();
  4282. //Funs[plcNo].WriteMultipleRegisters<short>(2120, (short)4); // 4代表上位机报警
  4283. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4284. writeToPLC_Flag.Name = "e1AGVUpCall";
  4285. writeToPLC_Flag.Adress = 2120;
  4286. writeToPLC_Flag.Value = (short)4;
  4287. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpCall", writeToPLC_Flag);
  4288. stopwatch2.Stop();
  4289. }
  4290. stopwatch1.Stop();
  4291. AddMessage(LogType.Info, stationNameStr + "_AGV上料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4292. }
  4293. /// <summary>
  4294. /// [S5] Tray盘下料装备 - AGV上料完成
  4295. /// </summary>
  4296. /// <param name="plcNo">PLC编号</param>
  4297. /// <param name="stationNameStr">工站全称</param>
  4298. private void S5AGV上料完成(int plcNo, string stationNameStr)
  4299. {
  4300. Stopwatch stopwatch1 = new Stopwatch();
  4301. Stopwatch stopwatch2 = new Stopwatch();
  4302. try
  4303. {
  4304. stopwatch1.Start();
  4305. // ZS AGV上料完成,让小车离开
  4306. short e1AGVUpEnd = 2;
  4307. stopwatch2.Start();
  4308. // e1AGVUpEnd
  4309. //Funs[plcNo].WriteMultipleRegisters<short>(2122, e1AGVUpEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  4310. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4311. writeToPLC_Flag.Name = "e1AGVUpEnd";
  4312. writeToPLC_Flag.Adress = 2122;
  4313. writeToPLC_Flag.Value = e1AGVUpEnd;
  4314. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpEnd", writeToPLC_Flag);
  4315. stopwatch2.Stop();
  4316. }
  4317. catch (Exception ex)
  4318. {
  4319. string str = ex.StackTrace;
  4320. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV上料完成出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4321. // e1AGVUpEnd
  4322. stopwatch2.Start();
  4323. //Funs[plcNo].WriteMultipleRegisters<short>(2122, (short)4); // 4代表上位机报警
  4324. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4325. writeToPLC_Flag.Name = "e1AGVUpEnd";
  4326. writeToPLC_Flag.Adress = 2122;
  4327. writeToPLC_Flag.Value = (short)4;
  4328. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVUpEnd", writeToPLC_Flag);
  4329. stopwatch2.Stop();
  4330. }
  4331. stopwatch1.Stop();
  4332. AddMessage(LogType.Info, stationNameStr + "_AGV上料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4333. }
  4334. /// <summary>
  4335. /// [S5] Tray盘下料装备 - AGV下料叫agv
  4336. /// </summary>
  4337. /// <param name="plcNo">PLC编号</param>
  4338. /// <param name="stationNameStr">工站全称</param>
  4339. private void S5AGV下料叫agv(int plcNo, string stationNameStr)
  4340. {
  4341. Stopwatch stopwatch1 = new Stopwatch();
  4342. Stopwatch stopwatch2 = new Stopwatch();
  4343. try
  4344. {
  4345. stopwatch1.Start();
  4346. // ZS 呼叫AGV
  4347. short e1AGVDownCall = 2;
  4348. stopwatch2.Start();
  4349. // e1AGVDownCall
  4350. //Funs[plcNo].WriteMultipleRegisters<short>(2133, e1AGVDownCall); // 1:plc请求下料(plc请求);10秒响应清证明上位机掉线;2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  4351. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4352. writeToPLC_Flag.Name = "e1AGVDownCall";
  4353. writeToPLC_Flag.Adress = 2133;
  4354. writeToPLC_Flag.Value = e1AGVDownCall;
  4355. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownCall", writeToPLC_Flag);
  4356. stopwatch2.Stop();
  4357. }
  4358. catch (Exception ex)
  4359. {
  4360. string str = ex.StackTrace;
  4361. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料叫agv出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4362. // e1AGVDownCall
  4363. stopwatch2.Start();
  4364. //Funs[plcNo].WriteMultipleRegisters<short>(2133, (short)4); // 4代表上位机报警
  4365. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4366. writeToPLC_Flag.Name = "e1AGVDownCall";
  4367. writeToPLC_Flag.Adress = 2133;
  4368. writeToPLC_Flag.Value = (short)4;
  4369. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownCall", writeToPLC_Flag);
  4370. stopwatch2.Stop();
  4371. }
  4372. stopwatch1.Stop();
  4373. AddMessage(LogType.Info, stationNameStr + "_AGV下料叫agv;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4374. }
  4375. /// <summary>
  4376. /// [S5] Tray盘下料装备 - AGV下料完成
  4377. /// </summary>
  4378. /// <param name="plcNo">PLC编号</param>
  4379. /// <param name="stationNameStr">工站全称</param>
  4380. private void S5AGV下料完成(int plcNo, string stationNameStr)
  4381. {
  4382. Stopwatch stopwatch1 = new Stopwatch();
  4383. Stopwatch stopwatch2 = new Stopwatch();
  4384. try
  4385. {
  4386. stopwatch1.Start();
  4387. // ZS AGV上料完成,让小车离开
  4388. short e1AGVDownEnd = 2;
  4389. stopwatch2.Start();
  4390. // e1AGVDownEnd
  4391. //Funs[plcNo].WriteMultipleRegisters<short>(2135, e1AGVDownEnd); // 1:plc通知完成结果(plc请求);2:调用成功(上位机返回);3:AGV报警(上位机返回);4:上位机报警(上位机返回);
  4392. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4393. writeToPLC_Flag.Name = "e1AGVDownEnd";
  4394. writeToPLC_Flag.Adress = 2135;
  4395. writeToPLC_Flag.Value = e1AGVDownEnd;
  4396. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownEnd", writeToPLC_Flag);
  4397. stopwatch2.Stop();
  4398. }
  4399. catch (Exception ex)
  4400. {
  4401. string str = ex.StackTrace;
  4402. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} AGV下料完成出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4403. // e1AGVDownEnd
  4404. stopwatch2.Start();
  4405. //Funs[plcNo].WriteMultipleRegisters<short>(2135, (short)4); // 4代表上位机报警
  4406. WriteToPLC_Flag writeToPLC_Flag = new WriteToPLC_Flag(); // MES_Flag
  4407. writeToPLC_Flag.Name = "e1AGVDownEnd";
  4408. writeToPLC_Flag.Adress = 2135;
  4409. writeToPLC_Flag.Value = (short)4;
  4410. SxPLCWriteData_Add(ref s5PLCWriteData, "e1AGVDownEnd", writeToPLC_Flag);
  4411. stopwatch2.Stop();
  4412. }
  4413. stopwatch1.Stop();
  4414. AddMessage(LogType.Info, stationNameStr + "_AGV下料完成;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4415. }
  4416. #endregion [S5] Tray盘下料装备
  4417. #endregion PLC5 张超凡
  4418. /// <summary>
  4419. /// [S6] 顶盖装配设备
  4420. /// </summary>
  4421. /// <param name="plcNo">PLC编号</param>
  4422. private void ReadStation_S6(int plcNo)
  4423. {
  4424. string stationCode = "[S6]";
  4425. string stationName = "顶盖装配设备";
  4426. string stationNameStr = stationCode + stationName;
  4427. string tagBaseName = "g_OP60_MES"; //标签变量名称
  4428. string tagMesCommName = "mesCommToPC"; //标签变量名称
  4429. string tagAgvCommName = "agvCommFrmPC";
  4430. string tagBarsetName = "BarcodeSet";
  4431. OP60_MesData_t stPLC_MesData; //PLC的MES数据
  4432. (int, string) result;
  4433. bool ProgressState = true;
  4434. #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4435. // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4436. s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  4437. s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  4438. s1PLCSignal_Old.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  4439. s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  4440. s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4441. s1PLCSignal_Old.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  4442. s1PLCSignal_Old.Add("a1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  4443. s1PLCSignal_Old.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  4444. s1PLCSignal_Old.Add("a1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  4445. // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4446. s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  4447. s1PLCData.Add("a1MES_FLAG_VehicleStates", 0); // MES_FLAG
  4448. s1PLCData.Add("a1ProductSN_VehicleStates", ""); // 产品SN(载具码)
  4449. s1PLCData.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  4450. s1PLCData.Add("a1MES_FLAG_Check", 0); // MES_FLAG
  4451. s1PLCData.Add("a1ProductSN_Check", ""); // 产品SN(物料码)
  4452. s1PLCData.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  4453. s1PLCData.Add("a1MES_FLAG", 0); // MES_FLAG
  4454. s1PLCData.Add("a1ProductSN", ""); // 产品SN(载具SN)
  4455. s1PLCData.Add("a1PartNo1", ""); // 物料码1(穴位1)
  4456. s1PLCData.Add("a1PartNo2", ""); // 物料码2(穴位2)
  4457. s1PLCData.Add("a1Result", 0); // 产品结果
  4458. s1PLCData.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  4459. s1PLCData.Add("a1MES_FLAG_ICT", 0); // MES_FLAG
  4460. s1PLCData.Add("a1ProductSN_ICT", ""); // 产品SN(载具SN)
  4461. s1PLCData.Add("a1PartNo1_ICT", ""); // 物料码1(穴位1)
  4462. s1PLCData.Add("a1PartNo2_ICT", ""); // 物料码2(穴位2)
  4463. s1PLCData.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4464. s1PLCData.Add("a1OEEMES_FLAG", 0); // MES_FLAG
  4465. s1PLCData.Add("a1OEEPartNo", ""); // 物料码(物料码还未绑定载具SN时必填)
  4466. s1PLCData.Add("a1OEEVehicleCode", ""); // 载具SN
  4467. s1PLCData.Add("a1OEEPartNum", 0); // 穴位号
  4468. s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  4469. s1PLCData.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  4470. s1PLCData.Add("a1AGVUpStart", 0); // AGV上料开始信号
  4471. s1PLCData.Add("a1AGVUpEnd", 0); // AGV上料完成信号
  4472. s1PLCData.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  4473. s1PLCData.Add("a1AGVDownStart", 0); // AGV下料开始信号
  4474. s1PLCData.Add("a1AGVDownEnd", 0); // AGV下料完成信号
  4475. #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4476. while (true)
  4477. {
  4478. try
  4479. {
  4480. if (!GlobalContext._IsCon_Funs1)
  4481. {
  4482. UpdatePLCMonitor(1, plcNo, 0);
  4483. continue;
  4484. }
  4485. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  4486. {
  4487. Stopwatch stopwatch1 = new Stopwatch();
  4488. Stopwatch stopwatch2 = new Stopwatch();
  4489. stopwatch1.Start();
  4490. stopwatch2.Start();
  4491. #region 一次性读取所有数据
  4492. // 一次性读取所有数据
  4493. result = Funs[plcNo].Read_SingleTag<OP60_MesData_t>(tagBaseName, 1, out stPLC_MesData); //读取单个结构体数据
  4494. if (result.Item1 != 0)
  4495. {
  4496. //richTextBox1.AppendText("\n" + strRet);
  4497. }
  4498. else
  4499. {
  4500. //richTextBox1.AppendText("\n" + "读取成功");
  4501. }
  4502. #endregion 一次性读取所有数据
  4503. stopwatch2.Stop();
  4504. #region 进站
  4505. try
  4506. {
  4507. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
  4508. {
  4509. ProgressState = false;
  4510. Task.Run(() => S6进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, out ProgressState));
  4511. }
  4512. }
  4513. catch (Exception ex)
  4514. {
  4515. ProgressState = false;
  4516. string str = ex.StackTrace;
  4517. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4518. }
  4519. #endregion 进站
  4520. #region 出站
  4521. try
  4522. {
  4523. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
  4524. {
  4525. ProgressState = false;
  4526. Task.Run(() => S6出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
  4527. }
  4528. }
  4529. catch (Exception ex)
  4530. {
  4531. string str = ex.StackTrace;
  4532. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4533. }
  4534. #endregion 进站
  4535. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  4536. stopwatch1.Stop();
  4537. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  4538. }
  4539. else
  4540. {
  4541. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4542. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  4543. Funs[plcNo].Connect(); // 重连
  4544. }
  4545. }
  4546. catch (Exception ex)
  4547. {
  4548. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4549. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  4550. }
  4551. Thread.Sleep(IntervalReadPLC);
  4552. }
  4553. }
  4554. /// <summary>
  4555. /// [S6] 顶盖装配设备 - 进站
  4556. /// </summary>
  4557. /// <param name="plcNo">PLC编号</param>
  4558. /// <param name="stationNameStr">工站全称</param>
  4559. /// <param name="stPLC_MesData"></param>
  4560. /// <param name="tagMesCommName"></param>
  4561. private void S6进站(int plcNo, string stationNameStr, OP60_MesData_t stPLC_MesData, string tagMesCommName, out bool ProgressState)
  4562. {
  4563. int nRet = 0;
  4564. string strRet = "";
  4565. Stopwatch stopwatch1 = new Stopwatch();
  4566. Stopwatch stopwatch2 = new Stopwatch();
  4567. ProgressState = true;
  4568. try
  4569. {
  4570. stopwatch1.Start();
  4571. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  4572. string MachineId = GlobalContext.S6_MachineId; // 装备ID(可配置)
  4573. string StationId = GlobalContext.S6_StationId; // 工位ID(可配置)
  4574. // 产品SN(物料码)校验
  4575. List<TestItem> item = new List<TestItem>();
  4576. stopwatch2.Start();
  4577. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
  4578. stopwatch2.Stop();
  4579. //指令执行结果 1:OK 110:失败
  4580. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  4581. //进站结果写入PLC
  4582. CommandFromPLC resultToPlC = new CommandFromPLC();
  4583. resultToPlC.cmd = 0;
  4584. resultToPlC.cmdParam = 0; //指令参数
  4585. resultToPlC.cmdResult = mesResultFrmWeb;
  4586. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4587. }
  4588. catch (Exception ex)
  4589. {
  4590. string str = ex.StackTrace;
  4591. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4592. CommandFromPLC resultToPlC = new CommandFromPLC();
  4593. resultToPlC.cmd = 0;
  4594. resultToPlC.cmdParam = 0; //指令参数
  4595. resultToPlC.cmdResult = 110;
  4596. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4597. }
  4598. stopwatch1.Stop();
  4599. AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4600. }
  4601. /// <summary>
  4602. /// [S6] 顶盖装配设备 - 出站接口
  4603. /// </summary>
  4604. private void S6出站(int plcNo, string stationNameStr, OP60_MesData_t stPLC_MesData, string tagMesCommName, string stationCode, string stationName, out bool ProgressState)
  4605. {
  4606. ProgressState = true;
  4607. Stopwatch stopwatch1 = new Stopwatch();
  4608. Stopwatch stopwatch2 = new Stopwatch();
  4609. try
  4610. {
  4611. stopwatch1.Start();
  4612. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  4613. string processItem = stationName; // 测试项目
  4614. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  4615. string supplierCode = ""; // 供应商代码
  4616. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  4617. string batch_num = GlobalContext.BatchNumber; // 批次号
  4618. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  4619. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  4620. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  4621. string MachineId = GlobalContext.S6_MachineId; // 装备id(可配置) // ZS
  4622. string StationId = GlobalContext.S6_StationId; // ⼯位ID(可配置) // ZS
  4623. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  4624. bool pass = a1Result == 1;
  4625. List<TestItem> items = new List<TestItem>();
  4626. items.Add(new TestItem()
  4627. {
  4628. Parameter_name = "载具码",
  4629. Parameter_value = CarrierBarcode,
  4630. Parameter_unit = ""
  4631. });
  4632. items.Add(new TestItem()
  4633. {
  4634. Parameter_name = "产品码",
  4635. Parameter_value = mtltmrk,
  4636. Parameter_unit = ""
  4637. });
  4638. //绑定载具和产品
  4639. ResponseMessage message = new ResponseMessage();
  4640. message = SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
  4641. if (message.result == false)
  4642. {
  4643. AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
  4644. }
  4645. //绑定PLC返回MES数据到本地
  4646. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  4647. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
  4648. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  4649. stopwatch2.Start();
  4650. //进站结果写入PLC
  4651. CommandFromPLC resultToPlC = new CommandFromPLC();
  4652. resultToPlC.cmd = 0;
  4653. resultToPlC.cmdParam = 0; //指令参数
  4654. resultToPlC.cmdResult = mesResultFrmWeb;
  4655. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4656. stopwatch2.Stop();
  4657. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
  4658. }
  4659. catch (Exception ex)
  4660. {
  4661. stopwatch2.Start();
  4662. CommandFromPLC resultToPlC = new CommandFromPLC();
  4663. resultToPlC.cmd = 0;
  4664. resultToPlC.cmdParam = 0; //指令参数
  4665. resultToPlC.cmdResult = 110;
  4666. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4667. stopwatch2.Stop();
  4668. string str = ex.StackTrace;
  4669. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4670. }
  4671. stopwatch1.Stop();
  4672. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4673. }
  4674. /// <summary>
  4675. /// [S8] 3D螺丝高度检测设备
  4676. /// </summary>
  4677. /// <param name="plcNo">PLC编号</param>
  4678. private void ReadStation_S8(int plcNo)
  4679. {
  4680. string stationCode = "[S8]";
  4681. string stationName = "3D螺丝高度检测设备";
  4682. string stationNameStr = stationCode + stationName;
  4683. string tagBaseName = "g_OP80_MES"; //标签变量名称
  4684. string tagMesCommName = "mesCommToPC"; //标签变量名称
  4685. string tagAgvCommName = "agvCommFrmPC";
  4686. string tagBarsetName = "BarcodeSet";
  4687. OP80_MesData_t stPLC_MesData; //PLC的MES数据
  4688. (int, string) result;
  4689. bool ProgressState = true;
  4690. #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4691. // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4692. s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  4693. s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  4694. s1PLCSignal_Old.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  4695. s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  4696. s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4697. s1PLCSignal_Old.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  4698. s1PLCSignal_Old.Add("a1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  4699. s1PLCSignal_Old.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  4700. s1PLCSignal_Old.Add("a1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  4701. // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4702. s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  4703. s1PLCData.Add("a1MES_FLAG_VehicleStates", 0); // MES_FLAG
  4704. s1PLCData.Add("a1ProductSN_VehicleStates", ""); // 产品SN(载具码)
  4705. s1PLCData.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  4706. s1PLCData.Add("a1MES_FLAG_Check", 0); // MES_FLAG
  4707. s1PLCData.Add("a1ProductSN_Check", ""); // 产品SN(物料码)
  4708. s1PLCData.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  4709. s1PLCData.Add("a1MES_FLAG", 0); // MES_FLAG
  4710. s1PLCData.Add("a1ProductSN", ""); // 产品SN(载具SN)
  4711. s1PLCData.Add("a1PartNo1", ""); // 物料码1(穴位1)
  4712. s1PLCData.Add("a1PartNo2", ""); // 物料码2(穴位2)
  4713. s1PLCData.Add("a1Result", 0); // 产品结果
  4714. s1PLCData.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  4715. s1PLCData.Add("a1MES_FLAG_ICT", 0); // MES_FLAG
  4716. s1PLCData.Add("a1ProductSN_ICT", ""); // 产品SN(载具SN)
  4717. s1PLCData.Add("a1PartNo1_ICT", ""); // 物料码1(穴位1)
  4718. s1PLCData.Add("a1PartNo2_ICT", ""); // 物料码2(穴位2)
  4719. s1PLCData.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4720. s1PLCData.Add("a1OEEMES_FLAG", 0); // MES_FLAG
  4721. s1PLCData.Add("a1OEEPartNo", ""); // 物料码(物料码还未绑定载具SN时必填)
  4722. s1PLCData.Add("a1OEEVehicleCode", ""); // 载具SN
  4723. s1PLCData.Add("a1OEEPartNum", 0); // 穴位号
  4724. s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  4725. s1PLCData.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  4726. s1PLCData.Add("a1AGVUpStart", 0); // AGV上料开始信号
  4727. s1PLCData.Add("a1AGVUpEnd", 0); // AGV上料完成信号
  4728. s1PLCData.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  4729. s1PLCData.Add("a1AGVDownStart", 0); // AGV下料开始信号
  4730. s1PLCData.Add("a1AGVDownEnd", 0); // AGV下料完成信号
  4731. #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4732. while (true)
  4733. {
  4734. try
  4735. {
  4736. if (!GlobalContext._IsCon_Funs1)
  4737. {
  4738. UpdatePLCMonitor(1, plcNo, 0);
  4739. continue;
  4740. }
  4741. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  4742. {
  4743. Stopwatch stopwatch1 = new Stopwatch();
  4744. Stopwatch stopwatch2 = new Stopwatch();
  4745. stopwatch1.Start();
  4746. stopwatch2.Start();
  4747. #region 一次性读取所有数据
  4748. // 一次性读取所有数据
  4749. result = Funs[plcNo].Read_SingleTag<OP80_MesData_t>(tagBaseName, 1, out stPLC_MesData); //读取单个结构体数据
  4750. if (result.Item1 != 0)
  4751. {
  4752. //richTextBox1.AppendText("\n" + strRet);
  4753. }
  4754. else
  4755. {
  4756. //richTextBox1.AppendText("\n" + "读取成功");
  4757. }
  4758. #endregion 一次性读取所有数据
  4759. stopwatch2.Stop();
  4760. #region 进站
  4761. try
  4762. {
  4763. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
  4764. {
  4765. ProgressState = false;
  4766. Task.Run(() => S8进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, out ProgressState));
  4767. }
  4768. }
  4769. catch (Exception ex)
  4770. {
  4771. ProgressState = false;
  4772. string str = ex.StackTrace;
  4773. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4774. }
  4775. #endregion 进站
  4776. #region 出站
  4777. try
  4778. {
  4779. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
  4780. {
  4781. ProgressState = false;
  4782. Task.Run(() => S8出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
  4783. }
  4784. }
  4785. catch (Exception ex)
  4786. {
  4787. string str = ex.StackTrace;
  4788. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4789. }
  4790. #endregion 进站
  4791. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  4792. stopwatch1.Stop();
  4793. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  4794. }
  4795. else
  4796. {
  4797. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4798. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  4799. Funs[plcNo].Connect(); // 重连
  4800. }
  4801. }
  4802. catch (Exception ex)
  4803. {
  4804. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  4805. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  4806. }
  4807. Thread.Sleep(IntervalReadPLC);
  4808. }
  4809. }
  4810. /// <summary>
  4811. /// [S8] 3D螺丝高度检测设备 - 进站
  4812. /// </summary>
  4813. /// <param name="plcNo">PLC编号</param>
  4814. /// <param name="stationNameStr">工站全称</param>
  4815. /// <param name="stPLC_MesData"></param>
  4816. /// <param name="tagMesCommName"></param>
  4817. private void S8进站(int plcNo, string stationNameStr, OP80_MesData_t stPLC_MesData, string tagMesCommName, out bool ProgressState)
  4818. {
  4819. int nRet = 0;
  4820. string strRet = "";
  4821. Stopwatch stopwatch1 = new Stopwatch();
  4822. Stopwatch stopwatch2 = new Stopwatch();
  4823. ProgressState = true;
  4824. try
  4825. {
  4826. stopwatch1.Start();
  4827. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  4828. string MachineId = GlobalContext.S8_MachineId; // 装备ID(可配置)
  4829. string StationId = GlobalContext.S8_StationId; // 工位ID(可配置)
  4830. // 产品SN(物料码)校验
  4831. List<TestItem> item = new List<TestItem>();
  4832. stopwatch2.Start();
  4833. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
  4834. stopwatch2.Stop();
  4835. //指令执行结果 1:OK 110:失败
  4836. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  4837. //进站结果写入PLC
  4838. CommandFromPLC resultToPlC = new CommandFromPLC();
  4839. resultToPlC.cmd = 0;
  4840. resultToPlC.cmdParam = 0; //指令参数
  4841. resultToPlC.cmdResult = mesResultFrmWeb;
  4842. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4843. }
  4844. catch (Exception ex)
  4845. {
  4846. string str = ex.StackTrace;
  4847. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4848. CommandFromPLC resultToPlC = new CommandFromPLC();
  4849. resultToPlC.cmd = 0;
  4850. resultToPlC.cmdParam = 0; //指令参数
  4851. resultToPlC.cmdResult = 110;
  4852. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4853. }
  4854. stopwatch1.Stop();
  4855. AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4856. }
  4857. /// <summary>
  4858. /// [S8] 3D螺丝高度检测设备 - 出站接口
  4859. /// </summary>
  4860. private void S8出站(int plcNo, string stationNameStr, OP80_MesData_t stPLC_MesData, string tagMesCommName, string stationCode, string stationName, out bool ProgressState)
  4861. {
  4862. ProgressState = true;
  4863. Stopwatch stopwatch1 = new Stopwatch();
  4864. Stopwatch stopwatch2 = new Stopwatch();
  4865. try
  4866. {
  4867. stopwatch1.Start();
  4868. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  4869. string processItem = stationName; // 测试项目
  4870. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  4871. string supplierCode = ""; // 供应商代码
  4872. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  4873. string batch_num = GlobalContext.BatchNumber; // 批次号
  4874. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  4875. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  4876. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  4877. string MachineId = GlobalContext.S8_MachineId; // 装备id(可配置) // ZS
  4878. string StationId = GlobalContext.S8_StationId; // ⼯位ID(可配置) // ZS
  4879. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  4880. bool pass = a1Result == 1;
  4881. List<TestItem> items = new List<TestItem>();
  4882. items.Add(new TestItem()
  4883. {
  4884. Parameter_name = "载具码",
  4885. Parameter_value = CarrierBarcode,
  4886. Parameter_unit = ""
  4887. });
  4888. items.Add(new TestItem()
  4889. {
  4890. Parameter_name = "产品码",
  4891. Parameter_value = mtltmrk,
  4892. Parameter_unit = ""
  4893. });
  4894. //绑定载具和产品
  4895. ResponseMessage message = new ResponseMessage();
  4896. message = SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
  4897. if (message.result == false)
  4898. {
  4899. AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
  4900. }
  4901. //绑定PLC返回MES数据到本地
  4902. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  4903. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
  4904. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  4905. stopwatch2.Start();
  4906. //进站结果写入PLC
  4907. CommandFromPLC resultToPlC = new CommandFromPLC();
  4908. resultToPlC.cmd = 0;
  4909. resultToPlC.cmdParam = 0; //指令参数
  4910. resultToPlC.cmdResult = mesResultFrmWeb;
  4911. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4912. stopwatch2.Stop();
  4913. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
  4914. }
  4915. catch (Exception ex)
  4916. {
  4917. stopwatch2.Start();
  4918. CommandFromPLC resultToPlC = new CommandFromPLC();
  4919. resultToPlC.cmd = 0;
  4920. resultToPlC.cmdParam = 0; //指令参数
  4921. resultToPlC.cmdResult = 110;
  4922. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  4923. stopwatch2.Stop();
  4924. string str = ex.StackTrace;
  4925. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  4926. }
  4927. stopwatch1.Stop();
  4928. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  4929. }
  4930. /// <summary>
  4931. /// [S9] 下料设备
  4932. /// </summary>
  4933. /// <param name="plcNo">PLC编号</param>
  4934. private void ReadStation_S9(int plcNo)
  4935. {
  4936. string stationCode = "[S9]";
  4937. string stationName = "下料设备";
  4938. string stationNameStr = stationCode + stationName;
  4939. string tagBaseName = "g_OP90_MES"; //标签变量名称
  4940. string tagMesCommName = "mesCommToPC"; //标签变量名称
  4941. string tagAgvCommName = "agvCommFrmPC";
  4942. string tagBarsetName = "BarcodeSet";
  4943. OP90_MesData_t stPLC_MesData; //PLC的MES数据
  4944. (int, string) result;
  4945. bool ProgressState = true;
  4946. #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4947. // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4948. s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  4949. s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  4950. s1PLCSignal_Old.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  4951. s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  4952. s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4953. s1PLCSignal_Old.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  4954. s1PLCSignal_Old.Add("a1AGVUpEnd", 0); // AGV上料完成信号 AGV上料
  4955. s1PLCSignal_Old.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  4956. s1PLCSignal_Old.Add("a1AGVDownEnd", 0); // AGV下料完成信号 AGV下料
  4957. // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4958. s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0); // PLC_FLAG 载具进站查询状态
  4959. s1PLCData.Add("a1MES_FLAG_VehicleStates", 0); // MES_FLAG
  4960. s1PLCData.Add("a1ProductSN_VehicleStates", ""); // 产品SN(载具码)
  4961. s1PLCData.Add("a1PLC_FLAG_Check", 0); // PLC_FLAG 上料进站校验
  4962. s1PLCData.Add("a1MES_FLAG_Check", 0); // MES_FLAG
  4963. s1PLCData.Add("a1ProductSN_Check", ""); // 产品SN(物料码)
  4964. s1PLCData.Add("a1PLC_FLAG", 0); // PLC_FLAG 出站接口
  4965. s1PLCData.Add("a1MES_FLAG", 0); // MES_FLAG
  4966. s1PLCData.Add("a1ProductSN", ""); // 产品SN(载具SN)
  4967. s1PLCData.Add("a1PartNo1", ""); // 物料码1(穴位1)
  4968. s1PLCData.Add("a1PartNo2", ""); // 物料码2(穴位2)
  4969. s1PLCData.Add("a1Result", 0); // 产品结果
  4970. s1PLCData.Add("a1PLC_FLAG_ICT", 0); // PLC_FLAG 将SN发给ICT标机(串口)
  4971. s1PLCData.Add("a1MES_FLAG_ICT", 0); // MES_FLAG
  4972. s1PLCData.Add("a1ProductSN_ICT", ""); // 产品SN(载具SN)
  4973. s1PLCData.Add("a1PartNo1_ICT", ""); // 物料码1(穴位1)
  4974. s1PLCData.Add("a1PartNo2_ICT", ""); // 物料码2(穴位2)
  4975. s1PLCData.Add("a1OEEPLC_FLAG", 0); // PLC_FLAG 节拍接口
  4976. s1PLCData.Add("a1OEEMES_FLAG", 0); // MES_FLAG
  4977. s1PLCData.Add("a1OEEPartNo", ""); // 物料码(物料码还未绑定载具SN时必填)
  4978. s1PLCData.Add("a1OEEVehicleCode", ""); // 载具SN
  4979. s1PLCData.Add("a1OEEPartNum", 0); // 穴位号
  4980. s1PLCData.Add("a1OEEType", 0); // 节拍类型(plc写入)
  4981. s1PLCData.Add("a1AGVUpCall", 0); // AGV上料叫agv信号 AGV上料
  4982. s1PLCData.Add("a1AGVUpStart", 0); // AGV上料开始信号
  4983. s1PLCData.Add("a1AGVUpEnd", 0); // AGV上料完成信号
  4984. s1PLCData.Add("a1AGVDownCall", 0); // AGV下料叫agv信号 AGV下料
  4985. s1PLCData.Add("a1AGVDownStart", 0); // AGV下料开始信号
  4986. s1PLCData.Add("a1AGVDownEnd", 0); // AGV下料完成信号
  4987. #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
  4988. while (true)
  4989. {
  4990. try
  4991. {
  4992. if (!GlobalContext._IsCon_Funs1)
  4993. {
  4994. UpdatePLCMonitor(1, plcNo, 0);
  4995. continue;
  4996. }
  4997. if (Funs[plcNo].IsConnected) // 检查PLC是否已连接上
  4998. {
  4999. Stopwatch stopwatch1 = new Stopwatch();
  5000. Stopwatch stopwatch2 = new Stopwatch();
  5001. stopwatch1.Start();
  5002. stopwatch2.Start();
  5003. #region 一次性读取所有数据
  5004. // 一次性读取所有数据
  5005. result = Funs[plcNo].Read_SingleTag<OP90_MesData_t>(tagBaseName, 1, out stPLC_MesData); //读取单个结构体数据
  5006. if (result.Item1 != 0)
  5007. {
  5008. //richTextBox1.AppendText("\n" + strRet);
  5009. }
  5010. else
  5011. {
  5012. //richTextBox1.AppendText("\n" + "读取成功");
  5013. }
  5014. #endregion 一次性读取所有数据
  5015. stopwatch2.Stop();
  5016. #region 进站
  5017. try
  5018. {
  5019. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
  5020. {
  5021. ProgressState = false;
  5022. Task.Run(() => S9进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, out ProgressState));
  5023. }
  5024. }
  5025. catch (Exception ex)
  5026. {
  5027. ProgressState = false;
  5028. string str = ex.StackTrace;
  5029. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5030. }
  5031. #endregion 进站
  5032. #region 出站
  5033. try
  5034. {
  5035. if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
  5036. {
  5037. ProgressState = false;
  5038. Task.Run(() => S9出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
  5039. }
  5040. }
  5041. catch (Exception ex)
  5042. {
  5043. string str = ex.StackTrace;
  5044. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5045. }
  5046. #endregion 进站
  5047. UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  5048. stopwatch1.Stop();
  5049. OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
  5050. }
  5051. else
  5052. {
  5053. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  5054. AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
  5055. Funs[plcNo].Connect(); // 重连
  5056. }
  5057. }
  5058. catch (Exception ex)
  5059. {
  5060. UpdatePLCMonitor(1, plcNo, 0); // 更新PLC状态的UI
  5061. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
  5062. }
  5063. Thread.Sleep(IntervalReadPLC);
  5064. }
  5065. }
  5066. /// <summary>
  5067. /// [S9] 下料设备 - 进站
  5068. /// </summary>
  5069. /// <param name="plcNo">PLC编号</param>
  5070. /// <param name="stationNameStr">工站全称</param>
  5071. /// <param name="stPLC_MesData"></param>
  5072. /// <param name="tagMesCommName"></param>
  5073. private void S9进站(int plcNo, string stationNameStr, OP90_MesData_t stPLC_MesData, string tagMesCommName, out bool ProgressState)
  5074. {
  5075. int nRet = 0;
  5076. string strRet = "";
  5077. Stopwatch stopwatch1 = new Stopwatch();
  5078. Stopwatch stopwatch2 = new Stopwatch();
  5079. ProgressState = true;
  5080. try
  5081. {
  5082. stopwatch1.Start();
  5083. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品SN(物料码)
  5084. string MachineId = GlobalContext.S9_MachineId; // 装备ID(可配置)
  5085. string StationId = GlobalContext.S9_StationId; // 工位ID(可配置)
  5086. // 产品SN(物料码)校验
  5087. List<TestItem> item = new List<TestItem>();
  5088. stopwatch2.Start();
  5089. int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
  5090. stopwatch2.Stop();
  5091. //指令执行结果 1:OK 110:失败
  5092. byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
  5093. //进站结果写入PLC
  5094. CommandFromPLC resultToPlC = new CommandFromPLC();
  5095. resultToPlC.cmd = 0;
  5096. resultToPlC.cmdParam = 0; //指令参数
  5097. resultToPlC.cmdResult = mesResultFrmWeb;
  5098. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5099. }
  5100. catch (Exception ex)
  5101. {
  5102. string str = ex.StackTrace;
  5103. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5104. CommandFromPLC resultToPlC = new CommandFromPLC();
  5105. resultToPlC.cmd = 0;
  5106. resultToPlC.cmdParam = 0; //指令参数
  5107. resultToPlC.cmdResult = 110;
  5108. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5109. }
  5110. stopwatch1.Stop();
  5111. AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
  5112. }
  5113. /// <summary>
  5114. /// [S9] 下料设备 - 出站接口
  5115. /// </summary>
  5116. private void S9出站(int plcNo, string stationNameStr, OP90_MesData_t stPLC_MesData, string tagMesCommName, string stationCode, string stationName, out bool ProgressState)
  5117. {
  5118. ProgressState = true;
  5119. Stopwatch stopwatch1 = new Stopwatch();
  5120. Stopwatch stopwatch2 = new Stopwatch();
  5121. try
  5122. {
  5123. stopwatch1.Start();
  5124. string equipmentCode = GlobalContext.LineCode + "-" + stationCode; // 设备编号
  5125. string processItem = stationName; // 测试项目
  5126. string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
  5127. string supplierCode = ""; // 供应商代码
  5128. string workorder_code = GlobalContext.WorkOrderCode; // 工单号
  5129. string batch_num = GlobalContext.BatchNumber; // 批次号
  5130. string mtltmrk = GlobalContext.Mtltmrk; // 产品型号
  5131. string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode; // 产品条码;
  5132. string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具条码;
  5133. string MachineId = GlobalContext.S9_MachineId; // 装备id(可配置) // ZS
  5134. string StationId = GlobalContext.S9_StationId; // ⼯位ID(可配置) // ZS
  5135. int a1Result = (int)stPLC_MesData.iotData.testStatus; // 产品结果
  5136. bool pass = a1Result == 1;
  5137. List<TestItem> items = new List<TestItem>();
  5138. items.Add(new TestItem()
  5139. {
  5140. Parameter_name = "载具码",
  5141. Parameter_value = CarrierBarcode,
  5142. Parameter_unit = ""
  5143. });
  5144. items.Add(new TestItem()
  5145. {
  5146. Parameter_name = "产品码",
  5147. Parameter_value = mtltmrk,
  5148. Parameter_unit = ""
  5149. });
  5150. //绑定载具和产品
  5151. ResponseMessage message = new ResponseMessage();
  5152. message = SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
  5153. if (message.result == false)
  5154. {
  5155. AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
  5156. }
  5157. //绑定PLC返回MES数据到本地
  5158. int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
  5159. , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
  5160. byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
  5161. stopwatch2.Start();
  5162. //进站结果写入PLC
  5163. CommandFromPLC resultToPlC = new CommandFromPLC();
  5164. resultToPlC.cmd = 0;
  5165. resultToPlC.cmdParam = 0; //指令参数
  5166. resultToPlC.cmdResult = mesResultFrmWeb;
  5167. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5168. stopwatch2.Stop();
  5169. WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
  5170. }
  5171. catch (Exception ex)
  5172. {
  5173. stopwatch2.Start();
  5174. CommandFromPLC resultToPlC = new CommandFromPLC();
  5175. resultToPlC.cmd = 0;
  5176. resultToPlC.cmdParam = 0; //指令参数
  5177. resultToPlC.cmdResult = 110;
  5178. WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
  5179. stopwatch2.Stop();
  5180. string str = ex.StackTrace;
  5181. AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5182. }
  5183. stopwatch1.Stop();
  5184. AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
  5185. }
  5186. #region 缓存读取到的PLC数据 与 需要写入的PLC数据
  5187. /// <summary>
  5188. /// PLC读取到的数据 -添加数据
  5189. /// </summary>
  5190. public static void SxPLCData_Add(ref Dictionary<string, object> sxPlcData, string newKey, object newValue)
  5191. {
  5192. if (sxPlcData.ContainsKey(newKey))
  5193. sxPlcData[newKey] = newValue;
  5194. else
  5195. sxPlcData.Add(newKey, newValue);
  5196. }
  5197. /// <summary>
  5198. /// PLC需要写入的数据 -添加数据
  5199. /// </summary>
  5200. public static void SxPLCWriteData_Add(ref Dictionary<string, WriteToPLC_Flag> sxPLCWriteData, string newKey, WriteToPLC_Flag newValue)
  5201. {
  5202. if (sxPLCWriteData.ContainsKey(newKey))
  5203. sxPLCWriteData[newKey] = newValue;
  5204. else
  5205. sxPLCWriteData.Add(newKey, newValue);
  5206. }
  5207. /// <summary>
  5208. /// PLC回写操作,写后清空flag
  5209. /// </summary>
  5210. /// <param name="modbusClient">modbus对象</param>
  5211. /// <param name="pLCReadDatas">读取到的数据字典</param>
  5212. /// <param name="pLCWriteDatas">需要写入的数据</param>
  5213. public static void PLCWriteData(ModbusClientHelper modbusClient, ref Dictionary<string, object> pLCReadDatas, ref Dictionary<string, WriteToPLC_Flag> pLCWriteDataDic)
  5214. {
  5215. if (pLCWriteDataDic != null && pLCWriteDataDic.Count > 0)
  5216. {
  5217. List<WriteToPLC_Flag> pLCWriteDatas = pLCWriteDataDic.Values.ToList();
  5218. for (int i = 0; i < pLCWriteDatas.Count; i++)
  5219. {
  5220. string mesFlagName = pLCWriteDatas[i].Name;
  5221. int mesFlagAdress = pLCWriteDatas[i].Adress;
  5222. short mesFlagValue = (short)pLCWriteDatas[i].Value; // short
  5223. if (mesFlagValue != 0) // 不为0则证明需要写入结果信息
  5224. {
  5225. // 先回写数据
  5226. List<WriteToPLC_Data> writeToPLCDatas = pLCWriteDatas[i].WriteToPLCDatas;
  5227. for (int j = 0; j < writeToPLCDatas.Count; j++)
  5228. {
  5229. int mesDataAdress = writeToPLCDatas[j].Adress;
  5230. PLCValueType mesDataType = writeToPLCDatas[j].ValueType;
  5231. switch (mesDataType)
  5232. {
  5233. case PLCValueType.Short:
  5234. short mesDataValueShort = (short)writeToPLCDatas[j].Value;
  5235. modbusClient.WriteMultipleRegisters<short>(mesDataAdress, mesDataValueShort);
  5236. break;
  5237. case PLCValueType.String:
  5238. string mesDataValueStr = (string)writeToPLCDatas[j].Value;
  5239. int mesDataValueStrLength = writeToPLCDatas[j].ValueTypeStrLength;
  5240. modbusClient.WriteMultipleRegisters<string>(mesDataAdress, mesDataValueStr, mesDataValueStrLength);
  5241. break;
  5242. }
  5243. }
  5244. // 再回写信号
  5245. modbusClient.WriteMultipleRegisters<short>(mesFlagAdress, mesFlagValue);
  5246. // 存储读取数据的字典
  5247. pLCReadDatas[mesFlagName] = (int)mesFlagValue;
  5248. // 存储写入数据的字典 - 清空写入值
  5249. pLCWriteDatas[i].Value = (short)0;
  5250. pLCWriteDataDic[mesFlagName] = pLCWriteDatas[i];
  5251. }
  5252. }
  5253. }
  5254. }
  5255. /// <summary>
  5256. /// 提交点检数据到MES - 取数据库中缓存的 点检数据
  5257. /// </summary>
  5258. /// <param name="no">3</param>
  5259. /// <param name="stationCode">设备编号</param>
  5260. /// <param name="stationNameStr">设备名称</param>
  5261. /// <param name="plcOrder">车间订单号</param>
  5262. private void SubmitOneCheckDataToMESByDB(int plcNo, int stationCode, string stationNameStr, string plcOrder)
  5263. {
  5264. try
  5265. {
  5266. /// [S2]FCT (2-上传点检数据;102-清空该工单该工单的所有点检项缓存)
  5267. /// [S3]值板机 (3-上传点检数据;103-清空该工单该工单的所有点检项缓存)
  5268. /// [S4]取放桁架 (4-上传点检数据;104-清空该工单该工单的所有点检项缓存)
  5269. /// [S6]CCD检测 (6-上传点检数据;106-清空该工单该工单的所有点检项缓存)
  5270. int result1 = 0;
  5271. switch (stationCode)
  5272. {
  5273. case 2:
  5274. case 3:
  5275. case 4:
  5276. case 6:
  5277. result1 = SubmitToMESByDB(stationCode.ToString(), stationNameStr, plcOrder);
  5278. break;
  5279. case 102:
  5280. result1 = ClearOneCheckDataByDB("2", stationNameStr, plcOrder);
  5281. break;
  5282. case 103:
  5283. result1 = ClearOneCheckDataByDB("3", stationNameStr, plcOrder);
  5284. break;
  5285. case 104:
  5286. result1 = ClearOneCheckDataByDB("4", stationNameStr, plcOrder);
  5287. break;
  5288. case 106:
  5289. result1 = ClearOneCheckDataByDB("6", stationNameStr, plcOrder);
  5290. break;
  5291. default:
  5292. // MES_Flag 为“6未找到正确设备编号”
  5293. //Funs[plcNo].WriteMultipleRegisters<int>(2406, 6);
  5294. AddMessage_Station(stationNameStr, LogType.Error, $"PLC通知上传点检数据到MES运行出错!未找到需要点检的正确设备编号");
  5295. return;
  5296. }
  5297. short result = result1 == 1 ? (short)1 : (short)2;
  5298. //Funs[plcNo].WriteMultipleRegisters<int>(2406, result); // MES_Flag 为4MES报错
  5299. WritePLCLog(LogType.Debug, $"PLC{plcNo}_PLC通知MES上传点检数据运行完毕!-Write" + (result == 1 ? "成功!" : "失败!"));
  5300. }
  5301. catch (Exception ex)
  5302. {
  5303. // MES_Flag 为2上位机报错
  5304. //Funs[plcNo].WriteMultipleRegisters<int>(2406, 2);
  5305. string str = ex.StackTrace;
  5306. AddMessage_Station(stationNameStr, LogType.Error, $"PLC通知上传点检数据到MES运行出错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5307. }
  5308. }
  5309. #endregion 缓存读取到的PLC数据 与 需要写入的PLC数据
  5310. #region 日志
  5311. #region 各工位定制日志(同步至PLC交互页面)
  5312. /// <summary>
  5313. /// 添加日志
  5314. /// </summary>
  5315. /// <param name="stationNameStr">工站名称</param>
  5316. /// <param name="logType">日志类型</param>
  5317. /// <param name="message">日志内容</param>
  5318. /// <param name="snNumber">产品数字SN</param>
  5319. public void AddMessage_Station(string stationNameStr, LogType logType, string message, string snNumber = "")
  5320. {
  5321. if (!(stationNameStr.Equals("获取设备报警数据与状态信息")
  5322. && (message.Contains("更新整线运行数据完毕") || message.Contains("更新整线报警数据完毕"))
  5323. ))
  5324. {
  5325. AddMessage(logType, message); // 首页展示+日志记录
  5326. }
  5327. PLCDBFormMessage plcMessage = new PLCDBFormMessage()
  5328. {
  5329. StationName = stationNameStr,
  5330. SnNumber = snNumber,
  5331. Message = message,
  5332. CreateTime = DateTime.Now
  5333. };
  5334. // PLC交互页展示
  5335. Task.Run(() =>
  5336. {
  5337. try
  5338. {
  5339. if (Form_Main.formPLCDB != null && !Form_Main.formPLCDB.IsDisposed)
  5340. {
  5341. Form_Main.formPLCDB.UpdateMessage(plcMessage);
  5342. }
  5343. }
  5344. catch { }
  5345. });
  5346. }
  5347. #endregion 各工位定制日志(同步至PLC交互页面)
  5348. /// <summary>
  5349. /// 添加日志
  5350. /// </summary>
  5351. /// <param name="logType">日志类型</param>
  5352. /// <param name="message">日志内容</param>
  5353. public void AddMessage(LogType logType, string message)
  5354. {
  5355. OnMessage(logType, message);
  5356. string date = DateTime.Now.ToString("yyyy/MM/dd");
  5357. string time = DateTime.Now.ToString("HH:mm:ss:fff");
  5358. string msgShow = time + "--> " + message + "\r\n";
  5359. this.BeginInvoke(new Action(() =>
  5360. {
  5361. systemLog.Rows.Insert(0, date, time, message);
  5362. if (systemLog.Rows.Count >= 100)
  5363. systemLog.Rows.RemoveAt(systemLog.Rows.Count - 1);
  5364. }));
  5365. }
  5366. /// <summary>
  5367. /// 添加日志-保存
  5368. /// </summary>
  5369. /// <param name="logType">日志类型</param>
  5370. /// <param name="message">日志内容</param>
  5371. private void OnMessage(LogType logType, string msg)
  5372. {
  5373. MessageEvent?.Invoke(logType, msg);
  5374. }
  5375. /// <summary>
  5376. /// 保存PLC日志
  5377. /// </summary>
  5378. /// <param name="logType"></param>
  5379. /// <param name="logValue"></param>
  5380. private void WritePLCLog(LogType logType, string logValue)
  5381. {
  5382. switch ((int)logType)
  5383. {
  5384. case 0:
  5385. _PLCLogNet.WriteDebug(logValue);
  5386. break;
  5387. case 1:
  5388. _PLCLogNet.WriteInfo(logValue);
  5389. break;
  5390. case 2:
  5391. _PLCLogNet.WriteWarn(logValue);
  5392. break;
  5393. case 3:
  5394. _PLCLogNet.WriteError(logValue);
  5395. break;
  5396. default:
  5397. _PLCLogNet.WriteFatal(logValue);
  5398. break;
  5399. }
  5400. }
  5401. #endregion 日志
  5402. #region 保存数据
  5403. /// <summary>
  5404. /// 调用进站接口并保存进站数据
  5405. /// </summary>
  5406. /// <param name="stationNameStr">工站信息</param>
  5407. /// <param name="workorder_code">工单号</param>
  5408. /// <param name="mtltmrk">型号(物料号)</param>
  5409. /// <param name="sn">产品SN</param>
  5410. /// <param name="items">进站数据</param>
  5411. /// <returns>1成功;5MES报警;6上位机报警</returns>
  5412. public int SaveStationInData(string stationNameStr, string workorder_code, string mtltmrk, string sn, List<TestItem> items,string MachineId,string StationId)
  5413. {
  5414. int result = 0;
  5415. XmMES_StationInRequest_Body inRequest_Body = new XmMES_StationInRequest_Body();
  5416. inRequest_Body.machineId = MachineId; // 装备ID(可配置)
  5417. inRequest_Body.stationId = StationId; // ⼯位ID(可配置)
  5418. inRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
  5419. inRequest_Body.clientTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
  5420. inRequest_Body.unitSn = sn; // 产品SN
  5421. inRequest_Body.userId = GlobalContext.MESUserId; // 用户ID;非必填
  5422. inRequest_Body.factoryId = GlobalContext.Factory_Code; // 工厂ID;非必填
  5423. string json_Body = JsonConvert.SerializeObject(inRequest_Body);
  5424. StationIn stationIn = new StationIn()
  5425. {
  5426. Workorder_code = workorder_code, // 车间订单号
  5427. Mtltmrk = mtltmrk, // 产品型号(物料号)
  5428. Sn = sn, // SN
  5429. StationIn_body = json_Body, // 进站接口Json数据 - Body
  5430. Parameter_values = items, // 进站数据
  5431. Write_user = inRequest_Body.userId, // 员工Id
  5432. Test_time = inRequest_Body.clientTime // 进站时间
  5433. };
  5434. // 本地数据
  5435. string sql = stationIn.ToStringInsert(0);
  5436. string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
  5437. result = ret == "成功" ? 1 : 6;
  5438. AddMessage_Station(stationNameStr, LogType.Info, string.Concat(stationNameStr, "_保存本地进站数据---" + ret));
  5439. //await Task.Delay(200);
  5440. // 上传MES
  5441. if (GlobalContext.IsSendStationIn)
  5442. {
  5443. try
  5444. {
  5445. XmMES_StationInResponse response = new XmMES_StationInResponse();
  5446. string mesRet = string.Empty;
  5447. int i = 0;
  5448. while (i < 2) // 1009会多次尝试上传
  5449. {
  5450. response = XiaomiMESHttp_StationInbound.StationIn(inRequest_Body);
  5451. if (response != null && response.header.code == "200")
  5452. break;
  5453. else if (!mesRet.Contains("1009")) // 1009是未知错误
  5454. i++;
  5455. i++;
  5456. mesRet = $"[{response?.header?.code}]{response?.header?.desc}";
  5457. // 记录失败原因
  5458. OnMessage(LogType.Error, "上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:" + mesRet + "参数:" + json_Body);
  5459. }
  5460. AddMessage_Station(stationNameStr, LogType.Info, stationNameStr + "_上传进站数据到MES服务器---" + mesRet);
  5461. if (response?.header?.code == "200")
  5462. {
  5463. string sql_Upd = stationIn.ToStringUpdateStatusByID(1);
  5464. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  5465. result = ret_Upd == "成功" ? 1 : 6;
  5466. AddMessage_Station(stationNameStr, LogType.Info, $"更新【进站数据 id {stationIn.GUID}】上传状态---" + ret_Upd);
  5467. }
  5468. else
  5469. {
  5470. result = 5;
  5471. OnMessage(LogType.Error, "上传进站数据到MES服务器---失败!接口报错信息:" + mesRet + "参数:" + json_Body);
  5472. }
  5473. }
  5474. catch (Exception ex)
  5475. {
  5476. result = 6;
  5477. string str = ex.StackTrace;
  5478. AddMessage_Station(stationNameStr, LogType.Error, $"PLC上传进站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5479. }
  5480. }
  5481. return result;
  5482. }
  5483. /// <summary>
  5484. /// 选择如何记录出站数据
  5485. /// </summary>
  5486. /// <param name="items">出站数据</param>
  5487. /// <param name="equipmentCode">设备编号</param>
  5488. /// <param name="processItem">测试项目</param>
  5489. /// <param name="workorder_code">车间订单号</param>
  5490. /// <param name="batch_num">批次号</param>
  5491. /// <param name="mtltmrk">型号</param>
  5492. /// <param name="proDate">日期</param>
  5493. /// <param name="supplierCode">供应商代码</param>
  5494. /// <param name="sn_Number">产品序列号的 数字序列部分</param>
  5495. /// <returns>上传成功时返回1;失败返回0</returns>
  5496. private int SwitctProcessData(string stationNameStr, List<TestItem> items, string equipmentCode, string processItem,
  5497. string workorder_code, string batch_num, string mtltmrk, string proDate,
  5498. string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string MachineId, string StationId)
  5499. {
  5500. return SaveProcessDataByDB(stationNameStr, items, equipmentCode, processItem, workorder_code, batch_num, mtltmrk,
  5501. proDate, supplierCode, sn, pass, vehicleSn, vehicleSlot, MachineId, StationId);
  5502. }
  5503. /// <summary>
  5504. /// 添加出站数据(提交到MES+本地保存到数据库)
  5505. /// </summary>
  5506. /// <param name="items">出站数据</param>
  5507. /// <param name="equipmentCode">设备编号</param>
  5508. /// <param name="processItem">测试项目</param>
  5509. /// <param name="workorder_code">车间订单号</param>
  5510. /// <param name="batch_num">批次号</param>
  5511. /// <param name="mtltmrk">型号</param>
  5512. /// <param name="proDate">日期</param>
  5513. /// <param name="supplierCode">供应商代码</param>
  5514. /// <param name="sn_Number">产品序列号的 数字序列部分</param>
  5515. /// <returns>上传成功时返回1;失败返回0</returns>
  5516. public int SaveProcessDataByDB(string stationNameStr, List<TestItem> items, string equipmentCode,
  5517. string processItem, string workorder_code, string batch_num, string mtltmrk,
  5518. string proDate, string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot,string machineId,string stationId)
  5519. {
  5520. int upload = 0;
  5521. int result = 0;
  5522. ProcessData processData = new ProcessData()
  5523. {
  5524. Equipment_code = equipmentCode,
  5525. Workorder_code = workorder_code,
  5526. Batch_number = batch_num,
  5527. Sn = sn, // SN
  5528. Testitem = processItem,
  5529. Parameter_values = items,
  5530. Write_user = GlobalContext.CurrentUser,
  5531. Test_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
  5532. };
  5533. // 本地数据
  5534. string sql = processData.ToStringInsert(upload);
  5535. string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
  5536. AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地出站数据---" + ret));
  5537. // 上传MES
  5538. if (GlobalContext.IsSendProcessData)
  5539. {
  5540. try
  5541. {
  5542. string id = processData.ID.Copy();
  5543. XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
  5544. outRequest_Body.machineId = machineId; // 装备id(可配置) // ZS
  5545. outRequest_Body.stationId = stationId; // ⼯位ID(可配置) // ZS
  5546. outRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
  5547. outRequest_Body.clientTime = processData.Test_time; // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
  5548. outRequest_Body.unitSn = sn; // 产品SN
  5549. outRequest_Body.state = pass ? "PASS" : "FAIL"; // 出站条件 PASS或FAIL
  5550. outRequest_Body.userId = GlobalContext.MESUserId; // ⽤⼾ID;非必填
  5551. outRequest_Body.factoryId = GlobalContext.Factory_Code; // ⼯⼚id;非必填
  5552. outRequest_Body.unitData.vehicleData.Add(
  5553. new XmMES_StationOutRequest_Body.XmStationOut_VehicleData()
  5554. {
  5555. vehicleSn = vehicleSn,
  5556. vehicleType = string.Empty,
  5557. slot = vehicleSlot
  5558. }); // 设备数据 - 载具信息
  5559. string jsonstr1 = JsonConvert.SerializeObject(outRequest_Body);
  5560. if (GlobalContext.IsSendProcessData)
  5561. {
  5562. XmMES_StationOutResponse response = new XmMES_StationOutResponse();
  5563. string mesRet = string.Empty;
  5564. int i = 0;
  5565. while (i < 2) // 1009会多次尝试上传
  5566. {
  5567. response = XiaomiMESHttp_StationOutbound.StationOut(outRequest_Body);
  5568. if (response != null && response.header.code == "200")
  5569. break;
  5570. else if (!mesRet.Contains("1009")) // 1009是未知错误
  5571. i++;
  5572. i++;
  5573. mesRet = $"[{response?.header?.code}]{response?.header?.desc}";
  5574. // 记录失败原因
  5575. OnMessage(LogType.Error, "上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:" + mesRet + "参数:" + jsonstr1);
  5576. }
  5577. AddMessage_Station(stationNameStr, LogType.Info, "[" + processItem + "]上传出站数据到MES服务器---" + mesRet);
  5578. if (response?.header?.code == "200")
  5579. {
  5580. string sql_Upd = ProcessData.ToStringUpdateStatusByID(1, id);
  5581. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  5582. result = 1;
  5583. AddMessage_Station(stationNameStr, LogType.Info, $"更新【出站数据 id {id}】上传状态---" + ret_Upd);
  5584. }
  5585. else
  5586. {
  5587. OnMessage(LogType.Error, "上传出站数据到MES服务器---失败!接口报错信息:" + mesRet + "参数:" + jsonstr1);
  5588. }
  5589. }
  5590. }
  5591. catch (Exception ex)
  5592. {
  5593. string str = ex.StackTrace;
  5594. AddMessage_Station(stationNameStr, LogType.Error, $"PLC上传出站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5595. }
  5596. }
  5597. return result;
  5598. }
  5599. /// <summary>
  5600. /// 选择如何记录点检数据
  5601. /// </summary>
  5602. /// <param name="names"></param>
  5603. /// <param name="contents"></param>
  5604. /// <param name="results"></param>
  5605. /// <param name="equipmentCode"></param>
  5606. /// <param name="stationNameStr"></param>
  5607. private int SwitctOneCheckData(OneCheckData oneCheckData, string equipmentCode, string stationNameStr)
  5608. {
  5609. //if (DataSwitch == 1)
  5610. //{
  5611. return SaveOneCheckDataByDB(oneCheckData, equipmentCode, stationNameStr);
  5612. //}
  5613. //else // 废弃
  5614. //{
  5615. // SaveOneCheckData(names, contents, results, equipmentCode, stationNameStr);
  5616. //}
  5617. }
  5618. /// <summary>
  5619. /// 添加点检数据ByDB(本地保存;不提交到MES)
  5620. /// </summary>
  5621. /// <param name="oneCheckData">点检数据</param>
  5622. /// <param name="equipmentCode">设备编号</param>
  5623. /// <param name="stationNameStr">工站名称</param>
  5624. public int SaveOneCheckDataByDB(OneCheckData oneCheckData, string equipmentCode, string stationNameStr)
  5625. {
  5626. int upload = 0;
  5627. //本地数据保存
  5628. string sql = oneCheckData.ToStringInsert(upload);
  5629. string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
  5630. AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地点检数据---", ret));
  5631. //Task.Run(() => // 上传mes-异步
  5632. //{
  5633. // //上传mes
  5634. // string jsonstr = JsonConvert.SerializeObject(oneCheckData);
  5635. // if (GlobalContext.IsSendCheckOneData)
  5636. // {
  5637. // string url = @"HTTP://" + GlobalContext.ServerHost + ":" + GlobalContext.ServerPort + @"/api/ProductionLine/OneCheckData";
  5638. // string mesRet = HttpUitls.SubmitDataToMES(url, jsonstr);
  5639. // AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]上传点检数据到MES---", mesRet));
  5640. // if (mesRet == "成功")
  5641. // {
  5642. // // 更新上传状态
  5643. // string sql_Upd = OneCheckData.ToStringUpdateStatusByID(1, oneCheckData.ID);
  5644. // string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  5645. // AddMessage_Station(stationNameStr, LogType.Info, $"更新【点检数据 id {oneCheckData.ID}】上传状态---" + ret_Upd);
  5646. // }
  5647. // }
  5648. //});
  5649. return ret == "成功" ? 1 : 0;
  5650. }
  5651. /// <summary>
  5652. /// 提交点检数据到MES
  5653. /// </summary>
  5654. /// <param name="procedure_code">工序编号 = 设备编号</param>
  5655. /// <param name="plcOrder">车间订单号</param>
  5656. /// <returns></returns>
  5657. public int SubmitToMESByDB(string procedure_code, string stationNameStr, string plcOrder)
  5658. {
  5659. // 获取今天的点检数据
  5660. string querySQL_Today = new OneCheckData().ToQuerySQL_Today(procedure_code, plcOrder);
  5661. DataSet ds = SQLHelper_New.Query(querySQL_Today, null);
  5662. if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
  5663. {
  5664. // 拼接所有点检数据
  5665. OneCheckData oneCheckDatas_MES = new OneCheckData()
  5666. {
  5667. ID = ds.Tables[0].Rows[0][0].ToString(),
  5668. Line_code = ds.Tables[0].Rows[0][1].ToString(),
  5669. Line_name = ds.Tables[0].Rows[0][2].ToString(),
  5670. Equipment_code = ds.Tables[0].Rows[0][3].ToString(),
  5671. Equipment_name = ds.Tables[0].Rows[0][4].ToString(),
  5672. Workorder_code = ds.Tables[0].Rows[0][5].ToString(),
  5673. Procedure_code = ds.Tables[0].Rows[0][6].ToString(),
  5674. Procedure_name = ds.Tables[0].Rows[0][7].ToString(),
  5675. Onecheck_empcode = ds.Tables[0].Rows[0][8].ToString(),
  5676. Onecheck_empname = ds.Tables[0].Rows[0][9].ToString(),
  5677. Onecheck_time = ds.Tables[0].Rows[0][10].ToString()
  5678. };
  5679. List<string> upd_Ids = new List<string>();
  5680. foreach (DataRow row in ds.Tables[0].Rows)
  5681. {
  5682. var obj1 = row["Oneckeck_values"];
  5683. if (obj1 != null)
  5684. {
  5685. upd_Ids.Add(row["ID"].ToString());
  5686. List<OneCheckItem> item = JsonConvert.DeserializeObject<List<OneCheckItem>>(obj1.ToString());
  5687. oneCheckDatas_MES.Oneckeck_values.AddRange(item);
  5688. }
  5689. }
  5690. //上传mes
  5691. string jsonstr = JsonConvert.SerializeObject(oneCheckDatas_MES);
  5692. if (GlobalContext.IsSendCheckOneData)
  5693. {
  5694. string url = @"HTTP://" + GlobalContext.ServerHost + ":" + @"/api/ProductionLine/OneCheckData";
  5695. string mesRet = HttpUitls.SubmitDataToMES(url, jsonstr);
  5696. AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[", stationNameStr, "]PLC通知上传点检数据到MES到---", mesRet));
  5697. if (mesRet == "成功")
  5698. {
  5699. // 更新上传状态
  5700. string sql_Upd = OneCheckData.ToStringUpdateStatusByIDs(1, upd_Ids);
  5701. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  5702. AddMessage_Station(stationNameStr, LogType.Info, $"更新【点检数据 id [{string.Join("','", upd_Ids)}]】上传状态---" + ret_Upd);
  5703. // 保存最新一条点检数据 到文件中
  5704. StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, "S" + procedure_code, "WorkOrderCode", GlobalContext.WorkOrderCode);
  5705. StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, "S" + procedure_code, "Oneckeck_values", JsonConvert.SerializeObject(oneCheckDatas_MES.Oneckeck_values));
  5706. return ret_Upd == "成功" ? 1 : 0;
  5707. }
  5708. }
  5709. }
  5710. //else
  5711. //{
  5712. // AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[", stationNameStr, "]PLC通知上传点检数据到MES---失败!今天还未点检。"));
  5713. //}
  5714. return 0;
  5715. }
  5716. /// <summary>
  5717. /// 添加点检数据ByDB(本地保存 + 提交到MES)
  5718. /// </summary>
  5719. /// <param name="oneCheckData">点检数据</param>
  5720. /// <param name="equipmentCode">设备编号</param>
  5721. /// <param name="stationNameStr">工站名称</param>
  5722. /// <returns></returns>
  5723. public int SaveOneCheckDataByDBAndSubmit(OneCheckData oneCheckData, string equipmentCode, string stationNameStr)
  5724. {
  5725. int upload = 0;
  5726. //本地数据保存
  5727. string sql = oneCheckData.ToStringInsert(upload);
  5728. string ret = SQLHelper_New.ExecuteNonQuery(sql, null);
  5729. AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地点检数据---", ret));
  5730. Task.Run(() => // 上传mes-异步
  5731. {
  5732. //上传mes
  5733. string jsonstr = JsonConvert.SerializeObject(oneCheckData);
  5734. string jsonItems = JsonConvert.SerializeObject(oneCheckData.Oneckeck_values);
  5735. if (GlobalContext.IsSendCheckOneData)
  5736. {
  5737. string url = @"HTTP://" + GlobalContext.ServerHost + ":" + @"/api/ProductionLine/OneCheckData";
  5738. string mesRet = HttpUitls.SubmitDataToMES(url, jsonstr);
  5739. AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]上传点检数据到MES---", mesRet));
  5740. if (mesRet == "成功")
  5741. {
  5742. // 更新上传状态
  5743. string sql_Upd = OneCheckData.ToStringUpdateStatusByID(1, oneCheckData.ID);
  5744. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null);
  5745. AddMessage_Station(stationNameStr, LogType.Info, $"更新【点检数据 id {oneCheckData.ID}】上传状态---" + ret_Upd);
  5746. // 保存最新一条点检数据 到文件中
  5747. StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, equipmentCode, "WorkOrderCode", GlobalContext.WorkOrderCode);
  5748. StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, equipmentCode, "Oneckeck_values", jsonItems);
  5749. }
  5750. }
  5751. });
  5752. return ret == "成功" ? 1 : 0;
  5753. }
  5754. /// <summary>
  5755. /// 清空 点检数据 By 工序号、订单号
  5756. /// </summary>
  5757. /// <param name="procedure_code">工序号</param>
  5758. /// <param name="stationNameStr">工站号</param>
  5759. /// <param name="plcOrder">订单号</param>
  5760. /// <returns></returns>
  5761. /// <exception cref="NotImplementedException"></exception>
  5762. private int ClearOneCheckDataByDB(string procedure_code, string stationNameStr, string plcOrder)
  5763. {
  5764. // 清空
  5765. string sql_Det = OneCheckData.ToDeteleByProcedurecodeAndPlcOrder(procedure_code, plcOrder);
  5766. string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Det, null);
  5767. AddMessage_Station(stationNameStr, LogType.Info, $"清空【工位编号{procedure_code}】【车间订单{plcOrder}】的点检项缓存 ---" + ret_Upd);
  5768. return ret_Upd == "成功" ? 1 : 2;
  5769. }
  5770. /// <summary>
  5771. /// 生产过程中,自动判断 是否 使用上次的点检数据
  5772. /// 在工单加工第一个产品时触发该方法
  5773. /// 如果工单是上次的点检工单则直接返回成功,工单不是上次的点检工单则使用上个工单的点检数据,上传点检信息
  5774. /// </summary>
  5775. /// <param name="stationNameStr"></param>
  5776. /// <param name="equipmentCode">设备编号</param>
  5777. /// <param name="accno">工序编号</param>
  5778. /// <param name="processItem">点检数据</param>
  5779. /// <returns></returns>
  5780. private int SwitctOneCheckData_First(string stationNameStr, string equipmentCode, string accno, string processItem)
  5781. {
  5782. string WorkOrderCode = StandardLibrary.IniFile.INIGetStringValue(GlobalContext.CheckOneDataPath, equipmentCode, "WorkOrderCode", string.Empty);
  5783. //如果当前工单和记录中的工单是一致,表示这个工单是需要点检的,跳过
  5784. //如果当前工单和记录中的工单是不一致,表示这个工单和上个工单是同型号的,可以使用上个工单的点检数据
  5785. if (GlobalContext.WorkOrderCode == WorkOrderCode)
  5786. {
  5787. return 1;
  5788. }
  5789. //点检数据
  5790. string Oneckeck_values = StandardLibrary.IniFile.INIGetStringValue(GlobalContext.CheckOneDataPath, equipmentCode, "Oneckeck_values", string.Empty);
  5791. List<OneCheckItem> items = new List<OneCheckItem>();
  5792. try
  5793. {
  5794. items = JsonConvert.DeserializeObject<List<OneCheckItem>>(Oneckeck_values);
  5795. }
  5796. catch (Exception ex)
  5797. {
  5798. return 0;
  5799. }
  5800. // 拼接所有点检数据
  5801. OneCheckData oneCheckDatas_MES = new OneCheckData()
  5802. {
  5803. ID = Guid.NewGuid().ToString(),
  5804. Line_code = GlobalContext.LineCode,
  5805. Line_name = GlobalContext.LineName,
  5806. Equipment_code = equipmentCode,
  5807. Equipment_name = equipmentCode,
  5808. Workorder_code = GlobalContext.WorkOrderCode,
  5809. Procedure_code = accno,
  5810. Procedure_name = processItem,
  5811. Onecheck_empcode = "",
  5812. Onecheck_empname = "",
  5813. Onecheck_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
  5814. Oneckeck_values = items
  5815. };
  5816. // 本地保存 + 提交到MES
  5817. return SaveOneCheckDataByDBAndSubmit(oneCheckDatas_MES, equipmentCode, stationNameStr);
  5818. }
  5819. /// <summary>
  5820. /// 添加报警数据ByDB(提交到MES+本地保存)
  5821. /// </summary>
  5822. /// <param name="alarmData">数据</param>
  5823. /// <param name="isUpd">更新而不是新增</param>
  5824. public void SaveAlarmDataByDB(string stationNameStr, AlarmData alarmData, bool isUpd)
  5825. {
  5826. if (isUpd)
  5827. {
  5828. string sql = alarmData.ToStringUpdate();
  5829. SQLHelper_New.ExecuteSQL(sql, null);
  5830. AddMessage_Station(stationNameStr, LogType.Info, "消除报警[" + alarmData.LineName + "-" + alarmData.AlarmDesc + "]完毕!");
  5831. }
  5832. else
  5833. {
  5834. string sql = alarmData.ToStringInsert();
  5835. SQLHelper_New.ExecuteSQL(sql, null);
  5836. AddMessage_Station(stationNameStr, LogType.Info, "发生了报警[" + alarmData.LineName + "-" + alarmData.AlarmDesc + "]!");
  5837. }
  5838. }
  5839. /// <summary>
  5840. /// 上传节拍数据
  5841. /// </summary>
  5842. /// <returns></returns>
  5843. public (short, string) SaveOEEData(int plcNo, string stationNameStr, XiaomiDeviceOEE deviceOEE, string oEEPartNo, string oEEProductSN)
  5844. {
  5845. // 上传OEE
  5846. if (GlobalContext.IsMqttStationInputBegin)
  5847. {
  5848. Task.Run(() =>
  5849. {
  5850. try
  5851. {
  5852. StationInputBeginRequest oee = new StationInputBeginRequest();
  5853. oee.action = deviceOEE.ToString(); // 节拍动作(XiaomiDeviceOEE)
  5854. oee.beat_tm = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 节拍发⽣时间
  5855. oee.action_subject = oEEPartNo; // 该动作操作的⽬标对象(SN)
  5856. oee.action_subject_parent = oEEProductSN; // ⼤板SN/载具SN
  5857. oee.action_location = "ZS"; // ZS 该动作的位置信息(⼯位、槽位),如:F06-GSTPLA11_01-SLOT-01
  5858. oee.action_material = string.Empty; // 该动作的物料信息
  5859. oee.extra = string.Empty; // 额外信息
  5860. oee.class_level_1 = string.Empty; // 分类层级1
  5861. oee.class_level_2 = string.Empty; // 分类层级2
  5862. oee.class_level_3 = string.Empty; // 分类层级3
  5863. int result = XiaomiMqttClient_Extend.Write_StationInputBegin(oee);
  5864. string msg = $"[{result}]";
  5865. bool errCodeParse = Enum.TryParse(result.ToString(), out XiaomiMqttResponse_ErrCode errCode);
  5866. msg += errCodeParse ? errCode.ToString() : "ERR_UNKOWN";
  5867. AddMessage(LogType.Info, stationNameStr + $"_异步上传节拍接口;接口结果:-- {msg}");
  5868. }
  5869. catch (Exception ex)
  5870. {
  5871. string str = ex.StackTrace;
  5872. AddMessage(LogType.Error, $"PLC{plcNo}_{stationNameStr} 异步上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
  5873. }
  5874. });
  5875. return ((short)1, "异步上传中!");
  5876. }
  5877. else
  5878. return ((short)1, "未启用上传!");
  5879. }
  5880. /// <summary>
  5881. /// 回调方法- With DataId
  5882. /// </summary>
  5883. /// <param name="id"></param>
  5884. /// <param name="v"></param>
  5885. /// <param name="dataId"></param>
  5886. public void CallbackWithDataId(string id, string msg, string dataId)
  5887. {
  5888. //_MqttLogNet.WriteInfo("-------CallbackWithDataId-------");
  5889. //byte[] buffer1 = Encoding.Default.GetBytes(v);
  5890. //byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length);
  5891. //string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length);
  5892. //Console.WriteLine("{0} -> {1} {2}", id, strBuffer, dataId);
  5893. string datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
  5894. _MqttLogNet.WriteInfo($"{datetime}-> [消息ID:{id}][事件ID:{dataId}]{msg}");
  5895. }
  5896. #endregion 保存数据
  5897. #region UI刷新
  5898. /// <summary>
  5899. /// 更新商品信息的UI + 下发产品信息(SN)
  5900. /// </summary>
  5901. private void UpdateProductInfo()
  5902. {
  5903. currentBN.Text = GlobalContext.BatchNumber; // 批次号
  5904. currentWC.Text = GlobalContext.WorkOrderCode; // 订单号
  5905. currentMtltmrk.Text = GlobalContext.Mtltmrk; // 产品型号
  5906. txt_CurSupplierCode.Text = ""; // 供应商代号
  5907. // 下传给1号机,判断下plc对象数量
  5908. //if (Funs.Count > 1)
  5909. //{
  5910. // DownLoadProductInfo(1);
  5911. //}
  5912. }
  5913. /// <summary>
  5914. /// 更新PLC连接状态的UI
  5915. /// </summary>
  5916. /// <param name="no">PLC编号</param>
  5917. /// <param name="status">状态</param>
  5918. private void UpdatePLCMonitor(int imgNo, int plcNo, int status)
  5919. {
  5920. if (this != null && !this.IsDisposed)
  5921. {
  5922. switch (imgNo)
  5923. {
  5924. case 1:
  5925. this.BeginInvoke(new Action(() =>
  5926. {
  5927. pictureBox1.Image = imageListState.Images[status];
  5928. }));
  5929. break;
  5930. case 2:
  5931. this.BeginInvoke(new Action(() =>
  5932. {
  5933. pictureBox2.Image = imageListState.Images[status];
  5934. }));
  5935. break;
  5936. case 3:
  5937. this.BeginInvoke(new Action(() =>
  5938. {
  5939. pictureBox3.Image = imageListState.Images[status];
  5940. }));
  5941. break;
  5942. case 4:
  5943. this.BeginInvoke(new Action(() =>
  5944. {
  5945. pictureBox4.Image = imageListState.Images[status];
  5946. }));
  5947. break;
  5948. case 5:
  5949. this.BeginInvoke(new Action(() =>
  5950. {
  5951. pictureBox5.Image = imageListState.Images[status];
  5952. }));
  5953. break;
  5954. case 6:
  5955. this.BeginInvoke(new Action(() =>
  5956. {
  5957. pictureBox6.Image = imageListState.Images[status];
  5958. }));
  5959. break;
  5960. case 7:
  5961. this.BeginInvoke(new Action(() =>
  5962. {
  5963. pictureBox7.Image = imageListState.Images[status];
  5964. }));
  5965. break;
  5966. case 8:
  5967. this.BeginInvoke(new Action(() =>
  5968. {
  5969. pictureBox8.Image = imageListState.Images[status];
  5970. }));
  5971. break;
  5972. case 9:
  5973. this.BeginInvoke(new Action(() =>
  5974. {
  5975. pictureBox9.Image = imageListState.Images[status];
  5976. }));
  5977. break;
  5978. default:
  5979. break;
  5980. }
  5981. }
  5982. Task.Run(() => // 更新PLC交互页的指示灯
  5983. {
  5984. try
  5985. {
  5986. if (Form_Main.formPLCDB != null && !Form_Main.formPLCDB.IsDisposed)
  5987. {
  5988. Form_Main.formPLCDB.UpdatePLCFunMonitor(plcNo, status);
  5989. }
  5990. }
  5991. catch { }
  5992. });
  5993. }
  5994. #endregion UI刷新
  5995. /// <summary>
  5996. /// 实例化报警字典
  5997. /// </summary>
  5998. private void InitalDicAlarm()
  5999. {
  6000. #region 第一个工站(这里未区分工位,所以下面出现的‘工位代码’使用‘线别代码’代替)
  6001. List<Alarm> keyValues1 = new List<Alarm>
  6002. {
  6003. #region 第一组报警(电机)
  6004. new Alarm { 报警类型 = "电机故障", 报警详情 = "料盘搬运_Y轴电机故障" ,关联的PLC地址 = 5100 },
  6005. new Alarm { 报警类型 = "电机故障", 报警详情 = "壳体取料_X轴电机故障" ,关联的PLC地址 = 5101 },
  6006. new Alarm { 报警类型 = "电机故障", 报警详情 = "壳体取料_Z轴电机故障" ,关联的PLC地址 = 5102 },
  6007. new Alarm { 报警类型 = "电机故障", 报警详情 = "载具搬运_X轴电机故障" ,关联的PLC地址 = 5103 },
  6008. new Alarm { 报警类型 = "电机故障", 报警详情 = "镭射_X轴电机故障" ,关联的PLC地址 = 5104 },
  6009. new Alarm { 报警类型 = "电机故障", 报警详情 = "上相机_X轴电机故障" ,关联的PLC地址 = 5105 },
  6010. new Alarm { 报警类型 = "电机故障", 报警详情 = "上相机_Z轴电机故障" ,关联的PLC地址 = 5106 },
  6011. new Alarm { 报警类型 = "电机故障", 报警详情 = "下相机_X轴电机故障" ,关联的PLC地址 = 5107 },
  6012. new Alarm { 报警类型 = "电机故障", 报警详情 = "下料_Y轴电机故障" ,关联的PLC地址 = 5108 },
  6013. new Alarm { 报警类型 = "电机故障", 报警详情 = "下料_X轴电机故障" ,关联的PLC地址 = 5109 },
  6014. #endregion 第一组报警(电机)
  6015. #region 第二组报警(气缸)
  6016. new Alarm { 报警类型 = "气缸故障", 报警详情 = "上料仓分料进退气缸故障" ,关联的PLC地址 = 5200 },
  6017. new Alarm { 报警类型 = "气缸故障", 报警详情 = "上料仓分料升降气缸故障" ,关联的PLC地址 = 5201 },
  6018. new Alarm { 报警类型 = "气缸故障", 报警详情 = "上料仓顶升气缸故障" ,关联的PLC地址 = 5202 },
  6019. new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体取料夹爪气缸故障" ,关联的PLC地址 = 5203 },
  6020. new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料仓顶升气缸故障" ,关联的PLC地址 = 5204 },
  6021. new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料平移气缸故障" ,关联的PLC地址 = 5205 },
  6022. new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料升降气缸故障" ,关联的PLC地址 = 5206 },
  6023. new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料夹爪气缸故障" ,关联的PLC地址 = 5207 },
  6024. new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料旋转气缸故障" ,关联的PLC地址 = 5208 },
  6025. new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装平移气缸故障" ,关联的PLC地址 = 5209 },
  6026. new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装升降气缸故障" ,关联的PLC地址 = 5210 },
  6027. new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装夹爪气缸故障" ,关联的PLC地址 = 5211 },
  6028. new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装撑开气缸故障" ,关联的PLC地址 = 5212 },
  6029. new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具定位气缸1故障" ,关联的PLC地址 = 5213 },
  6030. new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具定位气缸2故障" ,关联的PLC地址 = 5214 },
  6031. new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具下料移载气缸故障" ,关联的PLC地址 = 5215 },
  6032. new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具侧推气缸故障" ,关联的PLC地址 = 5216 },
  6033. new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具回流气缸故障" ,关联的PLC地址 = 5217 },
  6034. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位2压料气缸故障" ,关联的PLC地址 = 5218 },
  6035. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位2电测气缸故障" ,关联的PLC地址 = 5219 },
  6036. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位2气密气缸故障" ,关联的PLC地址 = 5220 },
  6037. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位3下压气缸故障" ,关联的PLC地址 = 5221 },
  6038. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位3上顶气缸故障" ,关联的PLC地址 = 5222 },
  6039. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位5相机升降气缸故障" ,关联的PLC地址 = 5223 },
  6040. new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料模组升降气缸故障" ,关联的PLC地址 = 5224 },
  6041. new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料模组夹爪气缸1故障" ,关联的PLC地址 = 5225 },
  6042. new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料模组夹爪气缸2故障" ,关联的PLC地址 = 5226 },
  6043. new Alarm { 报警类型 = "气缸故障", 报警详情 = "机械手夹爪气缸故障" ,关联的PLC地址 = 5227 },
  6044. new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位4:镭射压料气缸故障" ,关联的PLC地址 = 5228 },
  6045. #endregion 第二组报警(气缸)
  6046. #region 第三组报警(其他故障)
  6047. new Alarm { 报警类型 = "其他故障", 报警详情 = "上料处缺料报警" ,关联的PLC地址 = 5300 },
  6048. new Alarm { 报警类型 = "其他故障", 报警详情 = "震盘缺料报警" ,关联的PLC地址 = 5301 },
  6049. new Alarm { 报警类型 = "其他故障", 报警详情 = "成品仓料满报警" ,关联的PLC地址 = 5302 },
  6050. new Alarm { 报警类型 = "其他故障", 报警详情 = "检测拍照超时报警" ,关联的PLC地址 = 5303 },
  6051. new Alarm { 报警类型 = "其他故障", 报警详情 = "检测拍照NG报警" ,关联的PLC地址 = 5304 },
  6052. new Alarm { 报警类型 = "其他故障", 报警详情 = "玻璃门打开报警" ,关联的PLC地址 = 5305 },
  6053. #endregion 第三组报警(其他故障)
  6054. };
  6055. DicAlarms_Cur.Add(GlobalContext.LineCode, keyValues1); // 这里使用线体代替工位
  6056. #endregion 第一个工站(这里使用线体代替工位)
  6057. # region 第二个工站-原来的写法(废弃)
  6058. //keyValues = new Dictionary<int, AlarmData[]>();
  6059. ////1
  6060. //dicAlarmName = new Dictionary<int, Alarm>();
  6061. //dicAlarmName.Add(0, new Alarm { Name = "M01衬套组模组X电机报警" });
  6062. //dicAlarmName.Add(1, new Alarm { Name = "M02衬套组模组Y电机报警" });
  6063. //dicAlarmName.Add(2, new Alarm { Name = "M03衬套组模组Z电机报警" });
  6064. //dicAlarmName.Add(3, new Alarm { Name = "M04衬套组模组U电机报警" });
  6065. //dicAlarmName.Add(4, new Alarm { Name = "M05外流线皮带电机报警" });
  6066. //alarmDatas = new AlarmData[dicAlarmName.Count];
  6067. //for (int i = 0; i < dicAlarmName.Count; i++)
  6068. //{
  6069. // alarmDatas[i] = new AlarmData();
  6070. // alarmDatas[i].Equipment_code = GlobalContext.LineCode + "-2";
  6071. // alarmDatas[i].AlarmDesc = dicAlarmName[i].Name;
  6072. // alarmDatas[i].AlarmName = dicAlarmName[i].Name;
  6073. // alarmDatas[i].AlarmType = 1;
  6074. //}
  6075. //keyValues.Add(1, alarmDatas);
  6076. ////2
  6077. //dicAlarmName = new Dictionary<int, Alarm>();
  6078. //dicAlarmName.Add(0, new Alarm { Name = "C01定位气缸故障" });
  6079. //dicAlarmName.Add(1, new Alarm { Name = "C02左推料气缸故障" });
  6080. //dicAlarmName.Add(2, new Alarm { Name = "C03右推料气缸故障" });
  6081. //dicAlarmName.Add(3, new Alarm { Name = "C04左压料气缸故障" });
  6082. //dicAlarmName.Add(4, new Alarm { Name = "C05右压料气缸故障" });
  6083. //dicAlarmName.Add(5, new Alarm { Name = "C06切料气缸故障" });
  6084. //dicAlarmName.Add(6, new Alarm { Name = "C07左入料吹气气缸故障" });
  6085. //dicAlarmName.Add(7, new Alarm { Name = "C08右入料吹气气缸故障" });
  6086. //alarmDatas = new AlarmData[dicAlarmName.Count];
  6087. //for (int i = 0; i < dicAlarmName.Count; i++)
  6088. //{
  6089. // alarmDatas[i] = new AlarmData();
  6090. // alarmDatas[i].Equipment_code = GlobalContext.LineCode + "-2";
  6091. // alarmDatas[i].AlarmDesc = dicAlarmName[i].Name;
  6092. // alarmDatas[i].AlarmName = dicAlarmName[i].Name;
  6093. // alarmDatas[i].AlarmType = 2;
  6094. //}
  6095. //keyValues.Add(2, alarmDatas);
  6096. ////3
  6097. //dicAlarmName = new Dictionary<int, Alarm>();
  6098. //dicAlarmName.Add(0, new Alarm { Name = "安全门报警" });
  6099. //dicAlarmName.Add(1, new Alarm { Name = "联机通信故障" });
  6100. //dicAlarmName.Add(2, new Alarm { Name = "连续NG报警" });
  6101. //dicAlarmName.Add(3, new Alarm { Name = "合格率低于设定值报警" });
  6102. //alarmDatas = new AlarmData[dicAlarmName.Count];
  6103. //for (int i = 0; i < dicAlarmName.Count; i++)
  6104. //{
  6105. // alarmDatas[i] = new AlarmData();
  6106. // alarmDatas[i].Equipment_code = GlobalContext.LineCode + "-3";
  6107. // alarmDatas[i].AlarmDesc = dicAlarmName[i].Name;
  6108. // alarmDatas[i].AlarmName = dicAlarmName[i].Name;
  6109. // alarmDatas[i].AlarmType = 3;
  6110. //}
  6111. //keyValues.Add(3, alarmDatas);
  6112. //DicAlarms.Add(2, keyValues);
  6113. #endregion 第二个工站-原来的写法(废弃)
  6114. }
  6115. private void groupBox3_Enter(object sender, EventArgs e)
  6116. {
  6117. }
  6118. }
  6119. }