using Common; using Common.DevicesModels; using Common.Models; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using MaterialDesignThemes.Wpf; using MegaRobo.C00224159App; using MegaRobo.C00225155.AppServer; using MegaRobo.C00225155.ControlDevices; using MegaRobo.C00225155.ControlDevices.Scanner; using MegaRobo.C00225155.DataAccess; using MegaRobo.C00225155.Entities; using MegaRobo.C00225155.Entities.Entity_DB; using MegaRobo.C00225155.Entities.Enums; using MegaRobo.C00225155App.MenuViews; using MegaRobo.Contract; using MegaRobo.ControlDevices.Models; using MegaRobo.Entities; using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices; using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices; using MegaRobo.WpfInfrastructure.Abstractions; using NetTaste; using SqlSugar; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Threading; using Telerik.Windows.Controls.Data; using static Org.BouncyCastle.Math.EC.ECCurve; using static System.Windows.Forms.MonthCalendar; using static Vanara.PInvoke.Gdi32; using static Vanara.PInvoke.Kernel32; using static Vanara.PInvoke.Kernel32.PSS_HANDLE_ENTRY; using Pipette1ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices; using Pipette5ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices; namespace MegaRobo.C00225155App.MenuViewModels { public class HomeViewModel : ViewModelBaseEx { #region 7个传送工装位置 public ObservableCollection BoxIndexList { get; set; } = new ObservableCollection(); private int selectedBoxIndex; public int SelectedBoxIndex { get { return selectedBoxIndex; } set { SetProperty(ref selectedBoxIndex, value); } } private BoxTypeEnum selectedboxtype; public BoxTypeEnum SelectedBoxType { get { return selectedboxtype; } set { SetProperty(ref selectedboxtype, value); if (selectedboxtype == BoxTypeEnum._40mL原液工装) { BoxIndexList.Clear(); BoxIndexList.Add(4);BoxIndexList.Add(5); } else if(selectedboxtype == BoxTypeEnum._12mL样品工装 || selectedboxtype == BoxTypeEnum._5mL样品工装) { BoxIndexList.Clear(); BoxIndexList.Add(1);BoxIndexList.Add(2); BoxIndexList.Add(3); ; } else { BoxIndexList.Clear(); BoxIndexList.Add(6);BoxIndexList.Add(7); } //BoxIndexList.Clear(); BoxIndexList.AddRange(new int[] { 1, 2, 3, 4, 5, 6, 7 }); } } private List baselocalInfo; public List BaselocalInfo { get { return baselocalInfo; } set { SetProperty(ref baselocalInfo, value); } } private ObservableCollection samplelist = new ObservableCollection(); private ObservableCollection liquidlist = new ObservableCollection(); private ObservableCollection powderlist = new ObservableCollection(); private ObservableCollection powderlist_125 = new ObservableCollection(); private ObservableCollection tipHeadslist = new ObservableCollection(); public ICommand LoadBoxCommand { get; set; } public IAsyncRelayCommand UploadBoxCommand { get; set; } public IAsyncRelayCommand TransferOutCommand { get; set; } public IAsyncRelayCommand TransferInCommand { get; set; } public IAsyncRelayCommand ClearTransferCommand { get; set; } public IAsyncRelayCommand StartUnloadCommand { get; set; } public IAsyncRelayCommand ResetSampleBottlesCommand { get; set; } public ICommand UpdateSampleBoxPropertyCommand { get; set; } #endregion #region 服务 private IModbusClientExtend _modbusClient_Plc1; private IModbusClientExtend _modbusClient_Plc2; private AppConfigService appConfigService { get; set; } private WorkService workService; protected IDataAccessService dataAccessService; /// /// 扫码枪服务 /// protected ScannerService scannerService; protected ScannerService scannerService_Powder; protected WeightService_Ts02 preWeight; #endregion #region properties private static readonly SemaphoreSlim _lockWaitSignal = new SemaphoreSlim(1, 1); private string tiptxt = "暂停"; /// /// 投料站的暂停按钮tooltip提示信息 /// public string PauseContinueTipText { get { return tiptxt; } set { SetProperty(ref tiptxt, value); } } private DateTime _lastReportTime { get; set; } = DateTime.Now; private string doseRunState = "Manual"; /// /// 投料站的 自动、暂停、待机状态,用于样式切换 /// public string DoseRunState { get => doseRunState; set => SetProperty(ref doseRunState, value); } private bool btnEnableState = true; /// /// 管控投料站的启动按钮是否可用IsEnable /// public bool BtnEnableState { get { return btnEnableState; } set { if (SetProperty(ref btnEnableState, value)) { if (btnEnableState) { DoseRunState = "Idel"; } else { DoseRunState = "Runing"; } } } } public ProjectProperty ProjectPro { get => workService.ProjectPro; set { if (workService.ProjectPro != value) { workService.ProjectPro = value; OnPropertyChanged(nameof(ProjectPro)); } } } #endregion properties #region events /// /// 设置运行的命令 /// public ICommand RunCommand { get; set; } /// /// 设置项目方案命令 /// public ICommand ProjectCommand { get; set; } public ICommand TipFeedCommand { get; set; } public RelayCommand OpenPipetteManageWindowCommand { get; set; } #endregion public HomeViewModel() { } #region functions public override void Initialize(ICoreService coreService, string title, params object[] args) { base.Initialize(coreService, title, args); samplelist = new ObservableCollection(); for (int i = 0; i < 12; i++) { samplelist.Add(new SampleBottleModel() { SampleBottleLidState = SampleBottleLidStateEnum.Close, PosId_InBox = i + 1, HaveBottle = true, bDoseFinish = false, SNCode = string.Empty, }); } liquidlist = new ObservableCollection(); for (int i = 0; i < 8; i++) { liquidlist.Add(new SourceLiquidBottleModel() { LiquidBottleLidState = SourceBottleLidStateEnum.Close, PosId_InBox = i + 1, HaveBottle = true, RemainVolume = 0, SNCode = string.Empty, SourceLiquidBottleState = SourceBottleStateEnum.Idl, }); } powderlist = new ObservableCollection(); for (int i = 0; i < 4; i++) { powderlist.Add(new SourcePowderBottleModel() { PosId_InBox = i + 1, HaveBottle = false, RemainWeight = 0, SNCode = string.Empty, PowderBottleType = PowderBottleTypeEnum._16mL, SourcePowderBottleState = SourceBottleStateEnum.Idl, }); } powderlist_125 = new ObservableCollection(); for (int i = 0; i < 2; i++) { powderlist_125.Add(new SourcePowderBottleModel() { PosId_InBox = i + 1, HaveBottle = false, RemainWeight = 0, SNCode = string.Empty, PowderBottleType = PowderBottleTypeEnum._125mL, SourcePowderBottleState = SourceBottleStateEnum.Idl, }); } tipHeadslist.Clear(); for (int i = 0; i < 96; i++) { tipHeadslist.Add(new TipHeadItem() { IsAvailable = true, UseIndex = i + 1, }); } } protected override void LoadServices() { base.LoadServices(); _modbusClient_Plc1 = this.CoreService.GetServiceInstance(DeviceNames.Plc1.ToString()); preWeight = this.CoreService.GetServiceInstance(DeviceNames.PreWeight.ToString()); scannerService = this.CoreService.GetServiceInstance(DeviceNames.Scanner.ToString()); scannerService_Powder = this.CoreService.GetServiceInstance(DeviceNames.Scanner_Powder.ToString()); appConfigService = this.CoreService.GetServiceInstance(); dataAccessService = this.CoreService.GetServiceInstance(); this.workService = this.CoreService.GetServiceInstance(); if (workService != null) { workService.ProjectProChanged += OnProjectProChanged; //更新当前界面绑定的Projectproperty属性 workService.stationService_Dose.UpdateDeviceStatusEvent += OnDeviceStatusChanged; workService.stationService_Dose.OnScanPlcErrorListEvent += StationService_Config_OnScanPlcErrorListEvent; } } /// /// 配置站的报警弹窗 /// /// /// private void StationService_Config_OnScanPlcErrorListEvent(object sender, List plcErrorsInfo) { if (plcErrorsInfo != null && plcErrorsInfo.Count > 0) { BaselocalInfo = plcErrorsInfo.Where(e => e.ErrorAddress.Contains(".")).Select(x => x.ErrorInfo).ToList(); //本地展示的数据 if ((DateTime.Now - _lastReportTime).TotalSeconds > 10) { _lastReportTime = DateTime.Now; var toBsInfo = plcErrorsInfo.Where(e => !e.ErrorAddress.Contains(".")).ToList(); //10S向BS推送一次 if (toBsInfo.Count > 0) { //todo:向BS报告 _ = Task.Run(async () => { //todo:暂时屏蔽报错推送 //var res = await workService.stationService_Dose.SendJson((new Guid()).ToString(), "error", toBsInfo.ToJson()); }); } } } } private void OnDeviceStatusChanged(object sender, C00225155.Entities.DeviceStatus e) { switch (e) { case C00225155.Entities.DeviceStatus.Idel: DoseRunState = "Idel"; break; case C00225155.Entities.DeviceStatus.CarryOn: DoseRunState = "CarryOn"; break; case C00225155.Entities.DeviceStatus.Runing: if (PauseContinueTipText == "继续") { PauseContinueTipText = "暂停"; } DoseRunState = "Runing"; break; case C00225155.Entities.DeviceStatus.Pause: if (PauseContinueTipText == "暂停") { PauseContinueTipText = "继续"; } DoseRunState = "Pause"; break; case C00225155.Entities.DeviceStatus.Finish: DoseRunState = "Finish"; break; case C00225155.Entities.DeviceStatus.Abort: DoseRunState = "Abort"; break; default: break; } } protected override void LoadDatas() { base.LoadDatas(); //加载项目文件 BoxIndexList.Clear(); //BoxIndexList.Add(1); BoxIndexList.Add(2); BoxIndexList.Add(3); //BoxIndexList.Add(4); BoxIndexList.Add(5); BoxIndexList.Add(6); BoxIndexList.Add(7); } protected override void Register() { base.Register(); RegisterCommand(); LoadBoxCommand = new RelayCommand(LoadBox); UploadBoxCommand = new AsyncRelayCommand(UploadBox); TransferOutCommand = new AsyncRelayCommand(TransferOut); TransferInCommand = new AsyncRelayCommand(TransferIn); ClearTransferCommand = new AsyncRelayCommand(ClearTransfer); StartUnloadCommand = new AsyncRelayCommand(StartUnload); ResetSampleBottlesCommand = new AsyncRelayCommand(ResetSampleBottles); UpdateSampleBoxPropertyCommand = new RelayCommand(UpdateSampleBoxProperty); WeakReferenceMessenger.Default.Register(this, (r, m) => { BtnEnableState = m.Value; }); } /// /// 按照瓶1配置信息更新样品工装 /// /// private void UpdateSampleBoxProperty(int sampleboxIdParam) { int index = 0; index = sampleboxIdParam; BaseBottleBox box = workService.ProjectPro.TransferArea.FirstOrDefault(f => f.BoxId_inDoseUpload == index); if (!(box is SampleBottleBoxModel)) return; SampleBottleBoxModel sampleBottlebox = box as SampleBottleBoxModel; if (sampleBottlebox != null) { for (int i = 0; i < sampleBottlebox.SampleBottleList.Count; i++) { SampleBottleModel sampleBottle = File_Operator.DeepCopy(sampleBottlebox.SampleBottleList[0]); SampleBottleModel needtochangemodel = sampleBottlebox.SampleBottleList.FirstOrDefault(f => f.PosId_InBox == (i + 1)); needtochangemodel.SampleBottleType = sampleBottle.SampleBottleType; needtochangemodel.MaterialDoseFlowList = sampleBottle.MaterialDoseFlowList; needtochangemodel.HaveBottle = sampleBottle.HaveBottle; //needtochangemodel.SampleFunctionFlowList = sampleBottle.SampleFunctionFlowList; //needtochangemodel.AddLiquidFunctionFlowList = sampleBottle.AddLiquidFunctionFlowList; } } OnPropertyChanged(nameof(ProjectPro)); } private async Task ResetSampleBottles(int arg) { workService.ProjectPro.TransferArea[arg - 1] = new BaseBottleBox() { BoxArea = BoxAreaEnum._手套箱传送平台, BoxId_inDoseUpload = arg, IsEmpty = true }; } public new event PropertyChangedEventHandler PropertyChanged; // 当ProjectPro变更时调用此方法 private void OnProjectProChanged() { // 通知视图ProjectPro属性已变更 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ProjectPro))); } #endregion functions private void RegisterCommand() { RunCommand = new RelayCommand(async (obj) => { if (obj is string param) { if (!workService.ProjectPro.bNoUseBS) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "请勾选不启用BS!" }); return; } switch (param) { //配置站启动 停止 暂停 case "Start": //if (!workService.stationService_Dose.StationProp.bHaveReset) //{ // WeakReferenceMessenger.Default.Send(new AlertMessage() // { // Header = "复位提示", // Content = "请先点复位按钮,复位后再启动!" // }); // break; //} //workService.stationService_Dose.StationProp.bStopButtonTrigger = false; //workService.stationService_Dose.StationProp.bRunFinish = false; //workService.stationService_Dose.StationProp.bResetButtonTrigger = false; //workService.stationService_Dose.StationProp.bStartButtonTrigger = true; //BtnEnableState = false; //workService.ProjectPro.Dose_CT = string.Empty; if (workService.stationService_Dose.StationProp.deviceStatus != C00225155.Entities.DeviceStatus.CarryOn) { var result = workService.ValidateSampleBottle(); if (!result.isSuccess) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = result.msg }); return; } await workService.stationService_Dose.WriteCmdToPlc("start"); await workService.stationService_Dose.ChangeDeviceStatus(C00225155.Entities.DeviceStatus.Runing); } else { WeakReferenceMessenger.Default.Send(new AlertMessage() { Header = "提示", Content = "搬运过程中无法启动!" }); } break; case "Stop": //BtnEnableState = true; //workService.stationService_Dose.StationProp.bStopButtonTrigger = true; //WeakReferenceMessenger.Default.Send(new SingleBoolPeifangMessage(true)); WeakReferenceMessenger.Default.Send(new ConfirmMessage() { Header = "确认", Content = "确认是否结束!", OkButtonContent = "确认", CancelButtonContent = "取消", ClosedAction = new Action((bool? issuccess) => { if (issuccess != null && (bool)issuccess) { workService.stationService_Dose.ChangeDeviceStatus(C00225155.Entities.DeviceStatus.Abort); } }), }); break; case "Pause": if (workService.stationService_Dose.StationProp.deviceStatus == C00225155.Entities.DeviceStatus.CarryOn) { WeakReferenceMessenger.Default.Send(new AlertMessage() { Header = "提示", Content = "搬运过程中无法暂停!" }); break; } if (PauseContinueTipText == "暂停") { PauseContinueTipText = "继续"; await workService.stationService_Dose.ChangeDeviceStatus(C00225155.Entities.DeviceStatus.Pause); //workService.stationService_Dose.StationProp.ManualResetEvent.Reset(); await workService.stationService_Dose.WriteCmdToPlc("pause"); } else if (PauseContinueTipText == "继续") { PauseContinueTipText = "暂停"; await workService.stationService_Dose.ChangeDeviceStatus(C00225155.Entities.DeviceStatus.Runing); await workService.stationService_Dose.WriteCmdToPlc("start"); //workService.stationService_Dose.StationProp.ManualResetEvent.Set(); } break; case "Reset": await workService.stationService_Dose.WriteCmdToPlc("reset"); //workService.stationService_Dose.StationProp.bResetButtonTrigger = true; //workService.stationService_Dose.StationProp.bHaveReset = true; break; case "Init": await workService.stationService_Dose.WriteCmdToPlc("init"); break; } } }); ProjectCommand = new RelayCommand((obj) => { if (obj is string param) { switch (param) { case "OpenProject": //导入方案 OpenFileDialog dlgopen = new OpenFileDialog(); dlgopen.Filter = "pro文件(*.pro)|*.pro"; if (!Directory.Exists(Application.StartupPath + @"\Projects")) Directory.CreateDirectory(Application.StartupPath + @"\Projects"); dlgopen.InitialDirectory = Application.StartupPath + @"\Projects"; if (dlgopen.ShowDialog() == DialogResult.OK) { ProjectProperty project = new ProjectProperty(); bool readOk = false; project = File_Operator.Xml_Serialize(dlgopen.FileName, false, project, out readOk); if (readOk) { workService.ProjectPro = project; workService.ProjectPro.LastOpenProject = dlgopen.FileName; IniHelper.IniWrite(Application.StartupPath + "\\projectOpen.ini", "OpenProject", "LastOpenProject", dlgopen.FileName); workService.ProjectPro.NowOpenProjectFile = dlgopen.FileName.Substring(dlgopen.FileName.LastIndexOf("\\") + 1).Trim(); OnPropertyChanged(nameof(ProjectPro)); WeakReferenceMessenger.Default.Send(new DesktopAlertMessage { Content = "导入方案成功!" }); } } break; } } }); OpenPipetteManageWindowCommand = new RelayCommand((type) => { if (type == "1ml") { WeakReferenceMessenger.Default.Send(new ShowViewMessage(viewName: ViewNames.Pipette1mlWindow.ToString()) { ViewType = ViewType.Windows }); return; } WeakReferenceMessenger.Default.Send(new ShowViewMessage(viewName: ViewNames.Pipette5mlWindow.ToString()) { ViewType = ViewType.Windows }); }); } #region 手动加载工装事件 private void LoadBox() { if (SelectedBoxIndex < 1 || SelectedBoxIndex > 7) // 修正:位置是1-7,不是0-7 { MessageBox.Show("请先选择一个传送工装位置(1-7)!"); return; } if ( (SelectedBoxIndex != 6 && SelectedBoxIndex != 7) && (SelectedBoxType == BoxTypeEnum._125mL粉末瓶工装 || SelectedBoxType == BoxTypeEnum._16mL粉末瓶工装 || SelectedBoxType == BoxTypeEnum._1000uLTip头工装 || SelectedBoxType == BoxTypeEnum._300uLTip头工装 || SelectedBoxType == BoxTypeEnum._50uLTip头工装)) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "tip/粉末只能放在6-7号位置"}); return; } if (SelectedBoxType == BoxTypeEnum._40mL原液工装 && SelectedBoxIndex != 4 && SelectedBoxIndex != 5) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "40ML原液瓶只能放在4-5号位置" }); return; } if ((SelectedBoxType == BoxTypeEnum._5mL样品工装 || SelectedBoxType == BoxTypeEnum._12mL样品工装) && SelectedBoxIndex != 1 && SelectedBoxIndex != 2 && SelectedBoxIndex != 1 && SelectedBoxIndex != 3) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "5/12ML原液瓶只能放在1-3号位置" }); return; } // 计算集合索引(SelectedBoxIndex是1-7,集合索引0-6) int transferIndex = SelectedBoxIndex - 1; switch (SelectedBoxType) { case BoxTypeEnum._40mL原液工装: var liquidBox = new SourceLiquidBottleBoxModel { FixtureType = SelectedBoxType, BoxSNCode = string.Empty, SourceLiquidBottleCollection = File_Operator.DeepCopy(liquidlist), // 复制集合,避免共享引用 IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = liquidBox; // 直接替换集合元素 break; case BoxTypeEnum._12mL样品工装: var sampleList12mL = File_Operator.DeepCopy(samplelist); // 复制集合 foreach (var bottle in sampleList12mL) { bottle.SampleBottleType = SampleBottleTypeEnum._12mL; } var sampleBox12mL = new SampleBottleBoxModel { FixtureType = SelectedBoxType, BoxSNCode = string.Empty, SampleBottleList = sampleList12mL, IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = sampleBox12mL; break; case BoxTypeEnum._5mL样品工装: var sampleList5mL = File_Operator.DeepCopy(samplelist); // 复制集合 foreach (var bottle in sampleList5mL) { bottle.SampleBottleType = SampleBottleTypeEnum._5mL; // 修正:改为5mL } var sampleBox5mL = new SampleBottleBoxModel { FixtureType = SelectedBoxType, BoxSNCode = string.Empty, SampleBottleList = sampleList5mL, IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = sampleBox5mL; break; case BoxTypeEnum._16mL粉末瓶工装: var powderList16mL = File_Operator.DeepCopy(powderlist); // 复制集合 foreach (var bottle in powderList16mL) { bottle.PowderBottleType = PowderBottleTypeEnum._16mL; } var powderBox16mL = new SourcePowderBottleBoxModel { FixtureType = SelectedBoxType, BoxSNCode = string.Empty, SourcePowderBottleCollection = powderList16mL, IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = powderBox16mL; break; case BoxTypeEnum._125mL粉末瓶工装: var powderList125mL = File_Operator.DeepCopy(powderlist_125); foreach (var bottle in powderList125mL) { bottle.PowderBottleType = PowderBottleTypeEnum._125mL; } var powderBox125mL = new SourcePowderBottleBoxModel_125ml { FixtureType = SelectedBoxType, BoxSNCode = string.Empty, SourcePowderBottleCollection = powderList125mL, IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = powderBox125mL; break; // Tip头工装逻辑类似,统一复制集合,避免共享引用 case BoxTypeEnum._300uLTip头工装: var tipBox300UL = new TipBoxModel { FixtureType = SelectedBoxType, TipType = TipTypeEnum._300UL, BoxSNCode = string.Empty, TipItems = File_Operator.DeepCopy(tipHeadslist), IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, HaveBox = true, // 标记有工装 BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = tipBox300UL; break; case BoxTypeEnum._50uLTip头工装: var tipBox50UL = new TipBoxModel { FixtureType = SelectedBoxType, TipType = TipTypeEnum._50UL, BoxSNCode = string.Empty, TipItems = File_Operator.DeepCopy(tipHeadslist), IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, HaveBox = true, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = tipBox50UL; break; case BoxTypeEnum._1000uLTip头工装: var tipBox1000UL = new TipBoxModel { FixtureType = SelectedBoxType, TipType = TipTypeEnum._1000UL, BoxSNCode = string.Empty, TipItems = File_Operator.DeepCopy(tipHeadslist), IsDoseFinish = false, IsEmpty = false, IsUseFinsh = false, HaveBox = true, BoxId_inDoseUpload = SelectedBoxIndex, BoxArea = BoxAreaEnum._手套箱传送平台 }; workService.ProjectPro.TransferArea[transferIndex] = tipBox1000UL; break; } OnPropertyChanged(nameof(ProjectPro)); } private async Task ClearTransfer() { var clearData = new { isContinueLoad = true, isBSRequest = true }; for (int i = 0; i < 7; i++) { App.Current.Dispatcher.Invoke(() => { ProjectPro.TransferArea[i] = new BaseBottleBox() { IsEmpty = true, BoxId_inDoseDnload = i + 1, BoxId_inDoseUpload = i + 1, IsDoseFinish = false, IsUseFinsh = false, BoxArea = BoxAreaEnum._手套箱传送平台 }; }); } await workService.stationService_Dose.ChangeDeviceStatus(C00225155.Entities.DeviceStatus.Idel); } private async Task StartUnload() { await workService.stationService_Dose.ChangeDeviceStatus(C00225155.Entities.DeviceStatus.Finish); } private async Task<(bool res, string msg)> TransferIn() { (bool res, string msg) result = (true, ""); if (workService.stationService_Dose.StationProp.bStartButtonTrigger) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "运行中不能打开门" }); result.res = false; result.msg = "运行中不能打开门"; return result; } //await TransferPlateformMoveTo(PlateformPos.TransferIn, cancellationTokenSource.Token); await TransferPlateformMoveTo(PlateformPos.TransferIn, cancellationTokenSource.Token); return result; } private async Task<(bool res,string msg)> TransferOut() { //await workService.stationService_Dose.TestSuckVolume(new CancellationToken(), 200,false); //return (true,""); (bool res, string msg) result = (true, ""); if (workService.stationService_Dose.StationProp.bStartButtonTrigger) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "运行中不能打开门"}); result.res = false; result.msg = "运行中不能打开门"; return result; } //await TransferPlateformMoveTo(PlateformPos.TransferIn, cancellationTokenSource.Token); await TransferPlateformMoveTo(PlateformPos.TransferOut,cancellationTokenSource.Token); return result; } private async Task UploadBox() { if (SelectedBoxIndex < 0 || SelectedBoxIndex > 7) { MessageBox.Show("请先选择一个传送工装位置(1-7)!"); return; } await UploadBoxFromTransferPlateToHCBox(cancellationTokenSource.Token); OnPropertyChanged(nameof(ProjectPro)); } #endregion /// /// 从传动平台取工装到 治具缓存区 线程 /// /// /// private async Task UploadBoxFromTransferPlateToHCBox(CancellationToken token) { if (!workService.ProjectPro.bNoUseBS) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "请选择不启用BS!" }); return; } if (workService.stationService_Dose.StationProp.deviceStatus == C00225155.Entities.DeviceStatus.Runing) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "运行过程中不能上下料!" }); return; } //todo:手动料需要做数据校验 await workService.stationService_Dose.ChangeDeviceStatus( C00225155.Entities.DeviceStatus.CarryOn); await workService.stationService_Dose.StartLoad(); /*//弃用 if (workService.stationService_Dose.StationProp.bStartButtonTrigger) { WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "运行中不能搬运" }); return; } await TransferPlateformMoveTo(PlateformPos.TransferIn, cancellationTokenSource.Token); // 3. 粉末瓶:从粉末工装 → 粉末缓存区(逐个处理)先处理粉末,放置干涉 while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装)) && workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle)) { await TransferPlateformMoveTo(PlateformPos.GloveBox1, cancellationTokenSource.Token); var powderFixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装)); SourcePowderBottleBoxModel powderBox = null; SourcePowderBottleBoxModel_125ml powderBox_125 = null; if (powderFixture is SourcePowderBottleBoxModel) { powderBox = powderFixture as SourcePowderBottleBoxModel; } else if (powderFixture is SourcePowderBottleBoxModel_125ml) { powderBox_125 = powderFixture as SourcePowderBottleBoxModel_125ml; } if (powderBox == null && powderBox_125 == null) return; int powderTransferIndex = workService.ProjectPro.TransferArea.IndexOf(powderFixture); if (powderBox != null) { for (int i = 0; i < powderBox.SourcePowderBottleCollection.Count; i++) { // 处理每个有瓶的粉末瓶(只处理一个,避免一次搬多个) var powderBottle = powderBox.SourcePowderBottleCollection.FirstOrDefault(b => b.HaveBottle); if (powderBottle == null) continue; // 找到粉末缓存区的空位置 var aimPowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle); if (aimPowderBottle == null) { MessageBox.Show("粉末缓存区已满,无法继续上料!"); return; } int aimPowderIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(aimPowderBottle); // 执行机械手操作 await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture.BoxId_inDoseUpload, powderBottle.PosId_InBox, powderBox.PowderBottleType, token); await FourAxisGoToScannPos_powder(token, powderBottle); // 称重 await preWeight.Peel(); await FourAxisPutPowderHeaderToPreWeight(token); double powderWeight = await preWeight.ReadWeightValue(); powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_PreWeightFinish, 1); // 放入缓存区 await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox.PowderBottleType, token); // 更新粉末缓存区(替换集合元素) var newPowderBottle = File_Operator.DeepCopy(powderBottle); newPowderBottle.HaveBottle = true; newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC; workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle; // 标记原粉末瓶为空 var updatedBottle = powderBox.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox); updatedBottle.HaveBottle = false; } workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel() { BoxId_inDoseUpload = powderTransferIndex + 1, IsEmpty = true, IsDoseFinish = false, FixtureType = BoxTypeEnum._16mL粉末瓶工装, SourcePowderBottleCollection = powderlist, }; } else if (powderBox_125 != null) { for (int i = 0; i < powderBox_125.SourcePowderBottleCollection.Count; i++) { // 处理每个有瓶的粉末瓶(只处理一个,避免一次搬多个) var powderBottle = powderBox_125.SourcePowderBottleCollection.FirstOrDefault(b => b.HaveBottle); if (powderBottle == null) continue; // 找到粉末缓存区的空位置 var aimPowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle); if (aimPowderBottle == null) { MessageBox.Show("粉末缓存区已满,无法继续上料!"); return; } int aimPowderIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(aimPowderBottle); // 执行机械手操作 await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture.BoxId_inDoseUpload, powderBottle.PosId_InBox, powderBox.PowderBottleType, token); await FourAxisGoToScannPos_powder(token, powderBottle); // 称重 await FourAxisPutPowderHeaderToPreWeight(token); await preWeight.Peel(); double powderWeight = await preWeight.ReadWeightValue(); powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_PreWeightFinish, 1); // 放入缓存区 await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox.PowderBottleType, token); // 更新粉末缓存区(替换集合元素) var newPowderBottle = File_Operator.DeepCopy(powderBottle); newPowderBottle.HaveBottle = true; newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC; workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle; // 标记原粉末瓶为空 var updatedBottle = powderBox_125.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox); updatedBottle.HaveBottle = false; } workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel_125ml() { BoxId_inDoseUpload = powderTransferIndex + 1, IsEmpty = true, IsDoseFinish = false, FixtureType = BoxTypeEnum._125mL粉末瓶工装, SourcePowderBottleCollection = powderlist_125, }; } OnPropertyChanged(nameof(ProjectPro)); } // 4. Tip头工装:从传送平台 → Tip头区域 while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装)) && workService.ProjectPro.TipHeadArea.Any(f => !f.HaveBox && f.IsEmpty)) { await TransferPlateformMoveTo(PlateformPos.GloveBox2, cancellationTokenSource.Token); var tipFixture = workService.ProjectPro.TransferArea.First(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装)); int tipTransferIndex = workService.ProjectPro.TransferArea.IndexOf(tipFixture); // 找到Tip头区域的空位置 var aimTipBox = workService.ProjectPro.TipHeadArea.First(f => !f.HaveBox && f.IsEmpty); int aimTipIndex = workService.ProjectPro.TipHeadArea.IndexOf(aimTipBox); // 执行机械手操作 await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipFixture.FixtureType, (ushort)tipFixture.BoxId_inDoseUpload, token); await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipFixture.FixtureType, (ushort)aimTipBox.BoxId_inDosingStation, token); // 复制Tip头工装到Tip区域(替换集合元素) BaseBottleBox TipBox = File_Operator.DeepCopy(tipFixture); if (TipBox is TipBoxModel newTipBox) { newTipBox.BoxId_inDosingStation = aimTipBox.BoxId_inDosingStation; newTipBox.HaveBox = true; newTipBox.IsEmpty = false; newTipBox.IsUseFinsh = false; workService.ProjectPro.TipHeadArea[aimTipIndex] = newTipBox; // 关键:更新集合元素 } else { MessageBox.Show("error"); } // 重置传送平台 workService.ProjectPro.TransferArea[tipTransferIndex] = new BaseBottleBox() { IsEmpty = true, BoxId_inDoseUpload = tipFixture.BoxId_inDoseUpload, IsDoseFinish = false, IsUseFinsh = false, BoxArea = BoxAreaEnum._手套箱传送平台 }; OnPropertyChanged(nameof(ProjectPro)); } // 1. 样品工装:从传送平台 → 工装缓存区(排除1、5号位置) while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装)) && workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5)) { await TransferPlateformMoveTo(PlateformPos.GloveBox2, cancellationTokenSource.Token); // 找到传送平台中的样品工装(取第一个非空) var sampleFixture = workService.ProjectPro.TransferArea.First(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装)); int sampleTransferIndex = workService.ProjectPro.TransferArea.IndexOf(sampleFixture); // 获取集合索引 // 找到缓存区的空位置 var aimFixture = workService.ProjectPro.FixtureCacheArea.First(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5 && a.BoxId_inDosingStation != 2 && a.BoxId_inDosingStation != 6); int aimCacheIndex = workService.ProjectPro.FixtureCacheArea.IndexOf(aimFixture); // 获取集合索引 // 执行机械手操作(传入原工装类型,而非空工装类型) await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, sampleFixture.FixtureType, (ushort)sampleFixture.BoxId_inDoseUpload, token); await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, sampleFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, token); // 复制样品工装到缓存区(替换集合元素) var newCacheFixture = File_Operator.DeepCopy(sampleFixture); newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation; newCacheFixture.IsDoseFinish = false; newCacheFixture.IsEmpty = false; newCacheFixture.IsUseFinsh = false; workService.ProjectPro.FixtureCacheArea[aimCacheIndex] = newCacheFixture; // 重置传送平台位置为空工装 workService.ProjectPro.TransferArea[sampleTransferIndex] = new BaseBottleBox() { IsEmpty = true, BoxId_inDoseDnload = sampleFixture.BoxId_inDoseUpload, BoxId_inDoseUpload = sampleFixture.BoxId_inDoseUpload, IsDoseFinish = false, IsUseFinsh = false, BoxArea = BoxAreaEnum._手套箱传送平台 }; OnPropertyChanged(nameof(ProjectPro)); } // 2. 原液工装:从传送平台 → 工装缓存区(任意空位置 改为 0,4号位置) while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装) && workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && (a.BoxId_inDosingStation == 0 || a.BoxId_inDosingStation == 4))) { await TransferPlateformMoveTo(PlateformPos.GloveBox2, cancellationTokenSource.Token); var liquidFixture = workService.ProjectPro.TransferArea.First(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装); int liquidTransferIndex = workService.ProjectPro.TransferArea.IndexOf(liquidFixture); var aimFixture = workService.ProjectPro.FixtureCacheArea.First(a => a.IsEmpty && (a.BoxId_inDosingStation == 1 || a.BoxId_inDosingStation == 5)); //原液只能放置在1,5 int aimCacheIndex = workService.ProjectPro.FixtureCacheArea.IndexOf(aimFixture); // 执行机械手操作(传入原工装类型) await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, liquidFixture.FixtureType, (ushort)liquidFixture.BoxId_inDoseUpload, token); await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, liquidFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, token); // 复制原液工装到缓存区 var newCacheFixture = File_Operator.DeepCopy(liquidFixture); newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation; newCacheFixture.IsDoseFinish = false; newCacheFixture.IsEmpty = false; newCacheFixture.IsUseFinsh = false; workService.ProjectPro.FixtureCacheArea[aimCacheIndex] = newCacheFixture; // 重置传送平台 workService.ProjectPro.TransferArea[liquidTransferIndex] = new BaseBottleBox() { IsEmpty = true, BoxId_inDoseDnload = liquidFixture.BoxId_inDoseUpload, BoxId_inDoseUpload = liquidFixture.BoxId_inDoseUpload, IsDoseFinish = false, IsUseFinsh = false, BoxArea = BoxAreaEnum._手套箱传送平台 }; OnPropertyChanged(nameof(ProjectPro)); } await TransferPlateformMoveTo(PlateformPos.TransferIn, cancellationTokenSource.Token); //最终停留在这个位置最安全 // 无符合条件的工装可上料 if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty)) { MessageBox.Show("无可用工装或目标区域已满,无法上料!"); } */ } #region 四轴机械手 private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); public async Task WaitForActionFinishAsync_FourAxis(ushort point, ushort waitValue, CancellationToken token) { await _lockWaitSignal.WaitAsync(); try { ushort result = 0; do { result = this._modbusClient_Plc1.Command.ReadValue(point); await Task.Delay(300, token); } while (result != waitValue && !token.IsCancellationRequested); } catch (Exception) { throw; } finally { _lockWaitSignal.Release(); } } /// /// 四轴机械手取托盘 /// /// 目标区域编号 /// 托盘类型 /// 目标托盘位置号 /// /// private async Task FourAxisTakeBox(ushort aimarea, BoxTypeEnum boxType, ushort pos, CancellationToken token) { ///// 目标区域 ///// 1:手套箱传送平台; 2:Tip托盘存放平台;12:托盘存放平台; ///// //public readonly static ushort W_Robot_AimArea = 2202; ///// ///// 目标托盘位置号 ///// //public readonly static ushort W_Robot_AimAreaBoxPosid = 2203; ///// ///// 托盘类型:1:40mL瓶; 2:12mL瓶; 3:5mL瓶; 4:TIP头; ///// //public readonly static ushort W_Robot_BoxType = 2204; if (token.IsCancellationRequested) return; ushort fixtureType = 0; switch (boxType) { case BoxTypeEnum._40mL原液工装: fixtureType = 1; break; case BoxTypeEnum._12mL样品工装: fixtureType = 2; break; case BoxTypeEnum._5mL样品工装: fixtureType = 3; break; case BoxTypeEnum._50uLTip头工装: fixtureType = 4; break; case BoxTypeEnum._300uLTip头工装: fixtureType = 4; break; case BoxTypeEnum._1000uLTip头工装: fixtureType = 4; break; } this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, pos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, fixtureType); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 11); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 5, token); } /// /// 四轴机械手放托盘 /// /// 目标区域编号 /// 托盘类型 /// 目标托盘位置号 /// /// private async Task FourAxisPutBox(ushort aimarea, BoxTypeEnum boxType, ushort pos, CancellationToken token) { ///// 目标区域 ///// 1:手套箱传送平台; 2:Tip托盘存放平台;12:托盘存放平台; ///// //public readonly static ushort W_Robot_AimArea = 2202; ///// ///// 目标托盘位置号 ///// //public readonly static ushort W_Robot_AimAreaBoxPosid = 2203; ///// ///// 托盘类型:1:40mL瓶; 2:12mL瓶; 3:5mL瓶; 4:TIP头; ///// //public readonly static ushort W_Robot_BoxType = 2204; if (token.IsCancellationRequested) return; ushort fixtureType = 0; switch (boxType) { case BoxTypeEnum._40mL原液工装: fixtureType = 1; break; case BoxTypeEnum._12mL样品工装: fixtureType = 2; break; case BoxTypeEnum._5mL样品工装: fixtureType = 3; break; case BoxTypeEnum._50uLTip头工装: fixtureType = 4; break; case BoxTypeEnum._300uLTip头工装: fixtureType = 4; break; case BoxTypeEnum._1000uLTip头工装: fixtureType = 4; break; } this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, pos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, fixtureType); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 12); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 5, token); } private async Task TransferPlateformMoveTo(PlateformPos plateformPos, CancellationToken token) { await workService.stationService_Dose.TransferPlateformMoveTo(plateformPos, token); //if (token.IsCancellationRequested) return; //this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)plateformPos); ////等待PLC回复执行完成 //await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token); ////信号清零 //this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0); //await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token); } /// /// 四轴机械手取粉末加样头 /// /// 目标区域编号 /// 目标托盘号 /// 目标位置号 /// 粉末类型 /// /// private async Task FourAxisTakePowderHeader(int aimarea, int aimarea_box, int bottlepos, PowderBottleTypeEnum powderbottletype, CancellationToken token) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, (ushort)aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, (ushort)aimarea_box); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, (ushort)bottlepos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, powderbottletype == PowderBottleTypeEnum._16mL ? (ushort)1 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 1); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 5, token); } /// /// 四轴机械手放粉末加样头 /// /// /// /// /// /// /// private async Task FourAxisPutPowderHeader(int aimarea, int aimarea_box, int bottlepos, PowderBottleTypeEnum powderbottletype, CancellationToken token) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, (ushort)aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, (ushort)aimarea_box); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, (ushort)bottlepos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, powderbottletype == PowderBottleTypeEnum._16mL ? (ushort)1 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 2); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 5, token); } /// /// 四轴运行到粉末瓶扫码位置 /// /// 是否是粉末瓶子 /// /// private async Task FourAxisGoToScannPos_powder(CancellationToken token, SourcePowderBottleModel powderbottle) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 3); await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_ArriveSideScanPos, 1, token); //触发扫码 string snCode = await scannerService_Powder.ReadAsnyc(TimeSpan.FromSeconds(5)); powderbottle.SNCode = snCode; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_SideScanResult, 1); //回复扫码完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_ArriveSideScanPos, 0, token); //清除信号 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_SideScanResult, 0); await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 5, token); } private async Task FourAxisPutPowderHeaderToPreWeight(CancellationToken token) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 4); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 2); //等待PLC回复到预称重位 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_ArrivePreWeightPos, 1, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); } /// /// 四轴机械手拿液体瓶子 /// /// 目标区域编号 /// 目标托盘位置号 /// 目标孔编号 /// 瓶类型 /// /// private async Task FourAxisTakeLiquidBottle(CancellationToken token, int aimarea, int aimarea_box, int bottlepos, SourceLiquidBottleModel sourceLiquidBottle) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, (ushort)aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, (ushort)aimarea_box); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, (ushort)bottlepos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 1); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, sourceLiquidBottle.LiquidBottleLidState == SourceBottleLidStateEnum.Close ? (ushort)1 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 21); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); } /// /// 四轴机械手放液体瓶子 /// /// 目标区域编号 /// 目标托盘位置号 /// 目标孔编号 /// 瓶类型 /// /// private async Task FourAxisPutLiquidBottle(CancellationToken token, int aimarea, int aimarea_box, int bottlepos, SourceLiquidBottleModel sourceLiquidBottle) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, (ushort)aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, (ushort)aimarea_box); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, (ushort)bottlepos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 1); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, sourceLiquidBottle.LiquidBottleLidState == SourceBottleLidStateEnum.Close ? (ushort)1 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 22); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); } /// /// 四轴机械手取样品瓶子 /// /// 目标区域编号 /// 目标托盘位置号 /// 目标孔编号 /// 瓶类型 /// /// private async Task FourAxisTakeSampleBottle(CancellationToken token, int aimarea, int aimarea_box, int bottlepos, SampleBottleModel sampleBottle) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, (ushort)aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, (ushort)aimarea_box); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, (ushort)bottlepos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL ? (ushort)3 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, sampleBottle.SampleBottleLidState == SampleBottleLidStateEnum.Close ? (ushort)1 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 21); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); } /// /// 四轴机械手放样品瓶子 /// /// 目标区域编号 /// 目标托盘位置号 /// 目标孔编号 /// 瓶类型 /// /// private async Task FourAxisPutSampleBottle(CancellationToken token, int aimarea, int aimarea_box, int bottlepos, SampleBottleModel sampleBottle) { if (token.IsCancellationRequested) return; this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, (ushort)aimarea); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, (ushort)aimarea_box); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, (ushort)bottlepos); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL ? (ushort)3 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, sampleBottle.SampleBottleLidState == SampleBottleLidStateEnum.Close ? (ushort)1 : (ushort)2); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 22); //等待PLC回复执行完成 await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_Robot_RunResult, 22, token); //信号清零 this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param1, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param2, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param3, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param4, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_Param5, 0); this._modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_Robot_TaskNo, 0); } #endregion } }