using Basler.Pylon; using Cognex.VisionPro; using Cognex.VisionPro.ToolBlock; using CSScripting; using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.RootFinding; using NPOI.SS.Formula.Functions; using NPOI.Util; using Opc.Ua; using OpenCvSharp; using OpenCvSharp.Flann; using Prism.Events; using Prism.Ioc; using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Drawing; using System.IO; using System.Linq; using System.Net.Sockets; using System.Reflection.Metadata; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Documents; using System.Windows.Forms; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Media3D; using Team.FFFeederService; using Team.FFFeederService.Interfaces; using TeamAAS_VP; using TeamAAS_VP.Core.PLCs; using TeamAAS_VP.Core.Robots; using TeamAAS_VP.Core.ScrewDriver; using TeamAAS_VP.Data; using TeamAAS_VP.Enums; using TeamAAS_VP.Events; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Models.Calibration; using TeamAAS_VP.Models.Feeder; using TeamAAS_VP.Models.Product; using TeamAAS_VP.Resources.Languages; using TeamAAS_VP.Services; using TeamAAS_VP.ViewModels.Home; using TouchSocket.Core; using TouchSocket.SerialPorts; using TouchSocket.Sockets; using static MaterialDesignThemes.Wpf.Theme.ToolBar; using static Org.BouncyCastle.Math.EC.ECCurve; using static System.Windows.Forms.AxHost; using Timer = System.Threading.Timer; 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; Timer yieldtimer; private DateTime StartTime = DateTime.Now; SerialPortClient client; #endregion #region 属性 private ObservableCollection _Renders; /// /// 显示界面 /// public ObservableCollection Renders { get { return _Renders; } set { SetProperty(ref _Renders, value); } } private ProductModel _CurrentProduct; /// /// 当前产品 /// public ProductModel CurrentProduct { get { return _CurrentProduct; } set { SetProperty(ref _CurrentProduct, value); } } public BgCommunicate BgCommunicate { get; private set; } public BgModbusTcpCommunicate BgModbusTcpCommunicate { get; private set; } private ObservableCollection _Status = new ObservableCollection(); /// /// 状态栏集合 /// public ObservableCollection Status { get { return _Status; } set { SetProperty(ref _Status, value); } } private Int64 _TotalQuantity; /// /// 总产量 /// public Int64 TotalQuantity { get { return _TotalQuantity; } set { SetProperty(ref _TotalQuantity, value); } } private Int64 _TotalQuantityToday; /// /// 当天的总产量 /// public Int64 TotalQuantityToday { get { return _TotalQuantityToday; } set { SetProperty(ref _TotalQuantityToday, value); } } private Int64 _CurrentUPH; /// /// 当前的UPH /// 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 BackupObject { get; set; } = new Dictionary(); private string _COM; /// /// 扭力测量仪COM /// public string COM { get { return _COM; } set { SetProperty(ref _COM, value); } } private string _SignalValue; /// /// 扭力测量仪获取的最大值 /// public string SignalValue { get { return _SignalValue; } set { SetProperty(ref _SignalValue, value); } } private double _Value; /// /// 电批扭力值 /// public double Value { get { return _Value; } set { SetProperty(ref _Value, value); } } private NumberStatistics _NumStatistics; /// /// 数量(批头、吸嘴、供料器) /// public NumberStatistics NumStatistics { get { return _NumStatistics; } set { SetProperty(ref _NumStatistics, 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) { _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(); _productService = productService; _remoteCommandService = remoteCommandService; _systemDatabaseService = systemDatabaseService; _lightManagerService = lightManagerService; } #region 读取配置参数 public void ReadConfig() { ReadNumber(); } /// /// 读取数量配置 /// public void ReadNumber() { try { if (File.Exists(FilePath.NumberStatisticsPath)) { NumStatistics = FileHelper.ReadJsonFile(FilePath.NumberStatisticsPath); } else { NumStatistics = new NumberStatistics(); FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath); } } catch (Exception ex) { NumStatistics = new NumberStatistics(); LogHelper.WriteLogError("加载数量配置文件时出错!", ex); } } #endregion #region 初始化硬件模块 /// /// 初始化Feeder /// /// 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()); } } /// /// 初始化机器人 /// /// 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()); } } /// /// 初始化PLC /// /// 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(Lang.为PLC写入系统参数和订阅变量时出错, ex); } if (sb.Length == 0) { return (true, ""); } else { return (false, sb.ToString()); } } /// /// 初始化相机 /// /// 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().Renders = Renders; if (sb.Length == 0) { return (true, ""); } else { return (false, sb.ToString()); } } /// /// 初始化光源控制器 /// /// 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()); //} } /// /// 初始化后台TCP服务器通讯 /// 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(Lang.开启后台服务器通讯时出错, ex); } } /// /// 初始化后台ModbusTCP从站 /// 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(Lang.开启后台ModbusTCP通讯时出错, ex); } } /// /// 初始化后台脚本 /// public void InitBackgroundcript() { try { if (!Directory.Exists(FilePath.BackgroundScriptPath)) { Directory.CreateDirectory(FilePath.BackgroundScriptPath); } try { string[] files = Directory.GetFiles(FilePath.BackgroundScriptPath); List ScriptFilesCollection = new List(); 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(string.Format(Lang.开启脚本时出错0, item), ex); } } } catch (Exception ex) { LogHelper.WriteLogError(Lang.读取本地脚本文件列表时出错, ex); } } catch (Exception ex) { LogHelper.WriteLogError(Lang.开启后台脚本时出错, ex); } } /// /// 初始化电批 /// /// public async Task InitScrewDriver() { try { var screwDriverConfig = _configService.GetScrewDriverConfig(); ScrewDriver = new XYD_ScrewDriver(screwDriverConfig.IPAdress, screwDriverConfig.Port); Status.Add(new StatusInfo(ScrewDriver.Id, Lang.电批未连接, new SolidColorBrush(Colors.Red))); ScrewDriver.ConnectStateChangedEvent += ScrewDriver_ConnectStateChangedEvent; ScrewDriver.SendTimeout = screwDriverConfig.SendTimeout; screwDriverConfig.ReceiveTimeout = screwDriverConfig.ReceiveTimeout; var isConnected = await ScrewDriver.ConnectAsync(); if (isConnected) { SendTaskMessage(Lang.电批已连接, MessageLevel.Debug); } else { SendTaskMessage(Lang.电批连接失败, MessageLevel.Error); } } catch (Exception ex) { SendTaskMessage(string.Format(Lang.电批连接失败0,ex.Message), MessageLevel.Alarm); LogHelper.WriteLogError(Lang.连接电批时出错, ex); } } /// /// 初始化扭力测量仪 /// /// public async Task InitSignal() { if (File.Exists(FilePath.SignalConfigPath)) { try { var port = FileHelper.ReadJsonFile(FilePath.SignalConfigPath); if (port != null) { client = new TouchSocket.SerialPorts.SerialPortClient(); client.Connecting = (client1, e) => { return EasyTask.CompletedTask; };//即将连接到端口 client.Connected = (client1, e) => { return EasyTask.CompletedTask; };//成功连接到端口 client.Closing = (client1, e) => { return EasyTask.CompletedTask; };//即将从端口断开连接。此处仅主动断开才有效。 client.Closed = (client1, e) => { return EasyTask.CompletedTask; };//从端口断开连接,当连接不成功时不会触发。 client.Received = async (c, e) => { //await Console.Out.WriteLineAsync(Encoding.UTF8.GetString(e.ByteBlock.Buffer)); await Console.Out.WriteLineAsync(e.ByteBlock.Span.ToString(Encoding.ASCII)); }; client.Received = Sp_DataReceived; await client.SetupAsync(new TouchSocketConfig() .SetSerialPortOption(new SerialPortOption() { BaudRate = 115200,//波特率 DataBits = 8,//数据位 Parity = System.IO.Ports.Parity.None,//校验位 PortName = port,//COM StopBits = System.IO.Ports.StopBits.One//停止位 }) .SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromMilliseconds(100) }) ); await client.ConnectAsync(); } } catch (Exception ex) { LogHelper.WriteLogError("初始化扭力测量仪时出错!", ex); SendTaskMessage("初始化扭力测量仪时出错!"+ex.Message, MessageLevel.Error); } } else { COM = "COM1"; FileHelper.WriteJsonFile(COM, FilePath.SignalConfigPath); } } #endregion #region 机器人指令执行 public Dictionary RobotTCPCollection = new Dictionary(); /// /// 机器人TCP接收 /// /// /// /// 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(Lang.TCP发送数据时出错, ex); SendTaskMessage(ex.Message, MessageLevel.Alarm); } }); } catch (Exception ex) { LogHelper.WriteLogError(Lang.处理机器人接收的命令时出错, ex); SendTaskMessage(ex.Message, MessageLevel.Alarm); } } #endregion #region 机器人&Feeder&相机连接状态事件 /// /// 机器人发送事件 /// /// /// /// /// private void Management_SendEvent(Guid robotid, object arg2, string arg3) { var r = _robotService.GetRobot(robotid); SendTaskMessage($"{r.Name}Send:{arg3}", MessageLevel.Info); } /// /// 机器人断开连接时 /// /// /// /// /// 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); })); } } /// /// 机器人连接成功时 /// /// /// /// /// 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); })); } } /// /// Feeder连接状态改变时 /// /// /// 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); } } /// /// 相机连接或者断开时 /// /// /// 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); })); } } } /// /// PLC连接状态改变事件 /// /// /// private void Management_PlcConnectChangedEvent(object sender, bool isconnected) { IPlc plc = sender as IPlc; var sta = Status.FirstOrDefault(s => s.ID == plc.Id); if (plc.IsConnected) { SendTaskMessage($"{plc.Name}{Lang.已连接}!", MessageLevel.Debug); if (sta == null) return; App.Current.Dispatcher.Invoke(new Action(() => { sta.Message = $"{plc.Name}{Lang.已连接}"; sta.Background = new SolidColorBrush(Colors.Green); })); } else { SendTaskMessage($"{plc.Name}{Lang.断开连接}!", MessageLevel.Error); if (sta == null) return; App.Current.Dispatcher.Invoke(new Action(() => { sta.Message = $"{plc.Name}{Lang.未连接}"; sta.Background = new SolidColorBrush(Colors.Red); })); } } /// /// 电批连接状态改变时 /// /// /// 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(Lang.电批连接状态改变时出错了, 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 BgCommunicateollection = new Dictionary(); 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(Lang.后台TCP发送数据时出错, ex); SendTaskMessage(ex.Message, MessageLevel.Alarm); } }); } catch (Exception ex) { LogHelper.WriteLogError(Lang.处理后台服务器接收的命令时出错, 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); } /// /// 扭力测量仪接收信息 /// /// /// /// private async Task Sp_DataReceived(ISerialPortClient client, ReceivedDataEventArgs e) { try { string poname = client.MainSerialPort.PortName; string data = e.ByteBlock.Span.ToString(Encoding.ASCII); await Console.Out.WriteLineAsync(data); string response = data.Split('\r')[0]; SendTaskMessage($"{poname}Receive:{response}", MessageLevel.Info); SignalValue = response; } catch (Exception ex) { LogHelper.WriteLogError("扭力测量仪接收信息时出错!", ex); SendTaskMessage("扭力测量仪接收信息时出错!" + ex.Message, MessageLevel.Error); Thread.Sleep(50); } } #endregion #region PLC /// /// 将系统参数写入PLC /// /// /// 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 nodeValues = new Dictionary(); 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); } /// /// 注册需要监控的PLC地址 /// public void RegisterPlcMonitorAddress() { var addressConfig = _configService.GetPlcAddresses(); var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC; if (plc == null || !plc.IsConnected) return; //PLC地址数组 List monitorNodeIds = new List() { addressConfig.In_DowmCameraExe.Address, addressConfig.In_UpCameraPickExe.Address, addressConfig.In_UpCameraPutExe.Address, addressConfig.In_UPCameracheckExe.Address, addressConfig.In_FixedCameraPickExe.Address, addressConfig.In_FixedCameraPutExe.Address, addressConfig.In_FixedCameracheckExe.Address, addressConfig.In_WorkStart.Address, addressConfig.In_WorkDone.Address, //addressConfig.In_MesCheck.Address, addressConfig.In_RequestPosition.Address, addressConfig.In_ScrewTeachExe.Address, addressConfig.In_PickINC.Address, }; for (int i = 0; i < 10; i++) { monitorNodeIds.Add(string.Format(addressConfig.In_MesCheck.Address, i)); } //订阅PLC地址变化 plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger); } /// /// 写入点位信息给PLC /// /// 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); } } } PointF[] DowmCameraResults = new PointF[10]; PointF[] UpCameraPutResults = new PointF[10]; bool _LastDowmCameraExe = false; bool _LastScrewTeachExe = false; bool _LastUpCameraPickExe = false; bool _LastUpCameraPutExe = false; bool _LastUPCameracheckExe = false; bool _LastFixedCameraPickExe = false; bool _LastFixedCameraPutExe = false; bool _LastFixedCameracheckExe = false; Int16 _LastWorkStart = 0; Int16 _LastWorkDone = 0; Int16 _LastRequestPosition = 0; Int16[] _LastMesCheck = new Int16[10]; Int16 _LastPickINC = 0; /// /// PLC命令触发时 /// /// 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(addressConfig.In_Code.Address); //如果产品编码为空,则以当前的时间戳作为编码 if (string.IsNullOrEmpty(_productService.CurrentProductCode)) { _productService.CurrentProductCode = DateTime.Now.ToString("yyyyMMddHHmmssfff"); } // 触发下相机拍照 if (addressConfig.In_DowmCameraExe.Address.Contains(tuple.nodeId)) { if (tuple.value is bool state) { if (_LastDowmCameraExe != state) { _LastDowmCameraExe = state; } else { return; } if (state) { SendTaskMessage(Lang.触发下相机拍照, MessageLevel.Debug); //相机的编号 Int16 cameraIndex = plc.ReadNode(addressConfig.In_DowmCameraNum.Address); SendTaskMessage(string.Format(Lang.编号0, cameraIndex), MessageLevel.Info); // 获取流程 var process = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId); if (process == null) { SendTaskMessage(string.Format(Lang.固定向上相机1视觉流程流程ID0, currentProduct.FixedUpCamera1ProcedureId), MessageLevel.Alarm); await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2); return; } // 获取机器人当前坐标 var robot = _robotService.GetAllRobots().FirstOrDefault(); if (robot == null) { SendTaskMessage(Lang.未找到机器人无法执行上相机锁附组装拍照视觉任务, MessageLevel.Alarm); await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.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_DownCameraStatus.Address, (Int16)1); return; } else { await plc.WriteNodeAsync(addressConfig.Out_DownCameraStatus.Address, (Int16)2); return; } } else { SendTaskMessage(Lang.触发下相机拍照信号已关闭, 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(Lang.触发下相机拍照, MessageLevel.Debug); //相机的编号 Int16 cameraIndex = plc.ReadNode(addressConfig.In_DowmCameraNum.Address); SendTaskMessage(string.Format(Lang.编号0,cameraIndex), MessageLevel.Info); // 获取流程 var process = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId); if (process == null) { SendTaskMessage(string.Format(Lang.固定向上相机1视觉流程流程ID0, currentProduct.FixedUpCamera1ProcedureId), MessageLevel.Alarm); await plc.WriteNodeAsync(addressConfig.Out_ScrewTeachOk.Address, (Int16)2); return; } // 获取机器人当前坐标 var robot = _robotService.GetAllRobots().FirstOrDefault(); if (robot == null) { SendTaskMessage(Lang.未找到机器人无法执行上相机锁附组装拍照视觉任务, 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(Lang.触发下相机拍照信号已关闭, 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(Lang.触发上相机取料拍照, MessageLevel.Debug); //相机的编号 //Int16 cameraIndex = plc.ReadNode(addressConfig.In_UpCameraPickNum.Address); await plc.WriteNodeAsync(addressConfig.Out_UpCameraPickStatus.Address, (Int16)1); } else { SendTaskMessage(Lang.触发上相机取料拍照信号已关闭, 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(Lang.触发上相机锁附组装拍照, MessageLevel.Debug); //相机的编号 Int16 cameraIndex = plc.ReadNode(addressConfig.In_UpCameraPutNum.Address); SendTaskMessage(string.Format(Lang.编号0, cameraIndex), MessageLevel.Info); // 获取流程 var process = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCameraLockPhotoProcedureId); if (process == null) { SendTaskMessage(string.Format(Lang.未找到上相机锁附组装拍照对应的视觉流程流程ID0,currentProduct.MoveDownCameraLockPhotoProcedureId), MessageLevel.Alarm); await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2); return; } // 获取机器人当前坐标 var robot = _robotService.GetAllRobots().FirstOrDefault(); if (robot == null) { SendTaskMessage(Lang.未找到机器人无法执行上相机锁附组装拍照视觉任务, MessageLevel.Alarm); await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2); return; } var currentPosition = robot.GetRobotPos(); // 执行视觉任务 var _cts = new CancellationTokenSource(); var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token); if (visionResult.IsSucceed) { UpCameraPutResults[cameraIndex] = new PointF((float)visionResult.X, (float)visionResult.Y); await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)1); } else { await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2); } } else { SendTaskMessage(Lang.触发上相机锁附组装拍照信号已关闭, 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(Lang.触发上相机检测拍照, MessageLevel.Debug); //相机的编号 //Int16 cameraIndex = plc.ReadNode(addressConfig.Out_UPCameracheckNum.Address); await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)1); } else { SendTaskMessage(Lang.触发上相机检测拍照信号已关闭, 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(Lang.触发固定相机取料拍照, MessageLevel.Debug); //相机的编号 //Int16 cameraIndex = plc.ReadNode(addressConfig.In_FixedCameraPickNum.Address); await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1); } else { SendTaskMessage(Lang.触发固定相机取料拍照信号已关闭, 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(Lang.触发固定相机锁附组装拍照, MessageLevel.Debug); //相机的编号 //Int16 cameraIndex = plc.ReadNode(addressConfig.In_FixedCameraPutNum.Address); await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)1); } else { SendTaskMessage(Lang.触发固定相机锁附组装拍照信号已关闭, 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(Lang.触发固定相机检测拍照, MessageLevel.Debug); //相机的编号 //Int16 cameraIndex = plc.ReadNode(addressConfig.In_FixedCameracheckNum.Address); await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)1); } else { SendTaskMessage(Lang.触发固定相机检测拍照信号已关闭, MessageLevel.Alarm); await plc.WriteNodeAsync(addressConfig.Out_FixedCameracheckStatus.Address, (Int16)0); } } } // 开始锁付 else if (addressConfig.In_WorkStart.Address.Contains(tuple.nodeId)) { if (tuple.value is Int16 state) { if (_LastWorkStart != state) { _LastWorkStart = state; } else { return; } if (state == 1) { SendTaskMessage(Lang.收到开始锁付信号, MessageLevel.Debug); //位置编号 Int16 positionIndex = plc.ReadNode(addressConfig.In_ProductNum.Address); SendTaskMessage(string.Format(Lang.编号0,positionIndex), MessageLevel.Info); } else { SendTaskMessage(Lang.开始锁付信号已关闭, MessageLevel.Alarm); // 关闭时的处理(如需)可放在这里 } } } // 停止锁付 else if (addressConfig.In_WorkDone.Address.Contains(tuple.nodeId)) { if (tuple.value is Int16 state) { if (_LastWorkDone != state) { _LastWorkDone = state; } else { return; } if (state == 1 || state == 2) { SendTaskMessage(Lang.收到停止锁付信号, MessageLevel.Debug); //位置编号 Int16 positionIndex = plc.ReadNode(addressConfig.In_ProductNum.Address); SendTaskMessage(string.Format(Lang.编号0,positionIndex), MessageLevel.Info); //获取当前锁付点 var screwPoint = currentProduct.ScrewPoints.FirstOrDefault(p => p.Number == positionIndex); //获取当前的机器人点位 var robot = _robotService.GetAllRobots().FirstOrDefault(); var currentPosition = robot.GetRobotPos(); //读取压力值 float pressure = plc.ReadNode(addressConfig.In_PressureValue.Address); await Task.Delay(60); //获取电批结果 bool isSucced = ScrewDriver.GetData(); LockResult lockResult = new LockResult(); lockResult.ScrewdriverGetDataSucceed = isSucced; lockResult.Number = positionIndex; lockResult.LockPassed = ScrewDriver.Success; lockResult.ProductName = currentProduct.Name; lockResult.ProductNumber = _productService.CurrentProductCode; lockResult.LockTurns = (float)ScrewDriver.Truns; lockResult.LockTorque = (float)ScrewDriver.TorqueValue; lockResult.LockDuration = (float)ScrewDriver.FinalTime; lockResult.ScrewdriverProgramNumber = ScrewDriver.ProgramNumber; lockResult.ResultDetails = ScrewDriver.ErrorInfo; lockResult.Pressure = pressure; lockResult.TargetTorque = ScrewDriver.TargetTorque; lockResult.TargetTurnsUpperLimit = ScrewDriver.TargetTurnsUpperLimit; lockResult.TargetTurnsLowerLimit = ScrewDriver.TargetTurnsLowerLimit; lockResult.TargetLockSpeed = ScrewDriver.TargetLockSpeed; lockResult.StartPositionX = currentPosition.X; lockResult.StartPositionY = currentPosition.Y; lockResult.StartPositionZ = screwPoint.Z_Position_Start; lockResult.EndPositionZ = currentPosition.Z; lockResult.LockDescentSpeed = screwPoint.Z_Velocity_Stop; lockResult.FeederNumber = screwPoint != null ? screwPoint.Feeder : 0; lockResult.NozzleNumber = ""; lockResult.OperatorName = _systemDatabaseService.GetCurrentUser().UserName; lockResult.ProductImagePath = ""; lockResult.WaveDatas = ScrewDriver.WaveDatas; App.Current.Dispatcher.Invoke(() => { _eventAggregator.GetEvent().Publish(lockResult); }); await _systemDatabaseService.RecordLockResultAsync(lockResult); await plc.WriteNodeAsync(addressConfig.In_WorkDone.Address, (Int16)0); Value = lockResult.LockTorque; //电批吸嘴报警 NumStatistics.HeaderNum++;//批头数量 NumStatistics.NozzleNum++;//吸嘴数量 FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath); if (NumStatistics.HeaderNum < NumStatistics.HeaderAlarmValue) { System.Windows.MessageBox.Show("Electric Screwdriver Alarm!", "Alarm", MessageBoxButton.OK, MessageBoxImage.Warning); } if (NumStatistics.NozzleNum < NumStatistics.NozzleAlarmValue) { System.Windows.MessageBox.Show("Nozzle Alarm!", "Alarm", MessageBoxButton.OK, MessageBoxImage.Warning); } } else { SendTaskMessage(Lang.停止锁付信号已关闭, MessageLevel.Alarm); } } } // 多相机坐标合并 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(Lang.收到多相机坐标合并请求开始合并, MessageLevel.Debug); //是拍一个锁一个还是拍两个点锁所有 var systemConfig = _configService.GetSystemConfiguration(); //拍1打1 if (systemConfig.WorkMode == 1) { currentProduct.ScrewPoints[0].X_Position = UpCameraPutResults[1].X + DowmCameraResults[0].X; currentProduct.ScrewPoints[0].Y_Position = UpCameraPutResults[1].Y + DowmCameraResults[0].Y; await currentProduct.ScrewPoints[0].WriteToPlcAddress(addressConfig.Out_Screw, plc); } //拍1打所有 else if (systemConfig.WorkMode == 2) { //根据UpCameraPutResults[]中的索引1、2,和拍照点对应的Local下的坐标,从创建Local坐标系 PointF worldP1 = new PointF(UpCameraPutResults[1].X, UpCameraPutResults[1].Y); PointF worldP2 = new PointF(UpCameraPutResults[2].X, UpCameraPutResults[2].Y); PointF localP1 = new PointF(currentProduct.ScrewCameraLocalPos1.X_Position, currentProduct.ScrewCameraLocalPos1.Y_Position); PointF localP2 = new PointF(currentProduct.ScrewCameraLocalPos2.X_Position, currentProduct.ScrewCameraLocalPos2.Y_Position); CoordinateTransformer local = new CoordinateTransformer(worldP1, worldP2, localP1, localP2); for (int i = 0; i < currentProduct.ScrewPoints.Count; i++) { var localPoint = new PointF(currentProduct.ScrewPoints[i].X_Position, currentProduct.ScrewPoints[i].Y_Position); var worldPoint = local.ToOldCoord(localPoint.X, localPoint.Y); var point = currentProduct.ScrewPoints[i].Clone(); point.X_Position = (float)worldPoint[0]; point.Y_Position = (float)worldPoint[1]; SendTaskMessage($"点:{i},{point.X_Position:F3},{point.Y_Position:F4}", MessageLevel.Info); await point.WriteToPlcAddress(addressConfig.Out_Screw, plc); } await plc.WriteNodeAsync(addressConfig.Out_WorkNum.Address, (Int16)currentProduct.ScrewPoints.Count); } await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)1); } else { SendTaskMessage(string.Format(Lang.多相机坐标合并请求已结束或被取消state0,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); var feeders = _configService.GetRemainingCountByFeederNumber(state); if (state == 1) { NumStatistics.Feeder1Num = feeders; } else if (state == 2) { NumStatistics.Feeder2Num = feeders; } FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath); var res = _configService.CheckAlarm(state); if (res) { System.Windows.MessageBox.Show("Screw feeder alarm!", "Alarm", MessageBoxButton.OK, MessageBoxImage.Warning); } } } } // 过站检查 else { for (int i = 0; i < 10; i++) { if (string.Format(addressConfig.In_MesCheck.Address,i).Contains(tuple.nodeId)) { if (tuple.value is Int16 state) { if (_LastMesCheck[i] != state) { _LastMesCheck[i] = state; } else { return; } if (state == 1) { if(i == 0) { SendTaskMessage($"收到当前过站检查请求(当站是否生产)...", MessageLevel.Debug); } else { SendTaskMessage($"收到{i}过站检查请求(当站是否生产)...", 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 if (state == 2) { SendTaskMessage($"收到{i}上传本站数据请求...", MessageLevel.Debug); await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3); } else { SendTaskMessage($"{i}过站检查信号:state={state},处理为默认状态", MessageLevel.Alarm); await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)0); } } } } } } catch (Exception ex) { SendTaskMessage(ex.Message, MessageLevel.Error); } } #endregion #region 方法 private void SendTaskMessage(string msg, MessageLevel level) { App.Current.Dispatcher.Invoke(() => { _eventAggregator.GetEvent().Publish(new Models.MessageStruct() { Message = msg, level = level }); }); } private async void DoYieldTime(object state) { try { if (CurrentProduct == null) return; //获取当前产品 var currentproduct = _productService.GetCurrentProduct(); TotalQuantity = await _systemDatabaseService.GetOverallProductionAsync(CurrentProduct.Name); TotalQuantityToday = await _systemDatabaseService.GetTodayProductionAsync(CurrentProduct.Name); CurrentUPH = await _systemDatabaseService.GetLastHourProductionAsync(CurrentProduct.Name); } catch (Exception) { } } #region vm启动检测 /// /// 杀死所有VM有关进程 /// public void KillVMProcess() { KillProcess("VisionMasterServerApp"); KillProcess("VisionMaster"); KillProcess("VmModuleProxy.exe"); KillProcess("vServerApp.exe"); } /// /// 杀死指定进程名的进程 /// /// 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(string.Format(Lang.杀死进程0时失败, strKillName), ex); } } } } #endregion #endregion } }