| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901 |
- using Cognex.VisionPro.ToolBlock;
- using MathNet.Numerics.LinearAlgebra;
- using NPOI.SS.Formula.Functions;
- using NPOI.Util;
- using OpenCvSharp;
- using Prism.Events;
- using Prism.Ioc;
- using Prism.Mvvm;
- using Prism.Regions;
- using SqlSugar;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Drawing;
- using System.IO;
- using System.IO.Compression;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Media;
- using Team.FFFeederService.Interfaces;
- 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 TouchSocket.Core;
- using TouchSocket.Sockets;
- namespace TeamAAS_VP.Core
- {
- public class Management : BindableBase
- {
- #region 字段
- IRegionManager _regionManager;
- IEventAggregator _eventAggregator;
- IContainerProvider _container;
- IConfigService _configService;
- IRobotService _robotService;
- 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;
- // Pressure collection
- /// <summary>
- /// 压力采集信号控制CTS
- /// </summary>
- private CancellationTokenSource[] _pressureCts = new CancellationTokenSource[10];
- /// <summary>
- /// 压力采集超时CTS
- /// </summary>
- private CancellationTokenSource[] _pressureTimeoutCts = new CancellationTokenSource[10];
- /// <summary>
- /// 压力采集CTS
- /// </summary>
- private CancellationTokenSource[] _pressureLinkedCts = new CancellationTokenSource[10];
- /// <summary>
- /// 压力数据集合
- /// </summary>
- private List<(DateTime Timestamp, float Value)>[] _pressureSamples = new List<(DateTime, float)>[10];
- /// <summary>
- /// 采样间隔毫秒
- /// </summary>
- private int _pressureSampleIntervalMs = 50; //采样间隔毫秒
- /// <summary>
- /// 超时自动停止秒数
- /// </summary>
- private int _pressureMaxDurationSeconds = 30; //超时自动停止秒数
- DateTime[] StartCtqTime = new DateTime[3];//开始采集Ctq数据的时间
- /// <summary>
- /// 上次执行上传csv的日期
- /// </summary>
- private DateTime _lastCompressDate = DateTime.MinValue;
- /// <summary>
- /// 当天是否上传过csv
- /// </summary>
- private bool _hasCompressedToday = false;
- #endregion
- #region 属性
- private System.Windows.Media.Brush _StatusBackground;
- public System.Windows.Media.Brush StatusBackground
- {
- get { return _StatusBackground; }
- set { SetProperty(ref _StatusBackground, value); }
- }
- private System.Windows.Media.Brush _RunModelBackground;
- public System.Windows.Media.Brush RunModelBackground
- {
- get { return _RunModelBackground; }
- set { SetProperty(ref _RunModelBackground, value); }
- }
- private System.Windows.Media.Brush _ManualModeBackground;
- public System.Windows.Media.Brush ManualModeBackground
- {
- get { return _ManualModeBackground; }
- set { SetProperty(ref _ManualModeBackground, value); }
- }
- private System.Windows.Media.Brush _ClearModeBackground;
- public System.Windows.Media.Brush ClearModeBackground
- {
- get { return _ClearModeBackground; }
- set { SetProperty(ref _ClearModeBackground, value); }
- }
- private ObservableCollection<ShowRender> _Renders;
- /// <summary>
- /// 显示界面
- /// </summary>
- public ObservableCollection<ShowRender> Renders
- {
- get { return _Renders; }
- set { SetProperty(ref _Renders, 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 double _CTtime;
- /// <summary>
- /// ct
- /// </summary>
- public double CTtime
- {
- get { return _CTtime; }
- set { SetProperty(ref _CTtime, value); }
- }
- private ObservableCollection<DataFormCtq> _dfc = new ObservableCollection<DataFormCtq>();
- /// <summary>
- /// CTQ数据集合
- /// </summary>
- public ObservableCollection<DataFormCtq> DFC
- {
- get { return _dfc; }
- set { SetProperty(ref _dfc, value); }
- }
- private Int64 _ThrowNumber;
- /// <summary>
- /// 抛料数
- /// </summary>
- public Int64 ThrowNumber
- {
- get { return _ThrowNumber; }
- set { SetProperty(ref _ThrowNumber, value); }
- }
- private Int64 _NgNumber;
- /// <summary>
- /// ng数量
- /// </summary>
- public Int64 NgNumber
- {
- get { return _NgNumber; }
- set { SetProperty(ref _NgNumber, value); }
- }
- private double _Yield;
- /// <summary>
- /// 良率
- /// </summary>
- public double Yield
- {
- get { return _Yield; }
- set { SetProperty(ref _Yield, value); }
- }
- private ObservableCollection<ProductModel> _ProductList;
- public ObservableCollection<ProductModel> ProductList
- {
- get { return _ProductList; }
- set { SetProperty(ref _ProductList, 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)
- {
- _regionManager = regionManager;
- _eventAggregator = ea;
- _container = container;
- _configService = configService;
- _robotService = robotService;
- _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);
- InitPressure();
- }
- #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>
- /// 初始化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)
- {
- try
- {
- // Renders.Add(new ShowRender() { Id = item.Id, CameraName = item.CameraName });
- _cameraService.CreateCamera(item.Id, item);
- var camera = _cameraService.GetCamera(item.Id);
- Status.Add(new StatusInfo(item.Id, item.CameraName + $"{Lang.未连接}", new SolidColorBrush(Colors.Red)));
- camera.CameraConnectChangedEvent += Management_CameraConnectChangedEvent;
- 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());
- }
- }
- /// <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);
- }
- }
- #endregion
- #region 机器人指令执行
- public Dictionary<Guid, CancellationTokenSource> RobotTCPCollection = 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);
- }
- }
- #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_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_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>
- /// 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 async 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);
- }));
- try
- {
- await WriteSystemParameterToPlcAsync(_configService.GetSystemConfiguration());
- await WriteParameterToPlcExAsync();
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("PLC连接成功时,写入系统参数和点位信息时出错!", ex);
- }
- }
- 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);
- nodeValues.Add(addressConfig.Out_ScrewTeachNum.Address, (Int16)systemConfiguration.ScrewTeachNum);
- 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_RequestPosition.Address,
- addressConfig.In_ScrewTeachExe.Address,
- addressConfig.In_QrCodePhotoRequest.Address,
- addressConfig.In_PickINC.Address,
- addressConfig.In_Throw.Address,
- // addressConfig.RunMode.Address,
- addressConfig.ManualMode.Address,
- addressConfig.AutoRunning.Address,
- addressConfig.ClearMode.Address,
- // addressConfig.Fault.Address,
- };
- for (int i = 0; i < 10; i++)
- {
- monitorNodeIds.Add(string.Format(addressConfig.In_MesCheck.Address, i));
- }
- for (int i = 0; i < 7; i++)
- {
- monitorNodeIds.Add(string.Format(addressConfig.In_WorkStart.Address, i));
- monitorNodeIds.Add(string.Format(addressConfig.In_WorkDone.Address, i));
- }
- //订阅PLC地址变化
- plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger);
- }
- /// <summary>
- /// 将产品的参数统一写入PLC
- /// </summary>
- /// <returns></returns>
- public async Task WriteParameterToPlcExAsync()
- {
- await WritePositionToPlcAsync();// 写入点位信息给PLC
- await WriteParameterToPlcAsync();// 写入组装上下限给PLC
- await WriteProductLoadModeToPLC();//把当前产品型号,写入PLC
- }
- /// <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.WriteToPlcAddressEx(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.RemovePoints != null && current.RemovePoints.Count > 0)
- {
- foreach (var item in current.RemovePoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_RemovePos, plc);
- }
- }
- if (current.PressurePlacePoints != null && current.PressurePlacePoints.Count > 0)
- {
- foreach (var item in current.PressurePlacePoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_PressurePlace, plc);
- }
- }
- if (current.IndependentCamerPoints != null && current.IndependentCamerPoints.Count > 0)
- {
- foreach (var item in current.IndependentCamerPoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_IndependentCamer, plc);
- }
- }
- if (current.QrCodePoints != null && current.QrCodePoints.Count > 0)
- {
- foreach (var item in current.QrCodePoints)
- {
- await item.WriteToPlcAddress(addressConfig.Out_QrCodeCamera, plc);
- }
- }
- }
- /// <summary>
- /// 写入组装上下限给PLC
- /// </summary>
- /// <returns></returns>
- public async Task WriteParameterToPlcAsync()
- {
- 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;
- try
- {
- if (currentProduct.GlobalParamEx == null) currentProduct.GlobalParamEx = new Models.Product.ProductGlobalParamEx();
- if (currentProduct.GlobalParamEx.AssemblyPressure == null) currentProduct.GlobalParamEx.AssemblyPressure = new PressureModel();
- if (currentProduct.GlobalParamEx.DownPressure == null) currentProduct.GlobalParamEx.DownPressure = new PressureModel();
- await plc.WriteNodeAsync(addressConfig.PUT_Down_Time.Address, currentProduct.GlobalParamEx.AssemblyPressure.PressureTime);
- await plc.WriteNodeAsync(addressConfig.PUT_WetOut_Num.Address, currentProduct.GlobalParamEx.AssemblyPressure.PressureNum);
- await plc.WriteNodeAsync(addressConfig.PUT_WetOut_Num_max.Address, currentProduct.GlobalParamEx.AssemblyPressure.PressureNumMax);
- await plc.WriteNodeAsync(addressConfig.Down_Time.Address, currentProduct.GlobalParamEx.DownPressure.PressureTime);
- await plc.WriteNodeAsync(addressConfig.Down_WetOut_Num.Address, currentProduct.GlobalParamEx.DownPressure.PressureNum);
- await plc.WriteNodeAsync(addressConfig.Down_WetOut_Num_max.Address, currentProduct.GlobalParamEx.DownPressure.PressureNumMax);
- }
- catch (Exception)
- {
- }
- }
- /// <summary>
- /// 将当前产品类型写入PLC
- /// </summary>
- /// <param name="mode"></param>
- public async Task WriteProductLoadModeToPLC(int modeIndex)
- {
- var addressConfig = _configService.GetPlcAddresses();
- var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
- if (plc == null || !plc.IsConnected) return;
- await plc.WriteNodeAsync(addressConfig.Out_ProductLoadMode.Address, (Int16)modeIndex);
- }
- /// <summary>
- /// 将当前产品类型写入PLC
- /// </summary>
- /// <param name="mode"></param>
- public async Task WriteProductLoadModeToPLC()
- {
- 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;
- var qMes = await _systemDatabaseService.QueryProductFromMesAsync(current.Name);
- if (qMes == null) return;
- await plc.WriteNodeAsync(addressConfig.Out_ProductLoadMode.Address, (Int16)qMes.ProductLoadMode);
- }
- /// <summary>
- /// 固定向上相机拍照结果
- /// </summary>
- OpenCvSharp.Point3f[] DowmCameraResults = new OpenCvSharp.Point3f[10];
- /// <summary>
- /// 移动向下相机拍照结果
- /// </summary>
- OpenCvSharp.Point3f[] UpCameraPutResults = new OpenCvSharp.Point3f[10];
- /// <summary>
- /// 取料移动相机拍照结果
- /// </summary>
- OpenCvSharp.Point3f UpCameraPickResult = new OpenCvSharp.Point3f();
- /// <summary>
- /// 最终组装位置
- /// </summary>
- OpenCvSharp.Point3f PlaceActualCoord = new OpenCvSharp.Point3f();
- /// <summary>
- /// 零件SN
- /// </summary>
- string PartSN = "";
- /// <summary>
- /// 产品SN
- /// </summary>
- string[] ProductMainSN = new string[10];//产品主sn
- /// <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
- /// <summary>
- /// 复检结果
- /// </summary>
- Dictionary<string, string> gapDict = new Dictionary<string, string>();
- /// <summary>
- /// 二次定位相机的工具坐标
- /// </summary>
- ToolCoord DownTool = new ToolCoord();
- double _FixedUpCameraAngle = 0;
- double _MoveCameraAngle = 0;
- 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;
- bool _LastManualMode = false;
- bool _LastClearMode = false;
- bool _LastThrowExe = false;
- bool _LastRunModel = false;
- bool _LastFault = false;
- Int16[] _LastWorkStart = new Int16[7];
- Int16 _LastQrCodePhotoRequest = 0;
- Int16[] _LastWorkDone = new Int16[7];
- Int16 _LastRequestPosition = 0;
- Int16 _LastPickINC = 0;
- Int16[] _LastMesCheck = new Int16[10];
- DateTime[] _LastMesCheckTime = new DateTime[10];
- double[] currentPressure = new double[10];//当前压力
- /// <summary>
- /// PLC命令触发时
- /// </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;
- }
- ////获取产品编码
- //_productService.CurrentProductCode = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, 0));
- ////如果产品编码为空,则以当前的时间戳作为编码
- //if (string.IsNullOrEmpty(_productService.CurrentProductCode))
- //{
- // _productService.CurrentProductCode = DateTime.Now.ToString("yyyyMMddHHmmssfff");
- //}
- bool isDryMode = plc.ReadNode<bool>(addressConfig.In_DryMode.Address);
- // 触发下相机拍照--下相机拍屏幕,预定位
- if (addressConfig.In_DowmCameraExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastDowmCameraExe != state)
- {
- _LastDowmCameraExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发下相机拍照...", MessageLevel.Debug);
- //相机的编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_DowmCameraNum.Address);
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
- // 获取机器人当前坐标
- var robot = _robotService.GetAllRobots().FirstOrDefault();
- if (robot == null)
- {
- SendTaskMessage($"未找到机器人,无法执行上相机锁附/组装拍照视觉任务", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- var currentPosition = robot.GetRobotPos();
- //如果下相机拍照的次数是1,则判断用时拍照的相机是几个
- int downCameraNum = _configService.GetSystemConfiguration().DowmCameraNum;
- if (downCameraNum == 1)
- {
- //如果下相机2的流程id为空,则表示只有一个下相机
- if (currentProduct.FixedUpCamera2ProcedureId == Guid.Empty)
- {
- //获取固定向上相机1的流程
- var process = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId);
- if (process == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera1ProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, cameraIndex, null);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- if (visionResult.IsSucceed)
- {
- //float toolX = (float)(visionResult.X - currentPosition.X);
- //float toolY = (float)(visionResult.Y - currentPosition.Y);
- DowmCameraResults[0] = new OpenCvSharp.Point3f((float)visionResult.X, (float)visionResult.Y, (float)visionResult.U);
- //DownTool = new PointF(toolX, toolY);
- //以LCD的的上边中心创建工具坐标
- DownTool.ComputeTool(currentPosition.X, currentPosition.Y, currentPosition.U, DowmCameraResults[0].X, DowmCameraResults[0].Y);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- else
- {
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- }
- else
- {
- //获取固定向上相机1的流程
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId);
- if (process1 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera1ProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- //获取固定向上相机2的流程
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera2ProcedureId);
- if (process2 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera2ProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, null, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, null, _cts.Token, 2, null);
- var visionResults = await Task.WhenAll(task1, task2);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed)
- {
- float toolX = (float)(visionResults[0].X + visionResults[1].X) / 2;
- float toolY = (float)(visionResults[0].Y + visionResults[1].Y) / 2;
- _FixedUpCameraAngle = Common.CalculateAngleBetweenPointsDegrees(new PointF((float)visionResults[0].X, (float)visionResults[0].Y), new PointF((float)visionResults[1].X, (float)visionResults[1].Y));
- SendTaskMessage($"屏幕中心点位:{toolX:F3},{toolY:F4},{_FixedUpCameraAngle:F4}", MessageLevel.Info);
- SendTaskMessage($"当前机器人点位:{currentPosition.X:F3},{currentPosition.Y:F4},{currentPosition.U:F4}", MessageLevel.Info);
- DowmCameraResults[0] = new OpenCvSharp.Point3f(toolX, toolY, (float)_FixedUpCameraAngle);
- //DownTool = new PointF(toolX, toolY);
- //以LCD的的上边中心创建工具坐标
- DownTool.ComputeTool(currentPosition.X, currentPosition.Y, currentPosition.U, DowmCameraResults[0].X, DowmCameraResults[0].Y);
- SendTaskMessage($"屏幕Tool:{DownTool.X:F3},{DownTool.Y:F4}", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- }
- }
- else if (downCameraNum == 2)
- {
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- //如果下相机2的流程id为空,则表示只有一个下相机
- if (currentProduct.FixedUpCamera2ProcedureId == Guid.Empty)
- {
- //获取固定向上相机1的流程
- //var process = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId);
- //if (process == null)
- //{
- // SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera1ProcedureId}", MessageLevel.Alarm);
- // await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- // return;
- //}
- //// 执行视觉任务
- //var _cts = new CancellationTokenSource();
- //var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token);
- //if (visionResult.IsSucceed)
- //{
- // float toolX = (float)(visionResult.X - currentPosition.X);
- // float toolY = (float)(visionResult.Y - currentPosition.Y);
- // DowmCameraResults[cameraIndex] = new PointF(toolX, toolX);
- // if (cameraIndex == downCameraNum)
- // {
- // //求取多个DowmCameraResults的中心点
- // DownTool = new PointF(toolX, toolX);
- // }
- // await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- // return;
- //}
- //else
- //{
- // await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- // return;
- //}
- //暂时没有应用场景,不支持
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- else
- {
- //获取固定向上相机1的流程
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId);
- if (process1 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera1ProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- //获取固定向上相机2的流程
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera2ProcedureId);
- if (process2 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera2ProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, 2, null);
- var visionResults = await Task.WhenAll(task1, task2);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed)
- {
- float toolX = (float)(visionResults[0].X + visionResults[1].X) / 2;
- float toolY = (float)(visionResults[0].Y + visionResults[1].Y) / 2;
- _FixedUpCameraAngle = Common.CalculateAngleBetweenPointsDegrees(new PointF((float)visionResults[0].X, (float)visionResults[0].Y), new PointF((float)visionResults[1].X, (float)visionResults[1].Y));
- DowmCameraResults[cameraIndex] = new OpenCvSharp.Point3f(toolX, toolY, (float)_FixedUpCameraAngle);
- //DownTool = new PointF(toolX, toolY);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)1);
- return;
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- }
- }
- else
- {
- //暂时没有应用场景,不支持
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- }
- else
- {
- SendTaskMessage($"触发下相机拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)0);
- }
- }
- }
- // 触发下相机拍照披头
- if (addressConfig.In_ScrewTeachExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastScrewTeachExe != state)
- {
- _LastScrewTeachExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发下相机拍照...", MessageLevel.Debug);
- //相机的编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_DowmCameraNum.Address);
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
- // 获取流程
- //var process = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId);
- //if (process == null)
- //{
- // SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.FixedUpCamera1ProcedureId}", MessageLevel.Alarm);
- // await plc.WriteNodeAsync(addressConfig.Out_ScrewTeachOk.Address, (Int16)2);
- // return;
- //}
- //// 获取机器人当前坐标
- //var robot = _robotService.GetAllRobots().FirstOrDefault();
- //if (robot == null)
- //{
- // SendTaskMessage($"未找到机器人,无法执行上相机锁附/组装拍照视觉任务", MessageLevel.Alarm);
- // await plc.WriteNodeAsync(addressConfig.Out_ScrewTeachOk.Address, (Int16)2);
- // return;
- //}
- //var currentPosition = robot.GetRobotPos();
- //// 执行视觉任务
- //var _cts = new CancellationTokenSource();
- //var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, null, _cts.Token);
- //if (visionResult.IsSucceed)
- //{
- // //披头偏差
- // float offsetX = (float)(visionResult.X - currentPosition.X);
- // float offsetY = (float)(visionResult.Y - currentPosition.Y);
- // DowmCameraResults[cameraIndex] = new PointF(offsetX, offsetY);
- // await plc.WriteNodeAsync(addressConfig.Out_ScrewTeachOk.Address, (Int16)1);
- // return;
- //}
- //else
- //{
- // await plc.WriteNodeAsync(addressConfig.Out_ScrewTeachOk.Address, (Int16)2);
- // return;
- //}
- }
- else
- {
- SendTaskMessage($"触发下相机拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_ScrewTeachOk.Address, (Int16)0);
- }
- }
- }
- // 触发上相机取料拍照
- else if (addressConfig.In_UpCameraPickExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastUpCameraPickExe != state)
- {
- _LastUpCameraPickExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发上相机取料拍照...", MessageLevel.Debug);
- //相机的编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_UpCameraPickNum.Address);
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
- // 获取机器人当前坐标
- var robot = _robotService.GetAllRobots().FirstOrDefault();
- if (robot == null)
- {
- SendTaskMessage($"未找到机器人,无法执行上相机锁附/组装拍照视觉任务", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)2);
- return;
- }
- var currentPosition = robot.GetRobotPos();
- //如果上相机2的流程id为空,则表示只有一个下相机
- if (currentProduct.MoveDownCamer2PickPhotoProcedureId == Guid.Empty)
- {
- //获取移动向下相机1的流程
- var process = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCamer1PickPhotoProcedureId);
- if (process == null)
- {
- SendTaskMessage($"移动向下相机1视觉流程,流程ID:{currentProduct.MoveDownCamer1PickPhotoProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, cameraIndex, null);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)1);
- return;
- }
- if (visionResult.IsSucceed)
- {
- currentProduct.PickPoints[0].X_Position = (float)visionResult.X;
- currentProduct.PickPoints[0].Y_Position = (float)visionResult.Y;
- //currentProduct.PickPoints[0].U_Position += (float)visionResult.U;
- await currentProduct.ScrewPoints[0].WriteToPlcAddress(addressConfig.Out_Pick, plc);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)1);
- return;
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)2);
- return;
- }
- }
- else
- {
- //获取固定向上相机1的流程
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCamer1PickPhotoProcedureId);
- if (process1 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.MoveDownCamer1PickPhotoProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)2);
- return;
- }
- //获取固定向上相机2的流程
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCamer2PickPhotoProcedureId);
- if (process2 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.MoveDownCamer2PickPhotoProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, 2, null);
- var visionResults = await Task.WhenAll(task1, task2);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed)
- {
- float tool1X = (float)(visionResults[0].X - visionResults[0].X);
- float tool1Y = (float)(visionResults[0].Y - visionResults[0].Y);
- float tool2X = (float)(visionResults[1].X - visionResults[1].X);
- float tool2Y = (float)(visionResults[1].Y - visionResults[1].Y);
- float toolX = (tool1X + tool2X) / 2;
- float toolY = (tool1Y + tool2Y) / 2;
- //计算两个点的线角度
- currentProduct.PickPoints[0].X_Position = (float)toolX;
- currentProduct.PickPoints[0].Y_Position = (float)toolY;
- //currentProduct.PickPoints[0].U_Position += (float)visionResult.U;
- await currentProduct.ScrewPoints[0].WriteToPlcAddress(addressConfig.Out_Pick, plc);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)1);
- return;
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)2);
- return;
- }
- }
- }
- else
- {
- SendTaskMessage($"触发上相机取料拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)0);
- }
- }
- }
- // 上相机锁附/组装拍照
- else if (addressConfig.In_UpCameraPutExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastUpCameraPutExe != state)
- {
- _LastUpCameraPutExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发上相机锁附/组装拍照...", MessageLevel.Debug);
- //相机的编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_UpCameraPutNum.Address);
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
- // 获取机器人当前坐标
- var robot = _robotService.GetAllRobots().FirstOrDefault();
- if (robot == null)
- {
- SendTaskMessage($"未找到机器人,无法执行上相机锁附/组装拍照视觉任务", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
- return;
- }
- var currentPosition = robot.GetRobotPos();
- //如果上相机2的流程id为空,则表示只有一个上相机
- if (currentProduct.MoveDownCamera2LockPhotoProcedureId == Guid.Empty)
- {
- //获取移动向下相机1的流程
- var process = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCamera1LockPhotoProcedureId);
- if (process == null)
- {
- SendTaskMessage($"移动向下相机1视觉流程,流程ID:{currentProduct.MoveDownCamera1LockPhotoProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, cameraIndex, null);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)1);
- return;
- }
- if (visionResult.IsSucceed)
- {
- UpCameraPutResults[cameraIndex] = new OpenCvSharp.Point3f((float)visionResult.X, (float)visionResult.Y, (float)visionResult.U);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)1);
- return;
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
- return;
- }
- }
- else
- {
- //获取移动向下相机1的流程
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCamera1LockPhotoProcedureId);
- if (process1 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.MoveDownCamera1LockPhotoProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
- return;
- }
- //获取移动向下相机2的流程
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCamera2LockPhotoProcedureId);
- if (process2 == null)
- {
- SendTaskMessage($"固定向上相机1视觉流程,流程ID:{currentProduct.MoveDownCamera2LockPhotoProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, 2, null);
- var visionResults = await Task.WhenAll(task1, task2);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed)
- {
- float centerX = (float)(visionResults[0].X + visionResults[1].X) / 2;
- float centerY = (float)(visionResults[0].Y + visionResults[1].Y) / 2;
- _MoveCameraAngle = Common.CalculateAngleBetweenPointsDegrees(new PointF((float)visionResults[0].X, (float)visionResults[0].Y), new PointF((float)visionResults[1].X, (float)visionResults[1].Y));
- UpCameraPutResults[cameraIndex] = new OpenCvSharp.Point3f(centerX, centerY, (float)_MoveCameraAngle);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)1);
- return;
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
- return;
- }
- }
- }
- else
- {
- SendTaskMessage($"触发上相机锁附/组装拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)0);
- }
- }
- }
- // 上相机检测拍照
- else if (addressConfig.In_UPCameracheckExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastUPCameracheckExe != state)
- {
- _LastUPCameracheckExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发上相机检测拍照...", MessageLevel.Debug);
- //相机的编号
- Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_UPCameracheckNum.Address);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)1);
- return;
- }
- //视觉流程ID
- Guid procedureId = Guid.Empty;
- //获取锁付拍照的点位
- var pos = currentProduct.CheckCameraPoints.FirstOrDefault(p => p.Number == cameraIndex);
- if (pos != null)
- {
- procedureId = pos.VisionProcessID;
- }
- // 获取流程
- var process = _productService.GetCurrentProductProcedureModelById(procedureId);
- if (process == null)
- {
- SendTaskMessage(string.Format("未找到点位:{0}的视觉流程:{1}", cameraIndex, procedureId), MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)2);
- return;
- }
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, null, _cts.Token, cameraIndex, null);
- if (visionResult.IsSucceed)
- {
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)1);
- SendTaskMessage($"点位{cameraIndex}检测OK", MessageLevel.Debug);
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)2);
- SendTaskMessage($"点位{cameraIndex}检测NG", MessageLevel.Error);
- }
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)1);
- }
- else
- {
- SendTaskMessage($"触发上相机检测拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)0);
- }
- }
- }
- // 固定相机取料拍照--屏幕拍照,取上边沿中心(防呆作用)
- else if (addressConfig.In_FixedCameraPickExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastFixedCameraPickExe != state)
- {
- _LastFixedCameraPickExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发固定相机取料拍照...", MessageLevel.Debug);
- //相机的编号
- //Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameraPickNum.Address);
- if (currentProduct.IndependentCamer1AuxProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer2AuxProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer3AuxProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer4AuxProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- //获取四个独立相机的流程id
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer1AuxProcedureId);
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer2AuxProcedureId);
- var process3 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer3AuxProcedureId);
- var process4 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer4AuxProcedureId);
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, null, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, null, _cts.Token, 2, null);
- var task3 = _remoteCommandService.ExecutePhotoGetSinglePoint(process3, null, null, _cts.Token, 3, null);
- var task4 = _remoteCommandService.ExecutePhotoGetSinglePoint(process4, null, null, _cts.Token, 4, null);
- var visionResults = await Task.WhenAll(task1, task2, task3, task4);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed && visionResults[2].IsSucceed && visionResults[3].IsSucceed)
- {
- Vector<double> p1 = Vector<double>.Build.Dense(new double[] { visionResults[0].X, visionResults[0].Y });
- Vector<double> p2 = Vector<double>.Build.Dense(new double[] { visionResults[1].X, visionResults[1].Y });
- Vector<double> p3 = Vector<double>.Build.Dense(new double[] { visionResults[2].X, visionResults[2].Y });
- Vector<double> p4 = Vector<double>.Build.Dense(new double[] { visionResults[3].X, visionResults[3].Y });
- //var center = RectangleCenterCalculator.CalculateByDirectMethod(new List<Vector<double>> { p1, p2, p3, p4 });
- var center = RectangleCenterCalculator.CalculateOptimalCenter(new List<Vector<double>> { p1, p2, p3, p4 });//0215修改,不考虑点顺序
- //UpCameraPutResults[1].X = (float)center.Center[0];
- //UpCameraPutResults[1].Y = (float)center.Center[1];
- //UpCameraPutResults[1].Z = (float)center.MajorAxisAngle;
- UpCameraPutResults[1].X = ((float)center.TopLeft[0] + (float)center.TopRight[0]) / 2;
- UpCameraPutResults[1].Y = ((float)center.TopLeft[1] + (float)center.TopRight[1]) / 2;
- UpCameraPutResults[1].Z = (float)center.MajorAxisAngle;
- SendTaskMessage($"LCD拍照结果:X={UpCameraPutResults[1].X},Y={UpCameraPutResults[1].Y},Angle={UpCameraPutResults[1].Z}", MessageLevel.Info);
- var dist1 = RectangleCenterCalculator.Distance(center.TopLeft, center.TopRight);//长1
- var dist2 = RectangleCenterCalculator.Distance(center.TopRight, center.BottomRight);//宽1
- var dist3 = RectangleCenterCalculator.Distance(center.BottomLeft, center.BottomRight);//长2
- var dist4 = RectangleCenterCalculator.Distance(center.TopLeft, center.BottomLeft);//宽2
- LogHelper.WriteLogInfo($"dist1={dist1};dist2={dist2};dist3={dist3};dist4={dist4};");
- if (currentProduct.GlobalParamListCollection.Count >= 4)
- {
- var param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 2);
- if (param != null)//长
- {
- var length = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- if (!(((length + limtDown) <= dist1) && (dist1 <= (length + LimtUp)) && (((length + limtDown) <= dist3) && (dist3 <= (length + LimtUp)))))
- {
- SendTaskMessage($"屏幕长度超范围:长1={dist1},长2={dist3},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"屏幕长度防呆:长1={dist1},长2={dist3},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Info);
- }
- param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 3);
- if (param != null)//宽
- {
- var length = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- if (!(((length + limtDown) <= dist2) && (dist2 <= (length + LimtUp)) && (((length + limtDown) <= dist4) && (dist4 <= (length + LimtUp)))))
- {
- SendTaskMessage($"屏幕宽度超范围:宽1={dist2},宽2={dist4},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"屏幕宽度防呆:宽1={dist2},宽2={dist4},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Info);
- }
- if (currentProduct.GlobalParamListCollection.Count >= 7)
- {
- param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 4);
- if (param != null)//X防呆
- {
- var Limt_val = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- var dist = UpCameraPutResults[1].X - UpCameraPutResults[0].X;
- if (!(((Limt_val + limtDown) <= dist) && (dist <= (Limt_val + LimtUp))))
- {
- SendTaskMessage($"贴合X防呆超限:X实际差值={dist},X允许差值={Limt_val},下限={limtDown},上限={LimtUp}", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"贴合X防呆:X实际差值={dist},X允许差值={Limt_val},下限={limtDown},上限={LimtUp}", MessageLevel.Info);
- }
- param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 5);
- if (param != null)//Y防呆
- {
- var Limt_val = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- var dist = UpCameraPutResults[1].Y - UpCameraPutResults[0].Y;
- if (!(((Limt_val + limtDown) <= dist) && (dist <= (Limt_val + LimtUp))))
- {
- SendTaskMessage($"贴合Y防呆超限:Y实际差值={dist},Y允许差值={Limt_val},下限={limtDown},上限={LimtUp}", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"贴合Y防呆:Y实际差值={dist},Y允许差值={Limt_val},下限={limtDown},上限={LimtUp}", MessageLevel.Info);
- }
- param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 6);
- if (param != null)//U防呆
- {
- var Limt_val = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- var dist = UpCameraPutResults[1].Z - UpCameraPutResults[0].Z;
- if (!(((Limt_val + limtDown) <= dist) && (dist <= (Limt_val + LimtUp))))
- {
- SendTaskMessage($"贴合U防呆超限:U实际差值={dist},X允许差值={Limt_val},下限={limtDown},上限={LimtUp}", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"贴合U防呆:U实际差值={dist},X允许差值={Limt_val},下限={limtDown},上限={LimtUp}", MessageLevel.Info);
- }
- }
- }
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)2);
- return;
- }
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
- }
- else
- {
- SendTaskMessage($"触发固定相机取料拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)0);
- }
- }
- }
- // 固定相机锁附/组装拍照--外壳拍照
- else if (addressConfig.In_FixedCameraPutExe.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastFixedCameraPutExe != state)
- {
- _LastFixedCameraPutExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage($"触发固定相机锁附/组装拍照...", MessageLevel.Debug);
- //相机的编号
- //Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameraPutNum.Address);
- if (currentProduct.IndependentCamer1ProductProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer2ProductProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer3ProductProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer4ProductProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- //获取四个独立相机的流程id
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer1ProductProcedureId);
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer2ProductProcedureId);
- var process3 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer3ProductProcedureId);
- var process4 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer4ProductProcedureId);
- // 执行视觉任务
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetSinglePoint(process1, null, null, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetSinglePoint(process2, null, null, _cts.Token, 2, null);
- var task3 = _remoteCommandService.ExecutePhotoGetSinglePoint(process3, null, null, _cts.Token, 3, null);
- var task4 = _remoteCommandService.ExecutePhotoGetSinglePoint(process4, null, null, _cts.Token, 4, null);
- var visionResults = await Task.WhenAll(task1, task2, task3, task4);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed && visionResults[2].IsSucceed && visionResults[3].IsSucceed)
- {
- Vector<double> p1 = Vector<double>.Build.Dense(new double[] { visionResults[0].X, visionResults[0].Y });
- Vector<double> p2 = Vector<double>.Build.Dense(new double[] { visionResults[1].X, visionResults[1].Y });
- Vector<double> p3 = Vector<double>.Build.Dense(new double[] { visionResults[2].X, visionResults[2].Y });
- Vector<double> p4 = Vector<double>.Build.Dense(new double[] { visionResults[3].X, visionResults[3].Y });
- //var center = RectangleCenterCalculator.CalculateByDirectMethod(new List<Vector<double>> { p1, p2, p3, p4 });
- var center = RectangleCenterCalculator.CalculateOptimalCenter(new List<Vector<double>> { p1, p2, p3, p4 });//0215修改,不考虑点顺序
- //UpCameraPutResults[0].X = (float)center.Center[0];
- //UpCameraPutResults[0].Y = (float)center.Center[1];
- UpCameraPutResults[0].X = ((float)center.TopLeft[0] + (float)center.TopRight[0]) / 2;
- UpCameraPutResults[0].Y = ((float)center.TopLeft[1] + (float)center.TopRight[1]) / 2;
- UpCameraPutResults[0].Z = (float)center.MajorAxisAngle;
- SendTaskMessage($"产品拍照结果:X={UpCameraPutResults[0].X},Y={UpCameraPutResults[0].Y},Angle={UpCameraPutResults[0].Z}", MessageLevel.Info);
- var dist1 = RectangleCenterCalculator.Distance(center.TopLeft, center.TopRight);//长1
- var dist2 = RectangleCenterCalculator.Distance(center.TopRight, center.BottomRight);//宽1
- var dist3 = RectangleCenterCalculator.Distance(center.BottomLeft, center.BottomRight);//长2
- var dist4 = RectangleCenterCalculator.Distance(center.TopLeft, center.BottomLeft);//宽2
- LogHelper.WriteLogInfo($"dist1={dist1};dist2={dist2};dist3={dist3};dist4={dist4};");
- if (currentProduct.GlobalParamListCollection.Count >= 4)
- {
- var param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 0);
- if (param != null)//长
- {
- var length = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- if (!(((length + limtDown) <= dist1) && (dist1 <= (length + LimtUp)) && (((length + limtDown) <= dist3) && (dist3 <= (length + LimtUp)))))
- {
- SendTaskMessage($"外壳长度超范围:长1={dist1},长2={dist3},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"外壳长度防呆:长1={dist1},长2={dist3},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Info);
- }
- param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 1);
- if (param != null)//宽
- {
- var length = Double.Parse(param.Param1);
- var limtDown = Double.Parse(param.Param2);
- var LimtUp = Double.Parse(param.Param3);
- if (!(((length + limtDown) <= dist2) && (dist2 <= (length + LimtUp)) && (((length + limtDown) <= dist4) && (dist4 <= (length + LimtUp)))))
- {
- SendTaskMessage($"外壳宽度超范围:宽1={dist2},宽2={dist4},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"外壳宽度防呆:宽1={dist2},宽2={dist4},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Info);
- }
- }
- }
- else
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
- return;
- }
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)1);
- }
- else
- {
- SendTaskMessage($"触发固定相机锁附/组装拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.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)
- {
- SendTaskMessage($"触发固定相机检测拍照...", MessageLevel.Debug);
- //相机的编号
- //Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
- if (currentProduct.IndependentCamer1CheckProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer2CheckProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer3CheckProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
- return;
- }
- if (currentProduct.IndependentCamer4CheckProcedureId == Guid.Empty)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
- return;
- }
- //获取四个独立相机的流程id
- var process1 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer1CheckProcedureId);
- var process2 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer2CheckProcedureId);
- var process3 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer3CheckProcedureId);
- var process4 = _productService.GetCurrentProductProcedureModelById(currentProduct.IndependentCamer4CheckProcedureId);
- // 执行视觉任务(复检结果gap)
- var _cts = new CancellationTokenSource();
- var task1 = _remoteCommandService.ExecutePhotoGetDistance(process1, null, null, _cts.Token, 1, null);
- var task2 = _remoteCommandService.ExecutePhotoGetDistance(process2, null, null, _cts.Token, 2, null);
- var task3 = _remoteCommandService.ExecutePhotoGetDistance(process3, null, null, _cts.Token, 3, null);
- var task4 = _remoteCommandService.ExecutePhotoGetDistance(process4, null, null, _cts.Token, 4, null);
- var visionResults = await Task.WhenAll(task1, task2, task3, task4);
- if (isDryMode)
- {
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1);
- return;
- }
- if (visionResults[0].IsSucceed && visionResults[1].IsSucceed && visionResults[2].IsSucceed && visionResults[3].IsSucceed)
- {
- SendTaskMessage($"固定相机检测OK", MessageLevel.Debug);
- SendTaskMessage($"流程1结果:{visionResults[0].distance}", MessageLevel.Debug);
- SendTaskMessage($"流程2结果:{visionResults[1].distance}", MessageLevel.Debug);
- SendTaskMessage($"流程3结果:{visionResults[2].distance}", MessageLevel.Debug);
- SendTaskMessage($"流程4结果:{visionResults[3].distance}", MessageLevel.Debug);
- gapDict.Clear();
- gapDict.Add("Gap1", visionResults[0].distance.Split(',')[1]);
- gapDict.Add("Gap2", visionResults[1].distance.Split(',')[1]);
- gapDict.Add("Gap3", visionResults[2].distance.Split(',')[1]);
- gapDict.Add("Gap4", visionResults[3].distance.Split(',')[1]);
- //gapString = $"{visionResults[0].distance.Split(',')[1]},{visionResults[1].distance.Split(',')[1]},{visionResults[2].distance.Split(',')[1]},{visionResults[3].distance.Split(',')[1]}";
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1);
- return;
- }
- else
- {
- string res1 = "", res2 = "", res3 = "", res4 = "";
- if (visionResults[0].IsSucceed)
- {
- res1 = visionResults[0].distance.Split(',')[1];
- }
- if (visionResults[1].IsSucceed)
- {
- res2 = visionResults[1].distance.Split(',')[1];
- }
- if (visionResults[2].IsSucceed)
- {
- res3 = visionResults[2].distance.Split(',')[1];
- }
- if (visionResults[3].IsSucceed)
- {
- res4 = visionResults[3].distance.Split(',')[1];
- }
- SendTaskMessage($"固定相机检测NG", MessageLevel.Error);
- gapDict.Clear();
- gapDict.Add("Gap1", res1);
- gapDict.Add("Gap2", res2);
- gapDict.Add("Gap3", res3);
- gapDict.Add("Gap4", res4);
- //gapString = $"{res1},{res2},{res3},{res4}";
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)2);
- return;
- }
- }
- else
- {
- SendTaskMessage($"触发固定相机检测拍照信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.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)
- {
- SendTaskMessage($"收到多相机坐标合并请求,开始合并...", MessageLevel.Debug);
- if (isDryMode)//空跑模式
- {
- var point1 = currentProduct.ScrewPoints[0].Clone();
- SendTaskMessage($"空跑模式点:1,{point1.X_Position:F3},{point1.Y_Position:F4},{point1.U_Position:F4}", MessageLevel.Info);
- await point1.WriteToPlcAddress(addressConfig.Out_Screw, plc);
- await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)1);
- await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)1);
- return;
- }
- // 获取机器人当前坐标
- var robot = _robotService.GetAllRobots().FirstOrDefault();
- if (robot == null)
- {
- SendTaskMessage($"未找到机器人,无法执行上相机锁附/组装拍照视觉任务", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- var currentPosition = robot.GetRobotPos();
- //已经通过下相机拍屏幕两角获取--DownTool
- //以LCD的中线创建工具坐标
- //ToolCoord toolCoord = new ToolCoord();
- //toolCoord.ComputeTool(currentPosition.X, currentPosition.Y, currentPosition.U, UpCameraPutResults[1].X, UpCameraPutResults[1].Y);
- //添加新的补偿算法--20260213
- double offset_X = 0, offset_Y = 0, offset_U = 0;
- var current = _productService.GetCurrentProduct();
- if (current.ScrewPoints == null || current.ScrewPoints.Count <= 0)
- {
- SendTaskMessage($"未找到任务贴合补偿参数", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2);
- return;
- }
- offset_X = current.ScrewPoints[0].X_Offset;
- offset_Y = current.ScrewPoints[0].Y_Offset;
- offset_U = current.ScrewPoints[0].U_Offset;
- SendTaskMessage($"放料补偿:X={offset_X},Y={offset_Y},U={offset_U}", MessageLevel.Info);
- //利用补偿偏差算出,补偿后的壳体中心,p_new
- ToolCoord toolCoord2 = new ToolCoord();
- toolCoord2.SetTool(offset_X, offset_Y);
- var p_new_Vector = Vector<double>.Build.Dense(new double[] { UpCameraPutResults[0].X, UpCameraPutResults[0].Y });
- var p_new = toolCoord2.GetToolnCoord(p_new_Vector, UpCameraPutResults[0].Z);
- SendTaskMessage($"放料原点:1,{UpCameraPutResults[0].X:F3},{UpCameraPutResults[0].Y:F4},{UpCameraPutResults[0].Z:F4}", MessageLevel.Info);
- SendTaskMessage($"放料补偿点:2,{p_new[0]:F3},{p_new[1]:F4},{UpCameraPutResults[0].Z:F4}", MessageLevel.Info);
- //计算放料角度--带入下相机的角度
- double angle = currentPosition.U - DowmCameraResults[0].Z + UpCameraPutResults[0].Z + offset_U;
- //将产品的中心点坐标转换为Tool0下的坐标
- var point = currentProduct.ScrewPoints[0].Clone();
- //var pn = Vector<double>.Build.Dense(new double[] { UpCameraPutResults[0].X, UpCameraPutResults[0].Y });
- var pn = p_new;
- //var p0 = toolCoord.GetTool0Coord(pn, angle);
- var p0 = DownTool.GetTool0Coord(pn, angle);//下相机拍照tool,动态Tool
- point.X_Position = (float)p0[0];
- point.Y_Position = (float)p0[1];
- point.U_Position = (float)angle;
- PlaceActualCoord = new OpenCvSharp.Point3f(point.X_Position, point.Y_Position, point.U_Position);
- //SendTaskMessage($"点:1,{point.X_Position:F3},{point.Y_Position:F4},{point.U_Position:F4}", MessageLevel.Info);
- SendTaskMessage($"目标点:3,{point.X_Position:F3},{point.Y_Position:F4},{point.U_Position:F4}", MessageLevel.Info);
- await point.WriteToPlcAddressEx2(addressConfig.Out_Screw, plc);//补偿参数提前代入计算,直接发最终点位
- await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)1);
- await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)1);
- //原计算方法--20260213
- ////计算放料角度
- //double angle = currentPosition.U - UpCameraPutResults[1].Z + UpCameraPutResults[0].Z;
- ////将产品的中心点坐标转换为Tool0下的坐标
- //var point = currentProduct.ScrewPoints[0].Clone();
- //var pn = Vector<double>.Build.Dense(new double[] { UpCameraPutResults[0].X, UpCameraPutResults[0].Y });
- //var p0 = toolCoord.GetTool0Coord(pn, angle);
- //point.X_Position = (float)p0[0];
- //point.Y_Position = (float)p0[1];
- //point.U_Position = (float)angle;
- //PlaceActualCoord = new OpenCvSharp.Point3f(point.X_Position, point.Y_Position, point.U_Position);
- //SendTaskMessage($"点:1,{point.X_Position:F3},{point.Y_Position:F4},{point.U_Position:F4}", MessageLevel.Info);
- //await point.WriteToPlcAddress(addressConfig.Out_Screw, plc);
- //await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)1);
- //await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)1);
- }
- else
- {
- SendTaskMessage($"多相机坐标合并请求已结束或被取消,state={state}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)0);
- }
- }
- }
- // 螺丝供料器螺丝递减
- else if (addressConfig.In_PickINC.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is Int16 state)
- {
- if (_LastPickINC != state)
- {
- _LastPickINC = state;
- }
- else
- {
- return;
- }
- if (state != 0)
- {
- SendTaskMessage($"螺丝供料器...", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.In_PickINC.Address, (Int16)0);
- }
- }
- }
- // PLC请求二维码拍照
- else if (addressConfig.In_QrCodePhotoRequest.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is Int16 state)
- {
- if (_LastQrCodePhotoRequest != state)
- {
- _LastQrCodePhotoRequest = state;
- }
- else
- {
- return;
- }
- if (state == 1)
- {
- //相机的编号
- //Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_QrCodeCamera_ScanNum.Address);
- //SendTaskMessage(string.Format("扫码编号", cameraIndex), MessageLevel.Info);
- Guid qrCodeProcedureId = currentProduct.QrCodeProcedureId;
- //视觉流程ID
- var qrCodeProcess = _productService.GetCurrentProductProcedureModelById(qrCodeProcedureId);
- if (qrCodeProcess == null)
- {
- SendTaskMessage($"未找到二维码视觉流程,流程ID: {qrCodeProcedureId}", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)2);
- return;
- }
- SendTaskMessage($"开始执行二维码扫码视觉流程", MessageLevel.Debug);
- var _cts = new CancellationTokenSource();
- await _remoteCommandService.SetLightBeforePhoto(qrCodeProcess);
- var qrCodeResult = _remoteCommandService.ExecutePhoto(1, qrCodeProcess, out CogToolBlockTerminalCollection outputCollection);
- if (qrCodeResult && outputCollection.Contains("QR"))
- {
- PartSN = outputCollection["QR"].Value as string;
- if (!string.IsNullOrEmpty(PartSN))
- {
- await plc.WriteNodeAsync(addressConfig.Out_PartCode.Address, PartSN);
- SendTaskMessage($"二维码扫码成功:{PartSN}", MessageLevel.Info);
- var stationConfig = _configService.GetDeviceInfo(0);
- if (stationConfig.EnableMES)
- {
- (bool isSuccess, string response) = await _mesService.StationGetEx2Async(0, PartSN, "", 2);//询问零件码,是否可以使用
- if (!isSuccess)//如果二维码已使用,则返回false
- {
- await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)3);
- return;
- }
- }
- await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)1);
- }
- else
- {
- PartSN = "";
- SendTaskMessage("二维码扫码失败", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)2);
- return;
- }
- }
- else
- {
- PartSN = "";
- SendTaskMessage("二维码扫码失败", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)2);
- return;
- }
- }
- else
- {
- SendTaskMessage("二维码拍照点位发送信号已关闭", MessageLevel.Alarm);
- await plc.WriteNodeAsync(addressConfig.Out_QrCodePhotoResault.Address, (Int16)0);
- }
- }
- }
- // 抛料计数
- else if (addressConfig.In_Throw.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastThrowExe != state)
- {
- _LastThrowExe = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage("收到抛料信号", MessageLevel.Info);
- await _systemDatabaseService.RecordThrowNumberAsync(new ThrowRecord()
- {
- DayTime = DateTime.Now,
- ThrowCount = 1
- });
- }
- }
- }
- //切换成自动运行模式
- else if (addressConfig.AutoRunning.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastAutoRunning != state)
- {
- _LastAutoRunning = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- SendTaskMessage("收到切换成自动模式", MessageLevel.Info);
- }
- else
- {
- SendTaskMessage("收到关闭自动模式", MessageLevel.Info);
- }
- CurrentRunStatus();
- }
- }
- //切换成维修模式
- else if (addressConfig.ManualMode.Address.Contains(tuple.nodeId))
- {
- if (tuple.value is bool state)
- {
- if (_LastManualMode != state)
- {
- _LastManualMode = state;
- }
- else
- {
- return;
- }
- if (state)
- {
- ClearModeBackground = System.Windows.Media.Brushes.White;
- RunModelBackground = System.Windows.Media.Brushes.White;
- ManualModeBackground = System.Windows.Media.Brushes.Orange;
- 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)
- {
- ClearModeBackground = System.Windows.Media.Brushes.Yellow;
- RunModelBackground = System.Windows.Media.Brushes.White;
- ManualModeBackground = System.Windows.Media.Brushes.White;
- SendTaskMessage("收到切换成流线模式", MessageLevel.Info);
- }
- }
- }
- 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;
- }
- var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, i));
- string comp = PartSN;
- SendTaskMessage($"产品sn:{code},辅料码:{comp}", MessageLevel.Info);
- //询问mes
- if (state == 1)
- {
- //获取过站时间
- _LastMesCheckTime[i] = (await _mesService.GetServerTimeAsync(i, code, 2)).Now;
- //获取当前工位的配置
- var stationConfig = _configService.GetDeviceInfo(i);
- if (stationConfig.EnableDoubleMes)
- {
- SendTaskMessage($"收到{i}:{stationConfig.DeviceName}过站检查请求(当站是否生产)(当前需要双MES验证)...", MessageLevel.Debug);
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- (bool isSuccess, string response) = await _mesService.StationGetExAsync(i, code, PartSN, 2);//询问mes
- if (isSuccess)
- {
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- string ProductMainSN_Temp = "";
- 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);
- }
- (bool isSuccess2, string response2) = await _mesService.StationGetAsync(i, ProductMainSN_Temp, PartSN, 2);//询问mes
- if (isSuccess2)
- {
- LogHelper.WriteLogMes($"第二次询问mes成功");
- SendTaskMessage($"第二次询问mes成功:{response2}", MessageLevel.Debug);
- item = response2.Split('\n');
- //获取产品主sn和wo用于后续上传数据使用
- snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN[i] = snItem.Replace("sn=", "").Trim();
- if (i == 0)
- {
- _productService.CurrentProductCode = ProductMainSN[i];
- //_eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
- }
- SendTaskMessage($"产品主sn:{ProductMainSN[i]}", 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 revisionItem = item.FirstOrDefault(f => f.Contains("stage="));
- if (revisionItem != null)
- {
- revision[i] = revisionItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{revision[i]}", MessageLevel.Info);
- }
- //if (QRcode != camerasn)
- //{
- // SendTaskMessage($"Camera_SN与相机获取sn不一致", MessageLevel.Error);
- // await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- // return;
- //}
- //切换产品
- if (i == 0)//i=0时才会切换产品
- {
- var q = await _systemDatabaseService.QueryProductFromMesAsync(model_num[i], color[i]);
- if (q != null && !string.IsNullOrEmpty(q.ProductName))
- {
- 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 (currentProduct.ID != productId)
- {
- //切换产品
- await _productService.LoadProductAsync(productId);
- _productService.SetCurrentProduct(productId);
- await WriteParameterToPlcExAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- }
- }
- }
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
- }
- else
- {
- LogHelper.WriteLogMes($"第二次询问mes失败");
- SendTaskMessage($"第二次询问mes失败:{response2}", MessageLevel.Error);
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- }
- }
- else
- {
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- }
- LogHelper.WriteLogMes($"【mes结束QUERY】");
- SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
- }
- else if (stationConfig.EnableMES)
- {
- SendTaskMessage($"收到{i}:{stationConfig.DeviceName}过站检查请求(当站是否生产)(当前不需要双MES验证)...", MessageLevel.Debug);
- LogHelper.WriteLogMes($"【mes开始QUERY】");
- SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
- (bool isSuccess, string response) = await _mesService.StationGetAsync(i, code, PartSN, 2);//询问mes
- if (isSuccess)
- {
- string[] item = response.Split('\n');
- //获取产品主sn和wo用于后续上传数据使用
- string snItem = item.FirstOrDefault(f => f.Contains("sn="));
- if (snItem != null)
- {
- ProductMainSN[i] = snItem.Replace("sn=", "").Trim();
- if (i == 0)
- {
- _productService.CurrentProductCode = ProductMainSN[i];
- //_eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
- }
- SendTaskMessage($"产品主sn:{ProductMainSN[i]}", 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 revisionItem = item.FirstOrDefault(f => f.Contains("stage="));
- if (revisionItem != null)
- {
- revision[i] = revisionItem.Replace("stage=", "").Trim();
- SendTaskMessage($"stage:{revision[i]}", MessageLevel.Info);
- }
- //if (QRcode != camerasn)
- //{
- // SendTaskMessage($"Camera_SN与相机获取sn不一致", MessageLevel.Alarm);
- // await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- // return;
- //}
- LogHelper.WriteLogMes($"询问mes成功");
- SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
- //切换产品
- if (i == 0)//i=0时才会切换产品
- {
- var q = await _systemDatabaseService.QueryProductFromMesAsync(model_num[i], color[i]);
- if (q != null && !string.IsNullOrEmpty(q.ProductName))
- {
- 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 (currentProduct.ID != productId)
- {
- //切换产品
- await _productService.LoadProductAsync(productId);
- _productService.SetCurrentProduct(productId);
- await WriteParameterToPlcExAsync();
- SendTaskMessage($"切换产品成功", MessageLevel.Debug);
- }
- }
- }
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
- }
- else
- {
- LogHelper.WriteLogMes($"询问mes失败");
- SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
- //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
- await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
- }
- LogHelper.WriteLogMes($"【mes结束QUERY】");
- SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
- }
- else
- {
- ProductMainSN[i] = DateTime.Now.ToString();
- if (i == 0)
- {
- _productService.CurrentProductCode = ProductMainSN[i];
- //_eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
- }
- LogHelper.WriteLogMes($"【未启用mes】");
- SendTaskMessage($"未启用mes", MessageLevel.Info);
- await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
- }
- }
- // 上传本站数据
- else if (state == 2)
- {
- DFC.Clear();//CTQ数据集合
- //获取当前工位的配置
- var stationConfig = _configService.GetDeviceInfo(i);
- SendTaskMessage($"收到{i}:{stationConfig.DeviceName}上传本站数据请求...", MessageLevel.Debug);
- //从服务器中获取当前时间
- var serverTimeResult = await _mesService.GetServerTimeAsync(i, ProductMainSN[i], 2);
- double ct = serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds;
- if (i == 0)
- {
- CTtime = ct;
- _eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
- }
- //从PLC获取零件编号
- PartSN = plc.ReadNode<string>(addressConfig.In_PartCode.Address);
- comp = PartSN;
- //读取产品结果
- Int16 resultIndex = plc.ReadNode<Int16>(string.Format(addressConfig.In_Result.Address, i));
- resultIndex = 1;
- #region 组装结果显示列表信息
- AssemblyRecord assemblyRecord = new AssemblyRecord();
- assemblyRecord.ProductSN = code;
- assemblyRecord.RecipeName = currentProduct.Name;
- assemblyRecord.PartSN = PartSN;
- assemblyRecord.AssemblyDurationSeconds = ct;
- assemblyRecord.AssemblyPressure = currentPressure[i];
- assemblyRecord.DeviceId = i;
- assemblyRecord.DeviceName = stationConfig.DeviceName;
- assemblyRecord.OperatorName = _systemDatabaseService.GetCurrentUser().UserName;
- assemblyRecord.Success = resultIndex == 1 ? true : false;
- assemblyRecord.DownCameraCoord1 = "";
- assemblyRecord.DownCameraCoord2 = "";
- assemblyRecord.DownCameraCoord3 = "";
- assemblyRecord.DownCameraCoord4 = "";
- assemblyRecord.PickMoveCameraCoord = "";
- assemblyRecord.PlaceMoveCameraCoord1 = "";
- assemblyRecord.PlaceMoveCameraCoord2 = "";
- assemblyRecord.PlaceMoveCameraCoord3 = "";
- assemblyRecord.PlaceMoveCameraCoord4 = "";
- assemblyRecord.PlaceActualCoord = "";
- //目前只记录当前站
- if (i == 0)
- {
- await _systemDatabaseService.RecordProductionAsync(new ProductionRecord()
- {
- ProductName = currentProduct.Name,
- ProductCode = code,
- DeviceId = i,
- DeviceName = "",
- Category = resultIndex == 1 ? "OK" : "NG",
- Quantity = 1,
- Remark = $"TotalSeconds:{ct.ToString("F2")}",
- UserName = _systemDatabaseService.GetCurrentUser().UserName,
- });
- assemblyRecord.PlaceMoveCameraCoord1 = $"{UpCameraPutResults[0].X:F3},{UpCameraPutResults[0].Y:F3},{UpCameraPutResults[0].Z:F3}";
- assemblyRecord.PlaceMoveCameraCoord2 = $"{UpCameraPutResults[1].X:F3},{UpCameraPutResults[1].Y:F3},{UpCameraPutResults[1].Z:F3}";
- assemblyRecord.PlaceActualCoord = $"{PlaceActualCoord.X:F3},{PlaceActualCoord.Y:F3},{PlaceActualCoord.Z:F3}";
- App.Current.Dispatcher.Invoke(() =>
- {
- _eventAggregator.GetEvent<AssemblyFinishNotification>().Publish(assemblyRecord);
- });
- }
- await _systemDatabaseService.RecordAssemblyAsync(assemblyRecord);
- #endregion
- LogHelper.WriteLogMes($"【mes开始ADD】");
- SendTaskMessage($"mes开始ADD", MessageLevel.Info);
- Dictionary<string, string> data = new Dictionary<string, string>();
- string press = ""; string presstime = ""; string assypress = "";
- if (i == 0)
- {
- try
- {
- assypress = currentPressure[0].ToString("F2");
- if (currentPressure[0] >= currentProduct.GlobalParamEx.AssemblyPressure.PressureDownLimit && currentPressure[0] <= currentProduct.GlobalParamEx.AssemblyPressure.PressureUpLimit)
- {
- resultIndex = 1;
- }
- else
- {
- resultIndex = 2;
- }
- }
- catch (Exception ex)
- {
- assypress = "0";
- resultIndex = 2;
- }
- data = gapDict.Copy();
- data.Add("AssyPressure1", assypress);
- SendTaskMessage($"Gap1:{gapDict["Gap1"]},Gap2:{gapDict["Gap2"]},Gap3:{gapDict["Gap3"]},Gap4:{gapDict["Gap4"]},组装压力:{assypress}", MessageLevel.Info);
- #region CSV数据
- bool assyPresRes;
- if (currentPressure[0] >= currentProduct.GlobalParamEx.AssemblyPressure.PressureDownLimit && currentPressure[0] <= currentProduct.GlobalParamEx.AssemblyPressure.PressureUpLimit)
- {
- assyPresRes = true;
- }
- else assyPresRes = false;
- DFC.Clear();
- string upLimitValue = "NA", downLimitValue = "NA", midValue = "NA", saveppid = "NA";
- if (stationConfig.SaveCsvPPID) saveppid = ppid[i];
- foreach (var item in gapDict)
- {
- switch (item.Key)
- {
- case "Gap1":
- upLimitValue = currentProduct.GlobalParamEx.Gap1UpLimit.ToString("F3");
- downLimitValue = currentProduct.GlobalParamEx.Gap1DownLimit.ToString("F3");
- midValue = ((currentProduct.GlobalParamEx.Gap1UpLimit + currentProduct.GlobalParamEx.Gap1DownLimit) / 2).ToString("F3");
- break;
- case "Gap2":
- upLimitValue = currentProduct.GlobalParamEx.Gap2UpLimit.ToString("F3");
- downLimitValue = currentProduct.GlobalParamEx.Gap2DownLimit.ToString("F3");
- midValue = ((currentProduct.GlobalParamEx.Gap2UpLimit + currentProduct.GlobalParamEx.Gap2DownLimit) / 2).ToString("F3");
- break;
- case "Gap3":
- upLimitValue = currentProduct.GlobalParamEx.Gap3UpLimit.ToString("F3");
- downLimitValue = currentProduct.GlobalParamEx.Gap3DownLimit.ToString("F3");
- midValue = ((currentProduct.GlobalParamEx.Gap3UpLimit + currentProduct.GlobalParamEx.Gap3DownLimit) / 2).ToString("F3");
- break;
- case "Gap4":
- upLimitValue = currentProduct.GlobalParamEx.Gap4UpLimit.ToString("F3");
- downLimitValue = currentProduct.GlobalParamEx.Gap4DownLimit.ToString("F3");
- midValue = ((currentProduct.GlobalParamEx.Gap4UpLimit + currentProduct.GlobalParamEx.Gap4DownLimit) / 2).ToString("F3");
- break;
- }
- 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.Key,
- CTQ_VALUE = item.Value,
- CTQ_LSL = downLimitValue,
- CTQ_USL = upLimitValue,
- 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+"_"+ revision[i],
- WO = wo[i],
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = "Pass",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "mm",
- ERROR_MESSAGE = "NA",
- PD_ATTR_01 = midValue,
- PD_ATTR_02 = ProductMainSN[i],
- PD_ATTR_03 = PartSN,
- PD_ATTR_04 = code,
- PD_ATTR_05 = "NA",
- });
- }
- midValue = ((currentProduct.GlobalParamEx.AssemblyPressure.PressureDownLimit + currentProduct.GlobalParamEx.AssemblyPressure.PressureUpLimit) / 2).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 = "Assy_Pressure",
- CTQ_VALUE = assypress,
- CTQ_LSL = currentProduct.GlobalParamEx.AssemblyPressure.PressureDownLimit.ToString("F3"),
- CTQ_USL = currentProduct.GlobalParamEx.AssemblyPressure.PressureUpLimit.ToString("F3"),
- 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 + "_" + revision[i],
- WO = wo[i],
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = assyPresRes ? "Pass" : "Fail",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "kg",
- ERROR_MESSAGE = assyPresRes ? "NA" : "Assy_Pressure OOS",
- PD_ATTR_01 = midValue,
- PD_ATTR_02 = ProductMainSN[i],
- PD_ATTR_03 = PartSN,
- PD_ATTR_04 = code,
- PD_ATTR_05 = "NA",
- });
- #endregion
- }
- else if (i == 1)
- {
- try
- {
- press = currentPressure[1].ToString("F2");
- if (currentPressure[1] >= currentProduct.GlobalParamEx.DownPressure.PressureDownLimit && currentPressure[1] <= currentProduct.GlobalParamEx.DownPressure.PressureUpLimit)
- {
- resultIndex = 1;
- }
- else
- {
- resultIndex = 2;
- }
- }
- catch (Exception ex)
- {
- press = "0";
- resultIndex = 2;
- }
- presstime = currentProduct.GlobalParamEx.DownPressure.PressureTime.ToString();
- data.Add("Pressure1", press);
- data.Add("PressureTime1", presstime);
- SendTaskMessage($"保压压力:{press},保压时间:{presstime}", MessageLevel.Info);
- #region CSV数据
- bool presRes;
- if (currentPressure[1] >= currentProduct.GlobalParamEx.DownPressure.PressureDownLimit && currentPressure[1] <= currentProduct.GlobalParamEx.DownPressure.PressureUpLimit)
- {
- presRes = true;
- }
- else presRes = false;
- DFC.Clear();
- string midValue = "NA", saveppid = "NA";
- midValue = ((currentProduct.GlobalParamEx.DownPressure.PressureDownLimit + currentProduct.GlobalParamEx.DownPressure.PressureUpLimit) / 2).ToString("F3");
- if (stationConfig.SaveCsvPPID) saveppid = ppid[i];
- 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 = "Pressure",
- CTQ_VALUE = press,
- CTQ_LSL = currentProduct.GlobalParamEx.DownPressure.PressureDownLimit.ToString("F3"),
- CTQ_USL = currentProduct.GlobalParamEx.DownPressure.PressureUpLimit.ToString("F3"),
- 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 + "_" + revision[i],
- WO = wo[i],
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = presRes ? "Pass" : "Fail",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "kg",
- ERROR_MESSAGE = presRes ? "NA" : "Pressure OOS",
- PD_ATTR_01 = midValue,
- PD_ATTR_02 = ProductMainSN[i],
- PD_ATTR_03 = "NA",
- PD_ATTR_04 = code,
- PD_ATTR_05 = "NA",
- });
- midValue = ((currentProduct.GlobalParamEx.DownPressure.PressureTime + currentProduct.GlobalParamEx.DownPressure.PressureTime) / 2).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 = "Pressure_time",
- CTQ_VALUE = Math.Round(double.Parse(presstime), 3).ToString(),
- CTQ_LSL = currentProduct.GlobalParamEx.DownPressure.PressureTime.ToString("F3"),
- CTQ_USL = currentProduct.GlobalParamEx.DownPressure.PressureTime.ToString("F3"),
- 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 + "_" + revision[i],
- WO = stationConfig.DataInfo.WO,
- MFG_LOT = stationConfig.DataInfo.MFG_LOT,
- MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
- PROCESS_OUTCOME = "Pass",
- PROCESS_MACHINE_ID = stationConfig.DataInfo.PROCESS_MACHINE_ID,
- CTQ_UNIT_OF_MEASURE = "s",
- ERROR_MESSAGE = "NA",
- PD_ATTR_01 = midValue,
- PD_ATTR_02 = ProductMainSN[i],
- PD_ATTR_03 = "NA",
- PD_ATTR_04 = code,
- PD_ATTR_05 = "NA",
- });
- #endregion
- }
- //gap-复检gap参数, press-保压站实际压力值, presstime-保压站保压时间, assypress-组装站实际压力值
- (bool isSuccess, string response) = await _mesService.SubmitGetAsync(i, ProductMainSN[i], comp, resultIndex == 1 ? true : false, data, _LastMesCheckTime[i], serverTimeResult.Now);
- if (!stationConfig.EnableMES || isSuccess)
- {
- LogHelper.WriteLogMes($"上传mes成功");
- SendTaskMessage($"上传mes成功", MessageLevel.Debug);
- }
- else
- {
- LogHelper.WriteLogMes($"上传mes失败");
- SendTaskMessage($"上传mes失败", MessageLevel.Error);
- }
-
- //是否保存当前的产品记录至CSV?
- if (stationConfig.SaveCsv)
- {
- //判断锁付路径字符串是否为空,如果不为空则保存,否则不保存
- if (!string.IsNullOrEmpty(stationConfig.SaveCsvPath))
- {
- bool recordResult = RecordStationResult(i, DFC, ProductMainSN[i], serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath);
- if (recordResult)
- {
- SendTaskMessage($"{i}:{stationConfig.DeviceName}产品记录保存成功", MessageLevel.Debug);
- //上传数据
- try
- {
- if (stationConfig.EnableMES)
- {
- DateTime dt = DateTime.Now;
- string filename = $"{ProductMainSN[i]}_{dt.ToString("yyyyMMddHHmmss")}";
- //string csvfilename = $"{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}";
- var device = _configService.GetDeviceInfo(i);
- var systemConfig = _configService.GetSystemConfiguration();
- var pressureSensorConfig = systemConfig.PressureSensorConfig.FirstOrDefault();
- (bool isSuc, string resp) = await _mesService.SendFtpFileAsync(ProductMainSN[i], filename);
- if (isSuc)
- {
- LogHelper.WriteLogMes($"上传数据成功");
- SendTaskMessage($"上传数据成功", MessageLevel.Debug);
- string filePath = $"D:\\image\\Recored\\{dt.ToString("yyyy-MM")}\\{dt.ToString("MM-dd")}\\{currentProduct.Name}\\{ProductMainSN[i]}";
- string source_csv2 = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}\\{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}";
- if (!Directory.Exists(filePath))
- {
- Directory.CreateDirectory(filePath);
- }
- //复制csv
- string source_csv = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}\\{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}.csv";
- 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);
- //判断是否保存锁付曲线
- if (pressureSensorConfig.IsSavePressureCurve)
- {
- string target_Directory = filePath + "\\压力曲线\\";
- string source_Torque_Image = pressureSensorConfig.PressureCurvePath + $"\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}\\{currentProduct.Name}\\{ProductMainSN[i]}";
- var col = Directory.GetFiles(source_Torque_Image);
- try
- {
- Directory.CreateDirectory(target_Directory);
- foreach (var item in col)
- {
- string target_Torque = target_Directory + item.Replace(source_Torque_Image, "");
- File.Copy(item, target_Torque, true);
- SendTaskMessage($"曲线图{i}保存成功", MessageLevel.Debug);
- }
- }
- catch (Exception)
- {
- SendTaskMessage($"扭力曲线图读取失败", MessageLevel.Error);
- }
- }
- CompressionImage(filePath, filename, device.Station, device.FixtureId);
- //上传csv
- bool isAfter20 = dt.Hour >= 20;
- //判断是否是新的一天
- bool isNewDay = dt.Date != _lastCompressDate.Date;
- //当天还没执行过压缩
- if (isAfter20 && isNewDay && !_hasCompressedToday)
- {
- // 执行压缩
- CompressionImage(source_csv2, filename, 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);
- }
- LogHelper.WriteLogMes($"【mes结束ADD】");
- SendTaskMessage($"mes结束ADD", MessageLevel.Info);
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
- return;
- }
- else
- {
- SendTaskMessage($"{i}过站检查信号:state={state},处理为默认状态", MessageLevel.Alarm);
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)0);
- return;
- }
- }
- }
- }
- //开始/停止 组装/锁附
- for (int i = 0; i < 7; i++)
- {
- //开始组装
- if (string.Format(addressConfig.In_WorkStart.Address, i).Contains(tuple.nodeId))
- {
- if (tuple.value is Int16 state)
- {
- if (_LastWorkStart[i] != state)
- {
- _LastWorkStart[i] = state;
- }
- else
- {
- return;
- }
- var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, i));
- if (state == 1)
- {
- //SendTaskMessage($"收到开始组装信号[{i}]...", MessageLevel.Debug);
- SendTaskMessage($"收到开始保压信号[{i}]...", MessageLevel.Debug);
- // 开始采集压力值
- StartPressureCollection(currentProduct.Name, ProductMainSN[i], i);
- StartCtqTime[i] = DateTime.Now;
- }
- else
- {
- SendTaskMessage($"关闭开始保压信号[{i}]...", MessageLevel.Debug);
- }
- }
- }
- //停止组装
- else if (string.Format(addressConfig.In_WorkDone.Address, i).Contains(tuple.nodeId))
- {
- if (tuple.value is Int16 state)
- {
- if (_LastWorkDone[i] != state)
- {
- _LastWorkDone[i] = state;
- }
- else
- {
- return;
- }
- if (state == 1)
- {
- SendTaskMessage($"收到停止压力信号[{i}]...", MessageLevel.Debug);
- //读取压力值
- //float pressure = plc.ReadNode<float>(addressConfig.In_PressureValue.Address);
- //读取压力值
- //float pressure = plc.ReadNode<float>(string.Format(addressConfig.In_PressureValue.Address, i));
- float pressure = plc.ReadNode<float>(string.Format(addressConfig.In_PressureLastValue.Address, i));
- currentPressure[i] = pressure;
- SendTaskMessage($"[{i}]压力:{pressure}", MessageLevel.Info);
- //await Task.Delay(60);
- await plc.WriteNodeAsync(string.Format(addressConfig.In_WorkDone.Address, i), (Int16)0);
- var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, i));
- // 停止采集压力并保存
- await StopAndSavePressureCollectionAsync(currentProduct.Name, ProductMainSN[i], i);
- }
- else
- {
- SendTaskMessage($"停止压力信号[{i}]已关闭", MessageLevel.Alarm);
- }
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- SendTaskMessage(ex.Message, MessageLevel.Error);
- LogHelper.WriteLogError("PLC命令执行时出错!", ex);
- }
- }
- #endregion
- #region 方法
- private void SendTaskMessage(string msg, MessageLevel level)
- {
- App.Current.Dispatcher.Invoke(() =>
- {
- _eventAggregator.GetEvent<TaskMessageNotification>().Publish(new Models.MessageStruct() { Message = msg, level = level });
- });
- }
- public bool concurrenty = true;
- public void CurrentRunStatus()
- {
- if (!concurrenty)
- {
- return;
- }
- concurrenty = true;
- bool connectStaus = true;
- bool mesStatus = true;
- //bool paraStatus = true;
- try
- {
- var allDevices = _configService.GetAllDeviceInfos();
- for (int i = 0; i < allDevices.Count; i++)
- {
- var stationConfig = allDevices.FirstOrDefault(d => d.DeviceNo == i);
- //var stationConfig = _configService.GetDeviceInfo(i);
- if (!string.IsNullOrEmpty(stationConfig.Station) && stationConfig.Station != ""&&!string.IsNullOrEmpty(stationConfig.DeviceName) && stationConfig.DeviceName != "")
- {
- if (!stationConfig.EnableMES || !stationConfig.EnableDoubleMes || !stationConfig.SaveCsv)
- {
- SendTaskMessage("当前MES功能/双验证功能/保存CSV功能未启用,请检查...", MessageLevel.Info);
- mesStatus = false;
- break;
- }
- }
- }
- //var systemConfig = _configService.GetSystemConfiguration();
- //if (!systemConfig.PressureSensorConfig[0].IsSavePressureCurve || !systemConfig.PressureSensorConfig[1].IsSavePressureCurve)
- //{
- // paraStatus = false;
- //}
- foreach (var item in Status)
- {
- if (item.Background == System.Windows.Media.Brushes.Red)
- {
- SendTaskMessage("当前有设备未连接,请检查...", MessageLevel.Info);
- connectStaus = false;
- break;
- }
- }
- }
- catch (Exception)
- {
- connectStaus = false;
- mesStatus = false;
- //paraStatus = false;
- }
- if (connectStaus && mesStatus && _LastAutoRunning)
- {
- RunModelBackground = System.Windows.Media.Brushes.Green;
- ClearModeBackground = System.Windows.Media.Brushes.White;
- ManualModeBackground = System.Windows.Media.Brushes.White;
- SendTaskMessage("当前为生产模式", MessageLevel.Info);
- }
- else
- {
- RunModelBackground = System.Windows.Media.Brushes.White;
- ClearModeBackground = System.Windows.Media.Brushes.White;
- ManualModeBackground = System.Windows.Media.Brushes.Orange;
- SendTaskMessage("当前为调机模式", MessageLevel.Info);
- }
- concurrenty = true;
- }
- #region Pressure collection helpers
- public void InitPressure()
- {
- for (int i = 0; i < _pressureSamples.Length; i++)
- {
- _pressureSamples[i] = new List<(DateTime, float)>();
- }
- for (int i = 0; i < _pressureCts.Length; i++)
- {
- _pressureCts[i] = new CancellationTokenSource();
- }
- for (int i = 0; i < _pressureTimeoutCts.Length; i++)
- {
- _pressureTimeoutCts[i] = new CancellationTokenSource();
- }
- for (int i = 0; i < _pressureLinkedCts.Length; i++)
- {
- _pressureLinkedCts[i] = new CancellationTokenSource();
- }
- }
- /// <summary>
- /// 开始采集压力值
- /// </summary>
- /// <param name="productName">配方名称</param>
- /// <param name="productCode">产品编号</param>
- /// <param name="Index">编号</param>
- private void StartPressureCollection(string productName, string productCode, int Index)
- {
- try
- {
- // cancel existing if any
- //_pressureCts[Index]?.Cancel();
- //_pressureTimeoutCts[Index]?.Cancel();
- //_pressureLinkedCts[Index]?.Dispose();
- _pressureSamples[Index]?.Clear();
- _pressureCts[Index] = new CancellationTokenSource();
- _pressureTimeoutCts[Index] = new CancellationTokenSource();
- // timeout after configured seconds
- _pressureTimeoutCts[Index].CancelAfter(TimeSpan.FromSeconds(_pressureMaxDurationSeconds));
- // link tokens so either stop or timeout cancels
- _pressureLinkedCts[Index] = CancellationTokenSource.CreateLinkedTokenSource(_pressureCts[Index].Token, _pressureTimeoutCts[Index].Token);
- var token = _pressureLinkedCts[Index].Token;
- var addressConfig = _configService.GetPlcAddresses();
- var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
- if (plc == null || !plc.IsConnected) return;
- Task.Run(async () =>
- {
- SendTaskMessage($"Pressure collection started for position {Index}", MessageLevel.Debug);
- while (!token.IsCancellationRequested)
- {
- try
- {
- float pressure = plc.ReadNode<float>(string.Format(addressConfig.In_PressureValue.Address, Index));
- lock (_pressureSamples[Index])
- {
- _pressureSamples[Index].Add((DateTime.Now, pressure));
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("采集压力值时出错", ex);
- }
- await Task.Delay(_pressureSampleIntervalMs);
- }
- // if cancelled due to timeout
- //if (_pressureTimeoutCts[Index].IsCancellationRequested && !_pressureCts[Index].IsCancellationRequested)
- //{
- // SendTaskMessage("Pressure collection timed out, saving collected data.", MessageLevel.Alarm);
- // await StopAndSavePressureCollectionAsync(productName, productCode, Index);
- //}
- }, token);
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("StartPressureCollection error", ex);
- SendTaskMessage($"压力采集时出错:{ex.Message}", MessageLevel.Error);
- }
- }
- /// <summary>
- /// 停止采集并保存压力数据
- /// </summary>
- /// <param name="productName"></param>
- /// <param name="productCode"></param>
- /// <param name="positionIndex"></param>
- /// <returns></returns>
- private async Task StopAndSavePressureCollectionAsync(string productName, string productCode, int Index)
- {
- try
- {
- // cancel sampling
- //_pressureCts[Index]?.Cancel();
- // allow worker to observe cancel
- await Task.Delay(50);
- List<(DateTime Timestamp, float Value)> snapshot;
- lock (_pressureSamples[Index])
- {
- snapshot = new List<(DateTime, float)>(_pressureSamples[Index]);
- }
- if (snapshot.Count == 0)
- {
- SendTaskMessage("No pressure samples collected.", MessageLevel.Info);
- return;
- }
- // save to file under configured path
- try
- {
- //获取系统参数
- var systemConfig = _configService.GetSystemConfiguration();
- if (systemConfig.PressureSensorConfig == null || systemConfig.PressureSensorConfig.Count <= 0)
- {
- SendTaskMessage("当前没有配置任何压力传感器!", MessageLevel.Alarm);
- return;
- }
- //获取当前压力传感器配置
- var pressureSensorConfig = systemConfig.PressureSensorConfig.FirstOrDefault(p => p.SensorId == Index);
- if (pressureSensorConfig == null)
- {
- SendTaskMessage($"当前压力传感器配置不存在!- {Index}", MessageLevel.Alarm);
- return;
- }
- //PressureFinishNotification : Prism.Events.PubSubEvent<(bool IsSuccess, int Index, (DateTime Timestamp, float Value)[] values,string SavePath )>
- string basePath = pressureSensorConfig?.PressureCurvePath ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
- string datePath = DateTime.Now.ToString("yyyy-MM") + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
- string dirPath = Path.Combine(basePath, datePath, productName ?? "UnknownProduct", productCode ?? DateTime.Now.ToString("yyyyMMddHHmmssfff"));
- if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
- string csvfileName = $"pressure-{productCode}-{Index}-{DateTime.Now.ToString("HHmmss")}.csv";
- string csvPath = Path.Combine(dirPath, csvfileName);
- string pngfileName = $"pressure-{productCode}-{Index}-{DateTime.Now.ToString("HHmmss")}.png";
- string pngPath = Path.Combine(dirPath, pngfileName);
- if (!pressureSensorConfig.IsSavePressureCurve)
- {
- csvPath = string.Empty;
- pngPath = string.Empty;
- }
- App.Current.Dispatcher.Invoke(() =>
- {
- _eventAggregator.GetEvent<PressureFinishNotification>().Publish((true, Index, snapshot.ToArray(), pngPath));
- });
- //判断是否保存锁付曲线
- if (pressureSensorConfig.IsSavePressureCurve)
- {
- if (!string.IsNullOrEmpty(csvPath))
- {
- var sb = new StringBuilder();
- sb.AppendLine("Timestamp,Value");
- foreach (var s in snapshot)
- {
- sb.AppendLine($"{s.Timestamp:O},{s.Value}");
- }
- File.WriteAllText(csvPath, sb.ToString());
- SendTaskMessage($"Pressure samples saved to {csvPath}", MessageLevel.Debug);
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("保存压力采样文件时出错", ex);
- SendTaskMessage("保存压力采样文件时出错: " + ex.Message, MessageLevel.Error);
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("StopAndSavePressureCollectionAsync error", ex);
- }
- finally
- {
- try
- {
- _pressureLinkedCts[Index]?.Cancel();
- _pressureLinkedCts[Index]?.Dispose();
- _pressureTimeoutCts[Index]?.Dispose();
- _pressureCts[Index]?.Dispose();
- _pressureSamples[Index]?.Clear();
- }
- catch { }
- }
- }
- #endregion
- private async void DoYieldTime(object state)
- {
- try
- {
- //获取当前产品
- var currentproduct = _productService.GetCurrentProduct();
- if (currentproduct == null) return;
- TotalQuantity = await _systemDatabaseService.GetOverallProductionAsync(currentproduct.Name);
- TotalQuantityToday = await _systemDatabaseService.GetTodayProductionAsync(currentproduct.Name);
- CurrentUPH = await _systemDatabaseService.GetLastHourProductionAsync(currentproduct.Name);
- //
- ThrowNumber = await _systemDatabaseService.GetThrowNumberAsync();
- NgNumber = await _systemDatabaseService.GetNGProductionAsync(currentproduct.Name);
- Yield = ((double)TotalQuantityToday - (double)NgNumber) / (double)TotalQuantityToday * 100;
- }
- catch (Exception)
- {
- }
- }
- #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
- /// <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(stationIndex);
- 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);
- }
- }
- //结果保存至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);
- 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");
- 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}");
- 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;
- }
- }
- #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);
- }
- }
- #endregion
- #endregion
- }
- }
|