| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076 |
- using Cognex.VisionPro;
- using Cognex.VisionPro.ToolBlock;
- using CSScripting;
- using NPOI.OpenXml4Net.OPC.Internal;
- using NPOI.OpenXmlFormats.Dml.Diagram;
- using NPOI.SS.Formula.Eval;
- using NPOI.SS.Formula.Functions;
- using NPOI.Util;
- using Org.BouncyCastle.Ocsp;
- //using ICSharpCode.SharpZipLib.Zip;
- using Prism.Events;
- using Prism.Ioc;
- using Prism.Mvvm;
- using Prism.Regions;
- using SqlSugar;
- using SqlSugar.SplitTableExtensions;
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Drawing;
- using System.IO;
- using System.IO.Compression;
- using System.IO.MemoryMappedFiles;
- using System.Linq;
- using System.Text;
- using System.Text.Json;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Web.UI.WebControls;
- using System.Windows.Media;
- using Team.FFFeederService.Interfaces;
- using TeamAAS_VP.Controls;
- using TeamAAS_VP.Core.PLCs;
- using TeamAAS_VP.Core.ScrewDriver;
- using TeamAAS_VP.Enums;
- using TeamAAS_VP.Events;
- using TeamAAS_VP.Interfaces;
- using TeamAAS_VP.Models;
- using TeamAAS_VP.Resources.Languages;
- using TeamAAS_VP.ViewModels;
- using TeamAAS_VP.ViewModels.Home;
- using TouchSocket.Core;
- using TouchSocket.SerialPorts;
- using TouchSocket.Sockets;
- using System.IO.MemoryMappedFiles;
- namespace TeamAAS_VP.Core
- {
- public class Management : BindableBase
- {
- #region 字段
- IRegionManager _regionManager;
- IEventAggregator _eventAggregator;
- IContainerProvider _container;
- IConfigService _configService;
- IRobotService _robotService;
- IScannerService _scannerService;
- ICameraService _cameraService;
- IFeederService _feederService;
- IPlcService _plcService;
- ILightManagerService _lightManagerService;
- IProductService _productService;
- ICalibrationService _calibrationService;
- IRemoteCommandService _remoteCommandService;
- ISystemDatabaseService _systemDatabaseService;
- IMesService _mesService;
- Timer yieldtimer;
- private DateTime StartTime = DateTime.Now;
- /// <summary>
- /// 产品主sn
- /// </summary>
- string ProductMainSN = "";
- //string[] ProductMainSN1 { get; set; } = new string[10];
- /// <summary>
- /// 工单信息
- /// </summary>
- string[] wo = new string[10];
- string[] model_num = new string[10];//产品model_num
- string[] color = new string[10];//产品color
- string[] ppid = new string[10];//产品ppid
- string[] revision = new string[10];//产品revision
- string[] stage = new string[10];//产品revision
- string[] kb_sn = new string[10];//产品kb_sn
- string[] kb_pn = new string[10];
- /// <summary>
- /// 上次执行上传csv的日期
- /// </summary>
- private DateTime _lastCompressDate = DateTime.MinValue;
- /// <summary>
- /// 当天是否上传过csv
- /// </summary>
- private bool _hasCompressedToday = false;
- #endregion
- #region 属性
- private Guid _defaultScannerId = Guid.Empty;
- private volatile TaskCompletionSource<string> _scanTcs; // 最简单:只支持单通道“当前一次扫
- public string[] CsvData = new string[50];
- public int[] ResultData = new int[200];
- public string code = "";
- ConcurrentBag<LockResult> lockResultsAll = new ConcurrentBag<LockResult>();//一个产品的总结果
- CountdownEvent countdown = new CountdownEvent(10);
- ConcurrentBag<bool> AllResult = new ConcurrentBag<bool>();
- private ObservableCollection<ShowRender> _Renders;
- private double _CTtime;
- public int ResultDataCount;
- public string PhotoPath = "";
- // 扫码结果
- private string ScanValue = "";
- // 扫码完成事件
- private readonly ManualResetEventSlim _scanDoneEvent = new ManualResetEventSlim(false);
- //键盘数据
- public ConcurrentDictionary<string, double> keyData = new ConcurrentDictionary<string, double> { };
- //键盘单独数据
- public ConcurrentDictionary<string, double> keyData1 = new ConcurrentDictionary<string, double> { };
- public int completed = 0;
- //键盘差值
- public bool isValueOk;
- private SerialPortClient _Scan_Client;
- public SerialPortClient Scan_Client
- {
- get { return _Scan_Client; }
- set { _Scan_Client = value; }
- }
- private bool _ShowMes_Query;
- /// <summary>
- /// 显示查询结果
- /// </summary>
- public bool ShowMes_Query
- {
- get { return _ShowMes_Query; }
- set { SetProperty(ref _ShowMes_Query, value); }
- }
- private bool _ShowMes_Result = false;
- /// <summary>
- /// 显示上传结果
- /// </summary>
- public bool ShowMes_Result
- {
- get { return _ShowMes_Result; }
- set { SetProperty(ref _ShowMes_Result, value); }
- }
- /// <summary>
- /// ct
- /// </summary>
- public double CTtime
- {
- get { return _CTtime; }
- set { SetProperty(ref _CTtime, value); }
- }
- private double _CTtime2;
- /// <summary>
- /// ct2
- /// </summary>
- public double CTtime2
- {
- get { return _CTtime2; }
- set { SetProperty(ref _CTtime2, value); }
- }
- /// <summary>
- /// 显示界面
- /// </summary>
- public ObservableCollection<ShowRender> Renders
- {
- get { return _Renders; }
- set { SetProperty(ref _Renders, value); }
- }
- private ProductModel _CurrentProduct;
- /// <summary>
- /// 当前产品
- /// </summary>
- public ProductModel CurrentProduct
- {
- get { return _CurrentProduct; }
- set { SetProperty(ref _CurrentProduct, value); }
- }
- public BgCommunicate BgCommunicate { get; private set; }
- public BgModbusTcpCommunicate BgModbusTcpCommunicate { get; private set; }
- private ObservableCollection<StatusInfo> _Status = new ObservableCollection<StatusInfo>();
- /// <summary>
- /// 状态栏集合
- /// </summary>
- public ObservableCollection<StatusInfo> Status
- {
- get { return _Status; }
- set { SetProperty(ref _Status, value); }
- }
- private Int64 _TotalQuantity;
- /// <summary>
- /// 总产量
- /// </summary>
- public Int64 TotalQuantity
- {
- get { return _TotalQuantity; }
- set { SetProperty(ref _TotalQuantity, value); }
- }
- private Int64 _TotalQuantityToday;
- /// <summary>
- /// 当天的总产量
- /// </summary>
- public Int64 TotalQuantityToday
- {
- get { return _TotalQuantityToday; }
- set { SetProperty(ref _TotalQuantityToday, value); }
- }
- private Int64 _CurrentUPH;
- /// <summary>
- /// 当前的UPH
- /// </summary>
- public Int64 CurrentUPH
- {
- get { return _CurrentUPH; }
- set { SetProperty(ref _CurrentUPH, value); }
- }
- private XYD_ScrewDriver _ScrewDriver;
- public XYD_ScrewDriver ScrewDriver
- {
- get { return _ScrewDriver; }
- set { SetProperty(ref _ScrewDriver, value); }
- }
- public Dictionary<string, object> BackupObject { get; set; } = new Dictionary<string, object>();
- private ObservableCollection<ProductModel> _ProductList;
- public ObservableCollection<ProductModel> ProductList
- {
- get { return _ProductList; }
- set { SetProperty(ref _ProductList, value); }
- }
- /// <summary>
- /// 设备状态
- /// </summary>
- private RunDisplayMode _CurrentDisplayMode;
- public RunDisplayMode CurrentDisplayMode
- {
- get { return _CurrentDisplayMode; }
- set { SetProperty(ref _CurrentDisplayMode, value); }
- }
- private string _finalResultStatus = "Pending";
- private string _finalResultText = "";
- public string FinalResultStatus
- {
- get { return _finalResultStatus; }
- set { SetProperty(ref _finalResultStatus, value); }
- }
- public string FinalResultText
- {
- get { return _finalResultText; }
- set { SetProperty(ref _finalResultText, value); }
- }
- #endregion
- #region 命令
- #endregion
- #region 事件
- #endregion
- public Management(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IConfigService configService,
- IRobotService robotService, ICameraService cameraService, IFeederService feederService, IPlcService plcService, IProductService productService,
- ICalibrationService calibrationService, IRemoteCommandService remoteCommandService, ISystemDatabaseService systemDatabaseService, ILightManagerService lightManagerService, IMesService mesService, IScannerService scannerService)
- {
- _regionManager = regionManager;
- _eventAggregator = ea;
- _container = container;
- _configService = configService;
- _robotService = robotService;
- _scannerService = scannerService;
- _cameraService = cameraService;
- _feederService = feederService;
- _plcService = plcService;
- _calibrationService = calibrationService;
- yieldtimer = new Timer(DoYieldTime, null, 10000, 1000);
- Renders = new ObservableCollection<ShowRender>();
- _configService = configService;
- _productService = productService;
- _remoteCommandService = remoteCommandService;
- _systemDatabaseService = systemDatabaseService;
- _lightManagerService = lightManagerService;
- _mesService = mesService;
- _eventAggregator.GetEvent<CurrentStatusNotification>().Subscribe(CurrentRunStatus);
- }
- #region 初始化硬件模块
- /// <summary>
- /// 初始化Feeder
- /// </summary>
- /// <returns></returns>
- public async Task<(bool IsSucceed, string Msg)> InitFeeders()
- {
- var feeders = _configService.GetAllFeeders();
- StringBuilder sb = new StringBuilder();
- foreach (var item in feeders)
- {
- _feederService.CreateFeeder(item.Id, item.FeederNo, item.FeederName, item.IP, item.Port, item.FeederBrand);
- var feeder = _feederService.GetFeeder(item.Id);
- Status.Add(new StatusInfo(item.Id, item.FeederName + $"{Lang.未连接}", new SolidColorBrush(Colors.Red)));
- try
- {
- feeder.FeederConnectionStatusChanged += Management_FeederConnectionStatusChanged;
- await feeder.ConnectAsync(); //连接Feeder
- //SendTaskMessage($"{item.FeederName}已连接!", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- sb.AppendLine($"{item.FeederName}:{Lang.断开连接}![{ex.Message}]");
- SendTaskMessage($"{item.FeederName}{Lang.断开连接}!", MessageLevel.Alarm);
- }
- }
- if (sb.Length == 0)
- {
- return (true, "");
- }
- else
- {
- return (false, sb.ToString());
- }
- }
- /// <summary>
- /// 初始化机器人
- /// </summary>
- /// <returns></returns>
- public async Task<(bool IsSucceed, string Msg)> InitRobots()
- {
- var robots = _configService.GetAllRobots();
- StringBuilder sb = new StringBuilder();
- foreach (var item in robots)
- {
- _robotService.CreateRobot(item.Id, item);
- try
- {
- Status.Add(new StatusInfo(item.Id, item.RobotName + $"{Lang.未连接}", new SolidColorBrush(Colors.Red)));
- var robot = _robotService.GetRobot(item.Id);
- robot.ReceivedEvent += Management_ReceivedEvent;
- robot.SendEvent += Management_SendEvent;
- robot.ConnectedEvent += Management_ConnectedEvent;
- robot.DisconnectedEvent += Management_DisconnectedEvent;
- await robot.ConnectAsync(); //连接Robot
- SendTaskMessage($"{item.RobotName}{Lang.已连接}!", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- sb.AppendLine($"{item.RobotName}:{Lang.断开连接}![{ex.Message}]");
- SendTaskMessage($"{item.RobotName}{Lang.断开连接}!", MessageLevel.Alarm);
- }
- }
- if (sb.Length == 0)
- {
- return (true, "");
- }
- else
- {
- return (false, sb.ToString());
- }
- }
- /// <summary>
- /// 初始化扫码枪
- /// </summary>
- /// <returns></returns>
- public async Task<(bool IsSucceed, string Msg)> InitScanners()
- {
- var scanners = _configService.GetAllScanners();
- StringBuilder sb = new StringBuilder();
- foreach (var item in scanners)
- {
- _scannerService.CreateScanner(item.Id, item);
- try
- {
- Status.Add(new StatusInfo(item.Id, item.ScannerName + $"{Lang.未连接}", new SolidColorBrush(Colors.Red)));
- var scanner = _scannerService.GetScanner(item.Id);
- scanner.ReceivedEvent += Management_ScannerReceivedEvent;
- scanner.SendEvent += Management_ScannerSendEvent;
- scanner.ConnectedEvent += Management_ScannerConnectedEvent;
- scanner.DisconnectedEvent += Management_ScannerDisconnectedEvent;
- await scanner.ConnectAsync(); //连接Scanner
- SendTaskMessage($"{item.ScannerName}{Lang.已连接}!", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- sb.AppendLine($"{item.ScannerName}:{Lang.断开连接}![{ex.Message}]");
- SendTaskMessage($"{item.ScannerName}{Lang.断开连接}!", MessageLevel.Alarm);
- }
- }
- if (sb.Length == 0)
- {
- return (true, "");
- }
- else
- {
- return (false, sb.ToString());
- }
- }
- /// <summary>
- /// 初始化PLC
- /// </summary>
- /// <returns></returns>
- public async Task<(bool IsSucceed, string Msg)> InitPlc()
- {
- var plcs = _configService.GetAllPlcs();
- StringBuilder sb = new StringBuilder();
- foreach (var item in plcs)
- {
- try
- {
- _plcService.CreatePlc(item.Id, item);
- var plc = _plcService.GetPlc(item.Id);
- Status.Add(new StatusInfo(item.Id, item.Name + $"{Lang.未连接}", new SolidColorBrush(Colors.Red)));
- plc.ConnectChangedEvent += Management_PlcConnectChangedEvent;
- await plc.ConnectAsync(); //连接PLC
- //SendTaskMessage($"{item.Name}{Lang.已连接}!", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- sb.AppendLine($"{item.Name}:{Lang.断开连接}![{ex.Message}]");
- SendTaskMessage($"{item.Name}{Lang.断开连接}!", MessageLevel.Alarm);
- }
- }
- try
- {
- await WriteSystemParameterToPlcAsync(_configService.GetSystemConfiguration());
- RegisterPlcMonitorAddress();
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("为PLC写入系统参数和订阅变量时出错", ex);
- }
- if (sb.Length == 0)
- {
- return (true, "");
- }
- else
- {
- return (false, sb.ToString());
- }
- }
- /// <summary>
- /// 初始化相机
- /// </summary>
- /// <returns></returns>
- public async Task<(bool IsSucceed, string Msg)> InitCameras()
- {
- var cameras = _configService.GetAllCameras();
- StringBuilder sb = new StringBuilder();
- foreach (var item in cameras)
- {
- if (item.DisplatConfigs != null)
- {
- foreach (var item1 in item.DisplatConfigs)
- {
- Renders.Add(new ShowRender() { Id = item1.Id, DisplayName = item1.DisplayName });
- }
- }
- _cameraService.CreateCamera(item.Id, item);
- try
- {
- var camera = _cameraService.GetCamera(item.Id);
- Status.Add(new StatusInfo(item.Id, item.CameraName + $"{Lang.未连接}", new SolidColorBrush(Colors.Red)));
- camera.CameraConnectChangedEvent += Management_CameraConnectChangedEvent;
- camera.ImageCallbackEvent += Camera_ImageCallbackEvent;
- try
- {
- if (await camera.OpenDeviceAsync())
- {
- SendTaskMessage($"{item.CameraName}{Lang.已连接}!", MessageLevel.Debug);
- }
- else
- {
- SendTaskMessage($"{item.CameraName}{Lang.连接失败}!", MessageLevel.Alarm);
- sb.AppendLine($"{item.CameraName}:{Lang.连接失败}!");
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage($"{item.CameraName}{ex.Message}!", MessageLevel.Alarm);
- sb.AppendLine($"{item.CameraName}:{ex.Message}!");
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage($"{item.CameraName}{Lang.连接失败}!", MessageLevel.Alarm);
- sb.AppendLine($"{item.CameraName}:{Lang.连接失败}!:{ex.Message}");
- }
- }
- _container.Resolve<ShowVisionRenderViewModel>().Renders = Renders;
- if (sb.Length == 0)
- {
- return (true, "");
- }
- else
- {
- return (false, sb.ToString());
- }
- }
- private void Camera_ImageCallbackEvent(ICogImage arg1, TimeSpan arg2, string arg3, Guid cameraId)
- {
- var camera = _configService.GetCamera(cameraId);
- SendTaskMessage($"相机[{camera.CameraName}]图像接收完成!", MessageLevel.Info);
- //if (camera.CameraNo == 1)
- //{
- // ImageData[1] = 1;
- //}
- //else if (camera.CameraNo == 2)
- //{
- // ImageData[2] = 1;
- //}
- //else if (camera.CameraNo == 3)
- //{
- // ImageData[3] = 1;
- // ImageData[4] = 1;
- //}
- //_eventAggregator.GetEvent<RenderUpdateNotification>().Publish(new ShowRender()
- //{
- // CameraName = camera.CameraName,
- // Id = cameraId,
- // Image = arg1,
- // Graphic = null,
- // Record = null,
- // Result = false,
- // IsShow = true,
- //});
- // 通知等待方:该相机新图到达
- //SignalImageArrived(cameraId, arg1);
- }
- /// <summary>
- /// 初始化光源控制器
- /// </summary>
- /// <returns></returns>
- public async Task<(bool IsSucceed, string Msg)> InitLightControllers()
- {
- var lightcontrollers = _configService.GetAllLightControllers();
- StringBuilder sb = new StringBuilder();
- foreach (var item in lightcontrollers)
- {
- try
- {
- var lishtCtr = await _lightManagerService.RegisterControllerAsync(item.Id, item);
- //var lightcontroller = _cameraService.GetLightController(item.Id);
- //await lightcontroller.ConnectAsync(); //连接光源控制器
- //SendTaskMessage($"{item.LightControllerName}{Lang.已连接}!", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- //sb.AppendLine($"{item.LightControllerName}:{Lang.断开连接}![{ex.Message}]");
- //SendTaskMessage($"{item.LightControllerName}{Lang.断开连接}!", MessageLevel.Alarm);
- }
- }
- if (lightcontrollers.Count > 0)
- {
- var result = await _lightManagerService.ConnectAllAsync();
- if (result)
- {
- return (true, "");
- }
- else
- {
- return (false, "Light Controller Connect Failed!");
- }
- }
- return (true, "");
- //if (sb.Length == 0)
- //{
- // return (true, "");
- //}
- //else
- //{
- // return (false, sb.ToString());
- //}
- }
- /// <summary>
- /// 初始化后台TCP服务器通讯
- /// </summary>
- public void InitBgTcp()
- {
- var config = _configService.GetBgTcp();
- try
- {
- BgCommunicate = new BgCommunicate(config);
- BgCommunicate.ConnectedEvent += BgCommunicate_ConnectedEvent;
- BgCommunicate.DisconnectedEvent += BgCommunicate_DisconnectedEvent;
- BgCommunicate.ReceivedEvent += BgCommunicate_ReceivedEvent;
- BgCommunicate.SendEvent += BgCommunicate_SendEvent;
- BgCommunicate.StartListening();
- SendTaskMessage($"{Lang.已开启监听端口}:{config.Port}", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- SendTaskMessage($"{Lang.未开启监听端口}:{config.Port}", MessageLevel.Error);
- LogHelper.WriteLogError("开启后台服务器通讯时出错!", ex);
- }
- }
- /// <summary>
- /// 初始化后台ModbusTCP从站
- /// </summary>
- public void InitModbusTcp()
- {
- try
- {
- var config = _configService.GetBgModbusTcp();
- BgModbusTcpCommunicate = new BgModbusTcpCommunicate(config);
- if (config.IsEnabled)
- {
- BgModbusTcpCommunicate.Listen();
- SendTaskMessage($"Start Modbus Tcp Slave:{BgModbusTcpCommunicate.IP}:{BgModbusTcpCommunicate.Port}:{BgModbusTcpCommunicate.SlaveID}", MessageLevel.Debug);
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage($"No Start Modbus Tcp Slave:{ex.Message}", MessageLevel.Alarm);
- LogHelper.WriteLogError("开启后台Modbus TCP通讯时出错!", ex);
- }
- }
- /// <summary>
- /// 初始化后台脚本
- /// </summary>
- public void InitBackgroundcript()
- {
- try
- {
- if (!Directory.Exists(FilePath.BackgroundScriptPath))
- {
- Directory.CreateDirectory(FilePath.BackgroundScriptPath);
- }
- try
- {
- string[] files = Directory.GetFiles(FilePath.BackgroundScriptPath);
- List<string> ScriptFilesCollection = new List<string>();
- foreach (string file in files)
- {
- string fileName = Path.GetFileName(file);
- string fileExtension = Path.GetExtension(file);
- if (fileExtension == ".cs")
- {
- ScriptFilesCollection.Add(file);
- }
- }
- foreach (var item in ScriptFilesCollection)
- {
- try
- {
- string script = FileHelper.ReadFile(item);
- SendTaskMessage($"{Lang.执行脚本}:{item}", MessageLevel.Info);
- Task.Factory.StartNew(() =>
- {
- ScriptHelper.ExecuteScriptingAsync(script, _regionManager, _eventAggregator, _container, rst =>
- {
- if (!rst.Item1)
- {
- foreach (var err in rst.Item2)
- {
- SendTaskMessage($"{Lang.后台脚本出错}:{err}", MessageLevel.Error);
- }
- }
- });
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"开启脚本时出错:{item}", ex);
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("读取本地脚本文件列表时出错", ex);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("开启后台脚本时出错!", ex);
- }
- }
- /// <summary>
- /// 初始化电批
- /// </summary>
- /// <returns></returns>
- public async Task InitScrewDriver()
- {
- try
- {
- var screwDriverConfig = _configService.GetScrewDriverConfig();
- ScrewDriver = new XYD_ScrewDriver(screwDriverConfig.IPAdress, screwDriverConfig.Port);
- Status.Add(new StatusInfo(ScrewDriver.Id, "电批未连接", new SolidColorBrush(Colors.Red)));
- ScrewDriver.ConnectStateChangedEvent += ScrewDriver_ConnectStateChangedEvent;
- ScrewDriver.SendTimeout = screwDriverConfig.SendTimeout;
- screwDriverConfig.ReceiveTimeout = screwDriverConfig.ReceiveTimeout;
- var isConnected = await ScrewDriver.ConnectAsync();
- if (isConnected)
- {
- SendTaskMessage($"电批已连接", MessageLevel.Debug);
- }
- else
- {
- SendTaskMessage($"电批连接失败", MessageLevel.Error);
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage($"电批连接失败:{ex.Message}", MessageLevel.Alarm);
- LogHelper.WriteLogError("连接电批时出错!", ex);
- }
- }
- public async Task InitScan()
- {
- if (!File.Exists(FilePath.ScanRS232ConfigPath))
- {
- var scan = new ScanRs232ConfigModel();
- FileHelper.WriteJsonFile(scan, FilePath.ScanRS232ConfigPath);
- }
- try
- {
- var res = FileHelper.ReadJsonFile<ScanRs232ConfigModel>(FilePath.ScanRS232ConfigPath);
- if (res != null)
- {
- Scan_Client = new SerialPortClient();
- Scan_Client.Connecting = (client1, e) => { return EasyTask.CompletedTask; };//即将连接到端口
- Scan_Client.Connected = (client1, e) => { return EasyTask.CompletedTask; };//成功连接到端口
- Scan_Client.Closing = (client1, e) => { return EasyTask.CompletedTask; };//即将从端口断开连接。此处仅主动断开才有效。
- Scan_Client.Closed = (client1, e) => { return EasyTask.CompletedTask; };//从端口断开连接,当连接不成功时不会触发。
- Scan_Client.Received = async (c, e) =>
- {
- //await Console.Out.WriteLineAsync(Encoding.UTF8.GetString(e.ByteBlock.Buffer));
- await Console.Out.WriteLineAsync(e.ByteBlock.Span.ToString(Encoding.ASCII));
- };
- Scan_Client.Received = Scan_DataReceived;
- await Scan_Client.SetupAsync(new TouchSocketConfig()
- .SetSerialPortOption(new SerialPortOption()
- {
- BaudRate = res.BaudRate,//波特率
- DataBits = res.DataBits,//数据位
- Parity = res.Parity,//校验位
- PortName = res.PortName,//COM
- StopBits = res.StopBits//停止位
- })
- .SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromMilliseconds(100) })
- );
- await Scan_Client.ConnectAsync();
- if (Scan_Client.Online)
- {
- SendTaskMessage(Lang.扫码机已连接, MessageLevel.Debug);
- }
- else
- {
- SendTaskMessage(Lang.扫码机未连接, MessageLevel.Debug);
- }
- }
- else
- {
- SendTaskMessage(Lang.请设置扫码机串口, MessageLevel.Error);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("初始化扫码枪时出错!", ex);
- SendTaskMessage(Lang.初始化扫码枪时出错 + ex.Message, MessageLevel.Error);
- }
- }
- #endregion
- #region 机器人指令执行
- public Dictionary<Guid, CancellationTokenSource> RobotTCPCollection = new Dictionary<Guid, CancellationTokenSource>();
- public Dictionary<Guid, CancellationTokenSource> ScannerTCPCollection = new Dictionary<Guid, CancellationTokenSource>();
- /// <summary>
- /// 机器人TCP接收
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- private async void Management_ReceivedEvent(Guid robotid, object arg2, TouchSocket.Sockets.ReceivedDataEventArgs e)
- {
- try
- {
- if (!RobotTCPCollection.ContainsKey(robotid))
- RobotTCPCollection.Add(robotid, new CancellationTokenSource());
- else
- {
- if (RobotTCPCollection[robotid].IsCancellationRequested)
- {
- RobotTCPCollection[robotid] = new CancellationTokenSource();
- }
- }
- var robot = await _robotService.GetRobotAsync(robotid);
- //从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
- var buffer = e.ByteBlock.Span.ToString(robot.GetEncoding());
- SendTaskMessage($"{robot.Name}Received:{buffer}", MessageLevel.Info);
- var _ = _remoteCommandService.ExecuteAsync(buffer, RobotTCPCollection[robotid].Token, async msg =>
- {
- try
- {
- if (robot.ConnectType == TCPConnectType.Client)
- {
- if (robot.IsConnected)
- {
- await robot.SendAsync($"{msg}");
- }
- }
- else
- {
- var cient = (ITcpSessionClient)arg2;
- if (cient.Online)
- {
- await robot.SendAsync(cient, $"{msg}");
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("TCP发送数据时出错!", ex);
- SendTaskMessage(ex.Message, MessageLevel.Alarm);
- }
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理机器人接收的命令时出错!", ex);
- SendTaskMessage(ex.Message, MessageLevel.Alarm);
- }
- }
- /// <summary>
- /// 扫码枪TCP接收
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- private async void Management_ScannerReceivedEvent(Guid scannerid, object arg2, TouchSocket.Sockets.ReceivedDataEventArgs e)
- {
- try
- {
- if (!ScannerTCPCollection.ContainsKey(scannerid))
- ScannerTCPCollection.Add(scannerid, new CancellationTokenSource());
- else
- {
- if (ScannerTCPCollection[scannerid].IsCancellationRequested)
- {
- ScannerTCPCollection[scannerid] = new CancellationTokenSource();
- }
- }
- var scanner = await _scannerService.GetScannerAsync(scannerid);
- //从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
- var buffer = e.ByteBlock.Span.ToString(scanner.GetEncoding());
- var reply = (buffer ?? string.Empty).Trim();
- SendTaskMessage($"{scanner.Name}Received:{reply}", MessageLevel.Info);
- // 只要有人在等扫码结果,就先完成等待(避免被下面 ExecuteAsync 干扰)
- var tcs = _scanTcs;
- if (tcs != null && !string.IsNullOrWhiteSpace(reply))
- {
- // 只完成一次
- tcs.TrySetResult(reply);
- }
- var _ = _remoteCommandService.ExecuteAsync(buffer, ScannerTCPCollection[scannerid].Token, async msg =>
- {
- try
- {
- if (scanner.ConnectType == TCPConnectType.Client)
- {
- if (scanner.IsConnected)
- {
- await scanner.SendAsync($"{msg}");
- }
- }
- else
- {
- var cient = (ITcpSessionClient)arg2;
- if (cient.Online)
- {
- await scanner.SendAsync(cient, $"{msg}");
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("TCP发送数据时出错!", ex);
- SendTaskMessage(ex.Message, MessageLevel.Alarm);
- }
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理扫码枪接收的命令时出错!", ex);
- SendTaskMessage(ex.Message, MessageLevel.Alarm);
- }
- }
- #endregion
- #region 机器人&Feeder&相机连接状态事件
- /// <summary>
- /// 机器人发送事件
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- /// <exception cref="NotImplementedException"></exception>
- private void Management_SendEvent(Guid robotid, object arg2, string arg3)
- {
- var r = _robotService.GetRobot(robotid);
- SendTaskMessage($"{r.Name}Send:{arg3}", MessageLevel.Info);
- }
- /// <summary>
- /// 扫码枪发送事件
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- /// <exception cref="NotImplementedException"></exception>
- private void Management_ScannerSendEvent(Guid scannerid, object arg2, string arg3)
- {
- var r = _scannerService.GetScanner(scannerid);
- SendTaskMessage($"{r.Name}Send:{arg3}", MessageLevel.Info);
- }
- /// <summary>
- /// 机器人断开连接时
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- /// <exception cref="NotImplementedException"></exception>
- private void Management_DisconnectedEvent(Guid robotid, object arg2, ClosedEventArgs arg3)
- {
- if (RobotTCPCollection.ContainsKey(robotid))
- {
- RobotTCPCollection[robotid].Cancel();
- }
- var r = _configService.GetRobot(robotid);
- if (r.ConnectType == TCPConnectType.Server)
- {
- ITcpSessionClient socketClient = arg2 as ITcpSessionClient;
- SendTaskMessage($"{r.RobotName}[{socketClient.Id}:{socketClient.IP}]{Lang.断开连接}!", MessageLevel.Error);
- var robot = _robotService.GetRobot(robotid);
- if (robot.TcpService.Count < 1)
- {
- var sta = Status.FirstOrDefault(s => s.ID == robotid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.RobotName}{Lang.未连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- else
- {
- SendTaskMessage($"{r.RobotName}{Lang.断开连接}!", MessageLevel.Error);
- var sta = Status.FirstOrDefault(s => s.ID == robotid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.RobotName}{Lang.断开连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- /// <summary>
- /// 扫码枪断开连接时
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- /// <exception cref="NotImplementedException"></exception>
- private void Management_ScannerDisconnectedEvent(Guid scannerid, object arg2, ClosedEventArgs arg3)
- {
- if (ScannerTCPCollection.ContainsKey(scannerid))
- {
- ScannerTCPCollection[scannerid].Cancel();
- }
- var r = _configService.GetScanner(scannerid);
- if (r.ConnectType == TCPConnectType.Server)
- {
- ITcpSessionClient socketClient = arg2 as ITcpSessionClient;
- SendTaskMessage($"{r.ScannerName}[{socketClient.Id}:{socketClient.IP}]{Lang.断开连接}!", MessageLevel.Error);
- var scanner = _scannerService.GetScanner(scannerid);
- if (scanner.TcpService.Count < 1)
- {
- var sta = Status.FirstOrDefault(s => s.ID == scannerid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.ScannerName}{Lang.未连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- else
- {
- SendTaskMessage($"{r.ScannerName}{Lang.断开连接}!", MessageLevel.Error);
- var sta = Status.FirstOrDefault(s => s.ID == scannerid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.ScannerName}{Lang.断开连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- /// <summary>
- /// 机器人连接成功时
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- /// <exception cref="NotImplementedException"></exception>
- private void Management_ConnectedEvent(Guid robotid, object arg2, ConnectedEventArgs arg3)
- {
- var r = _configService.GetRobot(robotid);
- if (r.ConnectType == TCPConnectType.Server)
- {
- ITcpSessionClient socketClient = arg2 as ITcpSessionClient;
- SendTaskMessage($"{r.RobotName}[{socketClient.Id}:{socketClient.IP}]{Lang.已连接}!", MessageLevel.Debug);
- var robot = _robotService.GetRobot(robotid);
- if (robot.TcpService.Count > 0)
- {
- var sta = Status.FirstOrDefault(s => s.ID == robotid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.RobotName}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- }
- else
- {
- SendTaskMessage($"{r.RobotName}{Lang.已连接}!", MessageLevel.Debug);
- var sta = Status.FirstOrDefault(s => s.ID == robotid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.RobotName}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- }
- /// <summary>
- /// 扫码枪连接成功时
- /// </summary>
- /// <param name="arg1"></param>
- /// <param name="arg2"></param>
- /// <param name="arg3"></param>
- /// <exception cref="NotImplementedException"></exception>
- private void Management_ScannerConnectedEvent(Guid scannerid, object arg2, ConnectedEventArgs arg3)
- {
- var r = _configService.GetScanner(scannerid);
- if (r.ConnectType == TCPConnectType.Server)
- {
- ITcpSessionClient socketClient = arg2 as ITcpSessionClient;
- SendTaskMessage($"{r.ScannerName}[{socketClient.Id}:{socketClient.IP}]{Lang.已连接}!", MessageLevel.Debug);
- var scanner = _scannerService.GetScanner(scannerid);
- if (scanner.TcpService.Count > 0)
- {
- var sta = Status.FirstOrDefault(s => s.ID == scannerid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.ScannerName}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- }
- else
- {
- SendTaskMessage($"{r.ScannerName}{Lang.已连接}!", MessageLevel.Debug);
- var sta = Status.FirstOrDefault(s => s.ID == scannerid);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{r.ScannerName}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- }
- /// <summary>
- /// Feeder连接状态改变时
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="state"></param>
- private void Management_FeederConnectionStatusChanged(object sender, bool state)
- {
- IFeeder feeder = sender as IFeeder;
- var sta = Status.FirstOrDefault(s => s.ID == feeder.Id);
- if (state)
- {
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{feeder.Name}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- SendTaskMessage($"{feeder.Name}{Lang.已连接}!", MessageLevel.Debug);
- }
- else
- {
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{feeder.Name}{Lang.未连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- SendTaskMessage($"{feeder.Name}{Lang.断开连接}!", MessageLevel.Error);
- }
- }
- /// <summary>
- /// 相机连接或者断开时
- /// </summary>
- /// <param name="id"></param>
- /// <param name="state"></param>
- private void Management_CameraConnectChangedEvent(Guid id, bool state)
- {
- var sta = Status.FirstOrDefault(s => s.ID == id);
- var camera = _configService.GetCamera(id);
- if (sta != null && camera != null)
- {
- if (state)
- {
- App.Current.Dispatcher.Invoke(new Action(() =>
- {
- sta.Message = $"{camera.CameraName}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- else
- {
- App.Current.Dispatcher.Invoke(new Action(() =>
- {
- sta.Message = $"{camera.CameraName}{Lang.断开连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- }
- /// <summary>
- /// PLC连接状态改变事件
- /// </summary>
- /// <param name="plc"></param>
- /// <param name="isconnected"></param>
- private void Management_PlcConnectChangedEvent(object sender, bool isconnected)
- {
- IPlc plc = sender as IPlc;
- var sta = Status.FirstOrDefault(s => s.ID == plc.Id);
- if (plc.IsConnected)
- {
- SendTaskMessage($"{plc.Name}{Lang.已连接}!", MessageLevel.Debug);
- if (sta == null) return;
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{plc.Name}{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- else
- {
- SendTaskMessage($"{plc.Name}{Lang.断开连接}!", MessageLevel.Error);
- if (sta == null) return;
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"{plc.Name}{Lang.未连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- /// <summary>
- /// 电批连接状态改变时
- /// </summary>
- /// <param name="screwDevice"></param>
- /// <param name="state"></param>
- private void ScrewDriver_ConnectStateChangedEvent(object screwDevice, bool state)
- {
- try
- {
- XYD_ScrewDriver screwDriver = screwDevice as XYD_ScrewDriver;
- if (state)
- {
- SendTaskMessage($"电批{Lang.已连接}!", MessageLevel.Debug);
- var sta = Status.FirstOrDefault(s => s.ID == screwDriver.Id);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"电批{Lang.已连接}";
- sta.Background = new SolidColorBrush(Colors.Green);
- }));
- }
- else
- {
- SendTaskMessage($"电批{Lang.未连接}!", MessageLevel.Error);
- var sta = Status.FirstOrDefault(s => s.ID == screwDriver.Id);
- App.Current.Dispatcher.Invoke(new
- Action(() =>
- {
- sta.Message = $"电批{Lang.未连接}";
- sta.Background = new SolidColorBrush(Colors.Red);
- }));
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("电批连接状态改变时出错了", ex);
- }
- }
- #endregion
- #region 后台服务器通讯事件
- private void BgCommunicate_SendEvent(ITcpSessionClient client, string msg)
- {
- SendTaskMessage($"{Lang.服务器}[{client.ServicePort}] Send To {Lang.客户端}[{client.Id}:{client.IP}]:{msg}", MessageLevel.Info);
- }
- public Dictionary<string, CancellationTokenSource> BgCommunicateollection = new Dictionary<string, CancellationTokenSource>();
- private async void BgCommunicate_ReceivedEvent(ITcpSessionClient client, string msg)
- {
- try
- {
- if (!BgCommunicateollection.ContainsKey(client.Id))
- {
- BgCommunicateollection.Add(client.Id, new CancellationTokenSource());
- }
- SendTaskMessage($"{Lang.服务器}[{client.ServicePort}]ReceiveFor{Lang.客户端}[{client.Id}:{client.IP}]:{msg}", MessageLevel.Info);
- var _ = _remoteCommandService.ExecuteAsync(msg, BgCommunicateollection[client.Id].Token, async response =>
- {
- try
- {
- if (!client.Online)
- {
- return;
- }
- await BgCommunicate.SendAsync(client, $"{response}");
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("后台TCP发送数据时出错!", ex);
- SendTaskMessage(ex.Message, MessageLevel.Alarm);
- }
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理后台服务器接收的命令时出错!", ex);
- SendTaskMessage(ex.Message, MessageLevel.Alarm);
- }
- }
- private void BgCommunicate_DisconnectedEvent(ITcpSessionClient client, ClosedEventArgs e)
- {
- SendTaskMessage($"{Lang.服务器}[{client.ServicePort}]{Lang.客户端}[{client.Id}:{client.IP}]{Lang.断开连接}!", MessageLevel.Alarm);
- if (BgCommunicateollection.ContainsKey(client.Id))
- {
- BgCommunicateollection[client.Id].Cancel();
- }
- }
- private void BgCommunicate_ConnectedEvent(ITcpSessionClient client, ConnectedEventArgs e)
- {
- SendTaskMessage($"{Lang.服务器}[{client.ServicePort}]{Lang.客户端}[{client.Id}:{client.IP}]{Lang.连接成功}!", MessageLevel.Debug);
- }
- #endregion
- #region PLC
- /// <summary>
- /// 将系统参数写入PLC
- /// </summary>
- /// <param name="systemConfiguration"></param>
- /// <returns></returns>
- public async Task WriteSystemParameterToPlcAsync(SystemConfiguration systemConfiguration)
- {
- var addressConfig = _configService.GetPlcAddresses();
- var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
- if (plc == null || !plc.IsConnected) return;
- Dictionary<string, object> nodeValues = new Dictionary<string, object>();
- nodeValues.Add(addressConfig.Out_WorkMode.Address, (Int16)systemConfiguration.WorkMode);
- nodeValues.Add(addressConfig.Out_PickPointNum.Address, (Int16)systemConfiguration.PickPointNum);
- nodeValues.Add(addressConfig.Out_DowmCameraNum.Address, (Int16)systemConfiguration.DowmCameraNum);
- nodeValues.Add(addressConfig.Out_UpCameraPickNum.Address, (Int16)systemConfiguration.UpCameraPickNum);
- nodeValues.Add(addressConfig.Out_UpCameraPutNum.Address, (Int16)systemConfiguration.UpCameraPutNum);
- nodeValues.Add(addressConfig.Out_UPCameracheckNum.Address, (Int16)systemConfiguration.UPCameracheckNum);
- nodeValues.Add(addressConfig.Out_FixedCameraPickNum.Address, (Int16)systemConfiguration.FixedCameraPickNum);
- nodeValues.Add(addressConfig.Out_FixedCameraPutNum.Address, (Int16)systemConfiguration.FixedCameraPutNum);
- nodeValues.Add(addressConfig.Out_FixedCameracheckNum.Address, (Int16)systemConfiguration.FixedCameracheckNum);
- var res = await plc.WriteNodesAsync(nodeValues);
- }
- /// <summary>
- /// 注册需要监控的PLC地址
- /// </summary>
- public void RegisterPlcMonitorAddress()
- {
- var addressConfig = _configService.GetPlcAddresses();
- var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
- if (plc == null || !plc.IsConnected) return;
- //PLC地址数组
- List<string> monitorNodeIds = new List<string>()
- {
- addressConfig.In_DowmCameraExe.Address,
- addressConfig.In_UpCameraPickExe.Address,
- addressConfig.In_UpCameraPutExe.Address,
- addressConfig.In_UPCameracheckExe.Address,
- addressConfig.In_FixedCameraPickExe.Address,
- addressConfig.In_FixedCameraPutExe.Address,
- addressConfig.In_FixedCameracheckExe.Address,
- addressConfig.In_WorkStart.Address,
- addressConfig.In_WorkDone.Address,
- addressConfig.In_MesCheck.Address,
- addressConfig.In_RequestPosition.Address,
- addressConfig.AutoRunning.Address,
- addressConfig.ManualMode.Address,
- addressConfig.ClearMode.Address,
- addressConfig.WorkCt.Address,
- //addressConfig.WorkSpeed.Address,
- };
- for (int i = 0; i < 10; i++)
- {
- monitorNodeIds.Add(string.Format(addressConfig.In_MesCheck.Address, i));
- }
- //订阅PLC地址变化
- //plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger, OpcUaSubscriptionMode.CustomPolling);
- // 1. 初始订阅(使用原生模式)
- plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger, OpcUaSubscriptionMode.CustomPolling);
- // 2. 监听重连事件,重连成功后自动重新订阅
- plc.ConnectChangedEvent -= Plc_ConnectChanged; // 防止重复注册
- plc.ConnectChangedEvent += Plc_ConnectChanged;
- // 定义重连处理方法(写在同一个类里即可)
- void Plc_ConnectChanged(object sender, bool isConnected)
- {
- if (isConnected)
- {
- // 重连成功后,重新订阅节点
- plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger, OpcUaSubscriptionMode.CustomPolling);
- }
- }
- }
- /// <summary>
- /// 写入点位信息给PLC
- /// </summary>
- /// <returns></returns>
- public async Task WritePositionToPlcAsync()
- {
- var addressConfig = _configService.GetPlcAddresses();
- var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
- if (plc == null || !plc.IsConnected) return;
- var current = _productService.GetCurrentProduct();
- if (current == null) return;
- if (current.PickCameraPoints != null && current.PickCameraPoints.Count > 0)
- {
- foreach (var item in current.PickCameraPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_PickCamera, plc);
- }
- }
- if (current.PickPoints != null && current.PickPoints.Count > 0)
- {
- foreach (var item in current.PickPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_Pick, plc);
- }
- }
- if (current.SecPosCameraPoints != null && current.SecPosCameraPoints.Count > 0)
- {
- foreach (var item in current.SecPosCameraPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_SecPosCamera, plc);
- }
- }
- if (current.ScrewCameraPoints != null && current.ScrewCameraPoints.Count > 0)
- {
- foreach (var item in current.ScrewCameraPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_ScrewCamera, plc);
- }
- }
- //if (current.ScrewPoints != null && current.ScrewPoints.Count > 0)
- //{
- // foreach (var item in current.ScrewPoints)
- // {
- // await item.WriteToPlcAddress(addressConfig.Out_Screw, plc);
- // }
- // await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)current.ScrewPoints.Count);
- //}
- if (current.CheckCameraPoints != null && current.CheckCameraPoints.Count > 0)
- {
- foreach (var item in current.CheckCameraPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_CheckCamera, plc);
- }
- }
- if (current.AoiPoints != null && current.AoiPoints.Count > 0)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickNum.Address, (Int16)current.AoiPoints.Count);
- foreach (var item in current.AoiPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_AoiCamera, plc);
- }
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickNum.Address, 0);
- }
- }
- PointF[] DowmCameraResults = new PointF[10];
- PointF[] UpCameraPutResults = new PointF[10];
- bool _LastDowmCameraExe = false;
- bool _LastScrewTeachExe = false;
- bool _LastUpCameraPickExe = false;
- bool _LastUpCameraPutExe = false;
- bool _LastUPCameracheckExe = false;
- bool _LastFixedCameraPickExe = false;
- bool _LastFixedCameraPutExe = false;
- bool _LastFixedCameracheckExe = false;
- public bool _LastAutoRunning = false;
- public bool _LastManualMode = false;
- bool _LastFzCameracheckExe = false;
- bool _LastClearMode = false;
- bool _Lastworkct = false;
- Int16 _Lastworkspeed = 0;
- Int16 _LastWorkStart = 0;
- Int16 _LastWorkDone = 0;
- Int16 _LastRequestPosition = 0;
- Int16[] _LastMesCheck = new Int16[10];
- Int16 _LastPickINC = 0;
- DateTime[] _LastMesCheckTime = new DateTime[10];
- List<Task<(bool IsSucceed, bool[] Result, string Message)>> _PrcTaskList = new List<Task<(bool IsSucceed, bool[] Result, string Message)>>();
- //List<Task<(bool IsSucceed, ICogImage[] Images, string Message, int cameraIndex, Guid procedureId)>> _ImageTaskList = new List<Task<(bool IsSucceed, ICogImage[] Images, string Message, int cameraIndex, Guid procedureId)>>();
- private readonly object _stateLock = new object();
- // private SharedSpeedFileHelper _speedFileHelper = new SharedSpeedFileHelper();
- /// <summary>
- /// PLC命令触发时S
- /// </summary>
- /// <param name="tuple"></param>
- private async void PlcCommandTrigger((string key, string nodeId, object value) tuple)
- {
- try
- {
- if (tuple.key != "AutoSensor")
- {
- return;
- }
- var addressConfig = _configService.GetPlcAddresses();
- var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
- if (plc == null || !plc.IsConnected) return;
- // 获取当前产品
- var currentProduct = _productService.GetCurrentProduct();
- if (currentProduct == null)
- {
- return;
- }
- // 写入3D相机长度
- if (addressConfig.In_UPCameracheckExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastUPCameracheckExe != state)
- {
- _LastUPCameracheckExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"写入3D相机长度...", MessageLevel.Debug);
- //相机的编号
- //Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
- // 读取相机编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
- // 找到对应编号的 PlcPoint
- var targetPoint = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == cameraIndex);
- if (targetPoint == null)
- {
- SendTaskMessage($"未找到 AOI 点位,编号:{cameraIndex}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)2);
- return;
- }
- SetProducts(new int[] { targetPoint.Camera_Product1, targetPoint.Camera_Product2, targetPoint.Camera_Product3, targetPoint.Camera_Product4 });
- SetBatchPoints(new int[] { targetPoint.Camera_Data1, targetPoint.Camera_Data2, targetPoint.Camera_Data3, targetPoint.Camera_Data4 });
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)1);
- }
- else
- {
- SendTaskMessage($"写入3D相机长度信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)0);
- }
- }
- }
- // 发送点位个数
- else if (addressConfig.In_RequestPosition.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is Int16 state)
- {
- if (_LastRequestPosition != state)
- {
- _LastRequestPosition = state;
- }
- else
- {
- return;
- }
- if (state == 1)
- {
- var current = _productService.GetCurrentProduct();
- if (current == null) return;
- await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)1);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickNum.Address, (Int16)current.AoiPoints.Count);
- }
- else
- {
- SendTaskMessage($"多相机坐标合并请求已结束或被取消,state={state}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)0);
- }
- }
- }
- // 固定相机检测拍照
- else if (addressConfig.In_FixedCameracheckExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastFixedCameracheckExe != state)
- {
- _LastFixedCameracheckExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- LockResult lockResult = new LockResult();
- lockResult.TimeStart = DateTime.Now;
- SendTaskMessage($"触发固定相机检测拍照...", MessageLevel.Debug);
- // 读取相机编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
- // 找到对应编号的 PlcPoint
- var targetPoint = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == cameraIndex);
- if (targetPoint == null)
- {
- SendTaskMessage($"未找到 AOI 点位,编号:{cameraIndex}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
- return;
- }
- // 收集要执行的流程 id(仅添加大于0的)
- var procIds = new List<Guid>();
- try
- {
- if (targetPoint.CameraProcedureId1 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId1)) procIds.Add(targetPoint.CameraProcedureId1);
- if (targetPoint.CameraProcedureId2 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId2)) procIds.Add(targetPoint.CameraProcedureId2);
- if (targetPoint.CameraProcedureId3 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId3)) procIds.Add(targetPoint.CameraProcedureId3);
- if (targetPoint.CameraProcedureId4 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId4)) procIds.Add(targetPoint.CameraProcedureId4);
- if (targetPoint.CameraProcedureId5 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId5)) procIds.Add(targetPoint.CameraProcedureId5);
- if (targetPoint.CameraProcedureId6 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId6)) procIds.Add(targetPoint.CameraProcedureId6);
- if (targetPoint.CameraProcedureId7 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId7)) procIds.Add(targetPoint.CameraProcedureId7);
- if (targetPoint.CameraProcedureId8 != Guid.Empty && !procIds.Contains(targetPoint.CameraProcedureId8)) procIds.Add(targetPoint.CameraProcedureId8);
- }
- catch { }
- var sysConfig = _configService.GetSystemConfiguration();
- #region 扫码枪扫码
- if (sysConfig.ScannerUse == true && cameraIndex == 1 && sysConfig.CodeUse2 == true)
- {
- FinalResultStatus = "检测中";
- FinalResultText = "检测中";
- ScanValue = "";
- _scanDoneEvent.Reset(); // 重要:先关门
- await Scan_Client.SendAsync("T");
- // 等待扫码结果,最多 3 秒
- bool scanOk = await Task.Run(() => _scanDoneEvent.Wait(3000));
- if (!scanOk || ScanValue.IsNullOrWhiteSpace())
- {
- SendTaskMessage("二维码拍照失败或超时", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (short)3);
- return;
- }
- code = ScanValue;
- SendTaskMessage($"扫码成功,SN:{code}", MessageLevel.Info);
- //这里缺少从MES获取产品配方的内容,需要补充
- _LastMesCheckTime[0] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
- //_LastMesCheckTime[1] = DateTime.Now;
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- (bool isSuccess, string response) = await _mesService.StationGetAsync(code, "", 2);//询问mes
- if (isSuccess)
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- if (response != "MES功能未启用!")
- {
- string[] items = response.Split('\n');
- string snItem = items.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- string woItem = items.FirstOrDefault(f => f.Contains("wo="));
- if (woItem != null)
- {
- wo[0] = woItem.Replace("wo=", "").Trim();
- SendTaskMessage($"产品wo:{wo}", MessageLevel.Info);
- }
- string modelItem = items.FirstOrDefault(f => f.Contains("model_num="));
- if (modelItem != null)
- {
- model_num[0] = modelItem.Replace("model_num=", "").Trim();
- SendTaskMessage($"model_num:{model_num}", MessageLevel.Info);
- }
- string colorItem = items.FirstOrDefault(f => f.Contains("color="));
- if (colorItem != null)
- {
- color[0] = colorItem.Replace("color=", "").Trim();
- SendTaskMessage($"color:{color}", MessageLevel.Info);
- }
- string ppidItem = items.FirstOrDefault(f => f.Contains("ppid="));
- if (ppidItem != null)
- {
- ppid[0] = ppidItem.Replace("ppid=", "").Trim();
- SendTaskMessage($"ppid:{ppid}", MessageLevel.Info);
- }
- string stageItem = items.FirstOrDefault(f => f.Contains("stage="));
- if (stageItem != null)
- {
- stage[0] = stageItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{stage}", MessageLevel.Info);
- }
- string kbsnitem = items.FirstOrDefault(f => f.Contains("KB="));
- if (kbsnitem != null)
- {
- kb_sn[0] = kbsnitem.Replace("KB=", "").Trim();
- SendTaskMessage($"KB:{kb_sn}", MessageLevel.Info);
- }
- string kbpnsnitem = items.FirstOrDefault(f => f.Contains("KB_PN="));
- if (kbpnsnitem != null)
- {
- kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
- SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
- }
- var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
- foreach (var q in item1)
- {
- if (!string.IsNullOrEmpty(q.ProductName))
- {
- ProductWithMes productWithMes = new ProductWithMes();
- ProductList = new ObservableCollection<ProductModel>(_productService.GetAllProducts());
- Guid productId = Guid.Empty;
- foreach (var itt in ProductList)
- {
- if (itt.Name == q.ProductName)
- {
- productId = itt.ID;
- break;
- }
- }
- if (_configService.GetSystemConfiguration().IsTP_AOI)
- {
- if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- else
- {
- if (currentProduct.ID != productId && model_num[0].Contains(q.ProductCode))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- }
- }
- }
- LogHelper.WriteLogMes($"【mes结束QUERY】");
- SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- return;
- }
- else
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- return;
- }
- }
- if (sysConfig.ScannerUse == true && cameraIndex == 1 && sysConfig.CodeUse == true)
- {
- FinalResultStatus = "检测中";
- FinalResultText = "检测中";
- ScanValue = "";
- _scanDoneEvent.Reset(); // 重要:先关门
- await Scan_Client.SendAsync("T");
- // 等待扫码结果,最多 3 秒
- bool scanOk = await Task.Run(() => _scanDoneEvent.Wait(3000));
- if (!scanOk || ScanValue.IsNullOrWhiteSpace())
- {
- SendTaskMessage("二维码拍照失败或超时", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (short)3);
- return;
- }
- code = ScanValue;
- SendTaskMessage($"扫码成功,SN:{code}", MessageLevel.Info);
- //这里缺少从MES获取产品配方的内容,需要补充
- _LastMesCheckTime[0] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- //(bool isSuccess, string response) = await _mesService.StationGetAsync(code, "", 2);//询问mes
- (bool isSuccess, string response) = await _mesService.StationGetExAsync(code, "", 2);//基于电池的SN获取产品SN,询问mes
- if (isSuccess)
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- string ProductMainSN_Temp = "";
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- if (response != "MES功能未启用!")
- {
- string[] item = response.Split('\n');
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN_Temp = snItem.Replace("sn=", "").Trim();
- SendTaskMessage($"sn:{ProductMainSN_Temp}", MessageLevel.Info);
- }
- }
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- //20260214,特别版(电池组装)
- (bool isSuccess2, string response2) = await _mesService.StationGetAsync(ProductMainSN_Temp, "", 2);//询问mes
- if (isSuccess2)
- {
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response2}", MessageLevel.Debug);
- if (response2 != "MES功能未启用!")
- {
- string[] item = response2.Split('\n');
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- string woItem = item.FirstOrDefault(f => f.Contains("wo="));
- if (woItem != null)
- {
- wo[0] = woItem.Replace("wo=", "").Trim();
- SendTaskMessage($"产品wo:{wo[0]}", MessageLevel.Info);
- }
- string modelItem = item.FirstOrDefault(f => f.Contains("model_num="));
- if (modelItem != null)
- {
- model_num[0] = modelItem.Replace("model_num=", "").Trim();
- SendTaskMessage($"model_num:{model_num[0]}", MessageLevel.Info);
- }
- string colorItem = item.FirstOrDefault(f => f.Contains("color="));
- if (colorItem != null)
- {
- color[0] = colorItem.Replace("color=", "").Trim();
- SendTaskMessage($"color:{color[0]}", MessageLevel.Info);
- }
- string ppidItem = item.FirstOrDefault(f => f.Contains("ppid="));
- if (ppidItem != null)
- {
- ppid[0] = ppidItem.Replace("ppid=", "").Trim();
- SendTaskMessage($"ppid:{ppid[0]}", MessageLevel.Info);
- }
- string stageItem = item.FirstOrDefault(f => f.Contains("stage="));
- if (stageItem != null)
- {
- stage[0] = stageItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{stage[0]}", MessageLevel.Info);
- }
- string kbsnitem = item.FirstOrDefault(f => f.Contains("KB="));
- if (kbsnitem != null)
- {
- kb_sn[0] = kbsnitem.Replace("KB=", "").Trim();
- SendTaskMessage($"KB:{kb_sn[0]}", MessageLevel.Info);
- }
- string kbpnsnitem = item.FirstOrDefault(f => f.Contains("KB_PN="));
- if (kbpnsnitem != null)
- {
- kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
- SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
- }
- var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
- foreach (var q in item1)
- {
- if (!string.IsNullOrEmpty(q.ProductName))
- {
- ProductWithMes productWithMes = new ProductWithMes();
- ProductList = new ObservableCollection<ProductModel>(_productService.GetAllProducts());
- Guid productId = Guid.Empty;
- foreach (var itt in ProductList)
- {
- if (itt.Name == q.ProductName)
- {
- productId = itt.ID;
- break;
- }
- }
- if (_configService.GetSystemConfiguration().IsTP_AOI)
- {
- if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- else
- {
- if (currentProduct.ID != productId && model_num[0].Contains(q.ProductCode))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- }
- }
- }
- LogHelper.WriteLogMes($"第二次询问mes成功");
- SendTaskMessage($"第二次询问mes成功:{response2}", MessageLevel.Debug);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- }
- else
- {
- LogHelper.WriteLogMes($"第二次询问mes失败");
- SendTaskMessage($"第二次询问mes失败:{response2}", MessageLevel.Error);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- string[] item = response2.Split('\n');
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- await plc.WriteNodeAsync<string>(string.Format(addressConfig.In_Code.Address, 0), ProductMainSN);
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- }
- }
- else
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- }
- return;
- }
- #endregion
- if (procIds.Count == 0 && cameraIndex != currentProduct.PhotoCountStop)
- {
- SendTaskMessage($"Point#{cameraIndex} 未配置任何视觉流程 (CameraProcedureId1/2/3)", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- var cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures == null || cameraProcedures.Count == 0)
- {
- if (cameraIndex != currentProduct.PhotoCountStop)
- {
- SendTaskMessage($"当前产品未配置 CameraProcedures,无法执行视觉流程", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- }
- if (cameraIndex == currentProduct.PhotoCount)
- {
- //_PrcTaskList.Clear();
- AllResult = new ConcurrentBag<bool>();
- lockResultsAll = new ConcurrentBag<LockResult>();
- int count = 0;
- int isscan = 0;
- var AllProcId = new List<Guid>();
- foreach (var item in currentProduct.AoiPoints)
- {
- if (item.Enable_Start_Node == 1)
- {
- #region 判断执行视觉模板个数
- if (item.Label == "扫码")
- {
- isscan = -1;
- }
- if (item.CameraProcedureId1 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId1)) AllProcId.Add(item.CameraProcedureId1);
- if (item.CameraProcedureId2 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId2)) AllProcId.Add(item.CameraProcedureId2);
- if (item.CameraProcedureId3 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId3)) AllProcId.Add(item.CameraProcedureId3);
- if (item.CameraProcedureId4 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId4)) AllProcId.Add(item.CameraProcedureId4);
- if (item.CameraProcedureId5 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId5)) AllProcId.Add(item.CameraProcedureId5);
- if (item.CameraProcedureId6 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId6)) AllProcId.Add(item.CameraProcedureId6);
- if (item.CameraProcedureId7 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId7)) AllProcId.Add(item.CameraProcedureId7);
- if (item.CameraProcedureId8 != Guid.Empty && !AllProcId.Contains(item.CameraProcedureId8)) AllProcId.Add(item.CameraProcedureId8);
- #endregion
- }
- }
- count = AllProcId.Count + isscan;
- countdown = new CountdownEvent(count);
- SendTaskMessage($"需要执行模板数:{count}", MessageLevel.Alarm);
- _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- _eventAggregator.GetEvent<LockResetNotification>().Publish();
- }));
- }
- #region 相机扫码
- if (sysConfig.CodeUse == true && cameraIndex == 1)
- {
- FinalResultStatus = "检测中";
- FinalResultText = "检测中";
- var cts = new CancellationTokenSource();
- // CameraProcedureId 存储的是具体的视觉流程 Id(ProcedureModel.Id),
- // 需要在所有 CameraProcedures 的 ProcedureModels 中查找匹配的流程。
- ProcedureModel selectedProcedure = null;
- try
- {
- cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures != null)
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == targetPoint.CameraProcedureId1);
- if (selectedProcedure != null) break;
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{cameraIndex} ProcedureId={targetPoint.CameraProcedureId1}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- if (selectedProcedure.Id == currentProduct.FixedDownCameraProcedureId && sysConfig.TurnOnAllLightUse == true)
- {
- await _remoteCommandService.SetLightBeforePhoto(selectedProcedure);
- }
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint2(selectedProcedure, null, null, cts.Token);
- if (visionResult.IsSucceed)
- {
- code = visionResult.X.ToUpper();
- SendTaskMessage($"扫码成功,SN:{code}", MessageLevel.Info);
- //这里缺少从MES获取产品配方的内容,需要补充
- _LastMesCheckTime[0] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- //(bool isSuccess, string response) = await _mesService.StationGetAsync(code, "", 2);//询问mes
- (bool isSuccess, string response) = await _mesService.StationGetExAsync(code, "", 2);
- if (isSuccess)
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- string ProductMainSN_Temp = "";
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- if (response != "MES功能未启用!")
- {
- string[] item = response.Split('\n');
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN_Temp = snItem.Replace("sn=", "").Trim();
- SendTaskMessage($"sn:{ProductMainSN_Temp}", MessageLevel.Info);
- }
- }
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- //20260214,特别版(电池组装)
- (bool isSuccess2, string response2) = await _mesService.StationGetAsync(ProductMainSN_Temp, "", 2);//询问mes
- if (isSuccess2)
- {
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response2}", MessageLevel.Debug);
- if (response2 != "MES功能未启用!")
- {
- string[] item = response2.Split('\n');
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- await plc.WriteNodeAsync<string>(string.Format(addressConfig.In_Code.Address, 0), ProductMainSN);
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- string woItem = item.FirstOrDefault(f => f.Contains("wo="));
- if (woItem != null)
- {
- wo[0] = woItem.Replace("wo=", "").Trim();
- SendTaskMessage($"产品wo:{wo[0]}", MessageLevel.Info);
- }
- string modelItem = item.FirstOrDefault(f => f.Contains("model_num="));
- if (modelItem != null)
- {
- model_num[0] = modelItem.Replace("model_num=", "").Trim();
- SendTaskMessage($"model_num:{model_num[0]}", MessageLevel.Info);
- }
- string colorItem = item.FirstOrDefault(f => f.Contains("color="));
- if (colorItem != null)
- {
- color[0] = colorItem.Replace("color=", "").Trim();
- SendTaskMessage($"color:{color[0]}", MessageLevel.Info);
- }
- string ppidItem = item.FirstOrDefault(f => f.Contains("ppid="));
- if (ppidItem != null)
- {
- ppid[0] = ppidItem.Replace("ppid=", "").Trim();
- SendTaskMessage($"ppid:{ppid[0]}", MessageLevel.Info);
- }
- string stageItem = item.FirstOrDefault(f => f.Contains("stage="));
- if (stageItem != null)
- {
- stage[0] = stageItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{stage[0]}", MessageLevel.Info);
- }
- string kbsnitem = item.FirstOrDefault(f => f.Contains("KB="));
- if (kbsnitem != null)
- {
- kb_sn[0] = kbsnitem.Replace("KB=", "").Trim();
- SendTaskMessage($"KB:{kb_sn[0]}", MessageLevel.Info);
- }
- string kbpnsnitem = item.FirstOrDefault(f => f.Contains("KB_PN="));
- if (kbpnsnitem != null)
- {
- kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
- SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
- }
- var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
- foreach (var q in item1)
- {
- if (!string.IsNullOrEmpty(q.ProductName))
- {
- ProductWithMes productWithMes = new ProductWithMes();
- ProductList = new ObservableCollection<ProductModel>(_productService.GetAllProducts());
- Guid productId = Guid.Empty;
- foreach (var itt in ProductList)
- {
- if (itt.Name == q.ProductName)
- {
- productId = itt.ID;
- break;
- }
- }
- if (_configService.GetSystemConfiguration().IsTP_AOI)
- {
- if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- else
- {
- if (currentProduct.ID != productId && model_num[0].Contains(q.ProductCode))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- }
- }
- }
- LogHelper.WriteLogMes($"第二次询问mes成功");
- SendTaskMessage($"第二次询问mes成功:{response2}", MessageLevel.Debug);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- }
- else
- {
- LogHelper.WriteLogMes($"第二次询问mes失败");
- SendTaskMessage($"第二次询问mes失败:{response2}", MessageLevel.Error);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- string[] item = response2.Split('\n');
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- await plc.WriteNodeAsync<string>(string.Format(addressConfig.In_Code.Address, 0), ProductMainSN);
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- }
- }
- else
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- string[] items = response.Split('\n');
- string snItem = items.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- await plc.WriteNodeAsync<string>(string.Format(addressConfig.In_Code.Address, 0), ProductMainSN);
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- }
- }
- else
- {
- SendTaskMessage($"扫码失败", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- }
- return;
- }
- if (sysConfig.CodeUse2 == true && cameraIndex == 1)
- {
- FinalResultStatus = "检测中";
- FinalResultText = "检测中";
- var cts = new CancellationTokenSource();
- // CameraProcedureId 存储的是具体的视觉流程 Id(ProcedureModel.Id),
- // 需要在所有 CameraProcedures 的 ProcedureModels 中查找匹配的流程。
- ProcedureModel selectedProcedure = null;
- try
- {
- cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures != null)
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == targetPoint.CameraProcedureId1);
- if (selectedProcedure != null) break;
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{cameraIndex} ProcedureId={targetPoint.CameraProcedureId1}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- var ctsAll = new CancellationTokenSource();
- if (selectedProcedure.Id == currentProduct.FixedDownCameraProcedureId && sysConfig.TurnOnAllLightUse == true)
- {
- await _remoteCommandService.SetLightBeforePhoto(selectedProcedure);
- }
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint2(selectedProcedure, null, null, ctsAll.Token);
- if (visionResult.IsSucceed)
- {
- code = visionResult.X;
- ProductMainSN = visionResult.X;
- SendTaskMessage($"扫码成功,SN:{code}", MessageLevel.Info);
- //这里缺少从MES获取产品配方的内容,需要补充
- _LastMesCheckTime[0] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
- //_LastMesCheckTime[1] = DateTime.Now;
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- (bool isSuccess, string response) = await _mesService.StationGetAsync(code, "", 2);//询问mes
- if (isSuccess)
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- if (response != "MES功能未启用!")
- {
- string[] items = response.Split('\n');
- string snItem = items.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- await plc.WriteNodeAsync<string>(string.Format(addressConfig.In_Code.Address, 0), ProductMainSN);
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- string woItem = items.FirstOrDefault(f => f.Contains("wo="));
- if (woItem != null)
- {
- wo[0] = woItem.Replace("wo=", "").Trim();
- SendTaskMessage($"产品wo:{wo[0]}", MessageLevel.Info);
- }
- string modelItem = items.FirstOrDefault(f => f.Contains("model_num="));
- if (modelItem != null)
- {
- model_num[0] = modelItem.Replace("model_num=", "").Trim();
- SendTaskMessage($"model_num:{model_num[0]}", MessageLevel.Info);
- }
- string colorItem = items.FirstOrDefault(f => f.Contains("color="));
- if (colorItem != null)
- {
- color[0] = colorItem.Replace("color=", "").Trim();
- SendTaskMessage($"color:{color[0]}", MessageLevel.Info);
- }
- string ppidItem = items.FirstOrDefault(f => f.Contains("ppid="));
- if (ppidItem != null)
- {
- ppid[0] = ppidItem.Replace("ppid=", "").Trim();
- SendTaskMessage($"ppid:{ppid[0]}", MessageLevel.Info);
- }
- string stageItem = items.FirstOrDefault(f => f.Contains("stage="));
- if (stageItem != null)
- {
- stage[0] = stageItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{stage[0]}", MessageLevel.Info);
- }
- string kbsnitem = items.FirstOrDefault(f => f.Contains("KB="));
- if (kbsnitem != null)
- {
- kb_sn[0] = kbsnitem.Replace("KB=", "").Trim();
- SendTaskMessage($"KB:{kb_sn[0]}", MessageLevel.Info);
- }
- string kbpnsnitem = items.FirstOrDefault(f => f.Contains("KB_PN="));
- if (kbpnsnitem != null)
- {
- kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
- SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
- }
- var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
- foreach (var q in item1)
- {
- if (!string.IsNullOrEmpty(q.ProductName))
- {
- ProductWithMes productWithMes = new ProductWithMes();
- ProductList = new ObservableCollection<ProductModel>(_productService.GetAllProducts());
- Guid productId = Guid.Empty;
- foreach (var itt in ProductList)
- {
- if (itt.Name == q.ProductName)
- {
- productId = itt.ID;
- break;
- }
- }
- if (_configService.GetSystemConfiguration().IsTP_AOI)
- {
- if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- else
- {
- if (currentProduct.ID != productId && model_num[0].Contains(q.ProductCode))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- }
- }
- }
- LogHelper.WriteLogMes($"【mes结束QUERY】");
- SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- return;
- }
- else
- {
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- string[] items = response.Split('\n');
- string snItem = items.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- await plc.WriteNodeAsync<string>(string.Format(addressConfig.In_Code.Address, 0), ProductMainSN);
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- }
- }
- else
- {
- SendTaskMessage($"扫码失败", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)3);
- }
- return;
- }
- #endregion
- //不能使用全局变量,不然并发的时候会被清除掉,所以局部变量
- var _ImageTaskList = new List<Task<(bool IsSucceed, ICogImage[] Images, string Message, int cameraIndex, Guid procedureId)>>();
- foreach (var prcId in procIds)
- {
- ProcedureModel selectedProcedure = null;
- try
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == prcId);
- if (selectedProcedure != null) break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (sysConfig.TurnOnAllLightUse == false)
- {
- await _remoteCommandService.SetLightBeforePhoto(selectedProcedure);
- }
- if (sysConfig.PhotosUse == true)
- {
- bool Is3dPhoto = Is3D(prcId);
- var tt = await GrabImageEx(cameraIndex, prcId, Is3dPhoto, currentProduct, sysConfig);
- if (tt.IsSucceed == false)
- {
- SendTaskMessage($"图像采集失败!{cameraIndex}: {prcId}", MessageLevel.Alarm);
- return;
- }
- await ExecuteProcedureAsync(cameraIndex, prcId, tt.imges, Is3dPhoto, currentProduct);
- if (targetPoint.AiVision == 1)
- {
- var targetPoint2 = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == targetPoint.AiVision);
- await ExecuteProcedureAsync(targetPoint.AiVision, targetPoint2.CameraProcedureId1, tt.imges, Is3dPhoto, currentProduct);
- }
- }
- else
- {
- bool Is3dPhoto = Is3D(prcId);
- _ImageTaskList.Add(GrabImageEx(cameraIndex, prcId, Is3dPhoto, currentProduct, sysConfig));
- if (targetPoint.AiVision == 1)
- {
- break;
- }
- }
- if (sysConfig.TurnOnAllLightUse == false)
- {
- await _remoteCommandService.TurnOffLightAfterPhoto(selectedProcedure);
- }
- }
- if (cameraIndex != currentProduct.PhotoCountStop)
- {
- //直接放行,执行下一个检测点
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- }
- if (_ImageTaskList.Count > 0)//如果2D取图有队列
- {
- //并发
- _ = Task.Run(async () =>
- {
- var ImageTaskResults = await Task.WhenAll(_ImageTaskList);
- foreach (var item in ImageTaskResults)
- {
- if (item.IsSucceed)
- {
- bool Is3d = Is3D(item.procedureId);
- if (targetPoint.AiVision == 1)
- {
- var targetPoint2 = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == cameraIndex);
- await ExecuteProcedureAsync(targetPoint.AiVision, targetPoint2.CameraProcedureId2, item.Images, Is3d, currentProduct);
- }
- await ExecuteProcedureAsync(item.cameraIndex, item.procedureId, item.Images, Is3d, currentProduct);
- }
- else
- {
- SendTaskMessage($"图像采集失败!{item.cameraIndex}: {item.procedureId}", MessageLevel.Alarm);
- AllResult.Add(false);
- ClearCountdown();
- }
- }
- });
- }
- //如果最后一个拍照点,则需要等待前面所有的拍照处理完成
- if (cameraIndex == currentProduct.PhotoCountStop)
- {
- //结果输出
- bool resultFlog = true;
- //等待所有的图像处理流程处理完成
- //之前版本使用的是lock机制无法进行并发操作,目前能完美进行并发且能等待所有任务完成
- countdown.Wait();
- if (sysConfig.PhotosUse == true)
- {
- foreach (var item in lockResultsAll)
- {
- if (item.PhotoPassed == "NG")
- {
- resultFlog = false;
- break;
- }
- }
- }
- else
- {
- foreach (var item in AllResult)
- {
- if (!item)
- {
- resultFlog = false;
- break;
- }
- }
- }
- //全部OK
- if (resultFlog)
- {
- SendTaskMessage($"检测执行成功", MessageLevel.Debug);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- FinalResultStatus = "OK";
- FinalResultText = "OK";
- return;
- }
- //存在NG
- else
- {
- SendTaskMessage($"检测执行失败", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- FinalResultStatus = "NG";
- FinalResultText = "NG";
- return;
- }
- }
- return;
- }
- else
- {
- SendTaskMessage($"触发固定相机检测拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)0);
- }
- }
- }
- // 翻转相机检测拍照
- else if (addressConfig.In_FzCameraPixExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastFzCameracheckExe != state)
- {
- _LastFzCameracheckExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage("触发翻转相机拍照", MessageLevel.Debug);
- var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, 1));
- //这里缺少从MES获取产品配方的内容,需要补充
- _LastMesCheckTime[5] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
- var stationConfig2 = _configService.GetDeviceInfo(0);
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- (bool isSuccess, string response) = await _mesService.StationGetExAsync(code, "", 2);
- if (isSuccess)
- {
- string ProductMainSN_Temp = "";
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- string[] item = response.Split('\n');
- //获取过度件sn
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN_Temp = snItem.Replace("sn=", "").Trim();
- SendTaskMessage($"过度件sn:{ProductMainSN_Temp}", MessageLevel.Info);
- }
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- //20260214,螺丝机特别版
- (bool isSuccess2, string response2) = await _mesService.StationGetAsync(ProductMainSN_Temp, "", 2);//询问mes
- if (isSuccess2)
- {
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response2}", MessageLevel.Debug);
- string[] items = response2.Split('\n');
- //获取产品主sn和wo用于后续上传数据使用
- string snItem2 = items.FirstOrDefault(f => f.Contains("sn="));
- if (snItem2 != null)
- {
- var codesn = snItem2.Replace("sn=", "").Trim();
- SendTaskMessage($"产品主sn:{codesn}", MessageLevel.Info);
- }
- LogHelper.WriteLogMes($"第二次询问mes成功");
- SendTaskMessage($"第二次询问mes成功:{response2}", MessageLevel.Debug);
- }
- else
- {
- LogHelper.WriteLogMes($"第二次询问mes失败");
- SendTaskMessage($"第二次询问mes失败:{response2}", MessageLevel.Error);
- await plc.WriteNodeAsync(addressConfig.Out_FzCameraPickStatus.Address, (Int16)2);
- return;
- }
- }
- else
- {
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- await plc.WriteNodeAsync(addressConfig.Out_FzCameraPickStatus.Address, (Int16)2);
- return;
- }
- Guid FzCameraProcedureId = currentProduct.FzCameraProcedureId;
- var FzCameraProcess = _productService.GetCurrentProductProcedureModelById(FzCameraProcedureId);
- if (FzCameraProcess == null)
- {
- SendTaskMessage($"未找到翻转相机视觉流程,流程ID: {FzCameraProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FzCameraPickStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"开始执行翻转相机视觉流程", MessageLevel.Debug);
- var _cts = new CancellationTokenSource();
- await _remoteCommandService.SetLightBeforePhoto(FzCameraProcess);
- var FzCameraResult = _remoteCommandService.ExecutePhoto(FzCameraProcess, out CogToolBlockTerminalCollection outputCollection);
- if (FzCameraResult)
- {
- SendTaskMessage("翻转相机拍照成功", MessageLevel.Debug);
- await plc.WriteNodeAsync(addressConfig.Out_FzCameraPickStatus.Address, (Int16)1);
- }
- else
- {
- SendTaskMessage("翻转相机拍照失败", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FzCameraPickStatus.Address, (Int16)2);
- }
- }
- else
- {
- SendTaskMessage($"触发翻转相机检测拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FzCameraPickStatus.Address, (Int16)0);
- }
- }
- }
- //切换成自动运行模式
- else if (addressConfig.AutoRunning.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastAutoRunning != state)
- {
- _LastAutoRunning = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- CurrentRunStatus();
- SendTaskMessage("收到切换成自动模式", MessageLevel.Info);
- }
- }
- }
- //切换成维修模式
- else if (addressConfig.ManualMode.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastManualMode != state)
- {
- _LastManualMode = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- CurrentDisplayMode = RunDisplayMode.Manual;
- SendTaskMessage("收到切换成维修模式", MessageLevel.Info);
- }
- }
- }
- //切换成流线模式
- else if (addressConfig.ClearMode.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastClearMode != state)
- {
- _LastClearMode = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- CurrentDisplayMode = RunDisplayMode.Clear;
- SendTaskMessage("收到切换成流线模式", MessageLevel.Info);
- }
- }
- }
- //读取PLC生产CT
- else if (addressConfig.WorkCt.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_Lastworkct != state)
- {
- _Lastworkct = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- Int32 cttime = plc.ReadNode<Int32>(addressConfig.In_CycleTimeBefor.Address);
- SendTaskMessage($"读取PLC记录CT:{cttime}", MessageLevel.Info);
- CTtime2 = Convert.ToDouble(cttime);
- }
- }
- }
- // 过站检查
- else
- {
- for (int i = 0; i < 10; i++)
- {
- if (string.Format(addressConfig.In_MesCheck.Address, i).Contains(tuple.nodeId))
- {
- if (tuple.value is Int16 state)
- {
- if (_LastMesCheck[i] != state)
- {
- _LastMesCheck[i] = state;
- }
- else
- {
- return;
- }
- if (i == 1)
- {
- SendTaskMessage($"收到人工站请求不处理", MessageLevel.Debug);
- return;
- }
- var sysConfig = _configService.GetSystemConfiguration();
- if (sysConfig.CodeUse == true && state == 1)
- {
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
- return;
- }
- if (sysConfig.CodeUse2 == true && state == 1)
- {
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
- return;
- }
- if (sysConfig.CodeUse == false && sysConfig.CodeUse2 == false)
- {
- code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, i));
- }
- //var homeview = _container.Resolve<HomeViewModel>();
- if (i == 0)
- {
- SendTaskMessage($"收到当前过站检查请求(当站是否生产)...", MessageLevel.Debug);
- }
- else
- {
- SendTaskMessage($"收到{i}过站检查请求(当站是否生产)...", MessageLevel.Debug);
- }
- //过站检查
- if (state == 1)
- {
- FinalResultStatus = "检测中";
- FinalResultText = "检测中";
- //这里缺少从MES获取产品配方的内容,需要补充
- _LastMesCheckTime[i] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
- DeviceInfo stationConfig2 = new DeviceInfo();
- try
- {
- stationConfig2 = _configService.GetDeviceInfo(i);
- }
- catch (Exception)
- {
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- SendTaskMessage($"设置无当前站点:{i}", MessageLevel.Error);
- return;
- }
- //if (homeview.IsNoCode == false)
- //{
- // var device = _configService.GetDeviceInfo(0);
- // code = device.XnSN;
- //}
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- ShowMes_Query = false;
- (bool isSuccess, string response) = await _mesService.StationGetExAsync(code, "", 2);
- if (isSuccess)
- {
- string ProductMainSN_Temp = "";
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- string[] item2 = response.Split('\n');
- //获取过度件sn
- string snItem2 = item2.FirstOrDefault(f => f.Contains("sn="));
- if (snItem2 != null)
- {
- ProductMainSN_Temp = snItem2.Replace("sn=", "").Trim();
- SendTaskMessage($"过度件sn:{ProductMainSN_Temp}", MessageLevel.Info);
- }
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- (bool isSuccess2, string response2) = await _mesService.StationGetAsync(ProductMainSN_Temp, "", 2);//询问mes
- if (isSuccess)
- {
- string[] item = response2.Split('\n');
- //获取产品主sn和wo用于后续上传数据使用
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- if (i == 0)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- }
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- string woItem = item.FirstOrDefault(f => f.Contains("wo="));
- if (woItem != null)
- {
- wo[i] = woItem.Replace("wo=", "").Trim();
- SendTaskMessage($"工单信息:{wo[i]}", MessageLevel.Info);
- }
- string modelItem = item.FirstOrDefault(f => f.Contains("model_num="));
- if (modelItem != null)
- {
- model_num[i] = modelItem.Replace("model_num=", "").Trim();
- SendTaskMessage($"model_num:{model_num[i]}", MessageLevel.Info);
- }
- string colorItem = item.FirstOrDefault(f => f.Contains("color="));
- if (colorItem != null)
- {
- color[i] = colorItem.Replace("color=", "").Trim();
- SendTaskMessage($"color:{color[i]}", MessageLevel.Info);
- }
- string ppidItem = item.FirstOrDefault(f => f.Contains("ppid="));
- if (ppidItem != null)
- {
- ppid[i] = ppidItem.Replace("ppid=", "").Trim();
- SendTaskMessage($"ppid:{ppid[i]}", MessageLevel.Info);
- }
- string stageItem = item.FirstOrDefault(f => f.Contains("stage="));
- if (stageItem != null)
- {
- stage[i] = stageItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{stage[i]}", MessageLevel.Info);
- }
- string kbsnitem = item.FirstOrDefault(f => f.Contains("KB="));
- if (kbsnitem != null)
- {
- kb_sn[i] = kbsnitem.Replace("KB=", "").Trim();
- SendTaskMessage($"KB:{kb_sn[i]}", MessageLevel.Info);
- }
- string kbpnsnitem = item.FirstOrDefault(f => f.Contains("KB_PN="));
- if (kbpnsnitem != null)
- {
- kb_pn[i] = kbpnsnitem.Replace("KB_PN=", "").Trim();
- SendTaskMessage($"KB_PN:{kb_pn[i]}", MessageLevel.Info);
- }
- ShowMes_Query = true;
- if (stationConfig2.EnableMES)
- {
- //切换产品
- if (i == 0)//i=0时才会切换产品
- {
- try
- {
- //var q = await _systemDatabaseService.QueryProductFromMesAsync(model_num, color);
- var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
- foreach (var q in item1)
- {
- if (!string.IsNullOrEmpty(q.ProductName))
- {
- ProductWithMes productWithMes = new ProductWithMes();
- ProductList = new ObservableCollection<ProductModel>(_productService.GetAllProducts());
- Guid productId = Guid.Empty;
- foreach (var itt in ProductList)
- {
- if (itt.Name == q.ProductName)
- {
- productId = itt.ID;
- break;
- }
- }
- if (_configService.GetSystemConfiguration().IsTP_AOI)
- {
- if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[i]))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- else
- {
- if (currentProduct.ID != productId && model_num[i].Contains(q.ProductCode))
- {
- //切换产品
- SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
- _productService.LoadProduct(productId);
- _productService.SetCurrentProduct(productId);
- await WritePositionToPlcAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- break;
- }
- }
- }
- }
- }
- catch (Exception ex)
- { SendTaskMessage($"切换产品异常" + ex.Message, MessageLevel.Error); }
- }
- }
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
- LogHelper.WriteLogMes($"【mes结束QUERY】");
- SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
- // return;
- }
- else
- {
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- LogHelper.WriteLogMes($"二次询问mes失败");
- SendTaskMessage($"二次询问mes失败:{response}", MessageLevel.Error);
- string[] item = response2.Split('\n');
- //获取产品主sn和wo用于后续上传数据使用
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- if (i == 0)
- {
- ProductMainSN = snItem.Replace("sn=", "").Trim();
- _productService.CurrentProductCode = ProductMainSN;
- }
- SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
- }
- }
- }
- else
- {
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- }
- }
- // 上传本站数据
- else if (state == 2)
- {
- //获取当前工位的配置
- var stationConfig = _configService.GetDeviceInfo(0);
- List<DataFormCtq> DFC = new List<DataFormCtq>();
- SendTaskMessage($"收到{i}上传本站数据请求...", MessageLevel.Debug);
- //读取产品结果
- Int16 resultIndex = plc.ReadNode<Int16>(string.Format(addressConfig.In_Result.Address, i));
- SendTaskMessage($"读取plc结果{resultIndex}", MessageLevel.Debug);
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
- //这里缺少上传MES的本站数据结果及开始和结束时间,需要补充
- //从服务器中获取当前时间
- var serverTimeResult = await _mesService.GetServerTimeAsync(ProductMainSN, 2);
- double ct = serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds;
- if (i == 0)
- {
- CTtime = ct;
- }
- if (stationConfig.EnableMES)
- {
- //目前只记录当前站
- if (i == 0)
- await _systemDatabaseService.RecordProductionAsync(new ProductionRecord()
- {
- ProductName = currentProduct.Name,
- ProductCode = ProductMainSN,
- DeviceId = i,
- DeviceName = "",
- Category = resultIndex == 1 ? "OK" : "NG",
- Quantity = 1,
- Remark = $"TotalSeconds:{DateTime.UtcNow.Subtract(_LastMesCheckTime[i]).TotalSeconds.ToString("F2")}",
- });
- }
- LogHelper.WriteLogMes($"【mes开始ADD】");
- SendTaskMessage($"mes开始ADD", MessageLevel.Info);
- StringBuilder submitDataError = new StringBuilder();
- foreach (var item in lockResultsAll)
- {
- if (item.PhotoPassed == "NG")
- {
- submitDataError.Append(item.PhotoName + "_" + item.ResultData + "_Fail,");
- }
- }
- StringBuilder submitData = new StringBuilder();
- StringBuilder submitData2 = new StringBuilder();
- StringBuilder submitData3 = new StringBuilder();
- StringBuilder submitData4 = new StringBuilder();
- foreach (var item in lockResultsAll)
- {
- //if (submitData.Length < 3500)
- //{
- // submitData.Append($"{item.PhotoName}={item.ResultData}");
- //}
- string PhotoName = item.PhotoName.Replace("?", "%3F").Replace("#", "%23").Replace("+", "%2B").Replace("/", "%2F").Replace("%", "%25");
- string data = $"{PhotoName}={item.ResultData}&";
- //string data = $"{item.PhotoName}={item.ResultData}&";
- // 按顺序填满,不超过 3500 就加进去
- if (submitData.Length + data.Length <= 3500)
- {
- submitData.Append(data);
- }
- else if (submitData2.Length + data.Length <= 3500)
- {
- submitData2.Append(data);
- }
- else if (submitData3.Length + data.Length <= 3500)
- {
- submitData3.Append(data);
- }
- else if (submitData4.Length + data.Length <= 3500)
- {
- submitData4.Append(data);
- }
- else
- {
- SendTaskMessage($"上传数据数据超出4组最大限制", MessageLevel.Error);
- }
- }
- bool allSuccess = true;
- bool ok = false;
- string name = currentProduct.Name;
- if (stationConfig.SaveCsvkeyData)
- {
- if (keyData != null)
- {
- ok = CheckKeyBoardValue(keyData, name, out string msg);
- }
- if (ok && resultIndex == 1 ? true : false && isValueOk)
- {
- ShowMes_Result = true;
- }
- else
- {
- ShowMes_Result = false;
- }
- }
- ShowMes_Result = resultIndex == 1 ? true : false;
- //StringBuilder submitDataError2 = new StringBuilder();
- //foreach (var item in keyData)
- //{
- // submitData.Append($"{item.Key}={item.Value}");
- //}
- //keyData.Clear();
- // ShowMes_Result = resultIndex == 1 ? true : false;
- //(bool isSuccess, string response) = await _mesService.SubmitGetAsync(ProductMainSN, "", submitData.ToString(), resultIndex == 1 ? true : false, _LastMesCheckTime[i], serverTimeResult.Now);
- if (submitData.Length > 0)
- {
- string data1 = submitData.ToString().TrimEnd('&');
- (bool isSuccess, string response) = await _mesService.SubmitGetAsync(0, ProductMainSN, "", submitData.ToString(), ShowMes_Result, submitDataError.ToString(), _LastMesCheckTime[i], serverTimeResult.Now);
- allSuccess &= isSuccess;
- }
- if (submitData2.Length > 0)
- {
- string data2 = submitData2.ToString().TrimEnd('&');
- (bool isSuccess, string response) = await _mesService.SubmitGetAsync(1, ProductMainSN, "", submitData2.ToString(), ShowMes_Result, submitDataError.ToString(), _LastMesCheckTime[i], serverTimeResult.Now);
- allSuccess &= isSuccess;
- }
- if (submitData3.Length > 0)
- {
- string data3 = submitData3.ToString().TrimEnd('&');
- (bool isSuccess, string response) = await _mesService.SubmitGetAsync(2, ProductMainSN, "", submitData3.ToString(), ShowMes_Result, submitDataError.ToString(), _LastMesCheckTime[i], serverTimeResult.Now);
- allSuccess &= isSuccess;
- }
- if (submitData4.Length > 0)
- {
- string data4 = submitData4.ToString().TrimEnd('&');
- (bool isSuccess, string response) = await _mesService.SubmitGetAsync(3, ProductMainSN, "", submitData4.ToString(), ShowMes_Result, submitDataError.ToString(), _LastMesCheckTime[i], serverTimeResult.Now);
- allSuccess &= isSuccess;
- }
- if (allSuccess)
- {
- LogHelper.WriteLogMes($"上传mes成功");
- SendTaskMessage($"上传mes成功", MessageLevel.Debug);
- }
- else
- {
- LogHelper.WriteLogMes($"上传mes失败");
- SendTaskMessage($"上传mes失败", MessageLevel.Error);
- }
- //是否保存当前的产品记录至CSV?
- if (stationConfig.SaveCsv)
- {
- string saveppid = "NA";
- string names = currentProduct.Name;
- if (stationConfig.SaveCsvPPID) saveppid = ppid[i];
- // Dictionary<string, double> adjacentDiffDict1 = GetAdjacentDiffDict(keyData1);
- //判断锁付路径字符串是否为空,如果不为空则保存,否则不保存
- if (!string.IsNullOrEmpty(stationConfig.SaveCsvPath))
- {
- foreach (var item in lockResultsAll)
- {
- for (int k = 1; k <= 8; k++)
- {
- if (item.PhotoName == "-" + "_" + k.ToString())
- {
- item.PhotoName = "'-" + "_" + k.ToString();
- }
- if (item.PhotoName == "=" + "_" + k.ToString())
- {
- item.PhotoName = "'=" + "_" + k.ToString();
- }
- //if (item.PhotoName=="-"+k.ToString())
- //{
- // item.PhotoName = "_" + k.ToString();
- //}
- }
- string temp_COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE;
- if (item.PhotoName.Contains("A1b"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware LCD CVR";
- }
- if (item.PhotoName.Contains("A1c") || item.PhotoName.Contains("A1d"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_LCD BZL";
- }
- if (item.PhotoName.Contains("A2"))
- {
- temp_COMMODITY_TYPE = "CAMERA";
- }
- if (item.PhotoName.Contains("A4"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_HNG CVR";
- }
- if (item.PhotoName.Contains("C4"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_PLMRST";
- }
- if (item.PhotoName.Contains("D5"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_DOOR";
- }
- if (item.PhotoName.Contains("B1"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_KB BKT";
- }
- if (item.PhotoName.Contains("B2"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_TP BKT";
- }
- if (item.PhotoName.Contains("D1"))
- {
- temp_COMMODITY_TYPE = "Mechanical Hardware_BTM CVR";
- }
- DFC.Add(new DataFormCtq
- {
- PPID = saveppid,
- PROCESS_NAME = stationConfig.DataInfo.PROCESS_NAME,
- PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
- CTQ_NAME = item.PhotoName,
- CTQ_VALUE = item.ResultData.Replace(",", ";"),
- //CTQ_VALUEE=item.ResultData1,
- CTQ_LSL = item.DownLimit,
- CTQ_USL = item.UpLimit,
- PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
- SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
- COMMODITY_TYPE = temp_COMMODITY_TYPE,
- REVISION = stationConfig.DataInfo.REVISION + "_" + stage,//
- WO = wo[i],//
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = item.PhotoPassed == "OK" ? "PASS" : "FAIL",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "mm",
- //ERROR_MESSAGE = item.PhotoPassed == "OK" ? "" : $"{item.PhotoName} OOS",
- ERROR_MESSAGE = item.PhotoPassed == "OK" ? "" : $"{item.PhotoName}_{item.ResultData.Replace(",", ";")}",
- PD_ATTR_01 = ProductMainSN,//
- PD_ATTR_02 = item.MidLimit,
- PD_ATTR_04 = code,
- PD_ATTR_05 = CTtime.ToString(),
- PD_ATTR_06 = CTtime2.ToString(),
- });
- }
- if (stationConfig.SaveCsvkeyData)
- {
- Dictionary<string, double> adjacentDiffDict = GetAdjacentDiffDict(keyData, names);
- foreach (var items in adjacentDiffDict)
- {
- string pairkey = items.Key;
- string diffvalue = items.Value.ToString("F3");
- DFC.Add(new DataFormCtq
- {
- PPID = saveppid,
- PROCESS_NAME = stationConfig.DataInfo.PROCESS_NAME,
- PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
- CTQ_NAME = pairkey,
- CTQ_VALUE = diffvalue,
- CTQ_LSL = "-0.3",
- CTQ_USL = "0.3",
- PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
- SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
- COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE,
- REVISION = stationConfig.DataInfo.REVISION + "_" + stage,//
- WO = wo[i],//
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = ok ? "Pass" : "FAIL",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "mm",
- ERROR_MESSAGE = ok ? "" : $"{diffvalue}",
- PD_ATTR_01 = ProductMainSN,//
- PD_ATTR_02 = "",
- PD_ATTR_03 = "",
- PD_ATTR_04 = code,
- PD_ATTR_05 = CTtime.ToString(),
- PD_ATTR_06 = CTtime2.ToString(),
- });
- }
- foreach (var items in keyData1)
- {
- string pairkey1 = items.Key;
- string diffvalue1 = items.Value.ToString("F3");
- DFC.Add(new DataFormCtq
- {
- PPID = saveppid,
- PROCESS_NAME = stationConfig.DataInfo.PROCESS_NAME,
- PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
- CTQ_NAME = pairkey1,
- CTQ_VALUE = diffvalue1,
- CTQ_LSL = "0",
- CTQ_USL = "0.3",
- PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
- SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
- COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE,
- REVISION = stationConfig.DataInfo.REVISION + "_" + stage,//
- WO = wo[i],//
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = ok ? "Pass" : "FAIL",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "mm",
- ERROR_MESSAGE = ok ? "" : $"{diffvalue1}",
- PD_ATTR_01 = ProductMainSN,//
- PD_ATTR_02 = "0.15",
- PD_ATTR_03 = "",
- PD_ATTR_04 = code,
- PD_ATTR_05 = CTtime.ToString(),
- PD_ATTR_06 = CTtime2.ToString(),
- });
- }
- }
- //测试使用,强制上传mes为pass
- //if (sysConfig.IsMesResult)
- //{
- // resultToMes.Clear();
- //}
- bool recordResult = RecordStationResult(i, DFC, ProductMainSN, serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath);
- // bool recordResult1 = WriteProductLog( ProductMainSN, serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath, DFC);
- //keyData.Clear();
- if (recordResult)
- {
- SendTaskMessage($"{i}:{stationConfig.DeviceName}产品记录保存成功", MessageLevel.Debug);
- //上传数据
- try
- {
- if (stationConfig.EnableMES)
- {
- DateTime dt = DateTime.Now;
- string filename = $"{ProductMainSN}_{dt.ToString("yyyyMMddHHmmss")}";
- var device = _configService.GetDeviceInfo(i);
- var config = _configService.GetSystemConfiguration();
- string filePath = "";
- (bool isSuc, string resp) = await _mesService.SendFtpFileAsync(ProductMainSN, filename);
- if (isSuc)
- {
- LogHelper.WriteLogMes($"上传数据成功");
- SendTaskMessage($"上传数据成功", MessageLevel.Debug);
- //filePath = $"D:\\Image\\Recored\\{dt.ToString("yyyy-MM")}\\{dt.ToString("MM-dd")}\\{currentProduct.Name}\\{ProductMainSN}";
- filePath = $"{PhotoPath}\\Recored\\{dt.ToString("yyyy-MM")}\\{dt.ToString("MM-dd")}\\{currentProduct.Name}\\{ProductMainSN}";
- //string source_csv2 = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}\\{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}";
- string csvfilename = $"{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}";
- //复制csv
- string source_csv = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}\\{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}.csv";
- //string source_csv1 = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}";
- string target_csv = Path.Combine(filePath, Path.GetFileName(source_csv));
- File.Copy(source_csv, target_csv, true);
- //复制log
- string source_log = $"..\\Log\\LogInfo\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}.txt";
- string target_log = Path.Combine(filePath, Path.GetFileName(source_log));
- File.Copy(source_log, target_log, true);
- CompressionImage(filePath, filename, device.Station, device.FixtureId);
- //上传csv
- bool isAfter20 = dt.Hour >= 20;
- //判断是否是新的一天
- bool isNewDay = dt.Date != _lastCompressDate.Date;
- //当天还没执行过压缩
- if (isAfter20 && isNewDay && !_hasCompressedToday)
- {
- // 执行压缩
- CompressionSingleCsv(source_csv, csvfilename, device.Station, device.FixtureId);
- _lastCompressDate = dt;
- _hasCompressedToday = true;
- LogHelper.WriteLogMes("csv上传数据成功");
- SendTaskMessage($"csv上传数据成功", MessageLevel.Debug);
- }
- // 跨天后重置当天执行标记
- if (!isNewDay && _hasCompressedToday)
- {
- _hasCompressedToday = false;
- }
- }
- else
- {
- LogHelper.WriteLogMes($"上传数据失败");
- SendTaskMessage($"上传数据失败", MessageLevel.Error);
- }
- }
- else
- {
- LogHelper.WriteLogMes($"未启用mes");
- SendTaskMessage($"未启用mes", MessageLevel.Error);
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage($"上传数据时出错:{ex.Message}", MessageLevel.Error);
- LogHelper.WriteLogError($"上传数据时出错", ex);
- }
- }
- else
- {
- SendTaskMessage($"{i}:{stationConfig.DeviceName}产品记录保存失败", MessageLevel.Error);
- }
- }
- else
- {
- SendTaskMessage($"{i}:{stationConfig.DeviceName}工位未配置保存路径,无法保存产品记录", MessageLevel.Error);
- }
- }
- else
- {
- SendTaskMessage($"{i}:{stationConfig.DeviceName}工位未配置保存产品记录", MessageLevel.Debug);
- }
- if (stationConfig.SaveCsvJmp)
- {
- bool kb = WriteProductLogKB(DFC, ProductMainSN);
- bool tp = WriteProductLogTP(DFC, ProductMainSN);
- if (kb)
- {
- SendTaskMessage($"保存KB键盘格JMP数据成功", MessageLevel.Debug);
- }
- else
- {
- SendTaskMessage($"保存KB键盘格JMP数据失败", MessageLevel.Error);
- }
- if (tp)
- {
- SendTaskMessage($"保存TP键盘格JMP数据成功", MessageLevel.Debug);
- }
- else
- {
- SendTaskMessage($"保存TP键盘格JMP数据失败", MessageLevel.Error);
- }
- }
- else
- {
- SendTaskMessage($"未启用保存键盘格JMP数据", MessageLevel.Info);
- }
- LogHelper.WriteLogMes($"【mes结束ADD】");
- SendTaskMessage($"mes结束ADD", MessageLevel.Info);
- }
- else
- {
- SendTaskMessage($"{i}过站检查信号:state={state},处理为默认状态", MessageLevel.Alarm);
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)0);
- }
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage(ex.Message, MessageLevel.Error);
- }
- }
- /// <summary>
- /// 异步执行流程拍照
- /// </summary>
- /// <param name="pointIndex"></param>
- /// <param name="procedureId"></param>
- /// <returns></returns>
- private Task<(bool IsSucceed, bool[] Result, string Message)> ExecuteProcedureAsync(int pointIndex, Guid procedureId)
- {
- return Task.Run(async () =>
- {
- List<bool> results = new List<bool>();
- // 获取当前产品
- var currentProduct = _productService.GetCurrentProduct();
- if (currentProduct == null)
- {
- return (false, null, "当前产品为空,未加载产品!");
- }
- var cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures == null || cameraProcedures.Count == 0)
- {
- SendTaskMessage($"当前产品未配置 CameraProcedures,无法执行视觉流程", MessageLevel.Alarm);
- return (false, null, $"当前产品未配置 CameraProcedures,无法执行视觉流程");
- }
- var ctsAll = new CancellationTokenSource();
- try
- {
- ProcedureModel selectedProcedure = null;
- try
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == procedureId);
- if (selectedProcedure != null) break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={pointIndex}", MessageLevel.Alarm);
- return (false, null, $"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId}");
- }
- SendTaskMessage($"开始执行 AOI 流程 (Point#{pointIndex}) 流程Id={pointIndex}", MessageLevel.Debug);
- try
- {
- //1. 执行拍照,图像处理
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint1(selectedProcedure, null, null, ctsAll.Token);
- if (visionResult.Count == 0)
- {
- SendTaskMessage("Count值为0", MessageLevel.Alarm);
- return (false, null, $"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId}");
- }
- //2. 结果分析
- for (int i = 1; i <= visionResult.Count; i++)
- {
- LockResult lockResult1 = new LockResult();
- //if (pointIndex == currentProduct.PhotoCount && selectedProcedure.Id == currentProduct.FixedUpCamera1ProcedureId && i == 1)
- //{
- // lockResult1.Number = 1;
- //}
- string[] strpoints1 = visionResult.Items[i].Split(',');
- lockResult1.PhotoName = strpoints1[0];
- string[] body1 = strpoints1[1].Split(";");
- string body2 = null;
- if (body1.Length == 8)
- {
- body2 = $"{body1[0]},{body1[2]},{body1[4]},{body1[6]}";
- }
- else
- {
- body2 = strpoints1[1];
- }
- lockResult1.ResultData = body2;
- lockResult1.PhotoCode = ProductMainSN;
- var globalParam = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Name == strpoints1[0]);
- if (globalParam != null)
- {
- lockResult1.UpLimit = globalParam.Param1;
- lockResult1.DownLimit = globalParam.Param2;
- lockResult1.MidLimit = globalParam.Param5;
- string ResData = strpoints1[1];
- if (ResData.Contains("NA"))
- {
- ResData = "-1000";
- }
- string[] body = ResData.Split(";");
- bool resultflog = true;
- foreach (var item in body)
- {
- if (Convert.ToDouble(item) >= Convert.ToDouble(globalParam.Param2) && Convert.ToDouble(item) <= Convert.ToDouble(globalParam.Param1))
- {
- }
- else
- {
- resultflog = false;
- }
- }
- if (resultflog)
- {
- lockResult1.PhotoPassed = "OK";
- results.Add(true);
- }
- else
- {
- lockResult1.PhotoPassed = "NG";
- results.Add(false);
- }
- }
- lock (_stateLock)
- {
- lockResultsAll.Add(lockResult1);
- }
- App.Current.Dispatcher.Invoke(() =>
- {
- _eventAggregator.GetEvent<LockFinishNotification>().Publish(lockResult1);
- });
- }
- //排序
- //lock (_stateLock)
- //{
- // var bf1 = lockResultsAll.OrderBy(p => p.Number);
- // lockResultsAll = new List<LockResult>(bf1);
- //}
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("执行 AOI 视觉流程时出错", ex);
- SendTaskMessage($"执行 AOI 视觉流程异常: {ex.Message}", MessageLevel.Alarm);
- }
- return (true, results.ToArray(), $"成功");
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理固定相机检测拍照时出错", ex);
- return (false, null, $"处理固定相机检测拍照时出错");
- }
- });
- }
- /// <summary>
- /// 异步执行流程拍照
- /// </summary>
- /// <param name="pointIndex"></param>
- /// <param name="procedureId"></param>
- /// <returns></returns>
- private async Task ExecuteProcedureAsync(int pointIndex, Guid procedureId, ICogImage[] images, bool is3dmodel, ProductModel currentProduct)
- {
- List<bool> results = new List<bool>();
- var cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures == null || cameraProcedures.Count == 0)
- {
- SendTaskMessage($"当前产品未配置 CameraProcedures,无法执行视觉流程", MessageLevel.Alarm);
- //return (false, null, $"当前产品未配置 CameraProcedures,无法执行视觉流程");
- AllResult.Add(false);
- }
- var ctsAll = new CancellationTokenSource();
- try
- {
- ProcedureModel selectedProcedure = null;
- try
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == procedureId);
- if (selectedProcedure != null) break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={pointIndex}", MessageLevel.Alarm);
- //return (false, null, $"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId}");
- AllResult.Add(false);
- }
- SendTaskMessage($"开始执行 AOI 流程 (Point#{pointIndex}) 流程Id={pointIndex}", MessageLevel.Debug);
- try
- {
- var sysConfig = _configService.GetSystemConfiguration();
- if (selectedProcedure.Id == currentProduct.MoveDownCameraLockPhotoProcedureId && sysConfig.TurnOffAllLightUse == true)
- {
- await _remoteCommandService.TurnOffLightAfterPhoto(selectedProcedure);
- }
- PhotoPath = selectedProcedure.SavePath;
- //1. 执行拍照,图像处理
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint1(selectedProcedure, images, null, null, ctsAll.Token, is3dmodel);
- if (visionResult.Count == 0)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId} Count值为0", MessageLevel.Alarm);
- //return (false, null, $"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId}");
- AllResult.Add(false);
- }
- //2. 结果分析
- var stationConfig = _configService.GetDeviceInfo(0);
- for (int i = 1; i <= visionResult.Count; i++)
- {
- LockResult lockResult1 = new LockResult();
- try
- {
- string[] strpoints1 = visionResult.Items[i].Split(',');
- string[] body1 = strpoints1[1].Split(";");
- if (body1.Length > 1)
- {
- for (int j = 1; j <= body1.Length; j++)
- {
- lockResult1.PhotoName = strpoints1[0] + "_" + j.ToString();
- lockResult1.ResultData = body1[j - 1];
- lockResult1.PhotoCode = ProductMainSN;
- var globalParam = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Name == strpoints1[0]);
- if (globalParam != null)
- {
- lockResult1.UpLimit = globalParam.Param1;
- lockResult1.DownLimit = globalParam.Param2;
- lockResult1.MidLimit = globalParam.Param5;
- string ResData = body1[j - 1];
- if (ResData.Contains("NA"))
- {
- ResData = "-999";
- }
- bool resultflog = true;
- if (Convert.ToDouble(ResData) >= Convert.ToDouble(globalParam.Param2) && Convert.ToDouble(ResData) <= Convert.ToDouble(globalParam.Param1))
- {
- }
- else
- {
- SendTaskMessage($"检测项{lockResult1.PhotoName}结果{ResData}超出上下限!", MessageLevel.Error);
- resultflog = false;
- }
- if (resultflog)
- {
- lockResult1.PhotoPassed = "OK";
- AllResult.Add(true);
- }
- else
- {
- lockResult1.PhotoPassed = "NG";
- AllResult.Add(false);
- }
- }
- lockResultsAll.Add(lockResult1.Copy());
- _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- _eventAggregator
- .GetEvent<LockFinishNotification>()
- .Publish(lockResult1);
- }));
- }
- }
- else
- {
- lockResult1.PhotoName = strpoints1[0];
- lockResult1.ResultData = strpoints1[1];
- lockResult1.PhotoCode = ProductMainSN;
- var globalParam = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Name == strpoints1[0]);
- if (globalParam != null)
- {
- lockResult1.UpLimit = globalParam.Param1;
- lockResult1.DownLimit = globalParam.Param2;
- lockResult1.MidLimit = globalParam.Param5;
- string ResData = strpoints1[1];
- if (ResData.Contains("NA"))
- {
- ResData = "-1000";
- }
- bool resultflog = true;
- if (Convert.ToDouble(ResData) >= Convert.ToDouble(globalParam.Param2) && Convert.ToDouble(ResData) <= Convert.ToDouble(globalParam.Param1))
- {
- }
- else
- {
- SendTaskMessage($"检测项{lockResult1.PhotoName}结果{ResData}超出上下限!", MessageLevel.Error);
- resultflog = false;
- }
- if (resultflog)
- {
- lockResult1.PhotoPassed = "OK";
- AllResult.Add(true);
- }
- else
- {
- lockResult1.PhotoPassed = "NG";
- AllResult.Add(false);
- }
- }
- lockResultsAll.Add(lockResult1.Copy());
- _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- _eventAggregator
- .GetEvent<LockFinishNotification>()
- .Publish(lockResult1);
- }));
- }
- if (stationConfig.SaveCsvkeyData)
- {
- if (body1.Length >= 5)
- {
- string keyName = strpoints1[0].Split('-').Last().Trim();
- List<double> list = new List<double>();
- foreach (string v in body1)
- {
- if (double.TryParse(v.Trim(), out double num))
- {
- if (num == 999)
- {
- continue;
- }
- list.Add(num);
- }
- }
- if (list.Count == 0)
- {
- continue;
- }
- double max = list.Max();
- double min = list.Min();
- double chazhi = max - min;
- double average = list.Average();
- if (max - min > 0.3)
- {
- isValueOk = false;
- SendTaskMessage($"键盘格{keyName}最大值{max}与最小值{min}相差大于0.3!", MessageLevel.Error);
- }
- if (keyData != null)
- {
- if (!keyData.ContainsKey(keyName))
- {
- keyData.TryAdd(keyName, average);
- }
- if (!keyData1.ContainsKey(keyName))
- {
- keyData1.TryAdd(keyName, chazhi);
- }
- }
- else
- {
- keyData.TryAdd(keyName, average);
- keyData1.TryAdd(keyName, chazhi);
- }
- }
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage($"拆分视觉结果出错:{ex}", MessageLevel.Error);
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("执行 AOI 视觉流程时出错", ex);
- SendTaskMessage($"执行 AOI 视觉流程异常: {ex.Message}", MessageLevel.Alarm);
- }
- //return (true, results.ToArray(), $"成功");
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理固定相机检测拍照时出错", ex);
- //return (false, null, $"处理固定相机检测拍照时出错");
- }
- finally
- {
- try
- {
- countdown?.Signal(); // -1
- }
- catch (InvalidOperationException ex)
- {
- LogHelper.WriteLogError("AOI流程完成计数Signal失败", ex);
- }
- }
- }
- private void ClearCountdown()
- {
- try
- {
- var currentCountdown = countdown;
- if (currentCountdown == null || currentCountdown.IsSet)
- {
- return;
- }
- currentCountdown.Signal(currentCountdown.CurrentCount);
- }
- catch (InvalidOperationException ex)
- {
- LogHelper.WriteLogError("AOI流程计数清零失败", ex);
- }
- }
- /// <summary>
- /// 是否是3D相机
- /// </summary>
- /// <param name="procedureId"></param>
- /// <returns></returns>
- private bool Is3D(Guid procedureId)
- {
- // 获取当前产品
- var currentProduct = _productService.GetCurrentProduct();
- if (currentProduct == null)
- {
- return false;
- }
- var cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures == null || cameraProcedures.Count == 0)
- {
- return false;
- }
- ProcedureModel selectedProcedure = null;
- try
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == procedureId);
- if (selectedProcedure != null) break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- return false;
- }
- var camera = _cameraService.GetCamera(selectedProcedure.CameraId);
- if (camera == null)
- {
- return false;
- }
- return camera.Is3D;
- }
- /// <summary>
- /// 2D相机先采集图像
- /// </summary>
- /// <param name="procedureId"></param>
- /// <returns></returns>
- private async Task<(bool IsSucceed, ICogImage[] imges, string Message)> GrabImage(int pointIndex, Guid procedureId)
- {
- // 获取当前产品
- var currentProduct = _productService.GetCurrentProduct();
- if (currentProduct == null)
- {
- return (false, null, "当前产品为空,未加载产品!");
- }
- var cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures == null || cameraProcedures.Count == 0)
- {
- SendTaskMessage($"当前产品未配置 CameraProcedures,无法执行视觉流程", MessageLevel.Alarm);
- return (false, null, $"当前产品未配置 CameraProcedures,无法执行视觉流程");
- }
- try
- {
- ProcedureModel selectedProcedure = null;
- try
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == procedureId);
- if (selectedProcedure != null) break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={pointIndex}", MessageLevel.Alarm);
- return (false, null, $"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId}");
- }
- SendTaskMessage($"开始执行 AOI 流程 (Point#{pointIndex}) 流程Id={pointIndex}", MessageLevel.Debug);
- try
- {
- var sysConfig = _configService.GetSystemConfiguration();
- if (selectedProcedure.Id == currentProduct.FixedDownCameraProcedureId && sysConfig.TurnOnAllLightUse == true)
- {
- await _remoteCommandService.SetLightBeforePhoto(selectedProcedure);
- }
- //1. 执行拍照
- //return await _remoteCommandService.ExecuteGrabImageAsync(selectedProcedure);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("执行 AOI 视觉图像采集时出错", ex);
- SendTaskMessage($"执行 AOI 视觉图像采集时出错: {ex.Message}", MessageLevel.Alarm);
- }
- return (false, null, $"图像采集失败");
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理固定相机检测拍照时出错", ex);
- return (false, null, $"处理固定相机检测拍照时出错");
- }
- }
- /// <summary>
- /// 为所有相机设置批处理点数(会调用具体相机实现的 SetBatchPoints)
- /// </summary>
- /// <param name="points"></param>
- public void SetBatchPoints(int CameraNum, int points)
- {
- try
- {
- if (points == 0 || points < 0)
- {
- return;
- }
- var cameras = _cameraService.GetCameraByNumber(CameraNum);
- if (cameras == null) return;
- try
- {
- // 优先针对已知的 SSZNCamera 类型直接调用
- if (cameras is TeamAAS_VP.Core.Cameras.SSZNCamera sszn)
- {
- sszn.CameraRevFinish = false;
- sszn.SetBatchPoints(points);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"SetBatchPoints to camera {cameras?.Name} failed", ex);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("SetBatchPoints failed", ex);
- }
- }
- /// <summary>
- /// 为所有相机设置产品配方(会调用具体相机实现的 SetBatchPoints)
- /// </summary>
- /// <param name="points"></param>
- public void SetProducts(int CameraNum, int points)
- {
- try
- {
- if (points < 0)
- {
- return;
- }
- var cameras = _cameraService.GetCameraByNumber(CameraNum);
- if (cameras == null) return;
- try
- {
- // 优先针对已知的 SSZNCamera 类型直接调用
- if (cameras is TeamAAS_VP.Core.Cameras.SSZNCamera sszn)
- {
- sszn.CameraRevFinish = false;
- sszn.SetProducts(CameraNum, points);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"SetBatchPoints to camera {cameras?.Name} failed", ex);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("SetBatchPoints failed", ex);
- }
- }
- public void SetBatchPoints(int[] CameraSpoints)
- {
- try
- {
- for (int i = 0; i < CameraSpoints.Length; i++)
- {
- SetBatchPoints(i + 1, CameraSpoints[i]);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("SetBatchPoints failed", ex);
- }
- }
- public void SetProducts(int[] CameraSpoints)
- {
- try
- {
- for (int i = 0; i < CameraSpoints.Length; i++)
- {
- SetProducts(i + 1, CameraSpoints[i]);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("SetProducts failed", ex);
- }
- }
- #endregion
- #region 方法
- private void SendTaskMessage(string msg, MessageLevel level)
- {
- _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- _eventAggregator.GetEvent<TaskMessageNotification>().Publish(new Models.MessageStruct() { Message = msg, level = level });
- }));
- }
- public bool concurrenty = true;
- public void CurrentRunStatus()
- {
- if (!concurrenty)
- {
- return;
- }
- concurrenty = false;
- bool connectStaus = true;
- bool mesStatus = true;
- bool paraStatus = true;
- try
- {
- var stationConfig = _configService.GetDeviceInfo(0);
- if (!stationConfig.EnableMES || !stationConfig.EnableDoubleMes || !stationConfig.SaveCsv)
- {
- mesStatus = false;
- }
- foreach (var item in Status)
- {
- if (item.Background == System.Windows.Media.Brushes.Red)
- {
- connectStaus = false;
- break;
- }
- }
- }
- catch (Exception)
- {
- connectStaus = false;
- }
- var curUser = _systemDatabaseService.GetCurrentUser();
- if (connectStaus && mesStatus && _LastAutoRunning && curUser.userPart == UserPart.Operator)
- {
- CurrentDisplayMode = RunDisplayMode.Auto;
- SendTaskMessage("当前为运行模式", MessageLevel.Info);
- }
- else
- {
- CurrentDisplayMode = RunDisplayMode.Manual;
- SendTaskMessage("当前为调机模式", MessageLevel.Info);
- }
- concurrenty = true;
- }
- #region 键盘相邻关系
- /// <summary>
- /// 校验键盘所有按键值,相邻差值不能大于 0.3
- /// </summary>
- public bool CheckKeyBoardValue(ConcurrentDictionary<string, double> keyDic, string name, out string errorMsg)
- {
- errorMsg = "";
- try
- {
- // 2. 获取每个按键的【真实相邻按键】
- Dictionary<string, List<string>> neighborMap = GetUSKeyboardNeighborMap();
- if (name.Contains("US"))
- {
- neighborMap = GetUSKeyboardNeighborMap();
- }
- else if (name.Contains("UK"))
- {
- neighborMap = GetUKKeyboardNeighborMap();
- }
- else if (name.Contains("JP"))
- {
- neighborMap = GetJPKeyboardNeighborMap();
- }
- else if (name.Contains("BZ"))
- {
- neighborMap = GetBZKeyboardNeighborMap();
- }
- else
- {
- SendTaskMessage("未查找到当前产品名称的键盘相邻关系", MessageLevel.Error);
- }
- // 3. 开始校验:每个按键 和 相邻按键 差值 ≤0.3
- foreach (var item in keyDic)
- {
- string key = item.Key.ToUpper();
- double val = item.Value;
- // 没有相邻关系就跳过
- if (!neighborMap.ContainsKey(key))
- continue;
- // 遍历所有相邻按键
- foreach (string neighbor in neighborMap[key])
- {
- string n = neighbor.ToUpper();
- if (!keyDic.ContainsKey(n))
- continue;
- double nVal = keyDic[n];
- double diff = Math.Abs(val - nVal);
- // 超过 0.3 直接报错
- if (diff > 0.3)
- {
- SendTaskMessage($"按键 {key}({val}) 与相邻按键 {n}({nVal}) 差值 {diff:F3} > 0.3,校验不通过", MessageLevel.Error);
- return false;
- }
- }
- }
- SendTaskMessage("所有键盘按键相邻差值校验通过", MessageLevel.Debug);
- return true;
- }
- catch (Exception ex)
- {
- errorMsg = "校验异常:" + ex.Message;
- return false;
- }
- }
- /// <summary>
- /// 键盘相邻关系-US
- /// </summary>
- private Dictionary<string, List<string>> GetUSKeyboardNeighborMap()
- {
- #region 以前的键盘相邻关系-US
- //return new Dictionary<string, List<string>>
- //{
- // // ==============================================
- // // 第一行:ESC + F1~F12
- // // ==============================================
- // ["ESC"] = new List<string> { "F1", "~", },
- // ["F1"] = new List<string> { "ESC", "F2", "1" },
- // ["F2"] = new List<string> { "F1", "F3", "2" },
- // ["F3"] = new List<string> { "F2", "F4", "2", "3" },
- // ["F4"] = new List<string> { "F3", "F5", "3", "4" },
- // ["F5"] = new List<string> { "F4", "F6", "4", "5" },
- // ["F6"] = new List<string> { "F5", "F7", "5", "6" },
- // ["F7"] = new List<string> { "F6", "F8", "6", "7" },
- // ["F8"] = new List<string> { "F7", "F9", "7", "8" },
- // ["F9"] = new List<string> { "F8", "F10", "8", "9" },
- // ["F10"] = new List<string> { "F9", "F11", "9", "0" },
- // ["F11"] = new List<string> { "F10", "F12", "0", "-" },
- // ["F12"] = new List<string> { "F11", "-", "=", "Insert" },
- // ["Insert"] = new List<string> { "F12", "Power", "Backspace" },
- // ["Power"] = new List<string> { "Backspace" },
- // // ==============================================
- // // 第二行:` 1 2 3 4 5 6 7 8 9 0 - = Backspace
- // // ==============================================
- // ["~"] = new List<string> { "ESC", "1", "TAB" },
- // ["1"] = new List<string> { "F1", "`", "2", "TAB", "Q" },
- // ["2"] = new List<string> { "F2", "1", "3", "Q", "W" },
- // ["3"] = new List<string> { "F3", "F4", "2", "4", "W", "E" },
- // ["4"] = new List<string> { "F4", "F5", "3", "5", "E", "R" },
- // ["5"] = new List<string> { "F5", "F6", "4", "6", "R", "T" },
- // ["6"] = new List<string> { "F6", "F7", "5", "7", "T", "Y" },
- // ["7"] = new List<string> { "F7", "F8", "6", "8", "Y", "U" },
- // ["8"] = new List<string> { "F8", "F9", "7", "9", "U", "I" },
- // ["9"] = new List<string> { "F9", "F10", "8", "0", "I", "O" },
- // ["0"] = new List<string> { "F10", "F11", "9", "-", "O", "P" },
- // ["-"] = new List<string> { "F11", "F12", "0", "=", "P", "{" },
- // ["="] = new List<string> { "F12", "-", "Backspace", "{", "}" },
- // ["Backspace"] = new List<string> { "Insert", "=", "}", "|", "Power" },
- // // ==============================================
- // // 第三行:TAB Q W E R T Y U I O P [ ] \
- // // ==============================================
- // ["TAB"] = new List<string> { "`", "1", "Q", "CapsLock" },
- // ["Q"] = new List<string> { "TAB", "`", "1", "2", "W", "A", "CapsLock" },
- // ["W"] = new List<string> { "Q", "1", "2", "3", "E", "A", "S" },
- // ["E"] = new List<string> { "W", "2", "3", "4", "R", "S", "D" },
- // ["R"] = new List<string> { "E", "3", "4", "5", "T", "D", "F" },
- // ["T"] = new List<string> { "R", "4", "5", "6", "Y", "F", "G" },
- // ["Y"] = new List<string> { "T", "5", "6", "7", "U", "G", "H" },
- // ["U"] = new List<string> { "Y", "6", "7", "8", "I", "H", "J" },
- // ["I"] = new List<string> { "U", "7", "8", "9", "O", "J", "K" },
- // ["O"] = new List<string> { "I", "8", "9", "0", "P", "K", "L" },
- // ["P"] = new List<string> { "O", "9", "0", "-", "{", "L", ";" },
- // ["{"] = new List<string> { "P", "0", "-", "=", "}", ";", "'" },
- // ["}"] = new List<string> { "{", "-", "=", "Backspace", "|", "'", "Enter" },
- // ["|"] = new List<string> { "}", "Backspace", "Enter" },
- // // ==============================================
- // // 第四行:CapsLock A S D F G H J K L ; ' Enter
- // // ==============================================
- // ["CapsLock"] = new List<string> { "TAB", "Q", "A", "LeftShift" },
- // ["A"] = new List<string> { "CapsLock", "Q", "W", "S", "LeftShift", "Z" },
- // ["S"] = new List<string> { "A", "W", "E", "D", "Z", "X", "LeftShift" },
- // ["D"] = new List<string> { "S", "E", "R", "F", "X", "C", "LeftShift" },
- // ["F"] = new List<string> { "D", "R", "T", "G", "C", "V" },
- // ["G"] = new List<string> { "F", "T", "Y", "H", "V", "B" },
- // ["H"] = new List<string> { "G", "Y", "U", "J", "B", "N" },
- // ["J"] = new List<string> { "H", "U", "I", "K", "N", "M" },
- // ["K"] = new List<string> { "J", "I", "O", "L", "M", "," },
- // ["L"] = new List<string> { "K", "O", "P", ";", "<", ">", "?" },
- // [";"] = new List<string> { "L", "P", "{", "'", ">", "?" },
- // ["'"] = new List<string> { ";", "{", "}", "Enter", "?" },
- // ["Enter"] = new List<string> { "'", "}", "|", "RightShift" },
- // // ==============================================
- // // 第五行:LeftShift Z X C V B N M , . / RightShift
- // // ==============================================
- // ["Shift"] = new List<string> { "CapsLock", "A", "S", "D", "Z", "Ctrl", "Fn" },
- // ["Z"] = new List<string> { "Shift", "A", "S", "X" },
- // ["X"] = new List<string> { "Z", "S", "D", "C" },
- // ["C"] = new List<string> { "X", "D", "F", "V" },
- // ["V"] = new List<string> { "C", "F", "G", "B" },
- // ["B"] = new List<string> { "V", "G", "H", "N" },
- // ["N"] = new List<string> { "B", "H", "J", "M" },
- // ["M"] = new List<string> { "N", "J", "K", "<" },
- // ["<"] = new List<string> { "M", "K", "L", ">" },
- // [">"] = new List<string> { "<", "L", ";", "?" },
- // ["?"] = new List<string> { ">", ";", "'", "Shift2" },
- // ["Shift2"] = new List<string> { "?", "Enter" },
- // // ==============================================
- // // 第六行:Ctrl Fn Win Alt Space Alt Fn Ctrl ← ↓ →
- // // ==============================================
- // ["Ctrl1"] = new List<string> { "Fn", "Shift" },
- // ["Fn"] = new List<string> { "Ctrl", "Win", "Shift" },
- // ["Win"] = new List<string> { "Fn", "Alt" },
- // ["Alt1"] = new List<string> { "Win", "Space" },
- // ["Space1"] = new List<string> { "Alt", "Alt2" },
- // ["Alt2"] = new List<string> { "Space", "Ctrl2" },
- // // ["RightFn"] = new List<string> { "RightAlt", "RightCtrl" },
- // ["Ctrl2"] = new List<string> { "Alt2", "Left", "Updown", "Right" },
- // ["Left"] = new List<string> { "RightCtrl", "Updown" },
- // ["Updown"] = new List<string> { "Left", "Right", "Ctrl2" },
- // ["Right"] = new List<string> { "Updown", "Ctrl2" }
- //};
- #endregion
- return new Dictionary<string, List<string>>
- {
- // ==============================================
- // 第一行:110 + 112~113
- // ==============================================
- ["110"] = new List<string> { "112", "1", },
- ["112"] = new List<string> { "110", "113", "2" },
- ["113"] = new List<string> { "112", "114", "3" },
- ["114"] = new List<string> { "113", "115", "4" },
- ["115"] = new List<string> { "114", "116", "5" },
- ["116"] = new List<string> { "115", "117", "6" },
- ["117"] = new List<string> { "116", "118", "7" },
- ["118"] = new List<string> { "117", "119", "8" },
- ["119"] = new List<string> { "118", "120", "8" },
- ["120"] = new List<string> { "119", "121", "9" },
- ["121"] = new List<string> { "120", "122", "10" },
- ["122"] = new List<string> { "121", "123", "11" },
- ["123"] = new List<string> { "122", "75", "12" },
- ["75"] = new List<string> { "123", "76", "13" },
- ["76"] = new List<string> { "75", "PWB", "15" },
- ["PWB"] = new List<string> { "76", "15" },
- // ==============================================
- // 第二行:` 1 2 3 4 5 6 7 8 9 10 11 12 13 15
- // ==============================================
- ["1"] = new List<string> { "110", "2", "16" },
- ["2"] = new List<string> { "112", "1", "3", "16" },
- ["3"] = new List<string> { "113", "2", "4", "17" },
- ["4"] = new List<string> { "114", "3", "5", "19" },
- ["5"] = new List<string> { "115", "4", "6", "20" },
- ["6"] = new List<string> { "116", "5", "7", "21" },
- ["7"] = new List<string> { "117", "6", "8", "22" },
- ["8"] = new List<string> { "118", "7", "9", "23" },
- ["9"] = new List<string> { "120", "8", "10", "24" },
- ["10"] = new List<string> { "121", "9", "11", "25" },
- ["11"] = new List<string> { "122", "10", "12", "26" },
- ["12"] = new List<string> { "123", "11", "13", "27" },
- ["13"] = new List<string> { "75", "12", "15", "28" },
- ["15"] = new List<string> { "76", "13", "29" },
- // ==============================================
- // 第三行:16 17 18 19 20 21 22 23 24 25 26 27 28 29
- // ==============================================
- ["16"] = new List<string> { "1", "17", "30" },
- ["17"] = new List<string> { "3", "16", "18", "31" },
- ["18"] = new List<string> { "3", "17", "19", "32" },
- ["19"] = new List<string> { "4", "18", "20", "33" },
- ["20"] = new List<string> { "5", "19", "21", "34" },
- ["21"] = new List<string> { "6", "20", "22", "35" },
- ["22"] = new List<string> { "7", "21", "23", "36" },
- ["23"] = new List<string> { "8", "22", "24", "37" },
- ["24"] = new List<string> { "9", "23", "25", "38" },
- ["25"] = new List<string> { "10", "24", "26", "39" },
- ["26"] = new List<string> { "11", "25", "27", "40" },
- ["27"] = new List<string> { "12", "26", "28", "41" },
- ["28"] = new List<string> { "13", "27", "29", "43" },
- ["29"] = new List<string> { "15", "28", "43" },
- // ==============================================
- // 第四行:30 31 32 33 34 35 36 37 38 39 40 41 43
- // ==============================================
- ["30"] = new List<string> { "16", "31", "44" },
- ["31"] = new List<string> { "17", "30", "32", "46" },
- ["32"] = new List<string> { "18", "31", "33", "47" },
- ["33"] = new List<string> { "19", "32", "34", "48" },
- ["34"] = new List<string> { "20", "33", "35", "49" },
- ["35"] = new List<string> { "21", "34", "36", "50" },
- ["36"] = new List<string> { "22", "35", "37", "51" },
- ["37"] = new List<string> { "23", "36", "38", "52" },
- ["38"] = new List<string> { "24", "37", "39", "53" },
- ["39"] = new List<string> { "25", "38", "40", "54" },
- ["40"] = new List<string> { "26", "39", "41", "55" },
- ["41"] = new List<string> { "27", "40", "43", "55" },
- ["43"] = new List<string> { "29", "41", "57" },
- // ==============================================
- // 第五行:44 46 47 48 49 50 51 52 53 54 55 57
- // ==============================================
- ["44"] = new List<string> { "30", "46", "58" },
- ["46"] = new List<string> { "31", "44", "47", "127" },
- ["47"] = new List<string> { "32", "46", "48", "60" },
- ["48"] = new List<string> { "33", "47", "49", "61_1" },
- ["49"] = new List<string> { "34", "48", "50", "61_1" },
- ["50"] = new List<string> { "35", "49", "51", "61_1" },
- ["51"] = new List<string> { "36", "50", "52", "61_2" },
- ["52"] = new List<string> { "37", "51", "53", "61_2" },
- ["53"] = new List<string> { "38", "52", "54", "62" },
- ["54"] = new List<string> { "39", "53", "55", "64" },
- ["55"] = new List<string> { "40", "54", "57", "79" },
- ["57"] = new List<string> { "43", "55", "89" },
- // ==============================================
- // 第六行:58 59 127 60 61_1 61_2 62 64 83_84 89
- // ==============================================
- ["58"] = new List<string> { "44", "59" },
- ["59"] = new List<string> { "44", "58", "60" },
- ["127"] = new List<string> { "46", "59", "60" },
- ["60"] = new List<string> { "47", "127", "61_1" },
- ["61_1"] = new List<string> { "49", "60" },
- ["61_2"] = new List<string> { "51", "62" },
- // ["RightFn"] = new List<string> { "RightAlt", "RightCtrl" },
- ["62"] = new List<string> { "53", "61_2", "64" },
- ["64"] = new List<string> { "54", "62", "79" },
- ["79"] = new List<string> { "55", "64", "83_84" },
- ["83_84"] = new List<string> { "57", "79", "89" },
- ["89"] = new List<string> { "57", "83_84" }
- };
- }
- /// <summary>
- /// UK欧版键盘相邻关系
- /// </summary>
- private Dictionary<string, List<string>> GetUKKeyboardNeighborMap()
- {
- #region 以前的键盘相邻关系-UK
- //return new Dictionary<string, List<string>>
- //{
- // // ==============================================
- // // 第一行:Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Insert delete Power
- // // ==============================================
- // ["Esc"] = new List<string> { "F1", "`" },
- // ["F1"] = new List<string> { "Esc", "F2", "`", "1" },
- // ["F2"] = new List<string> { "F1", "F3", "1", "2" },
- // ["F3"] = new List<string> { "F2", "F4", "2", "3" },
- // ["F4"] = new List<string> { "F3", "F5", "3", "4" },
- // ["F5"] = new List<string> { "F4", "F6", "4", "5" },
- // ["F6"] = new List<string> { "F5", "F7", "5", "6" },
- // ["F7"] = new List<string> { "F6", "F8", "6", "7" },
- // ["F8"] = new List<string> { "F7", "F9", "7", "8" },
- // ["F9"] = new List<string> { "F8", "F10", "8", "9" },
- // ["F10"] = new List<string> { "F9", "F11", "9", "0" },
- // ["F11"] = new List<string> { "F10", "F12", "0", "-" },
- // ["F12"] = new List<string> { "F11", "Insert", "-", "=" },
- // ["Insert"] = new List<string> { "F12", "Delete", "=", "backspace" },
- // ["Delete"] = new List<string> { "Insert", "backspace" },
- // // ==============================================
- // // 第二行 、1 2 3 4 5 6 7 8 9 0 _ = Backspace
- // // ==============================================
- // ["`"] = new List<string> { "Esc", "F1", "1", "Tab" },
- // ["1"] = new List<string> { "`", "F1", "F2", "2", "Tab", "Q" },
- // ["2"] = new List<string> { "1", "F2", "F3", "3", "Q", "W" },
- // ["3"] = new List<string> { "2", "F3", "F4", "4", "W", "E" },
- // ["4"] = new List<string> { "3", "F4", "F5", "5", "E", "R" },
- // ["5"] = new List<string> { "4", "F5", "F6", "6", "R", "T" },
- // ["6"] = new List<string> { "5", "F6", "F7", "7", "T", "Y" },
- // ["7"] = new List<string> { "6", "F7", "F8", "8", "Y", "U" },
- // ["8"] = new List<string> { "7", "F8", "F9", "9", "U", "I" },
- // ["9"] = new List<string> { "8", "F9", "F10", "0", "I", "O" },
- // ["0"] = new List<string> { "9", "F10", "F11", "-", "O", "P" },
- // ["-"] = new List<string> { "0", "F11", "F12", "=", "P", "[" },
- // ["="] = new List<string> { "-", "F12", "Insert", "backspace", "[", "]" },
- // ["backspace"] = new List<string> { "=", "Insert", "Delete", "]" },
- // // ==============================================
- // // 第三行 Tab Q W E R T Y U I O P { }
- // // ==============================================
- // ["Tab"] = new List<string> { "`", "1", "Q", "capslock" },
- // ["Q"] = new List<string> { "tab", "1", "2", "W", "capslock", "A" },
- // ["W"] = new List<string> { "Q", "2", "3", "E", "A", "S" },
- // ["E"] = new List<string> { "W", "3", "4", "R", "S", "D" },
- // ["R"] = new List<string> { "E", "4", "5", "T", "D", "F" },
- // ["T"] = new List<string> { "R", "5", "6", "Y", "F", "G" },
- // ["Y"] = new List<string> { "T", "6", "7", "U", "G", "H" },
- // ["U"] = new List<string> { "Y", "7", "8", "I", "H", "J" },
- // ["I"] = new List<string> { "U", "8", "9", "O", "J", "K" },
- // ["O"] = new List<string> { "I", "9", "0", "P", "K", "L" },
- // ["P"] = new List<string> { "O", "0", "-", "{", "L", ";" },
- // ["{"] = new List<string> { "P", "-", "=", "}", ";", "@" },
- // ["}"] = new List<string> { "[", "=", "backspace", "@", "Enter" },
- // // ==============================================
- // // 第四行 CapsLock A S D F G H J K L : ` ~ Enter
- // // ==============================================
- // ["capslock"] = new List<string> { "Tab", "Q", "A", "Shift1" },
- // ["A"] = new List<string> { "capslock", "Q", "W", "S", "Shift1", "|" },
- // ["S"] = new List<string> { "A", "W", "E", "D", "|", "X" },
- // ["D"] = new List<string> { "S", "E", "R", "F", "X", "C" },
- // ["F"] = new List<string> { "D", "R", "T", "G", "C", "V" },
- // ["G"] = new List<string> { "F", "T", "Y", "H", "V", "B" },
- // ["H"] = new List<string> { "G", "Y", "U", "J", "B", "N" },
- // ["J"] = new List<string> { "H", "U", "I", "K", "N", "M" },
- // ["K"] = new List<string> { "J", "I", "O", "L", "M", "<" },
- // ["L"] = new List<string> { "K", "O", "P", ";", "<", ">" },
- // [";"] = new List<string> { "L", "P", "{", "@", ">", "?" },
- // ["@"] = new List<string> { ";", "{", "}", "Enter", "?", "#" },
- // ["#"] = new List<string> { "@", "Enter", "Shift2" },
- // ["Enter"] = new List<string> { "@", "}", "#", "Shift2" },
- // // ==============================================
- // // 第五行 Shift1 \ Z X C V B N M < > ? Shift2
- // // ==============================================
- // ["Shift1"] = new List<string> { "capslock", "A", "|", "Ctrl1" },
- // ["|"] = new List<string> { "Shift1", "A", "S", "X", "Ctrl1", "Fn" },
- // ["Z"] = new List<string> { "|", "S", "X" },
- // ["X"] = new List<string> { "|", "S", "D", "C", "Fn", "Win" },
- // ["C"] = new List<string> { "X", "D", "F", "V", "Win", "Alt1" },
- // ["V"] = new List<string> { "C", "F", "G", "B", "Alt1", "space" },
- // ["B"] = new List<string> { "V", "G", "H", "N", "space", "altgr" },
- // ["N"] = new List<string> { "B", "H", "J", "M", "altgr", "Ctrl2" },
- // ["M"] = new List<string> { "N", "J", "K", "<", "Ctrl2", "Left" },
- // ["<"] = new List<string> { "M", "K", "L", ">", "Left", "UpDown" },
- // [">"] = new List<string> { "<", "L", ";", "?", "UpDown", "Right" },
- // ["?"] = new List<string> { ">", ";", "@", "#", "Shift2", "Right" },
- // ["Shift2"] = new List<string> { "?", "#", "Enter" },
- // // ==============================================
- // // 第六行 Ctrl1 fn Win Alt1 Space1 Space2 Alt2 Ctrl2 Left UpDown Right
- // // ==============================================
- // ["Ctrl1"] = new List<string> { "Shift1", "|", "Fn" },
- // ["Fn"] = new List<string> { "Ctrl1", "|", "X", "Win" },
- // ["Win"] = new List<string> { "Fn", "X", "C", "Alt1" },
- // ["Alt1"] = new List<string> { "Win", "C", "V", "space" },
- // ["space"] = new List<string> { "Alt1", "V", "B", "altgr" },
- // ["altgr"] = new List<string> { "space", "B", "N", "Ctrl2" },
- // ["Ctrl2"] = new List<string> { "altgr", "N", "M", "Left" },
- // ["Left"] = new List<string> { "Ctrl2", "M", ",", "UpDown" },
- // ["UpDown"] = new List<string> { "Left", ",", ".", "Right" },
- // ["Right"] = new List<string> { "UpDown", ".", "?" }
- //};
- #endregion
- return new Dictionary<string, List<string>>
- {
- // ==============================================
- // 第一行:110 + 112~113
- // ==============================================
- ["110"] = new List<string> { "112", "1", },
- ["112"] = new List<string> { "110", "113", "2" },
- ["113"] = new List<string> { "112", "114", "3" },
- ["114"] = new List<string> { "113", "115", "4" },
- ["115"] = new List<string> { "114", "116", "5" },
- ["116"] = new List<string> { "115", "117", "6" },
- ["117"] = new List<string> { "116", "118", "7" },
- ["118"] = new List<string> { "117", "119", "8" },
- ["119"] = new List<string> { "118", "120", "8" },
- ["120"] = new List<string> { "119", "121", "9" },
- ["121"] = new List<string> { "120", "122", "10" },
- ["122"] = new List<string> { "121", "123", "11" },
- ["123"] = new List<string> { "122", "75", "12" },
- ["75"] = new List<string> { "123", "76", "13" },
- ["76"] = new List<string> { "75", "PWB", "15" },
- ["PWB"] = new List<string> { "76", "15" },
- // ==============================================
- // 第二行:` 1 2 3 4 5 6 7 8 9 10 11 12 13 15
- // ==============================================
- ["1"] = new List<string> { "110", "2", "16" },
- ["2"] = new List<string> { "112", "1", "3", "16" },
- ["3"] = new List<string> { "113", "2", "4", "17" },
- ["4"] = new List<string> { "114", "3", "5", "19" },
- ["5"] = new List<string> { "115", "4", "6", "20" },
- ["6"] = new List<string> { "116", "5", "7", "21" },
- ["7"] = new List<string> { "117", "6", "8", "22" },
- ["8"] = new List<string> { "118", "7", "9", "23" },
- ["9"] = new List<string> { "120", "8", "10", "24" },
- ["10"] = new List<string> { "121", "9", "11", "25" },
- ["11"] = new List<string> { "122", "10", "12", "26" },
- ["12"] = new List<string> { "123", "11", "13", "27" },
- ["13"] = new List<string> { "75", "12", "15", "28" },
- ["15"] = new List<string> { "76", "13", "29" },
- // ==============================================
- // 第三行:16 17 18 19 20 21 22 23 24 25 26 27 28 43
- // ==============================================
- ["16"] = new List<string> { "1", "17", "30" },
- ["17"] = new List<string> { "3", "16", "18", "31" },
- ["18"] = new List<string> { "3", "17", "19", "32" },
- ["19"] = new List<string> { "4", "18", "20", "33" },
- ["20"] = new List<string> { "5", "19", "21", "34" },
- ["21"] = new List<string> { "6", "20", "22", "35" },
- ["22"] = new List<string> { "7", "21", "23", "36" },
- ["23"] = new List<string> { "8", "22", "24", "37" },
- ["24"] = new List<string> { "9", "23", "25", "38" },
- ["25"] = new List<string> { "10", "24", "26", "39" },
- ["26"] = new List<string> { "11", "25", "27", "40" },
- ["27"] = new List<string> { "12", "26", "28", "41" },
- ["28"] = new List<string> { "13", "27", "29", "43" },
- ["43"] = new List<string> { "15", "28", "42", "57" },
- // ==============================================
- // 第四行:30 31 32 33 34 35 36 37 38 39 40 41 42
- // ==============================================
- ["30"] = new List<string> { "16", "31", "44" },
- ["31"] = new List<string> { "17", "30", "32", "46" },
- ["32"] = new List<string> { "18", "31", "33", "47" },
- ["33"] = new List<string> { "19", "32", "34", "48" },
- ["34"] = new List<string> { "20", "33", "35", "49" },
- ["35"] = new List<string> { "21", "34", "36", "50" },
- ["36"] = new List<string> { "22", "35", "37", "51" },
- ["37"] = new List<string> { "23", "36", "38", "52" },
- ["38"] = new List<string> { "24", "37", "39", "53" },
- ["39"] = new List<string> { "25", "38", "40", "54" },
- ["40"] = new List<string> { "26", "39", "41", "55" },
- ["41"] = new List<string> { "27", "40", "43", "55" },
- ["42"] = new List<string> { "28", "41", "57" },
- // ==============================================
- // 第五行:44 46 47 48 49 50 51 52 53 54 55 57
- // ==============================================
- ["44"] = new List<string> { "30", "45", "58" },
- ["45"] = new List<string> { "30", "44", "46", "59" },
- ["46"] = new List<string> { "31", "44", "47", "127" },
- ["47"] = new List<string> { "32", "46", "48", "60" },
- ["48"] = new List<string> { "33", "47", "49", "61_1" },
- ["49"] = new List<string> { "34", "48", "50", "61_1" },
- ["50"] = new List<string> { "35", "49", "51", "61_1" },
- ["51"] = new List<string> { "36", "50", "52", "61_2" },
- ["52"] = new List<string> { "37", "51", "53", "61_2" },
- ["53"] = new List<string> { "38", "52", "54", "62" },
- ["54"] = new List<string> { "39", "53", "55", "64" },
- ["55"] = new List<string> { "40", "54", "57", "79" },
- ["57"] = new List<string> { "43", "55", "89" },
- // ==============================================
- // 第六行:58 59 127 60 61_1 61_2 62 64 83_84 89
- // ==============================================
- ["58"] = new List<string> { "44", "59" },
- ["59"] = new List<string> { "44", "58", "60" },
- ["127"] = new List<string> { "46", "59", "60" },
- ["60"] = new List<string> { "47", "127", "61_1" },
- ["61_1"] = new List<string> { "49", "60" },
- ["61_2"] = new List<string> { "51", "62" },
- // ["RightFn"] = new List<string> { "RightAlt", "RightCtrl" },
- ["62"] = new List<string> { "53", "61_2", "64" },
- ["64"] = new List<string> { "54", "62", "79" },
- ["79"] = new List<string> { "55", "64", "83_84" },
- ["83_84"] = new List<string> { "57", "79", "89" },
- ["89"] = new List<string> { "57", "83_84" }
- };
- }
- /// <summary>
- /// 日文JP键盘相邻关系
- /// </summary>
- private Dictionary<string, List<string>> GetJPKeyboardNeighborMap()
- {
- #region 之前的JP
- //return new Dictionary<string, List<string>>
- //{
- // // ==============================================
- // // 第一行:Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Insert Delete Power
- // // ==============================================
- // ["Esc"] = new List<string> { "F1", "/" },
- // ["F1"] = new List<string> { "Esc", "F2", "/" },
- // ["F2"] = new List<string> { "F1", "F3", "1" },
- // ["F3"] = new List<string> { "F2", "F4", "2" },
- // ["F4"] = new List<string> { "F3", "F5", "3" },
- // ["F5"] = new List<string> { "F4", "F6", "4" },
- // ["F6"] = new List<string> { "F5", "F7", "5" },
- // ["F7"] = new List<string> { "F6", "F8", "6" },
- // ["F8"] = new List<string> { "F7", "F9", "7" },
- // ["F9"] = new List<string> { "F8", "F10", "8" },
- // ["F10"] = new List<string> { "F9", "F11", "9" },
- // ["F11"] = new List<string> { "F10", "F12", "0" },
- // ["F12"] = new List<string> { "F11", "insert", "=" },
- // ["insert"] = new List<string> { "F12", "delete", "~" },
- // ["delete"] = new List<string> { "insert", "|" },
- // ["Power"] = new List<string> { "insert", "|" },
- // // ==============================================
- // // 第二行 / 1 2 3 4 5 6 7 8 9 0 = ~ | backspace
- // // ==============================================
- // ["/"] = new List<string> { "Esc", "F1", "1", "tab" },
- // ["1"] = new List<string> { "/", "F2", "2", "tab", "Q" },
- // ["2"] = new List<string> { "1", "F3", "3", "Q", "W" },
- // ["3"] = new List<string> { "2", "F4", "4", "W", "E" },
- // ["4"] = new List<string> { "3", "F5", "5", "E", "R" },
- // ["5"] = new List<string> { "4", "F6", "6", "R", "T" },
- // ["6"] = new List<string> { "5", "F7", "7", "T", "Y" },
- // ["7"] = new List<string> { "6", "F8", "8", "Y", "U" },
- // ["8"] = new List<string> { "7", "F9", "9", "U", "I" },
- // ["9"] = new List<string> { "8", "F10", "0", "I", "O" },
- // ["0"] = new List<string> { "9", "F11", "=", "O", "P" },
- // ["="] = new List<string> { "0", "F12", "~", "P", "@" },
- // ["~"] = new List<string> { "=", "insert", "|", "@", "{" },
- // ["|"] = new List<string> { "~", "delete", "backspace", "{" },
- // ["backspace"] = new List<string> { "|", "}" },
- // // ==============================================
- // // 第三行 Tab Q W E R T Y U I O P @ {
- // // ==============================================
- // ["Tab"] = new List<string> { "1", "Q", "capslock" },
- // ["Q"] = new List<string> { "Tab", "1", "2", "W", "capslock", "A" },
- // ["W"] = new List<string> { "Q", "2", "3", "E", "A", "S" },
- // ["E"] = new List<string> { "W", "3", "4", "R", "S", "D" },
- // ["R"] = new List<string> { "E", "4", "5", "T", "D", "F" },
- // ["T"] = new List<string> { "R", "5", "6", "Y", "F", "G" },
- // ["Y"] = new List<string> { "T", "6", "7", "U", "G", "H" },
- // ["U"] = new List<string> { "Y", "7", "8", "I", "H", "J" },
- // ["I"] = new List<string> { "U", "8", "9", "O", "J", "K" },
- // ["O"] = new List<string> { "I", "9", "0", "P", "K", "L" },
- // ["P"] = new List<string> { "O", "0", "=", "@", "L", ";" },
- // ["@"] = new List<string> { "P", "=", "~", "{", ";", ":" },
- // ["{"] = new List<string> { "@", "~", "|", "backspace", ":", "}" },
- // // ==============================================
- // // 第四行 CapsLock A S D F G H J K L ; : } Enter
- // // ==============================================
- // ["CapsLock"] = new List<string> { "tab", "Q", "A", "shift1" },
- // ["A"] = new List<string> { "CapsLock", "Q", "W", "S", "shift1", "Z" },
- // ["S"] = new List<string> { "A", "W", "E", "D", "Z", "X" },
- // ["D"] = new List<string> { "S", "E", "R", "F", "X", "C" },
- // ["F"] = new List<string> { "D", "R", "T", "G", "C", "V" },
- // ["G"] = new List<string> { "F", "T", "Y", "H", "V", "B" },
- // ["H"] = new List<string> { "G", "Y", "U", "J", "B", "N" },
- // ["J"] = new List<string> { "H", "U", "I", "K", "N", "M" },
- // ["K"] = new List<string> { "J", "I", "O", "L", "M", "<" },
- // ["L"] = new List<string> { "K", "O", "P", ";", "<", ">" },
- // [";"] = new List<string> { "L", "P", "@", ":", ">", "?" },
- // [":"] = new List<string> { ";", "@", "{", "}", "?", "\\" },
- // ["}"] = new List<string> { ":", "{", "backspace", "Enter", "ろ", "Shift2" },
- // ["Enter"] = new List<string> { "}", "Shift2" },
- // // ==============================================
- // // 第五行 Shift1 Z X C V B N M < > ? \ shift2
- // // ==============================================
- // ["shift1"] = new List<string> { "CapsLock", "A", "Z", "Ctrl1" },
- // ["Z"] = new List<string> { "shift1", "A", "S", "X", "Ctrl1", "Fn" },
- // ["X"] = new List<string> { "Z", "S", "D", "C", "Fn", "Win" },
- // ["C"] = new List<string> { "X", "D", "F", "V", "Win", "Alt1" },
- // ["V"] = new List<string> { "C", "F", "G", "B", "Alt1", "变换" },
- // ["B"] = new List<string> { "V", "G", "H", "N", "无变换", "Space1" },
- // ["N"] = new List<string> { "B", "H", "J", "M", "Space1", "Space2" },
- // ["M"] = new List<string> { "N", "J", "K", "<", "Space2", "变换" },
- // ["<"] = new List<string> { "M", "K", "L", ">", "变换", "口" },
- // [">"] = new List<string> { "<", "L", ";", "?", "口", "Left" },
- // ["?"] = new List<string> { ">", ";", ":", "\\", "Left", "UpDown" },
- // ["\\"] = new List<string> { "?", ":", "}", "Shift2", "UpDown", "Right" },
- // ["Shift2"] = new List<string> { "\\", "}", "Enter", "Right" },
- // // ==============================================
- // // 第六行 Ctrl1 fn Win Alt1 无变换 Space1 Space2 变换 口 Ctrl2 Left Updown Right
- // // ==============================================
- // ["Ctrl1"] = new List<string> { "shift1", "Z", "Fn" },
- // ["Fn"] = new List<string> { "Ctrl1", "Z", "X", "Win" },
- // ["Win"] = new List<string> { "Fn", "X", "C", "Alt1" },
- // ["Alt1"] = new List<string> { "Win", "C", "V", "无变换" },
- // ["无变换"] = new List<string> { "Alt1", "V", "B", "Space1" },
- // ["Space1"] = new List<string> { "无变换", "B", "N", "Space2" },
- // ["变换"] = new List<string> { "Space2", "M", ",", "口" },
- // ["口"] = new List<string> { "变换", ",", ">", "Left" },
- // ["Ctrl2"] = new List<string> { "Left", ">", "?", "口" },
- // ["Left"] = new List<string> { "口", ">", "?", "UpDown" },
- // ["UpDown"] = new List<string> { "Left", "?", "\\", "Right" },
- // ["Right"] = new List<string> { "UpDown", "\\", "Shift2" }
- //};
- //return new Dictionary<string, List<string>>
- //{
- // // ==============================================
- // // 第一行:Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Insert Delete Power
- // // ==============================================
- // ["Esc"] = new List<string> { "F1", "/" },
- // ["F1"] = new List<string> { "Esc", "F2", "1" },
- // ["F2"] = new List<string> { "F1", "F3", "2" },
- // ["F3"] = new List<string> { "F2", "F4", "3" },
- // ["F4"] = new List<string> { "F3", "F5", "3", "4" },
- // ["F5"] = new List<string> { "F4", "F6", "4", "5" },
- // ["F6"] = new List<string> { "F5", "F7", "5", "6" },
- // ["F7"] = new List<string> { "F6", "F8", "6", "7" },
- // ["F8"] = new List<string> { "F7", "F9", "7", "8" },
- // ["F9"] = new List<string> { "F8", "F10", "8", "9" },
- // ["F10"] = new List<string> { "F9", "F11", "9", "0" },
- // ["F11"] = new List<string> { "F10", "F12", "0", "_" },
- // ["F12"] = new List<string> { "F11", "insert", "_" },
- // ["insert"] = new List<string> { "F12", "delete", "~" },
- // ["delete"] = new List<string> { "insert", "Power", "|" },
- // ["Power"] = new List<string> { "delete", "backspace" },
- // // ==============================================
- // // 第二行 / 1 2 3 4 5 6 7 8 9 0 = ~ | backspace
- // // ==============================================
- // ["/"] = new List<string> { "Esc", "1", "tab" },
- // ["1"] = new List<string> { "/", "F1", "2", "tab", "Q" },
- // ["2"] = new List<string> { "1", "F2", "3", "Q", "W" },
- // ["3"] = new List<string> { "2", "F3", "4", "W", "E" },
- // ["4"] = new List<string> { "3", "F4", "F5", "5", "E", "R" },
- // ["5"] = new List<string> { "4", "F5", "F6", "6", "R", "T" },
- // ["6"] = new List<string> { "5", "F6", "F7", "7", "T", "Y" },
- // ["7"] = new List<string> { "6", "F7", "F8", "8", "Y", "U" },
- // ["8"] = new List<string> { "7", "F8", "F9", "9", "U", "I" },
- // ["9"] = new List<string> { "8", "F9", "F10", "0", "I", "O" },
- // ["0"] = new List<string> { "9", "F10", "F11", "_", "O", "P" },
- // ["_"] = new List<string> { "0", "F11", "F12", "~", "P", "@" },
- // ["~"] = new List<string> { "_", "insert", "|", "@", "{" },
- // ["|"] = new List<string> { "~", "delete", "backspace", "{", "Enter" },
- // ["backspace"] = new List<string> { "|", "Power", "Enter" },
- // // ==============================================
- // // 第三行 Tab Q W E R T Y U I O P @ {
- // // ==============================================
- // ["Tab"] = new List<string> { "/", "1", "Q", "capslock" },
- // ["Q"] = new List<string> { "Tab", "1", "2", "W", "capslock", "A" },
- // ["W"] = new List<string> { "Q", "2", "3", "E", "A", "S" },
- // ["E"] = new List<string> { "W", "3", "4", "R", "S", "D" },
- // ["R"] = new List<string> { "E", "4", "5", "T", "D", "F" },
- // ["T"] = new List<string> { "R", "5", "6", "Y", "F", "G" },
- // ["Y"] = new List<string> { "T", "6", "7", "U", "G", "H" },
- // ["U"] = new List<string> { "Y", "7", "8", "I", "H", "J" },
- // ["I"] = new List<string> { "U", "8", "9", "O", "J", "K" },
- // ["O"] = new List<string> { "I", "9", "0", "P", "K", "L" },
- // ["P"] = new List<string> { "O", "0", "_", "@", "L", ";" },
- // ["@"] = new List<string> { "P", "_", "~", "{", ";", "*" },
- // ["{"] = new List<string> { "@", "~", "|", "Enter", "*", "}" },
- // // ==============================================
- // // 第四行 CapsLock A S D F G H J K L ; * } Enter
- // // ==============================================
- // ["CapsLock"] = new List<string> { "tab", "Q", "A", "shift1" },
- // ["A"] = new List<string> { "CapsLock", "Q", "W", "S", "shift1", "Z" },
- // ["S"] = new List<string> { "A", "W", "E", "D", "Z", "X" },
- // ["D"] = new List<string> { "S", "E", "R", "F", "X", "C" },
- // ["F"] = new List<string> { "D", "R", "T", "G", "C", "V" },
- // ["G"] = new List<string> { "F", "T", "Y", "H", "V", "B" },
- // ["H"] = new List<string> { "G", "Y", "U", "J", "B", "N" },
- // ["J"] = new List<string> { "H", "U", "I", "K", "N", "M" },
- // ["K"] = new List<string> { "J", "I", "O", "L", "M", "<" },
- // ["L"] = new List<string> { "K", "O", "P", ";", "<", ">" },
- // [";"] = new List<string> { "L", "P", "@", "*", ">", "?" },
- // ["*"] = new List<string> { ";", "@", "{", "}", "?", "\\" },
- // ["}"] = new List<string> { "*", "{", "Enter", "ろ", "Shift2" },
- // ["Enter"] = new List<string> { "{", "|", "backspace", "}", "Shift2" },
- // // ==============================================
- // // 第五行 Shift1 Z X C V B N M < > ? \ shift2
- // // ==============================================
- // ["shift1"] = new List<string> { "CapsLock", "A", "Z", "Ctrl1", "Fn" },
- // ["Z"] = new List<string> { "shift1", "A", "S", "X", "Win" },
- // ["X"] = new List<string> { "Z", "S", "D", "C", "Alt1" },
- // ["C"] = new List<string> { "X", "D", "F", "V", "无变换" },
- // ["V"] = new List<string> { "C", "F", "G", "B", "Space", },
- // ["B"] = new List<string> { "V", "G", "H", "N", "Space" },
- // ["N"] = new List<string> { "B", "H", "J", "M", "Space" },
- // ["M"] = new List<string> { "N", "J", "K", "<", "Space", "变换" },
- // ["<"] = new List<string> { "M", "K", "L", ">", "变换", "口" },
- // [">"] = new List<string> { "<", "L", ";", "?", "口", "Ctrl2" },
- // ["?"] = new List<string> { ">", ";", "*", "\\", "Ctrl2", "Left" },
- // ["\\"] = new List<string> { "?", "*", "}", "Shift2", "Left", "UpDown" },
- // ["Shift2"] = new List<string> { "\\", "}", "Enter", "UpDown", "Right" },
- // // ==============================================
- // // 第六行 Ctrl1 fn Win Alt1 无变换 Space1 Space2 变换 口 Ctrl2 Left Updown Right
- // // ==============================================
- // ["Ctrl1"] = new List<string> { "shift1", "Fn" },
- // ["Fn"] = new List<string> { "Ctrl1", "shift1", "Win" },
- // ["Win"] = new List<string> { "Fn", "Z", "Alt1" },
- // ["Alt1"] = new List<string> { "Win", "X", "无变换" },
- // ["无变换"] = new List<string> { "Alt1", "C", "Space" },
- // ["Space"] = new List<string> { "无变换", "V", "B", "N", "M", "变换" },
- // ["变换"] = new List<string> { "Space", "M", ",", "口" },
- // ["口"] = new List<string> { "变换", "<", ">", "Ctrl2" },
- // ["Ctrl2"] = new List<string> { "口", ">", "?", "Left" },
- // ["Left"] = new List<string> { "Ctrl2", "?", "\\", "UpDown" },
- // ["UpDown"] = new List<string> { "Left", "\\", "Shift2", "Right" },
- // ["Right"] = new List<string> { "UpDown", "Shift2" }
- //};
- #endregion
- return new Dictionary<string, List<string>>
- {
- // ==============================================
- // 第一行:110 + 112~113
- // ==============================================
- ["110"] = new List<string> { "112", "1", },
- ["112"] = new List<string> { "110", "113", "2" },
- ["113"] = new List<string> { "112", "114", "3" },
- ["114"] = new List<string> { "113", "115", "4" },
- ["115"] = new List<string> { "114", "116", "5" },
- ["116"] = new List<string> { "115", "117", "6" },
- ["117"] = new List<string> { "116", "118", "7" },
- ["118"] = new List<string> { "117", "119", "8" },
- ["119"] = new List<string> { "118", "120", "8" },
- ["120"] = new List<string> { "119", "121", "9" },
- ["121"] = new List<string> { "120", "122", "10" },
- ["122"] = new List<string> { "121", "123", "11" },
- ["123"] = new List<string> { "122", "75", "12" },
- ["75"] = new List<string> { "123", "76", "13" },
- ["76"] = new List<string> { "75", "PWB", "15" },
- ["PWB"] = new List<string> { "76", "15" },
- // ==============================================
- // 第二行:` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- // ==============================================
- ["1"] = new List<string> { "110", "2", "16" },
- ["2"] = new List<string> { "112", "1", "3", "16" },
- ["3"] = new List<string> { "113", "2", "4", "17" },
- ["4"] = new List<string> { "114", "3", "5", "19" },
- ["5"] = new List<string> { "115", "4", "6", "20" },
- ["6"] = new List<string> { "116", "5", "7", "21" },
- ["7"] = new List<string> { "117", "6", "8", "22" },
- ["8"] = new List<string> { "118", "7", "9", "23" },
- ["9"] = new List<string> { "120", "8", "10", "24" },
- ["10"] = new List<string> { "121", "9", "11", "25" },
- ["11"] = new List<string> { "122", "10", "12", "26" },
- ["12"] = new List<string> { "123", "11", "13", "27" },
- ["13"] = new List<string> { "75", "12", "14", "28" },
- ["14"] = new List<string> { "76", "13", "15", "28" },
- ["15"] = new List<string> { "PWB", "14", "43" },
- // ==============================================
- // 第三行:16 17 18 19 20 21 22 23 24 25 26 27 28 29
- // ==============================================
- ["16"] = new List<string> { "1", "17", "30" },
- ["17"] = new List<string> { "3", "16", "18", "31" },
- ["18"] = new List<string> { "3", "17", "19", "32" },
- ["19"] = new List<string> { "4", "18", "20", "33" },
- ["20"] = new List<string> { "5", "19", "21", "34" },
- ["21"] = new List<string> { "6", "20", "22", "35" },
- ["22"] = new List<string> { "7", "21", "23", "36" },
- ["23"] = new List<string> { "8", "22", "24", "37" },
- ["24"] = new List<string> { "9", "23", "25", "38" },
- ["25"] = new List<string> { "10", "24", "26", "39" },
- ["26"] = new List<string> { "11", "25", "27", "40" },
- ["27"] = new List<string> { "12", "26", "28", "41" },
- ["28"] = new List<string> { "13", "27", "29", "43" },
- ["43"] = new List<string> { "15", "28", "42", "57" },
- // ==============================================
- // 第四行:30 31 32 33 34 35 36 37 38 39 40 41 43
- // ==============================================
- ["30"] = new List<string> { "16", "31", "44" },
- ["31"] = new List<string> { "17", "30", "32", "46" },
- ["32"] = new List<string> { "18", "31", "33", "47" },
- ["33"] = new List<string> { "19", "32", "34", "48" },
- ["34"] = new List<string> { "20", "33", "35", "49" },
- ["35"] = new List<string> { "21", "34", "36", "50" },
- ["36"] = new List<string> { "22", "35", "37", "51" },
- ["37"] = new List<string> { "23", "36", "38", "52" },
- ["38"] = new List<string> { "24", "37", "39", "53" },
- ["39"] = new List<string> { "25", "38", "40", "54" },
- ["40"] = new List<string> { "26", "39", "41", "55" },
- ["41"] = new List<string> { "27", "40", "43", "55" },
- ["42"] = new List<string> { "28", "41", "57" },
- // ==============================================
- // 第五行:44 46 47 48 49 50 51 52 53 54 55 56 57
- // ==============================================
- ["44"] = new List<string> { "30", "46", "58" },
- ["46"] = new List<string> { "31", "44", "47", "127" },
- ["47"] = new List<string> { "32", "46", "48", "60" },
- ["48"] = new List<string> { "33", "47", "49", "61_1" },
- ["49"] = new List<string> { "34", "48", "50", "61_1" },
- ["50"] = new List<string> { "35", "49", "51", "61_1" },
- ["51"] = new List<string> { "36", "50", "52", "61_2" },
- ["52"] = new List<string> { "37", "51", "53", "61_2" },
- ["53"] = new List<string> { "38", "52", "54", "62" },
- ["54"] = new List<string> { "39", "53", "55", "64" },
- ["55"] = new List<string> { "40", "54", "56", "79" },
- ["56"] = new List<string> { "41", "55", "57", "79" },
- ["57"] = new List<string> { "43", "56", "89" },
- // ==============================================
- // 第六行:58 59 127 60 130 61_1 61_2 62 64 83_84 89
- // ==============================================
- ["58"] = new List<string> { "44", "59" },
- ["59"] = new List<string> { "44", "58", "60" },
- ["127"] = new List<string> { "46", "59", "60" },
- ["60"] = new List<string> { "47", "127", "131" },
- ["131"] = new List<string> { "48", "60", "61_1" },
- ["61_1"] = new List<string> { "49", "131" },
- ["61_2"] = new List<string> { "51", "132" },
- ["132"] = new List<string> { "52", "61_2", "133" },
- ["133"] = new List<string> { "53", "61_2", "64" },
- ["64"] = new List<string> { "54", "133", "79" },
- ["79"] = new List<string> { "55", "64", "83_84" },
- ["83_84"] = new List<string> { "57", "79", "89" },
- ["89"] = new List<string> { "57", "83_84" }
- };
- }
- /// <summary>
- /// 巴西键盘相邻关系
- /// </summary>
- private Dictionary<string, List<string>> GetBZKeyboardNeighborMap()
- {
- #region 之前的BZ
- //return new Dictionary<string, List<string>>
- //{
- // // ==============================================
- // // 第一行:Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Insert Delete Power
- // // ==============================================
- // ["ESC"] = new List<string> { "F1", "`" },
- // ["F1"] = new List<string> { "ESC", "F2", "1" },
- // ["F2"] = new List<string> { "F1", "F3", "2" },
- // ["F3"] = new List<string> { "F2", "F4", "3" },
- // ["F4"] = new List<string> { "F3", "F5", "4" },
- // ["F5"] = new List<string> { "F4", "F6", "5" },
- // ["F6"] = new List<string> { "F5", "F7", "6" },
- // ["F7"] = new List<string> { "F6", "F8", "7" },
- // ["F8"] = new List<string> { "F7", "F9", "8" },
- // ["F9"] = new List<string> { "F8", "F10", "9" },
- // ["F10"] = new List<string> { "F9", "F11", "0" },
- // ["F11"] = new List<string> { "F10", "F12", "-" },
- // ["F12"] = new List<string> { "F11", "Insert", "=" },
- // ["Insert"] = new List<string> { "F12", "Backspace", "Delete" },
- // ["Delete"] = new List<string> { "Insert", "Power", "Backspace" },
- // ["Power"] = new List<string> { "Insert", "Delete", "Backspace" },
- // // ==============================================
- // // 第二行:` 1 2 3 4 5 6 7 8 9 0 _ = Backspace
- // // ==============================================
- // ["`"] = new List<string> { "ESC", "1", "TAB" },
- // ["1"] = new List<string> { "`", "2", "F1", "Q" },
- // ["2"] = new List<string> { "1", "3", "F2", "Q", "W" },
- // ["3"] = new List<string> { "2", "4", "F3", "W", "E" },
- // ["4"] = new List<string> { "3", "5", "F4", "E", "R" },
- // ["5"] = new List<string> { "4", "6", "F5", "R", "T" },
- // ["6"] = new List<string> { "5", "7", "F6", "T", "Y" },
- // ["7"] = new List<string> { "6", "8", "F7", "Y", "U" },
- // ["8"] = new List<string> { "7", "9", "F8", "U", "I" },
- // ["9"] = new List<string> { "8", "0", "F9", "I", "O" },
- // ["0"] = new List<string> { "9", "-", "F10", "O", "P" },
- // ["-"] = new List<string> { "0", "=", "F11", "P", "{" },
- // ["="] = new List<string> { "-", "Backspace", "F12", "{", "}" },
- // ["Backspace"] = new List<string> { "=", "Insert", "}", "\\" },
- // // ==============================================
- // // 第三行: TAB Q W E R T Y U I O P 、 {
- // // ==============================================
- // ["TAB"] = new List<string> { "`", "Q", "CapsLock" },
- // ["Q"] = new List<string> { "TAB", "1", "2", "W", "CapsLock" },
- // ["W"] = new List<string> { "Q", "2", "3", "E", "A", "S" },
- // ["E"] = new List<string> { "W", "3", "4", "R", "S", "D" },
- // ["R"] = new List<string> { "E", "4", "5", "T", "D", "F" },
- // ["T"] = new List<string> { "R", "5", "6", "Y", "F", "G" },
- // ["Y"] = new List<string> { "T", "6", "7", "U", "G", "H" },
- // ["U"] = new List<string> { "Y", "7", "8", "I", "H", "J" },
- // ["I"] = new List<string> { "U", "8", "9", "O", "J", "K" },
- // ["O"] = new List<string> { "I", "9", "0", "P", "K", "L" },
- // ["P"] = new List<string> { "O", "0", "-", "}", "L", "Ç" },
- // ["{"] = new List<string> { "P", "-", "=", "{", "Ç", "~" },
- // ["}"] = new List<string> { "{", "=", "Backspace", "~", "Enter" },
- // // ==============================================
- // // 第四行: fixa A S D F G H J K L C5 ~ } Enter
- // // ==============================================
- // ["fixa"] = new List<string> { "TAB", "Q", "A", "Shift1" },
- // ["A"] = new List<string> { "fixa", "Q", "W", "S", "Shift1", "Z" },
- // ["S"] = new List<string> { "A", "W", "E", "D", "Z", "X" },
- // ["D"] = new List<string> { "S", "E", "R", "F", "X", "C" },
- // ["F"] = new List<string> { "D", "R", "T", "G", "C", "V" },
- // ["G"] = new List<string> { "F", "T", "Y", "H", "V", "B" },
- // ["H"] = new List<string> { "G", "Y", "U", "J", "B", "N" },
- // ["J"] = new List<string> { "H", "U", "I", "K", "N", "M" },
- // ["K"] = new List<string> { "J", "I", "O", "L", "M", "<" },
- // ["L"] = new List<string> { "K", "O", "P", "C5", "<", ">." },
- // ["C5"] = new List<string> { "L", "P", "{", "~", ">", ":" },
- // ["~"] = new List<string> { "C5", "{", "}", "Enter", ":", "?" },
- // ["Enter"] = new List<string> { "~", "}", "?" },
- // // ==============================================
- // // 第五行: Shift1 \ Z X C V B N M < > : ? Shift2
- // // ==============================================
- // ["Shift1"] = new List<string> { "fixa", "A", "Z", "Ctrl1" },
- // ["Z"] = new List<string> { "Shift1", "A", "S", "X", "Ctrl1", "fn" },
- // ["X"] = new List<string> { "Z", "S", "D", "C", "fn", "Win" },
- // ["C"] = new List<string> { "X", "D", "F", "V", "Win", "Space1" },
- // ["V"] = new List<string> { "C", "F", "G", "B", "Space1", "Space2" },
- // ["B"] = new List<string> { "V", "G", "H", "N", "Space2", "altGr" },
- // ["N"] = new List<string> { "B", "H", "J", "M", "altGr", "Ctrl2" },
- // ["M"] = new List<string> { "N", "J", "K", "<", "Ctrl2", "," },
- // ["<"] = new List<string> { "M", "K", "L", ">", "Shift2" },
- // [">"] = new List<string> { "<", "L", "C5", ":", "Shift2" },
- // [":"] = new List<string> { ">", "C5", "~", "?", "Shift2" },
- // ["?"] = new List<string> { ":", "~", "Enter", "Shift2" },
- // ["Shift2"] = new List<string> { "<", ">", ":", "?" },
- // // ==============================================
- // // 第六行: Ctrl1 Fn Win Alt1 Space1 Space2 altgr Ctr2 Left UpDown Right
- // // ==============================================
- // ["Ctrl1"] = new List<string> { "Shift1", "Z", "Fn" },
- // ["Fn"] = new List<string> { "Ctrl1", "Z", "X", "Win" },
- // ["Win"] = new List<string> { "Fn", "X", "C", "Space1" },
- // ["Space1"] = new List<string> { "Win", "C", "V", "Space2" },
- // ["Space2"] = new List<string> { "Space1", "V", "B", "altGr" },
- // ["altGr"] = new List<string> { "Space2", "B", "N", "Ctrl2" },
- // ["Ctrl2"] = new List<string> { "altGr", "N", "M", "Left" },
- // ["Left"] = new List<string> { "Ctrl2", "UpDown" },
- // ["UpDown"] = new List<string> { "Left", "Right" },
- // ["Right"] = new List<string> { "UpDown", "Shift2" }
- //};
- #endregion
- return new Dictionary<string, List<string>>
- {
- // ==============================================
- // 第一行:110 + 112~113
- // ==============================================
- ["110"] = new List<string> { "112", "1", },
- ["112"] = new List<string> { "110", "113", "2" },
- ["113"] = new List<string> { "112", "114", "3" },
- ["114"] = new List<string> { "113", "115", "4" },
- ["115"] = new List<string> { "114", "116", "5" },
- ["116"] = new List<string> { "115", "117", "6" },
- ["117"] = new List<string> { "116", "118", "7" },
- ["118"] = new List<string> { "117", "119", "8" },
- ["119"] = new List<string> { "118", "120", "8" },
- ["120"] = new List<string> { "119", "121", "9" },
- ["121"] = new List<string> { "120", "122", "10" },
- ["122"] = new List<string> { "121", "123", "11" },
- ["123"] = new List<string> { "122", "75", "12" },
- ["75"] = new List<string> { "123", "76", "13" },
- ["76"] = new List<string> { "75", "PWB", "15" },
- ["PWB"] = new List<string> { "76", "15" },
- // ==============================================
- // 第二行:` 1 2 3 4 5 6 7 8 9 10 11 12 13 15
- // ==============================================
- ["1"] = new List<string> { "110", "2", "16" },
- ["2"] = new List<string> { "112", "1", "3", "16" },
- ["3"] = new List<string> { "113", "2", "4", "17" },
- ["4"] = new List<string> { "114", "3", "5", "19" },
- ["5"] = new List<string> { "115", "4", "6", "20" },
- ["6"] = new List<string> { "116", "5", "7", "21" },
- ["7"] = new List<string> { "117", "6", "8", "22" },
- ["8"] = new List<string> { "118", "7", "9", "23" },
- ["9"] = new List<string> { "120", "8", "10", "24" },
- ["10"] = new List<string> { "121", "9", "11", "25" },
- ["11"] = new List<string> { "122", "10", "12", "26" },
- ["12"] = new List<string> { "123", "11", "13", "27" },
- ["13"] = new List<string> { "75", "12", "15", "28" },
- ["15"] = new List<string> { "76", "13", "43" },
- // ==============================================
- // 第三行:16 17 18 19 20 21 22 23 24 25 26 27 28 29
- // ==============================================
- ["16"] = new List<string> { "1", "17", "30" },
- ["17"] = new List<string> { "3", "16", "18", "31" },
- ["18"] = new List<string> { "3", "17", "19", "32" },
- ["19"] = new List<string> { "4", "18", "20", "33" },
- ["20"] = new List<string> { "5", "19", "21", "34" },
- ["21"] = new List<string> { "6", "20", "22", "35" },
- ["22"] = new List<string> { "7", "21", "23", "36" },
- ["23"] = new List<string> { "8", "22", "24", "37" },
- ["24"] = new List<string> { "9", "23", "25", "38" },
- ["25"] = new List<string> { "10", "24", "26", "39" },
- ["26"] = new List<string> { "11", "25", "27", "40" },
- ["27"] = new List<string> { "12", "26", "28", "41" },
- ["28"] = new List<string> { "13", "27", "43", "42" },
- ["43"] = new List<string> { "15", "28", "57" },
- // ==============================================
- // 第四行:30 31 32 33 34 35 36 37 38 39 40 41 43
- // ==============================================
- ["30"] = new List<string> { "16", "31", "44" },
- ["31"] = new List<string> { "17", "30", "32", "46" },
- ["32"] = new List<string> { "18", "31", "33", "47" },
- ["33"] = new List<string> { "19", "32", "34", "48" },
- ["34"] = new List<string> { "20", "33", "35", "49" },
- ["35"] = new List<string> { "21", "34", "36", "50" },
- ["36"] = new List<string> { "22", "35", "37", "51" },
- ["37"] = new List<string> { "23", "36", "38", "52" },
- ["38"] = new List<string> { "24", "37", "39", "53" },
- ["39"] = new List<string> { "25", "38", "40", "54" },
- ["40"] = new List<string> { "26", "39", "41", "55" },
- ["41"] = new List<string> { "27", "40", "42", "55" },
- ["42"] = new List<string> { "29", "41", "57" },
- // ==============================================
- // 第五行:44 46 47 48 49 50 51 52 53 54 55 57
- // ==============================================
- ["44"] = new List<string> { "30", "45", "58" },
- ["45"] = new List<string> { "30", "44", "46", "59" },
- ["46"] = new List<string> { "31", "44", "47", "127" },
- ["47"] = new List<string> { "32", "46", "48", "60" },
- ["48"] = new List<string> { "33", "47", "49", "61_1" },
- ["49"] = new List<string> { "34", "48", "50", "61_1" },
- ["50"] = new List<string> { "35", "49", "51", "61_1" },
- ["51"] = new List<string> { "36", "50", "52", "61_2" },
- ["52"] = new List<string> { "37", "51", "53", "61_2" },
- ["53"] = new List<string> { "38", "52", "54", "62" },
- ["54"] = new List<string> { "39", "53", "55", "64" },
- ["55"] = new List<string> { "40", "54", "56", "79" },
- ["56"] = new List<string> { "41", "55", "57", "79" },
- ["57"] = new List<string> { "43", "55", "89" },
- // ==============================================
- // 第六行:58 59 127 60 61_1 61_2 62 64 83_84 89
- // ==============================================
- ["58"] = new List<string> { "44", "59" },
- ["59"] = new List<string> { "44", "58", "60" },
- ["127"] = new List<string> { "46", "59", "60" },
- ["60"] = new List<string> { "47", "127", "61_1" },
- ["61_1"] = new List<string> { "49", "60" },
- ["61_2"] = new List<string> { "51", "62" },
- // ["RightFn"] = new List<string> { "RightAlt", "RightCtrl" },
- ["62"] = new List<string> { "53", "61_2", "64" },
- ["64"] = new List<string> { "54", "62", "79" },
- ["79"] = new List<string> { "55", "64", "83_84" },
- ["83_84"] = new List<string> { "57", "79", "89" },
- ["89"] = new List<string> { "57", "83_84" }
- };
- }
- private Dictionary<string, double> GetAdjacentDiffDict(ConcurrentDictionary<string, double> keyData, string name)
- {
- var currentProduct = _productService.GetCurrentProduct();
- Dictionary<string, double> diffDict = new Dictionary<string, double>();
- var neighborMap = GetUSKeyboardNeighborMap();
- if (name.Contains("US"))
- {
- neighborMap = GetUSKeyboardNeighborMap();
- }
- else if (name.Contains("UK"))
- {
- neighborMap = GetUKKeyboardNeighborMap();
- }
- else if (name.Contains("JP"))
- {
- neighborMap = GetJPKeyboardNeighborMap();
- }
- else if (name.Contains("BZ"))
- {
- neighborMap = GetBZKeyboardNeighborMap();
- }
- else
- {
- SendTaskMessage("未查找到当前产品名称的键盘相邻关系", MessageLevel.Error);
- }
- foreach (var kvp in keyData)
- {
- string key1 = kvp.Key;
- double val1 = kvp.Value;
- if (!neighborMap.TryGetValue(key1, out var neighbors)) continue;
- foreach (string key2 in neighbors)
- {
- if (!keyData.TryGetValue(key2, out double val2)) continue;
- // 去重核心:保证 A-S 和 S-A 只存一次
- string pairKey = string.Compare(key1, key2) < 0 ? $"_{key1}_{key2}" : $"_{key2}_{key1}";
- if (diffDict.ContainsKey(pairKey)) continue; // 跳过已存的
- double diff = Math.Abs(val1 - val2);
- diffDict.Add(pairKey, diff);
- }
- }
- return diffDict;
- }
- #endregion
- #region vm启动检测
- /// <summary>
- /// 杀死所有VM有关进程
- /// </summary>
- public void KillVMProcess()
- {
- KillProcess("VisionMasterServerApp");
- KillProcess("VisionMaster");
- KillProcess("VmModuleProxy.exe");
- KillProcess("vServerApp.exe");
- }
- /// <summary>
- /// 杀死指定进程名的进程
- /// </summary>
- /// <param name="strKillName"></param>
- public void KillProcess(string strKillName)
- {
- foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
- {
- if (p.ProcessName.Contains(strKillName))
- {
- try
- {
- p.Kill();
- p.WaitForExit();
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"杀死进程:{strKillName}时失败!", ex);
- }
- }
- }
- }
- #endregion
- #region 保存CSV
- public bool WriteProductLogKB(IEnumerable<DataFormCtq> lockResults, string rfid)
- {
- try
- {
- DateTime dt = DateTime.Now;
- if (rfid == null || rfid.Count() == 0)
- {
- rfid = dt.ToString("MM-dd-mm");
- }
- if (lockResults.Count() == 0 || lockResults == null)
- {
- SendTaskMessage("保存KB数据为空", MessageLevel.Error);
- return false;
- }
- string path = $"D:\\Data\\JMS数据\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}\\KB_{rfid}.csv";
- StringBuilder sb = new StringBuilder();
- sb.Append($"PD_ATTR_01,CTQ_NAME,CTQ_VALUE,");
- sb.AppendLine();
- foreach (var item in lockResults)
- {
- try
- {
- //!item.CTQ_NAME.Contains("Left")|| !item.CTQ_NAME.Contains("Right")||!item.CTQ_NAME.Contains("Updown")|| !item.CTQ_NAME.Contains("Down")
- if (item.CTQ_NAME.Contains("Left") || item.CTQ_NAME.Contains("Down") || item.CTQ_NAME.Contains("Right") || item.CTQ_NAME.Contains("Updown"))
- {
- }
- else
- {
- sb.Append($"{item.PD_ATTR_01},{item.CTQ_NAME},{item.CTQ_VALUE},");
- sb.AppendLine();
- }
- }
- catch (Exception)
- {
- sb.Append($",,,,,,,,,,,,,,");
- return false;
- }
- }
- if (!Directory.Exists(Path.GetDirectoryName(path))) //判断文件夹是否
- {
- Directory.CreateDirectory(Path.GetDirectoryName(path)); //创建文件夹
- }
- if (File.Exists(path))
- {
- // 使用 StreamWriter 以追加模式打开文件
- StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8);
- sw.WriteLine(sb.ToString().TrimEnd(','));
- //sw.WriteLine(sb1.ToString().TrimEnd(','));
- sw.Close();
- sw.Dispose();
- }
- else
- {
- StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8);
- sw.WriteLine(sb.ToString().TrimEnd(','));
- sw.Close();
- sw.Dispose();
- }
- return true;
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("写入产品记录时出错!", ex);
- return false;
- }
- }
- public bool WriteProductLogTP(IEnumerable<DataFormCtq> lockResults, string rfid)
- {
- try
- {
- DateTime dt = DateTime.Now;
- if (rfid == null || rfid.Count() == 0)
- {
- rfid = dt.ToString("MM-dd-mm");
- }
- if (lockResults.Count() == 0 || lockResults == null)
- {
- SendTaskMessage("保存KB数据为空", MessageLevel.Error);
- return false;
- }
- string path = $"D:\\Data\\JMS数据\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}\\TP_{rfid}.csv";
- StringBuilder sb = new StringBuilder();
- sb.Append($"PD_ATTR_01,CTQ_NAME,CTQ_VALUE,");
- sb.AppendLine();
- foreach (var item in lockResults)
- {
- try
- {
- if (item.CTQ_NAME.Contains("Left") || item.CTQ_NAME.Contains("Down") || item.CTQ_NAME.Contains("Right") || item.CTQ_NAME.Contains("Updown"))
- {
- sb.Append($"{item.PD_ATTR_01},{item.CTQ_NAME},{item.CTQ_VALUE},");
- sb.AppendLine();
- }
- }
- catch (Exception)
- {
- sb.Append($",,,,,,,,,,,,,,");
- return false;
- }
- }
- if (!Directory.Exists(Path.GetDirectoryName(path))) //判断文件夹是否
- {
- Directory.CreateDirectory(Path.GetDirectoryName(path)); //创建文件夹
- }
- if (File.Exists(path))
- {
- // 使用 StreamWriter 以追加模式打开文件
- StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8);
- sw.WriteLine(sb.ToString().TrimEnd(','));
- //sw.WriteLine(sb1.ToString().TrimEnd(','));
- sw.Close();
- sw.Dispose();
- }
- else
- {
- StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8);
- sw.WriteLine(sb.ToString().TrimEnd(','));
- sw.Close();
- sw.Dispose();
- }
- return true;
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("写入产品记录时出错!", ex);
- return false;
- }
- }
- /// <summary>
- /// 记录工位的结果,其他工位要存储的数据项按照键值对集合的形式传入,键为数据项名称,值为数据项的值
- /// </summary>
- /// <param name="stationIndex"></param>
- /// <param name="dfcs"></param>
- /// <param name="productMainSN"></param>
- /// <param name="ct"></param>
- /// <param name="timestamp"></param>
- /// <param name="savePath"></param>
- /// <param name="isFirstEnter"></param>
- /// <returns></returns>
- private bool RecordStationResult(int stationIndex, IEnumerable<DataFormCtq> dfcs, string productMainSN, double ct, DateTime timestamp, string savePath, bool isFirstEnter = true)
- {
- try
- {
- //获取当前工位的配置
- var stationConfig = _configService.GetDeviceInfo(0);
- if (stationConfig == null) return false;
- //如果保存路径为空,则不保存
- if (string.IsNullOrEmpty(savePath)) return false;
- string fullPath = savePath;
- //如果保存路径是一个文件路径,则直接保存,否则按照工位和日期进行保存
- if (File.Exists(savePath) || Path.HasExtension(savePath))
- {
- fullPath = savePath;
- //如果路径不存在,则创建
- // 创建目录
- string directory = Path.GetDirectoryName(fullPath);
- if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
- }
- else
- {
- //结果保存至CSV文件,文件名格式:savePath\yyyy-MM\工位编号_工位名称_yyyy-MM-dd.csv
- string datePath = timestamp.ToString("yyyy-MM") + "\\";
- string dirPath = Path.Combine(savePath, datePath);
- if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
- string fileName = $"{stationIndex}_{stationConfig.DeviceName}_{timestamp.ToString("yyyy-MM-dd")}.csv";
- fullPath = Path.Combine(dirPath, fileName);
- }
- // ========== 新增:检查文件行数,如果达到上限则自动分片 ==========
- fullPath = GetAvailableFilePath(fullPath);
- // ============================================================
- StringBuilder sb = new StringBuilder();
- if (!File.Exists(fullPath))
- {
- sb.Append("PPID,PROCESS_NAME,PROCESS_START_TIME,CTQ_NAME,CTQ_VALUE,CTQ_LSL,CTQ_USL,PROCESS_END_TIME,SUPPLIER_NAME,COMMODITY_TYPE,REVISION,WO#,MFG_LOT#," +
- "MFG_ASSY_LINE,PROCESS_OUTCOME,PROCESS_MACHINE_ID,CTQ_UNIT_OF_MEASURE,ERROR_MESSAGE,PD_ATTR_01,PD_ATTR_02,PD_ATTR_03,PD_ATTR_04,PD_ATTR_05,PD_ATTR_06");
- sb.AppendLine();
- }
- if (dfcs == null || dfcs.Count() == 0)
- {
- return false;
- }
- foreach (var dfc in dfcs)
- {
- sb.Append($"{dfc.PPID},{dfc.PROCESS_NAME},{dfc.PROCESS_START_TIME},{dfc.CTQ_NAME},{dfc.CTQ_VALUE},{dfc.CTQ_LSL},{dfc.CTQ_USL},{dfc.PROCESS_END_TIME},{dfc.SUPPLIER_NAME},{dfc.COMMODITY_TYPE},{dfc.REVISION},{dfc.WO},{dfc.MFG_LOT},{dfc.MFG_ASSY_LINE},{dfc.PROCESS_OUTCOME},{dfc.PROCESS_MACHINE_ID},{dfc.CTQ_UNIT_OF_MEASURE},{dfc.ERROR_MESSAGE},{dfc.PD_ATTR_01},{dfc.PD_ATTR_02},{dfc.PD_ATTR_03},{dfc.PD_ATTR_04},{dfc.PD_ATTR_05},{dfc.PD_ATTR_06}");
- sb.AppendLine();
- }
- // 使用 StreamWriter 以追加模式打开文件
- StreamWriter sw = new StreamWriter(fullPath, true, Encoding.UTF8);
- sw.Write(sb.ToString());
- sw.Close();
- sw.Dispose();
- return true;
- }
- catch (Exception ex)
- {
- if (!isFirstEnter)
- {
- return false;
- }
- LogHelper.WriteLogError("记录其他工位结果时出错!", ex);
- //我希望在这里生成一个临时文件来保存这次的记录,因为如果本地文件被打开时可能会导致无法写入,如果不保存的话可能会丢失这次的记录,所以我想在这里生成一个临时文件来保存这次的记录
- //生成临时文件的路径,格式为savePath\yyyy-MM\工位编号_yyyy-MM-dd_temp\工位编号_yyyy-MM-dd_HH-mm-ss-fff_temp.csv
- string datePath = timestamp.ToString("yyyy-MM") + "\\";
- string tempDirPath = Path.Combine(savePath, datePath, $"{stationIndex}_{timestamp.ToString("yyyy-MM-dd")}_temp");
- string tempFileName = $"{stationIndex}_{timestamp.ToString("yyyy-MM-dd_HH-mm-ss-fff")}_temp.csv";
- RecordStationResult(stationIndex, dfcs, productMainSN, ct, timestamp, tempFileName, false);
- return false;
- }
- }
- /// <summary>
- /// Excel 最大行数限制(Excel 2007+ 为 1048576 行,这里设为 1000000 留有余量)
- /// </summary>
- private const int MaxExcelRows = 1000000;
- /// <summary>
- /// 获取可用的文件路径,如果当前文件行数达到上限,则自动生成新文件
- /// </summary>
- private string GetAvailableFilePath(string originalPath)
- {
- // 如果文件不存在,直接返回原路径
- if (!File.Exists(originalPath))
- {
- return originalPath;
- }
- // 获取当前文件的行数(包含表头)
- int currentRowCount = GetFileRowCount(originalPath);
- // 如果当前行数未达到上限,直接返回原路径
- if (currentRowCount < MaxExcelRows)
- {
- return originalPath;
- }
- // 文件已达上限,生成新文件路径
- string directory = Path.GetDirectoryName(originalPath);
- string fileName = Path.GetFileNameWithoutExtension(originalPath);
- string extension = Path.GetExtension(originalPath);
- // 查找可用的序号
- int fileIndex = 1;
- string newPath;
- do
- {
- string newFileName = $"{fileName}_{fileIndex:D4}{extension}";
- newPath = Path.Combine(directory, newFileName);
- fileIndex++;
- // 如果新文件存在,检查它的行数是否也达到上限
- if (File.Exists(newPath))
- {
- int newFileRowCount = GetFileRowCount(newPath);
- if (newFileRowCount < MaxExcelRows)
- {
- // 这个文件可用,直接返回
- return newPath;
- }
- // 否则继续找下一个
- }
- else
- {
- // 新文件不存在,可用
- return newPath;
- }
- } while (true);
- }
- /// <summary>
- /// 获取 CSV 文件的行数(快速方法,只读取第一行和总行数)
- /// </summary>
- private int GetFileRowCount(string filePath)
- {
- try
- {
- // 使用 StreamReader 快速获取行数
- using (var reader = new StreamReader(filePath, Encoding.UTF8))
- {
- int lineCount = 0;
- while (reader.ReadLine() != null)
- {
- lineCount++;
- }
- return lineCount;
- }
- }
- catch
- {
- // 如果读取失败,假设文件为0行(安全处理)
- return 0;
- }
- }
- #endregion
- private async void DoYieldTime(object state)
- {
- try
- {
- //获取当前产品
- var currentproduct = _productService.GetCurrentProduct();
- CurrentProduct = _productService.GetCurrentProduct();
- if (currentproduct == null) return;
- TotalQuantity = await _systemDatabaseService.GetOverallProductionAsync(currentproduct.Name);
- TotalQuantityToday = 0;
- CurrentUPH = 0;
- //NgNumber = 0;
- //Yield = 0;
- ObservableCollection<ProductModel> ProductList = new ObservableCollection<ProductModel>(_productService.GetAllProducts());
- foreach (var product in ProductList)
- {
- //TotalQuantity += await _systemDatabaseService.GetOverallProductionAsync(product.Name);
- TotalQuantityToday += await _systemDatabaseService.GetTodayProductionAsync(product.Name);
- CurrentUPH += await _systemDatabaseService.GetLastHourProductionAsync(product.Name);
- //NgNumber += await _systemDatabaseService.GetNGProductionAsync(product.Name);
- }
- }
- catch (Exception)
- {
- }
- }
- // 用于等待“指定相机的下一张图到达”
- private readonly object _imageSyncLock = new object();
- private readonly Dictionary<Guid, TaskCompletionSource<ICogImage>> _nextImageTcsByCamera =
- new Dictionary<Guid, TaskCompletionSource<ICogImage>>();
- private Task<ICogImage> PrepareNextImageWait(Guid cameraId)
- {
- lock (_imageSyncLock)
- {
- var tcs = new TaskCompletionSource<ICogImage>(TaskCreationOptions.RunContinuationsAsynchronously);
- _nextImageTcsByCamera[cameraId] = tcs;
- return tcs.Task;
- }
- }
- public async Task SignalImageArrived(Guid cameraId, ICogImage image)
- {
- await Task.Delay(500);
- TaskCompletionSource<ICogImage> tcs = null;
- lock (_imageSyncLock)
- {
- _nextImageTcsByCamera.TryGetValue(cameraId, out tcs);
- }
- tcs?.TrySetResult(image);
- }
- public async Task<ICogImage> WaitNextImageAsync(Guid cameraId, int timeoutMs, CancellationToken token)
- {
- var waitTask = PrepareNextImageWait(cameraId);
- var completed = await Task.WhenAny(waitTask, Task.Delay(timeoutMs, token)).ConfigureAwait(false);
- if (completed != waitTask) return null;
- return await waitTask.ConfigureAwait(false);
- }
- private Guid GetDefaultScannerId()
- {
- if (_defaultScannerId != Guid.Empty) return _defaultScannerId;
- var scannerInfo = _configService.GetAllScanners()
- .OrderBy(s => s.ScannerNo)
- .FirstOrDefault();
- _defaultScannerId = scannerInfo == null ? Guid.Empty : scannerInfo.Id;
- return _defaultScannerId;
- }
- private async Task Scan_DataReceived(ISerialPortClient client, ReceivedDataEventArgs e)
- {
- try
- {
- // 串口名
- string portName = client.MainSerialPort.PortName;
- // 注意:DataReceived 可能一次收到多段/包含回车换行
- string data = e.ByteBlock.Span.ToString(Encoding.ASCII);
- await Console.Out.WriteLineAsync(data);
- // 取第一段(到 \r 之前),并去掉首尾空白
- string response = data.Split('\r')[0].Trim();
- // 过滤:空数据不要当成一次有效扫码
- if (string.IsNullOrWhiteSpace(response))
- return;
- SendTaskMessage($"扫码机:{portName} Receive:{response}", MessageLevel.Info);
- // 写入结果
- ScanValue = response;
- // 通知等待方继续执行(PLC 逻辑里 Wait 的地方)
- _scanDoneEvent.Set();
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("扫码枪接收信息时出错!", ex);
- SendTaskMessage(Lang.扫码枪接收信息时出错 + ex.Message, MessageLevel.Error);
- }
- }
- /// <summary>
- /// 2D相机先采集图像
- /// </summary>
- /// <param name="procedureId"></param>
- /// <returns></returns>
- private async Task<(bool IsSucceed, ICogImage[] imges, string Message, int pointIndex, Guid procedureId)> GrabImageEx(int pointIndex, Guid procedureId, bool Is3dPhoto, ProductModel currentProduct, SystemConfiguration sysConfig)
- {
- // 获取当前产品
- //var currentProduct = _productService.GetCurrentProduct();
- if (currentProduct == null)
- {
- return (false, null, "当前产品为空,未加载产品!", pointIndex, procedureId);
- }
- var cameraProcedures = currentProduct.CameraProcedures;
- if (cameraProcedures == null || cameraProcedures.Count == 0)
- {
- SendTaskMessage($"当前产品未配置 CameraProcedures,无法执行视觉流程", MessageLevel.Alarm);
- return (false, null, $"当前产品未配置 CameraProcedures,无法执行视觉流程", pointIndex, procedureId);
- }
- try
- {
- ProcedureModel selectedProcedure = null;
- try
- {
- foreach (var cp in cameraProcedures)
- {
- if (cp?.ProcedureModels == null) continue;
- selectedProcedure = cp.ProcedureModels.FirstOrDefault(pm => pm.Id == procedureId);
- if (selectedProcedure != null) break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
- }
- if (selectedProcedure == null)
- {
- SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={pointIndex}", MessageLevel.Alarm);
- return (false, null, $"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={procedureId}", pointIndex, procedureId);
- }
- SendTaskMessage($"开始执行 AOI 流程 (Point#{pointIndex}) 流程Id={pointIndex}", MessageLevel.Debug);
- try
- {
- //var sysConfig = _configService.GetSystemConfiguration();
- if (selectedProcedure.Id == currentProduct.FixedDownCameraProcedureId && sysConfig.TurnOnAllLightUse == true)
- {
- await _remoteCommandService.SetLightBeforePhoto(selectedProcedure);
- }
- //1. 执行拍照
- var res = await _remoteCommandService.ExecuteGrabImageAsync(selectedProcedure, Is3dPhoto, sysConfig);
- return (res.IsSucceed, res.Image, res.Msg, pointIndex, procedureId);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("执行 AOI 视觉图像采集时出错", ex);
- SendTaskMessage($"执行 AOI 视觉图像采集时出错: {ex.Message}", MessageLevel.Alarm);
- }
- return (false, null, $"图像采集失败", pointIndex, procedureId);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("处理固定相机检测拍照时出错", ex);
- return (false, null, $"处理固定相机检测拍照时出错", pointIndex, procedureId);
- }
- }
- #region 压缩图片文件夹
- /// <summary>
- /// 压缩文件
- /// </summary>
- /// <param name="sourcePath">原路径</param>
- /// <param name="zipname">压缩后文件的名称</param>
- /// <param name="station">mes中的station</param>
- /// <param name="fixid">mes中的fixtureID</param>
- public async void CompressionImage(string sourcePath, string zipname, string station, string fixid)
- {
- string zipPath = "";
- try
- {
- SendTaskMessage($"开始压缩文件", MessageLevel.Info);
- await Task.Run(() =>
- {
- zipPath = $"Z:\\{station}\\{fixid}\\{DateTime.Now.ToString("yyyyMMdd")}\\{zipname}.zip";//生成的zip文件路径
- string path = $"Z:\\{station}\\{fixid}\\{DateTime.Now.ToString("yyyyMMdd")}";
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
- ZipFile.CreateFromDirectory(sourcePath, zipPath);
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"压缩文件时出错", ex);
- }
- }
- public async void CompressionSingleCsv(string csvFilePath, string zipname, string station, string fixid)
- {
- string zipPath = "";
- try
- {
- SendTaskMessage("开始压缩CSV文件", MessageLevel.Info);
- await Task.Run(() =>
- {
- if (!File.Exists(csvFilePath))
- {
- LogHelper.WriteLogMes($"CSV文件不存在,不压缩:{csvFilePath}");
- return;
- }
- zipPath = $"Z:\\{station}\\{fixid}\\{DateTime.Now.ToString("yyyyMMdd")}\\{zipname}.zip";
- string path = $"Z:\\{station}\\{fixid}\\{DateTime.Now.ToString("yyyyMMdd")}";
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
- using (FileStream fs = new FileStream(zipPath, FileMode.Create))
- {
- using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create))
- {
- archive.CreateEntryFromFile(csvFilePath, Path.GetFileName(csvFilePath));
- }
- }
- });
- SendTaskMessage("CSV文件压缩完成", MessageLevel.Debug);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("压缩CSV文件失败", ex);
- }
- }
- #endregion
- //#region 读取写入plc速度
- //// 速度数据模型
- //[Serializable]
- //public class SpeedData
- //{
- // public string SpeedValue { get; set; }
- // public DateTime UpdateTime { get; set; }
- // public int State { get; set; }
- //}
- //public class SharedSpeedFileHelper
- //{
- // private static readonly object _lockObj = new object();
- // string directoryPath = @"Z:\\XTM\\Speed";
- // //public SharedSpeedFileHelper()
- // //{
- // // try
- // // {
- // // string directoryPath = @"Z:\\1111\\2222\\3333";
- // // // 确保目录存在
- // // if (!Directory.Exists(directoryPath))
- // // Directory.CreateDirectory(directoryPath);
- // // _filePath = Path.Combine(directoryPath, "SharedSpeedData.json");
- // // }
- // // catch
- // // {
- // // LogHelper.WriteLogInfo("Z盘路径不存在");
- // // }
- // //}
- // // 写入速度数据
- // public void WriteSpeedData(string speed, int state)
- // {
- // lock (_lockObj)
- // {
- // try
- // {
- // var data = new SpeedData
- // {
- // SpeedValue = speed,
- // UpdateTime = DateTime.Now,
- // State = state
- // };
- // string json = JsonSerializer.Serialize(data, new JsonSerializerOptions
- // {
- // WriteIndented = true
- // });
- // // 确保目录存在
- // if (!Directory.Exists(directoryPath))
- // Directory.CreateDirectory(directoryPath);
- // string _filePath = Path.Combine(directoryPath, "SharedSpeedData.json");
- // File.WriteAllText(_filePath, json, Encoding.UTF8);
- // }
- // catch (Exception ex)
- // {
- // throw new InvalidOperationException($"写入速度文件失败: {ex.Message}", ex);
- // }
- // }
- // }
- // // 读取速度数据
- // public SpeedData ReadSpeedData()
- // {
- // lock (_lockObj)
- // {
- // try
- // {
- // // 确保目录存在
- // if (!Directory.Exists(directoryPath))
- // {
- // return null;
- // }
- // string _filePath = Path.Combine(directoryPath, "SharedSpeedData.json");
- // string json = File.ReadAllText(_filePath, Encoding.UTF8);
- // return JsonSerializer.Deserialize<SpeedData>(json);
- // }
- // catch (Exception ex)
- // {
- // throw new InvalidOperationException($"读取速度文件失败: {ex.Message}", ex);
- // }
- // }
- // }
- //}
- //#endregion
- #endregion
- }
- }
|